diff --git a/bundles/action/org.openhab.action.astro/.classpath b/bundles/action/org.openhab.action.astro/.classpath new file mode 100644 index 00000000000..6d224cd3d0d --- /dev/null +++ b/bundles/action/org.openhab.action.astro/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/bundles/core/org.openhab.core.drools/.project b/bundles/action/org.openhab.action.astro/.project similarity index 83% rename from bundles/core/org.openhab.core.drools/.project rename to bundles/action/org.openhab.action.astro/.project index f23161b86d0..731a444e40f 100644 --- a/bundles/core/org.openhab.core.drools/.project +++ b/bundles/action/org.openhab.action.astro/.project @@ -1,7 +1,7 @@ - org.openhab.core.drools - This is the optional Drools rule engine of the open Home Automation Bus (openHAB) + org.openhab.action.astro + This is the ${binding-name} binding of the open Home Automation Bus (openHAB) diff --git a/bundles/action/org.openhab.action.astro/META-INF/MANIFEST.MF b/bundles/action/org.openhab.action.astro/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..a93fdc7dc44 --- /dev/null +++ b/bundles/action/org.openhab.action.astro/META-INF/MANIFEST.MF @@ -0,0 +1,28 @@ +Manifest-Version: 1.0 +Private-Package: org.openhab.action.astro.internal +Ignore-Package: org.openhab.action.astro.internal +Bundle-License: http://www.eclipse.org/legal/epl-v10.html +Bundle-Name: openHAB Astro Action +Bundle-SymbolicName: org.openhab.action.astro +Bundle-Vendor: openHAB.org +Bundle-Version: 1.7.0.qualifier +Bundle-Activator: org.openhab.action.astro.internal.AstroActivator +Bundle-ManifestVersion: 2 +Bundle-Description: This is the Astro action of the open Home Aut + omation Bus (openHAB) +Import-Package: org.apache.commons.lang.builder, + org.openhab.core.items, + org.openhab.core.library.items, + org.openhab.core.library.types, + org.openhab.core.scriptengine.action, + org.openhab.core.types, + org.osgi.framework, + org.osgi.service.cm, + org.osgi.service.component, + org.slf4j +Bundle-DocURL: http://www.openhab.org +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Service-Component: OSGI-INF/action.xml +Bundle-ClassPath: . +Bundle-ActivationPolicy: lazy +Require-Bundle: org.openhab.binding.astro diff --git a/bundles/action/org.openhab.action.astro/OSGI-INF/action.xml b/bundles/action/org.openhab.action.astro/OSGI-INF/action.xml new file mode 100644 index 00000000000..fc94d4cfda2 --- /dev/null +++ b/bundles/action/org.openhab.action.astro/OSGI-INF/action.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/bundles/action/org.openhab.action.astro/build.properties b/bundles/action/org.openhab.action.astro/build.properties new file mode 100644 index 00000000000..30f33af0ad2 --- /dev/null +++ b/bundles/action/org.openhab.action.astro/build.properties @@ -0,0 +1,6 @@ +source.. = src/main/java/,\ + src/main/resources/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/ +output.. = target/classes/ diff --git a/bundles/action/org.openhab.action.astro/pom.xml b/bundles/action/org.openhab.action.astro/pom.xml new file mode 100644 index 00000000000..ce1acc48bde --- /dev/null +++ b/bundles/action/org.openhab.action.astro/pom.xml @@ -0,0 +1,35 @@ + + + + + org.openhab.bundles + action + 1.7.0-SNAPSHOT + + + + org.openhab.action.astro + org.openhab.action.astro + openhab-addon-action-astro + openhab addon action astro + + + 4.0.0 + org.openhab.action + org.openhab.action.astro + + openHAB Astro Action + + eclipse-plugin + + + + + org.vafer + jdeb + + + + + diff --git a/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/Astro.java b/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/Astro.java new file mode 100644 index 00000000000..3ad0d82bb75 --- /dev/null +++ b/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/Astro.java @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.action.astro.internal; + +import java.util.Calendar; +import java.util.Date; + +import org.openhab.binding.astro.internal.calc.SunCalc; +import org.openhab.binding.astro.internal.model.Sun; +import org.openhab.core.scriptengine.action.ActionDoc; +import org.openhab.core.scriptengine.action.ParamDoc; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class provides static methods that can be used in automation rules for + * calculating astronomical data. + * + * @author Gerhard Riegler + * @since 1.7.0 + */ +public class Astro { + private static final Logger logger = LoggerFactory.getLogger(Astro.class); + + private static final SunCalc sunCalc = new SunCalc(); + // simple microcache + private static AstroConfig lastConfig; + private static Sun lastSun; + + @ActionDoc(text = "Returns the sunrise start for the given date and coordinates") + public static Calendar getAstroSunriseStart( + @ParamDoc(name = "date", text = "The date to calculate the sunrise") Date date, + @ParamDoc(name = "latitude", text = "The latitude") double latitude, + @ParamDoc(name = "longitude", text = "The longitude") double longitude) { + return getSun(date, latitude, longitude).getRise().getStart(); + } + + @ActionDoc(text = "Returns the sunrise end for the given date and coordinates") + public static Calendar getAstroSunriseEnd( + @ParamDoc(name = "date", text = "The date to calculate the sunrise") Date date, + @ParamDoc(name = "latitude", text = "The latitude") double latitude, + @ParamDoc(name = "longitude", text = "The longitude") double longitude) { + return getSun(date, latitude, longitude).getRise().getEnd(); + } + + @ActionDoc(text = "Returns the sunset start for the given date and coordinates") + public static Calendar getAstroSunsetStart( + @ParamDoc(name = "date", text = "The date to calculate the sunset") Date date, + @ParamDoc(name = "latitude", text = "The latitude") double latitude, + @ParamDoc(name = "longitude", text = "The longitude") double longitude) { + return getSun(date, latitude, longitude).getSet().getStart(); + } + + @ActionDoc(text = "Returns the sunset end for the given date and coordinates") + public static Calendar getAstroSunsetEnd( + @ParamDoc(name = "date", text = "The date to calculate the sunset") Date date, + @ParamDoc(name = "latitude", text = "The latitude") double latitude, + @ParamDoc(name = "longitude", text = "The longitude") double longitude) { + return getSun(date, latitude, longitude).getSet().getEnd(); + } + + /** + * Calculates the sun data. + */ + private static Sun getSun(Date date, double latitude, double longitude) { + if (date == null) { + logger.warn("Unknown date: {}, using current date", date); + date = new Date(); + } + AstroConfig config = new AstroConfig(date, latitude, longitude); + if (lastConfig == null || !lastConfig.equals(config)) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + lastSun = sunCalc.getSunInfo(cal, latitude, longitude); + lastConfig = config; + } + return lastSun; + } +} diff --git a/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/AstroActionService.java b/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/AstroActionService.java new file mode 100644 index 00000000000..9dd5c3bb9f9 --- /dev/null +++ b/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/AstroActionService.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.action.astro.internal; + +import org.openhab.core.scriptengine.action.ActionService; + +/** + * This class registers an OSGi service for the Astro action. + * + * @author Gerhard Riegler + * @since 1.7.0 + */ +public class AstroActionService implements ActionService { + + public void activate() { + } + + public void deactivate() { + } + + /** + * {@inheritDoc} + */ + @Override + public String getActionClassName() { + return Astro.class.getCanonicalName(); + } + + /** + * {@inheritDoc} + */ + @Override + public Class getActionClass() { + return Astro.class; + } + +} diff --git a/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/AstroActivator.java b/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/AstroActivator.java new file mode 100644 index 00000000000..43edf1fec0b --- /dev/null +++ b/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/AstroActivator.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.action.astro.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Extension of the default OSGi bundle activator + * + * @author Gerhard Riegler + * @since 1.7.0 + */ +public final class AstroActivator implements BundleActivator { + private static Logger logger = LoggerFactory.getLogger(AstroActivator.class); + + private static BundleContext context; + + /** + * Called whenever the OSGi framework starts our bundle + */ + public void start(BundleContext bc) throws Exception { + context = bc; + logger.debug("Astro action has been started."); + } + + /** + * Called whenever the OSGi framework stops our bundle + */ + public void stop(BundleContext bc) throws Exception { + context = null; + logger.debug("Astro action has been stopped."); + } + + /** + * Returns the bundle context of this bundle + * + * @return the bundle context + */ + public static BundleContext getContext() { + return context; + } + +} diff --git a/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/AstroConfig.java b/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/AstroConfig.java new file mode 100644 index 00000000000..d07561707a0 --- /dev/null +++ b/bundles/action/org.openhab.action.astro/src/main/java/org/openhab/action/astro/internal/AstroConfig.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.action.astro.internal; + +import java.util.Date; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * Holds the rule method parameters. + * + * @author Gerhard Riegler + * @since 1.7.0 + */ +public class AstroConfig { + private Date date; + private double latitude; + private double longitude; + + /** + * Creates a new AstroConfig. + */ + public AstroConfig(Date date, double latitude, double longitude) { + this.date = date; + this.latitude = latitude; + this.longitude = longitude; + } + + /** + * Returns the date to calculate astro data. + */ + public Date getDate() { + return date; + } + + /** + * The latitude to calculate astro data. + */ + public double getLatitude() { + return latitude; + } + + /** + * The longitude to calculate astro data. + */ + public double getLongitude() { + return longitude; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return new HashCodeBuilder().append(date).append(latitude).append(longitude).toHashCode(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof AstroConfig)) { + return false; + } + AstroConfig config = (AstroConfig) obj; + return new EqualsBuilder().append(date, config.getDate()).append(latitude, config.getLatitude()) + .append(longitude, config.getLongitude()).isEquals(); + } +} diff --git a/bundles/action/org.openhab.action.astro/src/main/resources/readme.txt b/bundles/action/org.openhab.action.astro/src/main/resources/readme.txt new file mode 100644 index 00000000000..98698c670dc --- /dev/null +++ b/bundles/action/org.openhab.action.astro/src/main/resources/readme.txt @@ -0,0 +1 @@ +Bundle resources go in here! \ No newline at end of file diff --git a/bundles/action/org.openhab.action.mail/src/main/java/org/openhab/action/mail/internal/Mail.java b/bundles/action/org.openhab.action.mail/src/main/java/org/openhab/action/mail/internal/Mail.java index d590327aa91..3a5246f625c 100644 --- a/bundles/action/org.openhab.action.mail/src/main/java/org/openhab/action/mail/internal/Mail.java +++ b/bundles/action/org.openhab.action.mail/src/main/java/org/openhab/action/mail/internal/Mail.java @@ -112,7 +112,10 @@ static public boolean sendMail( try { email.setFrom(from); - email.addTo(to); + String[] toList = to.split(";"); + for (String toAddress : toList){ + email.addTo(toAddress); + } if(!StringUtils.isEmpty(subject)) email.setSubject(subject); if(!StringUtils.isEmpty(message)) email.setMsg(message); email.send(); diff --git a/bundles/action/org.openhab.action.mios/.classpath b/bundles/action/org.openhab.action.mios/.classpath new file mode 100644 index 00000000000..6d224cd3d0d --- /dev/null +++ b/bundles/action/org.openhab.action.mios/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/bundles/action/org.openhab.action.mios/.project b/bundles/action/org.openhab.action.mios/.project new file mode 100644 index 00000000000..8686b1a7c00 --- /dev/null +++ b/bundles/action/org.openhab.action.mios/.project @@ -0,0 +1,33 @@ + + + org.openhab.action.mios + This is the ${binding-name} binding of the open Home Automation Bus (openHAB) + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/bundles/action/org.openhab.action.mios/META-INF/MANIFEST.MF b/bundles/action/org.openhab.action.mios/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..2ad1aaafcef --- /dev/null +++ b/bundles/action/org.openhab.action.mios/META-INF/MANIFEST.MF @@ -0,0 +1,28 @@ +Manifest-Version: 1.0 +Private-Package: org.openhab.action.mios.internal +Ignore-Package: org.openhab.action.mios.internal +Bundle-License: http://www.eclipse.org/legal/epl-v10.html +Bundle-Name: openHAB MiOS Action +Bundle-SymbolicName: org.openhab.action.mios +Bundle-Vendor: openHAB.org +Bundle-Version: 1.7.0.qualifier +Bundle-Activator: org.openhab.action.mios.internal.MiosActivator +Bundle-ManifestVersion: 2 +Bundle-Description: This is the MiOS action of the open Home Aut + omation Bus (openHAB) +Import-Package: org.openhab.core.items, + org.openhab.core.library.items, + org.openhab.core.library.types, + org.openhab.core.scriptengine.action, + org.openhab.core.types, + org.eclipse.xtext.xbase.lib, + org.osgi.framework, + org.osgi.service.cm, + org.osgi.service.component, + org.slf4j +Bundle-DocURL: http://www.openhab.org +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Service-Component: OSGI-INF/action.xml +Bundle-ClassPath: . +Bundle-ActivationPolicy: lazy +Require-Bundle: org.openhab.binding.mios;bundle-version="1.7.0" diff --git a/bundles/action/org.openhab.action.mios/OSGI-INF/action.xml b/bundles/action/org.openhab.action.mios/OSGI-INF/action.xml new file mode 100644 index 00000000000..426263b416a --- /dev/null +++ b/bundles/action/org.openhab.action.mios/OSGI-INF/action.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + diff --git a/bundles/action/org.openhab.action.mios/README.md b/bundles/action/org.openhab.action.mios/README.md new file mode 100644 index 00000000000..633f1e7a073 --- /dev/null +++ b/bundles/action/org.openhab.action.mios/README.md @@ -0,0 +1,65 @@ +Documentation for the MiOS Action Binding. + +# Introduction +This binding exposes openHAB Rule extensions to be used with the [MiOS Bridge Binding](https://github.com/openhab/openhab/wiki/MiOS-Binding). + +It exposes the ability to do the following things in the MiOS HA Controller from within [openHAB Rules](https://github.com/openhab/openhab/wiki/Rules): + +* `Device Actions` - Asynchronously invoke MiOS Device Actions involving 0, 1 or more parameters. +* `Scenes Invocation` - Asynchronously invoke MiOS Scenes + +The MiOS Action Binding depends upon the installation of the MiOS Bridge Binding, and need only be installed if the target deployment uses MiOS Action extensions in it's Rules. + +# Releases + +* 1.7.0 - First release + +# Configuration + +The MiOS Action Binding relies upon the MiOS Bridge Binding being installed and configured, and the installation of the MiOS Action Binding Bundle (JAR) file. Once these are done, you're ready to use the Rule extensions this bundle provides. + +# Extensions + +Add-on Actions - MiOS Action + +* `sendMiosAction(Item item, String action)` - requests the _parameterless_ Device Action, specified through `action`, be invoked on the MiOS Device bound to `item`. +* `sendMiosAction(Item item, String action, List<> params)` - as above, but for parameterized Device Actions. +* `sendMiosScene(Item scene)` - requests the scene associated with the `scene` parameter be invoked on the MiOS Unit. + +The `action` string, of the `sendMiosAction` extension, is a string of the form: + + / + +or + + / + +where _ServiceURN_, _ServiceAlias_ and _ServiceAction_ have the same form as decribed in [MiOS Bridge Binding](https://github.com/openhab/openhab/wiki/MiOS-Binding) commands. + +You can use the MiOS `invoke` URL to discover the _Actions_, and _Action-parameters_, your particular MiOS Device supports: + + http://:3480/data_request?id=invoke + +## Examples + +* Invoking a Device Action and calling a Scene to turn off the AV. +``` + rule "Test action rules Off" + when + Time cron "0 45 23 * * ?" + then + sendMiosAction(FamilyMainLightsId, "Dimmer/SetLoadLevelTarget", newArrayList('newLoadlevelTarget' -> 0)) + sendMiosScene(SceneGoodNight) + end +``` + +* Invoking a Sonos Device on MiOS to _say_ something +``` + rule "Test action say" + when + Item HallGarageDoorZoneTripped changed to OPEN + then + sendMiosAction(OfficeSonosId, "Sonos/Say", newArrayList('Text' -> 'Warning! Garage door opened', 'Volume' -> 50)) + end +``` + diff --git a/bundles/action/org.openhab.action.mios/build.properties b/bundles/action/org.openhab.action.mios/build.properties new file mode 100644 index 00000000000..30f33af0ad2 --- /dev/null +++ b/bundles/action/org.openhab.action.mios/build.properties @@ -0,0 +1,6 @@ +source.. = src/main/java/,\ + src/main/resources/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/ +output.. = target/classes/ diff --git a/bundles/action/org.openhab.action.mios/pom.xml b/bundles/action/org.openhab.action.mios/pom.xml new file mode 100644 index 00000000000..e4b26a9ddcb --- /dev/null +++ b/bundles/action/org.openhab.action.mios/pom.xml @@ -0,0 +1,35 @@ + + + + + org.openhab.bundles + action + 1.7.0-SNAPSHOT + + + + org.openhab.action.mios + org.openhab.action.mios + openhab-addon-action-mios + openHAB Action addon for MiOS + + + 4.0.0 + org.openhab.action + org.openhab.action.mios + + openHAB MiOS Action + + eclipse-plugin + + + + + org.vafer + jdeb + + + + + diff --git a/bundles/action/org.openhab.action.mios/src/main/java/org/openhab/action/mios/internal/MiosAction.java b/bundles/action/org.openhab.action.mios/src/main/java/org/openhab/action/mios/internal/MiosAction.java new file mode 100644 index 00000000000..20d1f3ef11b --- /dev/null +++ b/bundles/action/org.openhab.action.mios/src/main/java/org/openhab/action/mios/internal/MiosAction.java @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.action.mios.internal; + +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import org.eclipse.xtext.xbase.lib.Pair; +import org.openhab.binding.mios.MiosActionProvider; +import org.openhab.core.items.Item; +import org.openhab.core.scriptengine.action.ActionDoc; +import org.openhab.core.scriptengine.action.ParamDoc; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class provides static methods, for invocation of MiOS Action and Scene requests, for use in automation rules. + * + * @author Mark Clark + * @since 1.7.0 + */ +public class MiosAction { + + private static final Logger logger = LoggerFactory.getLogger(MiosAction.class); + + /** + * Sends an Action invocation to a Device at a MiOS Unit, without parameters. + */ + @ActionDoc(text = "Sends an Action invocation to a Device at a MiOS Unit, without parameters.") + public static boolean sendMiosAction( + @ParamDoc(name = "item", text = "The Item used to determine the MiOS Unit Address information for sending the Action call.") Item item, + @ParamDoc(name = "action", text = "The Action string to be remotely invoked on the MiOS Unit.") String actionName) { + + return sendMiosActionInternal(item.getName(), actionName, null); + } + + /** + * Sends an Action invocation to a Device at a MiOS Unit, with parameters. + */ + @ActionDoc(text = "Sends an Action invocation to a Device at a MiOS Unit, with parameters.") + public static boolean sendMiosAction( + @ParamDoc(name = "item", text = "The Item used to determine the MiOS Unit Address information for sending the Action call.") Item item, + @ParamDoc(name = "actionName", text = "The Action string to be remotely invoked on the MiOS Unit.") String actionName, + @ParamDoc(name = "params", text = "The list of Action Parameters.") List params) { + + return sendMiosActionInternal(item.getName(), actionName, params); + } + + /** + * Sends a Scene invocation to a MiOS Unit. + */ + @ActionDoc(text = "Sends a Scene invocation to a MiOS Unit.") + public static boolean sendMiosScene( + @ParamDoc(name = "item", text = "The Item used to determine the MiOS Unit Address information for sending the Action call.") Item item) { + + return sendMiosSceneInternal(item.getName()); + } + + private static MiosActionProvider getActionProviderInternal(String itemName) throws Exception { + MiosActionService service = MiosActionService.getMiosActionService(); + if (service == null) { + throw new Exception(String.format("MiOS Service is not configured, Action for Item %1$s not queued.", + itemName)); + } + + MiosActionProvider actionProvider = service.getMiosActionProvider(); + if (actionProvider == null) { + throw new Exception(String.format( + "MiOS Action Provider is not configured, Action for Item %1$s not queued.", itemName)); + } + + return actionProvider; + } + + private static boolean sendMiosActionInternal(String itemName, String actionName, List params) { + try { + logger.debug("Attempting to invoke MiOS Action {} using Item {} and {} Parameters", new Object[] { + actionName, itemName, (params == null) ? 0 : params.size() }); + ArrayList> paramList; + + // Convert from XText to the form needed to invoke MiOS. + if (params != null) { + paramList = new ArrayList>(params.size()); + + for (Pair p : params) { + logger.trace("Type of parameter key={} value={}", p.getKey(), p.getValue()); + paramList.add(new AbstractMap.SimpleImmutableEntry(p.getKey(), p.getValue())); + } + } else { + paramList = null; + } + + MiosActionProvider actionProvider = getActionProviderInternal(itemName); + + return actionProvider.invokeMiosAction(itemName, actionName, paramList); + } catch (Exception ex) { + logger.error(ex.getMessage(), ex); + return false; + } + } + + private static boolean sendMiosSceneInternal(String itemName) { + try { + logger.debug("Attempting to invoke MiOS Scene using Item {}", itemName); + + MiosActionProvider actionProvider = getActionProviderInternal(itemName); + + return actionProvider.invokeMiosScene(itemName); + } catch (Exception ex) { + logger.error(ex.getMessage(), ex); + return false; + } + } +} diff --git a/bundles/action/org.openhab.action.mios/src/main/java/org/openhab/action/mios/internal/MiosActionService.java b/bundles/action/org.openhab.action.mios/src/main/java/org/openhab/action/mios/internal/MiosActionService.java new file mode 100644 index 00000000000..102f42cdb13 --- /dev/null +++ b/bundles/action/org.openhab.action.mios/src/main/java/org/openhab/action/mios/internal/MiosActionService.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.action.mios.internal; + +import java.util.Dictionary; + +import org.openhab.binding.mios.MiosActionProvider; +import org.openhab.core.scriptengine.action.ActionService; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class registers an OSGi service for the MiOS Action. + * + * @author Mark Clark + * @since 1.7.0 + */ +public class MiosActionService implements ActionService, ManagedService { + + private static final Logger logger = LoggerFactory.getLogger(MiosActionService.class); + + private MiosActionProvider actionProvider; + private static MiosActionService service; + + public static MiosActionService getMiosActionService() { + return service; + } + + public void activate() { + logger.debug("MiOS action service activated"); + service = this; + } + + public void deactivate() { + logger.debug("MiOS action service activated"); + service = null; + } + + /** + * {@inheritDoc} + */ + @Override + public String getActionClassName() { + return getActionClass().getCanonicalName(); + } + + /** + * {@inheritDoc} + */ + @Override + public Class getActionClass() { + return MiosAction.class; + } + + /** + * {@inheritDoc} + */ + @Override + public void updated(Dictionary properties) throws ConfigurationException { + } + + /** + * Setter for use by OSGi injection. + * + * @param actionProvider the MiOS Action Provider (provided by the MiOS Binding). + */ + public void setMiosActionProvider(MiosActionProvider actionProvider) { + this.actionProvider = actionProvider; + logger.debug("MiOS setMiosActionProvider called"); + } + + /** + * Unsetter for use by OSGi injection. + * + * @param actionProvider MiOS Action Provider to remove. + */ + public void unsetMiosActionProvider(MiosActionProvider actionProvider) { + this.actionProvider = null; + logger.debug("MiOS unsetMiosActionProvider called"); + } + + /** + * Get the MiosActionProvider instance injected by OSGi. + * + * @return the MiOS Action Provider associated with this Action Service. + */ + public MiosActionProvider getMiosActionProvider() { + return this.actionProvider; + } +} diff --git a/bundles/action/org.openhab.action.mios/src/main/java/org/openhab/action/mios/internal/MiosActivator.java b/bundles/action/org.openhab.action.mios/src/main/java/org/openhab/action/mios/internal/MiosActivator.java new file mode 100644 index 00000000000..b004f730610 --- /dev/null +++ b/bundles/action/org.openhab.action.mios/src/main/java/org/openhab/action/mios/internal/MiosActivator.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.action.mios.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Extension of the default OSGi bundle activator. + * + * @author Mark Clark + * @since 1.7.0 + */ +public final class MiosActivator implements BundleActivator { + + private static Logger logger = LoggerFactory.getLogger(MiosActivator.class); + + private static BundleContext context; + + /** + * Called whenever the OSGi framework starts our bundle. + */ + public void start(BundleContext bc) throws Exception { + context = bc; + logger.debug("MiOS Action has been started."); + } + + /** + * Called whenever the OSGi framework stops our bundle. + */ + public void stop(BundleContext bc) throws Exception { + context = null; + logger.debug("MiOS Action has been stopped."); + } + + /** + * Returns the bundle context of this bundle. + * + * @return the bundle context. + */ + public static BundleContext getContext() { + return context; + } + +} diff --git a/bundles/action/org.openhab.action.mios/src/main/resources/readme.txt b/bundles/action/org.openhab.action.mios/src/main/resources/readme.txt new file mode 100644 index 00000000000..98698c670dc --- /dev/null +++ b/bundles/action/org.openhab.action.mios/src/main/resources/readme.txt @@ -0,0 +1 @@ +Bundle resources go in here! \ No newline at end of file diff --git a/bundles/action/org.openhab.action.tinkerforge/.classpath b/bundles/action/org.openhab.action.tinkerforge/.classpath new file mode 100644 index 00000000000..1e446acfc62 --- /dev/null +++ b/bundles/action/org.openhab.action.tinkerforge/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/bundles/action/org.openhab.action.tinkerforge/.project b/bundles/action/org.openhab.action.tinkerforge/.project new file mode 100644 index 00000000000..b34f2c11851 --- /dev/null +++ b/bundles/action/org.openhab.action.tinkerforge/.project @@ -0,0 +1,33 @@ + + + org.openhab.action.tinkerforge + This is the ${binding-name} binding of the open Home Automation Bus (openHAB) + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/bundles/action/org.openhab.action.tinkerforge/.settings/org.eclipse.jdt.core.prefs b/bundles/action/org.openhab.action.tinkerforge/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..f42de363afa --- /dev/null +++ b/bundles/action/org.openhab.action.tinkerforge/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/bundles/action/org.openhab.action.tinkerforge/META-INF/MANIFEST.MF b/bundles/action/org.openhab.action.tinkerforge/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..de877ff992b --- /dev/null +++ b/bundles/action/org.openhab.action.tinkerforge/META-INF/MANIFEST.MF @@ -0,0 +1,29 @@ +Manifest-Version: 1.0 +Private-Package: org.openhab.action.tinkerforge.internal +Ignore-Package: org.openhab.action.tinkerforge.internal +Bundle-License: http://www.eclipse.org/legal/epl-v10.html +Bundle-Name: openHAB TinkerForge Action +Bundle-SymbolicName: org.openhab.action.tinkerforge +Bundle-Vendor: openHAB.org +Bundle-Version: 1.7.0.qualifier +Bundle-Activator: org.openhab.action.tinkerforge.internal.TinkerForgeActivator +Bundle-ManifestVersion: 2 +Bundle-Description: This is the TinkerForge action of the open Home Aut + omation Bus (openHAB) +Import-Package: org.apache.commons.lang, + org.openhab.core.scriptengine.action, + org.openhab.core.items, + org.openhab.core.library.items, + org.openhab.core.library.types, + org.openhab.core.types, + org.osgi.framework, + org.osgi.service.cm, + org.osgi.service.component, + org.slf4j +Bundle-DocURL: http://www.openhab.org +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Service-Component: OSGI-INF/action.xml +Bundle-ClassPath: . +Bundle-ActivationPolicy: lazy +Require-Bundle: org.openhab.binding.tinkerforge;bundle-version="1.7.0", + org.eclipse.emf.ecore diff --git a/bundles/action/org.openhab.action.tinkerforge/OSGI-INF/action.xml b/bundles/action/org.openhab.action.tinkerforge/OSGI-INF/action.xml new file mode 100644 index 00000000000..d07712c79d4 --- /dev/null +++ b/bundles/action/org.openhab.action.tinkerforge/OSGI-INF/action.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + diff --git a/bundles/action/org.openhab.action.tinkerforge/build.properties b/bundles/action/org.openhab.action.tinkerforge/build.properties new file mode 100644 index 00000000000..30f33af0ad2 --- /dev/null +++ b/bundles/action/org.openhab.action.tinkerforge/build.properties @@ -0,0 +1,6 @@ +source.. = src/main/java/,\ + src/main/resources/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/ +output.. = target/classes/ diff --git a/bundles/action/org.openhab.action.tinkerforge/pom.xml b/bundles/action/org.openhab.action.tinkerforge/pom.xml new file mode 100644 index 00000000000..48a1ddb98dc --- /dev/null +++ b/bundles/action/org.openhab.action.tinkerforge/pom.xml @@ -0,0 +1,35 @@ + + + + + org.openhab.bundles + action + 1.7.0-SNAPSHOT + + + + org.openhab.action.tinkerforge + org.openhab.action.tinkerforge + openhab-addon-action-tinkerforge + openhab addon action for TinkerForge devices + + + 4.0.0 + org.openhab.action + org.openhab.action.tinkerforge + + openHAB TinkerForge Action + + eclipse-plugin + + + + + org.vafer + jdeb + + + + + diff --git a/bundles/action/org.openhab.action.tinkerforge/src/main/java/org/openhab/action/tinkerforge/internal/TinkerForge.java b/bundles/action/org.openhab.action.tinkerforge/src/main/java/org/openhab/action/tinkerforge/internal/TinkerForge.java new file mode 100644 index 00000000000..60b2c556902 --- /dev/null +++ b/bundles/action/org.openhab.action.tinkerforge/src/main/java/org/openhab/action/tinkerforge/internal/TinkerForge.java @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.action.tinkerforge.internal; + +import org.openhab.binding.tinkerforge.ecosystem.TinkerforgeContext; +import org.openhab.binding.tinkerforge.internal.model.MBaseDevice; +import org.openhab.binding.tinkerforge.internal.model.MBrickDC; +import org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4; +import org.openhab.binding.tinkerforge.internal.model.MServo; +import org.openhab.core.scriptengine.action.ActionDoc; +import org.openhab.core.scriptengine.action.ParamDoc; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * This class contains the methods that are made available in scripts and rules for TinkerForge. + * + * @author Theo Weiss + * @since 1.7.0 + */ +public class TinkerForge { + + private static final Logger logger = LoggerFactory.getLogger(TinkerForge.class); + private static TinkerforgeContext context = TinkerforgeContext.getInstance(); + + @ActionDoc(text = "clears a TinkerForge LCD", returns = "true, if successful and false otherwise.") + public static boolean tfClearLCD(@ParamDoc(name = "uid", text = "the device uid") String uid) { + if (context.getEcosystem() != null) { + MBaseDevice mDevice = context.getEcosystem().getDevice(uid, null); + if (mDevice instanceof MBrickletLCD20x4) { + return ((MBrickletLCD20x4) mDevice).clear(); + } else { + logger.error("no lcd device found with uid {}", uid); + return false; + } + } else { + logger.warn("ecosystem was null"); + return false; + } + } + + @ActionDoc(text = "sets the position of a TinkerForge servo", returns = "true, if successful and false otherwise.") + public static boolean tfServoSetposition(@ParamDoc(name = "uid", text = "servo uid") String uid, + @ParamDoc(name = "num", text = "servo number 0-6") String num, + @ParamDoc(name = "position", text = "servo postion -9000 - 9000") String position, + @ParamDoc(name = "velocity", text = "servo velocity") String velocity, + @ParamDoc(name = "acceleration", text = "servo acceleration") String acceleration) { + if (context.getEcosystem() != null) { + MBaseDevice mDevice = context.getEcosystem().getDevice(uid, num); + if (mDevice instanceof MServo) { + logger.trace("servo setPoint action"); + return ((MServo) mDevice).setPoint(Short.parseShort(position), Integer.parseInt(velocity), + Integer.parseInt(acceleration)); + } else { + logger.trace("no servo device found with uid {}, num {}", uid, num); + return false; + } + } else { + logger.error("Action failed ecosystem is null"); + } + return false; + + } + + @ActionDoc(text = "sets the speed of a TinkerForge DC motor", returns = "true, if successful and false otherwise.") + public static boolean tfDCMotorSetspeed( + @ParamDoc(name = "uid", text = "Brick DC uid") String uid, + @ParamDoc(name = "speed", text = "speed -32767 - 32767") Short speed, + @ParamDoc(name = "acceleration", text = "motor acceleration") Integer acceleration, + @ParamDoc(name = "drivemode", text = "drive mode \"break\" or \"coast\"") String drivemode) { + if (context.getEcosystem() != null) { + MBaseDevice mDevice = context.getEcosystem().getDevice(uid, null); + if (mDevice instanceof MBrickDC) { + logger.trace("servo setPoint action"); + return ((MBrickDC) mDevice).setSpeed(speed, acceleration, drivemode); + } else { + logger.trace("no Brick DC device found with uid {}, num {}", uid); + return false; + } + } else { + logger.error("Action failed ecosystem is null"); + } + return false; + + } + + @ActionDoc(text = "sets the speed of a TinkerForge DC motor", returns = "true, if successful and false otherwise.") + public static boolean tfDCMotorSetspeed( + @ParamDoc(name = "uid", text = "Brick DC uid") String uid, + @ParamDoc(name = "speed", text = "speed -32767 - 32767") String speed, + @ParamDoc(name = "acceleration", text = "motor acceleration") String acceleration, + @ParamDoc(name = "drivemode", text = "drive mode \"break\" or \"coast\"") String drivemode) { + if (context.getEcosystem() != null) { + MBaseDevice mDevice = context.getEcosystem().getDevice(uid, null); + if (mDevice instanceof MBrickDC) { + logger.trace("servo setPoint action"); + return ((MBrickDC) mDevice).setSpeed(Short.parseShort(speed), + Integer.parseInt(acceleration), drivemode); + } else { + logger.trace("no Brick DC device found with uid {}, num {}", uid); + return false; + } + } else { + logger.error("Action failed ecosystem is null"); + } + return false; + + } +} diff --git a/bundles/action/org.openhab.action.tinkerforge/src/main/java/org/openhab/action/tinkerforge/internal/TinkerForgeActionService.java b/bundles/action/org.openhab.action.tinkerforge/src/main/java/org/openhab/action/tinkerforge/internal/TinkerForgeActionService.java new file mode 100644 index 00000000000..71a7dd8791a --- /dev/null +++ b/bundles/action/org.openhab.action.tinkerforge/src/main/java/org/openhab/action/tinkerforge/internal/TinkerForgeActionService.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.action.tinkerforge.internal; + +import org.openhab.core.scriptengine.action.ActionService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * This class registers an OSGi service for the TinkerForge action. + * + * @author Theo Weiss + * @since 1.7.0 + */ +public class TinkerForgeActionService implements ActionService { + + private static final Logger logger = LoggerFactory.getLogger(TinkerForgeActionService.class); + + /** + * Indicates whether this action is properly configured which means all necessary configurations + * are set. This flag can be checked by the action methods before executing code. + */ + /* default */static boolean isProperlyConfigured = false; + + public TinkerForgeActionService() { + } + + public void activate() { + logger.debug("TinkerForge action activated"); + } + + public void deactivate() { + logger.debug("TinkerForge action deactivated"); + } + + @Override + public String getActionClassName() { + return TinkerForge.class.getCanonicalName(); + } + + @Override + public Class getActionClass() { + return TinkerForge.class; + } + +} diff --git a/bundles/action/org.openhab.action.tinkerforge/src/main/java/org/openhab/action/tinkerforge/internal/TinkerForgeActivator.java b/bundles/action/org.openhab.action.tinkerforge/src/main/java/org/openhab/action/tinkerforge/internal/TinkerForgeActivator.java new file mode 100644 index 00000000000..3aaedf9c150 --- /dev/null +++ b/bundles/action/org.openhab.action.tinkerforge/src/main/java/org/openhab/action/tinkerforge/internal/TinkerForgeActivator.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.action.tinkerforge.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Extension of the default OSGi bundle activator + * + * @author Theo Weiss + * @since 1.7.0 + */ +public final class TinkerForgeActivator implements BundleActivator { + + private static Logger logger = LoggerFactory.getLogger(TinkerForgeActivator.class); + + private static BundleContext context; + + /** + * Called whenever the OSGi framework starts our bundle + */ + public void start(BundleContext bc) throws Exception { + context = bc; + logger.debug("TinkerForge action has been started."); + } + + /** + * Called whenever the OSGi framework stops our bundle + */ + public void stop(BundleContext bc) throws Exception { + context = null; + logger.debug("TinkerForge action has been stopped."); + } + + /** + * Returns the bundle context of this bundle + * @return the bundle context + */ + public static BundleContext getContext() { + return context; + } + +} diff --git a/bundles/action/org.openhab.action.tinkerforge/src/main/resources/readme.txt b/bundles/action/org.openhab.action.tinkerforge/src/main/resources/readme.txt new file mode 100644 index 00000000000..98698c670dc --- /dev/null +++ b/bundles/action/org.openhab.action.tinkerforge/src/main/resources/readme.txt @@ -0,0 +1 @@ +Bundle resources go in here! \ No newline at end of file diff --git a/bundles/action/org.openhab.action.xmpp/.classpath b/bundles/action/org.openhab.action.xmpp/.classpath index fdc1f1f8f10..fd002f99727 100644 --- a/bundles/action/org.openhab.action.xmpp/.classpath +++ b/bundles/action/org.openhab.action.xmpp/.classpath @@ -8,7 +8,7 @@ - + diff --git a/bundles/action/org.openhab.action.xmpp/META-INF/MANIFEST.MF b/bundles/action/org.openhab.action.xmpp/META-INF/MANIFEST.MF index 6b4624ece51..1c300c89183 100644 --- a/bundles/action/org.openhab.action.xmpp/META-INF/MANIFEST.MF +++ b/bundles/action/org.openhab.action.xmpp/META-INF/MANIFEST.MF @@ -31,5 +31,5 @@ Bundle-ClassPath: ., lib/smack-resolver-javax-4.0.6.jar, lib/smack-tcp-4.0.6.jar, lib/xpp3-1.1.4c.jar, - lib/java-pinning-jar-1.0.0.jar + lib/java-pinning-jar-1.0.1.jar Bundle-ActivationPolicy: lazy diff --git a/bundles/action/org.openhab.action.xmpp/build.properties b/bundles/action/org.openhab.action.xmpp/build.properties index c831de74f73..49e1931651b 100644 --- a/bundles/action/org.openhab.action.xmpp/build.properties +++ b/bundles/action/org.openhab.action.xmpp/build.properties @@ -8,5 +8,5 @@ bin.includes = META-INF/,\ lib/smack-resolver-javax-4.0.6.jar,\ lib/smack-tcp-4.0.6.jar,\ lib/xpp3-1.1.4c.jar,\ - lib/java-pinning-jar-1.0.0.jar + lib/java-pinning-jar-1.0.1.jar output.. = target/classes/ diff --git a/bundles/action/org.openhab.action.xmpp/lib-src/java-pinning-jar-1.0.0-sources.jar b/bundles/action/org.openhab.action.xmpp/lib-src/java-pinning-jar-1.0.0-sources.jar deleted file mode 100644 index e5885123a9d..00000000000 Binary files a/bundles/action/org.openhab.action.xmpp/lib-src/java-pinning-jar-1.0.0-sources.jar and /dev/null differ diff --git a/bundles/action/org.openhab.action.xmpp/lib-src/java-pinning-jar-1.0.1-sources.jar b/bundles/action/org.openhab.action.xmpp/lib-src/java-pinning-jar-1.0.1-sources.jar new file mode 100644 index 00000000000..ae8c84f8e84 Binary files /dev/null and b/bundles/action/org.openhab.action.xmpp/lib-src/java-pinning-jar-1.0.1-sources.jar differ diff --git a/bundles/action/org.openhab.action.xmpp/lib/java-pinning-jar-1.0.0.jar b/bundles/action/org.openhab.action.xmpp/lib/java-pinning-jar-1.0.0.jar deleted file mode 100644 index 5aaf6b9a458..00000000000 Binary files a/bundles/action/org.openhab.action.xmpp/lib/java-pinning-jar-1.0.0.jar and /dev/null differ diff --git a/bundles/action/org.openhab.action.xmpp/lib/java-pinning-jar-1.0.1.jar b/bundles/action/org.openhab.action.xmpp/lib/java-pinning-jar-1.0.1.jar new file mode 100644 index 00000000000..ae4cf683524 Binary files /dev/null and b/bundles/action/org.openhab.action.xmpp/lib/java-pinning-jar-1.0.1.jar differ diff --git a/bundles/action/org.openhab.action.xmpp/src/main/java/org/openhab/action/xmpp/internal/XMPPConnect.java b/bundles/action/org.openhab.action.xmpp/src/main/java/org/openhab/action/xmpp/internal/XMPPConnect.java index 91bef4a862b..065542a3cd4 100644 --- a/bundles/action/org.openhab.action.xmpp/src/main/java/org/openhab/action/xmpp/internal/XMPPConnect.java +++ b/bundles/action/org.openhab.action.xmpp/src/main/java/org/openhab/action/xmpp/internal/XMPPConnect.java @@ -24,6 +24,8 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.tcp.XMPPTCPConnection; +import org.jivesoftware.smack.util.DNSUtil; +import org.jivesoftware.smack.util.dns.javax.JavaxResolver; import org.jivesoftware.smackx.muc.MultiUserChat; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedService; @@ -41,6 +43,12 @@ */ public class XMPPConnect implements ManagedService { + static { + // Workaround for SMACK-635. This can be removed once Smack 4.1 (or higher) is used + // See https://igniterealtime.org/issues/browse/SMACK-635 + DNSUtil.setDNSResolver(JavaxResolver.getInstance()); + } + static private final Logger logger = LoggerFactory.getLogger(XMPPConnect.class); diff --git a/bundles/action/org.openhab.action.xmpp/src/main/java/org/openhab/action/xmpp/internal/XMPPConsole.java b/bundles/action/org.openhab.action.xmpp/src/main/java/org/openhab/action/xmpp/internal/XMPPConsole.java index 8d0b680e4dd..c914c79bd70 100644 --- a/bundles/action/org.openhab.action.xmpp/src/main/java/org/openhab/action/xmpp/internal/XMPPConsole.java +++ b/bundles/action/org.openhab.action.xmpp/src/main/java/org/openhab/action/xmpp/internal/XMPPConsole.java @@ -61,7 +61,7 @@ public void chatCreated(Chat chat, boolean arg1) { public void processMessage(Chat chat, Message msg) { logger.debug("Received XMPP message: {} of type {}", msg.getBody(), msg.getType()); - if (msg.getType() == Message.Type.error) { + if (msg.getType() == Message.Type.error || msg.getBody() == null) { return; } String cmd = msg.getBody(); diff --git a/bundles/action/pom.xml b/bundles/action/pom.xml index d4cf9a5eaf1..b57671a5de8 100644 --- a/bundles/action/pom.xml +++ b/bundles/action/pom.xml @@ -28,7 +28,9 @@ org.openhab.action.homematic org.openhab.action.openwebif org.openhab.action.weather + org.openhab.action.mios + org.openhab.action.astro + org.openhab.action.tinkerforge - - + \ No newline at end of file diff --git a/bundles/archetype/org.openhab.archetype.binding/.project b/bundles/archetype/org.openhab.archetype.binding/.project index 07a7dc39353..6d41ff3cb51 100644 --- a/bundles/archetype/org.openhab.archetype.binding/.project +++ b/bundles/archetype/org.openhab.archetype.binding/.project @@ -10,6 +10,11 @@ + + org.eclipse.pde.ds.core.builder + + + org.eclipse.jdt.core.javanature diff --git a/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/META-INF/MANIFEST.MF b/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/META-INF/MANIFEST.MF index 0af1e22eed6..0feccf28aaf 100644 --- a/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/META-INF/MANIFEST.MF +++ b/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/META-INF/MANIFEST.MF @@ -6,7 +6,6 @@ Bundle-Name: openHAB ${binding-name} Binding Bundle-SymbolicName: ${artifactId} Bundle-Vendor: openHAB.org Bundle-Version: ${version}.qualifier -Bundle-Activator: ${artifactId}.internal.${binding-name}Activator Bundle-ManifestVersion: 2 Bundle-Description: This is the ${binding-name} binding of the open Home Aut omation Bus (openHAB) @@ -19,7 +18,6 @@ Import-Package: org.apache.commons.lang, org.openhab.core.types, org.openhab.model.item.binding, org.osgi.framework, - org.osgi.service.cm, org.osgi.service.component, org.osgi.service.event, org.slf4j diff --git a/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/OSGI-INF/binding.xml b/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/OSGI-INF/binding.xml index dc91d7275ab..19f6aabee60 100644 --- a/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/OSGI-INF/binding.xml +++ b/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/OSGI-INF/binding.xml @@ -13,16 +13,14 @@ $symbol_escape = '\' ) http://www.eclipse.org/legal/epl-v10.html --> - + - - implements ManagedService { +public class ${binding-name}Binding extends AbstractActiveBinding<${binding-name}BindingProvider> { private static final Logger logger = LoggerFactory.getLogger(${binding-name}Binding.class); + /** + * The BundleContext. This is only valid when the bundle is ACTIVE. It is set in the activate() + * method and must not be accessed anymore once the deactivate() method was called or before activate() + * was called. + */ + private BundleContext bundleContext; + /** * the refresh interval which is used to poll values from the ${binding-name} @@ -49,10 +55,55 @@ public class ${binding-name}Binding extends AbstractActiveBinding<${binding-name } - public void activate() { + /** + * Called by the SCR to activate the component with its configuration read from CAS + * + * @param bundleContext BundleContext of the Bundle that defines this component + * @param configuration Configuration properties for this component obtained from the ConfigAdmin service + */ + public void activate(final BundleContext bundleContext, final Map configuration) { + this.bundleContext = bundleContext; + + // the configuration is guaranteed not to be null, because the component definition has the + // configuration-policy set to require. If set to 'optional' then the configuration may be null + + + // to override the default refresh interval one has to add a + // parameter to openhab.cfg like :refresh= + String refreshIntervalString = (String) configuration.get("refresh"); + if (StringUtils.isNotBlank(refreshIntervalString)) { + refreshInterval = Long.parseLong(refreshIntervalString); + } + + // read further config parameters here ... + + setProperlyConfigured(true); + } + + /** + * Called by the SCR when the configuration of a binding has been changed through the ConfigAdmin service. + * @param configuration Updated configuration properties + */ + public void modified(final Map configuration) { + // update the internal configuration accordingly } - public void deactivate() { + /** + * Called by the SCR to deactivate the component when either the configuration is removed or + * mandatory references are no longer satisfied or the component has simply been stopped. + * @param reason Reason code for the deactivation:
+ *
    + *
  • 0 – Unspecified + *
  • 1 – The component was disabled + *
  • 2 – A reference became unsatisfied + *
  • 3 – A configuration was changed + *
  • 4 – A configuration was deleted + *
  • 5 – The component was disposed + *
  • 6 – The bundle was stopped + *
+ */ + public void deactivate(final int reason) { + this.bundleContext = null; // deallocate resources here that are no longer needed and // should be reset when activating this binding again } @@ -91,7 +142,7 @@ protected void internalReceiveCommand(String itemName, Command command) { // the code being executed when a command was sent on the openHAB // event bus goes here. This method is only called if one of the // BindingProviders provide a binding for the given 'itemName'. - logger.debug("internalReceiveCommand() is called!"); + logger.debug("internalReceiveCommand({},{}) is called!", itemName, command); } /** @@ -102,28 +153,7 @@ protected void internalReceiveUpdate(String itemName, State newState) { // the code being executed when a state was sent on the openHAB // event bus goes here. This method is only called if one of the // BindingProviders provide a binding for the given 'itemName'. - logger.debug("internalReceiveUpdate() is called!"); - } - - /** - * @{inheritDoc} - */ - @Override - public void updated(Dictionary config) throws ConfigurationException { - if (config != null) { - - // to override the default refresh interval one has to add a - // parameter to openhab.cfg like :refresh= - String refreshIntervalString = (String) config.get("refresh"); - if (StringUtils.isNotBlank(refreshIntervalString)) { - refreshInterval = Long.parseLong(refreshIntervalString); - } - - // read further config parameters here ... - - setProperlyConfigured(true); - } + logger.debug("internalReceiveUpdate({},{}) is called!", itemName, newState); } - } diff --git a/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/src/main/java/internal/__binding-name__GenericBindingProvider.java b/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/src/main/java/internal/__binding-name__GenericBindingProvider.java index 73a3039571c..a5b87211c88 100644 --- a/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/src/main/java/internal/__binding-name__GenericBindingProvider.java +++ b/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/src/main/java/internal/__binding-name__GenericBindingProvider.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2014, openHAB.org and others. + * Copyright (c) 2010-2015, openHAB.org and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -61,6 +61,12 @@ public void processBindingConfiguration(String context, Item item, String bindin } + /** + * This is a helper class holding binding specific configuration details + * + * @author ${author} + * @since ${version} + */ class ${binding-name}BindingConfig implements BindingConfig { // put member fields here which holds the parsed values } diff --git a/bundles/binding/org.openhab.binding.alarmdecoder/.classpath b/bundles/binding/org.openhab.binding.alarmdecoder/.classpath index 72b0a483155..f92b13310e0 100644 --- a/bundles/binding/org.openhab.binding.alarmdecoder/.classpath +++ b/bundles/binding/org.openhab.binding.alarmdecoder/.classpath @@ -3,6 +3,5 @@ - diff --git a/bundles/binding/org.openhab.binding.alarmdecoder/src/main/java/org/openhab/binding/alarmdecoder/internal/AlarmDecoderBinding.java b/bundles/binding/org.openhab.binding.alarmdecoder/src/main/java/org/openhab/binding/alarmdecoder/internal/AlarmDecoderBinding.java index 0c1fc576e1d..c86f287904f 100644 --- a/bundles/binding/org.openhab.binding.alarmdecoder/src/main/java/org/openhab/binding/alarmdecoder/internal/AlarmDecoderBinding.java +++ b/bundles/binding/org.openhab.binding.alarmdecoder/src/main/java/org/openhab/binding/alarmdecoder/internal/AlarmDecoderBinding.java @@ -360,7 +360,12 @@ private void parseKeypadMessage(String msg) throws MessageParseException { parts.get(0).length()); } try { - int numeric = Integer.parseInt(parts.get(1)); + int numeric = 0; + try { + numeric = Integer.parseInt(parts.get(1)); + } catch (NumberFormatException e) { + numeric = Integer.parseInt(parts.get(1), 16); + } int upper = Integer.parseInt(parts.get(0).substring(1,6), 2); int nbeeps = Integer.parseInt(parts.get(0).substring(6,7)); int lower = Integer.parseInt(parts.get(0).substring(7,17), 2); diff --git a/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelBinding.java b/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelBinding.java index 28e5f139314..86c0881af97 100644 --- a/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelBinding.java +++ b/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelBinding.java @@ -39,7 +39,7 @@ public class AnelBinding extends AbstractActiveBinding impl * Delay before first initial refresh call for initialization (required at * any time after startup to make sure everything else is initialized). */ - private static final int THREAD_INITIALIZATION_DELAY = 30000; + private static final int THREAD_INITIALIZATION_DELAY = 60000; /** Interruption timeout when disconnecting all threads. */ private static final int THREAD_INTERRUPTION_TIMEOUT = 5000; @@ -54,12 +54,14 @@ static interface IInternalAnelBinding { /** * Get all item names that are registered for the given command type. * + * @param device + * The device name for which items should be searched. * @param cmd * A command type. * @return All item names that are registered for the given command * type. */ - Collection getItemNamesForCommandType(AnelCommandType cmd); + Collection getItemNamesForCommandType(String device, AnelCommandType cmd); /** * Connectors should use this to send updates to the event bus. @@ -84,8 +86,8 @@ static interface IInternalAnelBinding { private final IInternalAnelBinding bindingFacade = new IInternalAnelBinding() { @Override - public Collection getItemNamesForCommandType(AnelCommandType cmd) { - return AnelBinding.this.getItemNamesForCommandType(cmd); + public Collection getItemNamesForCommandType(String device, AnelCommandType cmd) { + return AnelBinding.this.getItemNamesForCommandType(device, cmd); } @Override @@ -269,15 +271,20 @@ public void run() { }).start(); } - private Collection getItemNamesForCommandType(AnelCommandType cmd) { + private Collection getItemNamesForCommandType(String device, AnelCommandType cmd) { if (cmd == null) return Collections.emptyList(); final Set itemNames = new HashSet(); for (final AnelBindingProvider provider : providers) { + // for each provider, check all items for (final String itemName : provider.getItemNames()) { - final AnelCommandType commandType = provider.getCommandType(itemName); - if (commandType.equals(cmd)) { - itemNames.add(itemName); + // we only want to collect items for our device + if (device.equals(provider.getDeviceId(itemName))) { + final AnelCommandType commandType = provider.getCommandType(itemName); + // if the item type matches, item should be returned + if (commandType.equals(cmd)) { + itemNames.add(itemName); + } } } } diff --git a/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelConfigReader.java b/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelConfigReader.java index 58b59a46da9..4b71ae33995 100644 --- a/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelConfigReader.java +++ b/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelConfigReader.java @@ -135,7 +135,7 @@ static long readConfig(Dictionary config, Map - // Format to switch off: Sw_off - // Example: Sw_on3adminanel - final String cmd = "Sw_" + (newState ? "on" : "off") + switchNr + user + password; - logger.debug("Sending to " + state.host + ": " + cmd); - try { - connector.sendDatagram(cmd.getBytes()); - } catch (Exception e) { - logger.error("Error occured when sending UDP data to Anel device: " + cmd, e); - } - } else { - logger.debug("switch " + switchNr + " is locked, nothing sent."); + // check that this switch is not locked! + if (switchLocked != null) { + if (!switchLocked) { + + // Format to switch on: Sw_on + // Format to switch off: Sw_off + // Example: Sw_on3adminanel + final String cmd = "Sw_" + (newState ? "on" : "off") + switchNr + user + password; + logger.debug("Sending to " + connector.host + ":" + connector.receivePort + " -> " + cmd); + try { + connector.sendDatagram(cmd.getBytes()); + } catch (Exception e) { + logger.error("Error occured when sending UDP data to Anel device: " + cmd, e); } } else { - logger.debug("switch " + switchNr + " lock state not yet initialized, nothing sent."); + logger.debug("switch " + switchNr + " is locked, nothing sent."); } } else { - logger.debug("switch " + switchNr + " has already the requested state " + (newState ? "ON" : "OFF") - + ", nothing sent."); + logger.debug("switch " + switchNr + " lock state not yet initialized, nothing sent."); } } @@ -150,33 +155,32 @@ protected void sendIO(int ioNr, boolean newState) { } // check via Boolean object because current state may be null - if (!Boolean.valueOf(newState).equals(ioState)) { - - // check whether IO is of direction output - if (isInput == null || !isInput) { - logger.warn("Attempted to change IO" + ioNr + " to " + (newState ? "ON" : "OFF") - + " but it's direction is " + (isInput == null ? "unknown" : "input")); - return; // better not send anything if direction is not - // 'out' - } + if (Boolean.valueOf(newState).equals(ioState)) { + logger.debug("IO " + ioNr + " has already the requested state " + (newState ? "ON" : "OFF") + + ", but sending update anyway."); + } - // Format to switch on: IO_on - // Format to switch off: IO_off - // Example: IO_on3adminanel - final String cmd = "IO_" + (newState ? "on" : "off") + ioNr + user + password; - logger.debug("Sending to " + state.host + ": " + cmd); - try { - connector.sendDatagram(cmd.getBytes()); - } catch (Exception e) { - if (e.getCause() instanceof UnknownHostException) { - logger.error("Could not check status of Anel device '" + state.host + "'"); - } else { - logger.error("Error occured when sending UDP data to Anel device: " + cmd, e); - } + // check whether IO is of direction output + if (isInput == null || !isInput) { + logger.warn("Attempted to change IO" + ioNr + " to " + (newState ? "ON" : "OFF") + + " but it's direction is " + (isInput == null ? "unknown" : "input")); + return; // better not send anything if direction is not + // 'out' + } + + // Format to switch on: IO_on + // Format to switch off: IO_off + // Example: IO_on3adminanel + final String cmd = "IO_" + (newState ? "on" : "off") + ioNr + user + password; + logger.debug("Sending to " + state.host + ": " + cmd); + try { + connector.sendDatagram(cmd.getBytes()); + } catch (Exception e) { + if (e.getCause() instanceof UnknownHostException) { + logger.error("Could not check status of Anel device '" + state.host + "'"); + } else { + logger.error("Error occured when sending UDP data to Anel device: " + cmd, e); } - } else { - logger.debug("IO " + ioNr + " has already the requested state " + (newState ? "ON" : "OFF") - + ", nothing sent."); } } @@ -246,13 +250,13 @@ public void run() { // updates are only needed if commands have been parsed if (newValues != null && !newValues.isEmpty()) { - logger.debug("newValues (len={}): {}", newValues.size(), newValues); + logger.debug("newValues ({}, len={}): {}", this.connector.host, newValues.size(), newValues); // get all item names and post updates to event bus for (AnelCommandType cmd : newValues.keySet()) { final org.openhab.core.types.State state = newValues.get(cmd); - final Collection itemNames = binding.getItemNamesForCommandType(cmd); + final Collection itemNames = binding.getItemNamesForCommandType(device, cmd); for (String itemName : itemNames) { binding.postUpdateToEventBus(itemName, state); } diff --git a/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelDataParser.java b/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelDataParser.java index 7a42c1285cf..a67b3db6791 100644 --- a/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelDataParser.java +++ b/bundles/binding/org.openhab.binding.anel/src/main/java/org/openhab/binding/anel/internal/AnelDataParser.java @@ -9,7 +9,7 @@ package org.openhab.binding.anel.internal; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.regex.Pattern; @@ -48,7 +48,16 @@ public class AnelDataParser { *
  • 24. <temperature> *
  • 25. <firmware version> (may contain trailing line break) * - * Source: http://www.anel-elektronik.de/forum_new/viewtopic.php?f=16&t=207 + * Source: Anel forum (German) + *

    + * It turned out that the HOME variant has a different format which contains + * only the first 16 segments. If that is the case, the remaining fields of + * {@link AnelState} are simply ignored (and remain unset). + *

    + * Source: Issue + * 2068 * * @param data * The data received from {@link AnelUDPConnector}. @@ -62,15 +71,15 @@ public static Map parseData(byte[] data, AnelState state final String string = new String(data); final String[] arr = string.split(":"); - if (arr.length != 26) - throw new IllegalArgumentException("Data with 26 values expected but " + arr.length + " received: " + if (arr.length != 26 && arr.length != 16) + throw new IllegalArgumentException("Data with 16 or 26 values expected but " + arr.length + " received: " + string); if (!arr[0].equals("NET-PwrCtrl")) throw new IllegalArgumentException("Data must start with 'NET-PwrCtrl' but it didn't: " + arr[0]); if (!state.host.equals(arr[2]) && !state.host.equalsIgnoreCase(arr[1].trim())) return Collections.emptyMap(); // this came from another device - final Map result = new HashMap(); + final Map result = new LinkedHashMap(); // check for switch changes, update cached state, and prepare command if // needed @@ -89,29 +98,33 @@ public static Map parseData(byte[] data, AnelState state addCommand(state.switchLocked, nr, (locked & (1 << nr)) > 0, "F" + (nr + 1) + "LOCKED", result); } - // check for IO changes, update cached state, and prepare commands if - // needed - for (int nr = 0; nr < 8; nr++) { - final String[] ioState = arr[16 + nr].split(","); - if (ioState.length == 3) { - // expected format - addCommand(state.ioName, nr, ioState[0], "IO" + (nr + 1) + "NAME", result); - addCommand(state.ioIsInput, nr, "1".equals(ioState[1]), "IO" + (nr + 1) + "ISINPUT", result); - addCommand(state.ioState, nr, "1".equals(ioState[2]), "IO" + (nr + 1), result); - } else { - // unexpected format, set states to null - addCommand(state.ioName, nr, null, "IO" + (nr + 1) + "NAME", result); - addCommand(state.ioIsInput, nr, null, "IO" + (nr + 1) + "ISINPUT", result); - addCommand(state.ioState, nr, null, "IO" + (nr + 1), result); + // IO and temperature is only available if array has length 24 + if (arr.length > 16) { + + // check for IO changes, update cached state, and prepare commands + // if needed + for (int nr = 0; nr < 8; nr++) { + final String[] ioState = arr[16 + nr].split(","); + if (ioState.length == 3) { + // expected format + addCommand(state.ioName, nr, ioState[0], "IO" + (nr + 1) + "NAME", result); + addCommand(state.ioIsInput, nr, "1".equals(ioState[1]), "IO" + (nr + 1) + "ISINPUT", result); + addCommand(state.ioState, nr, "1".equals(ioState[2]), "IO" + (nr + 1), result); + } else { + // unexpected format, set states to null + addCommand(state.ioName, nr, null, "IO" + (nr + 1) + "NAME", result); + addCommand(state.ioIsInput, nr, null, "IO" + (nr + 1) + "ISINPUT", result); + addCommand(state.ioState, nr, null, "IO" + (nr + 1), result); + } } - } - // example temperature string: '26.4°C' - // '°' is caused by some different encoding, so cut last 2 chars - final String temperature = arr[24].substring(0, arr[24].length() - 2); - if (hasTemperaturChanged(state, temperature)) { - result.put(AnelCommandType.TEMPERATURE, new DecimalType(temperature)); - state.temperature = temperature; + // example temperature string: '26.4°C' + // '°' is caused by some different encoding, so cut last 2 chars + final String temperature = arr[24].substring(0, arr[24].length() - 2); + if (hasTemperaturChanged(state, temperature)) { + result.put(AnelCommandType.TEMPERATURE, new DecimalType(temperature)); + state.temperature = temperature; + } } // maybe the device's name changed?! diff --git a/bundles/binding/org.openhab.binding.astro/.classpath b/bundles/binding/org.openhab.binding.astro/.classpath index c0d42c11aed..debbc3ff382 100644 --- a/bundles/binding/org.openhab.binding.astro/.classpath +++ b/bundles/binding/org.openhab.binding.astro/.classpath @@ -3,7 +3,6 @@ - diff --git a/bundles/binding/org.openhab.binding.astro/META-INF/MANIFEST.MF b/bundles/binding/org.openhab.binding.astro/META-INF/MANIFEST.MF index 17ce071a208..288151b5e10 100644 --- a/bundles/binding/org.openhab.binding.astro/META-INF/MANIFEST.MF +++ b/bundles/binding/org.openhab.binding.astro/META-INF/MANIFEST.MF @@ -34,4 +34,6 @@ Bundle-DocURL: http://www.openhab.org Service-Component: OSGI-INF/binding.xml, OSGI-INF/genericbindingprovider.xml Bundle-ClassPath: . Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Export-Package: org.openhab.binding.astro.internal.calc, + org.openhab.binding.astro.internal.model diff --git a/bundles/binding/org.openhab.binding.bticino/src/main/java/be/devlaminck/openwebnet/MonitorSessionThread.java b/bundles/binding/org.openhab.binding.bticino/src/main/java/be/devlaminck/openwebnet/MonitorSessionThread.java index ac94c334f8d..1a39ab7696d 100644 --- a/bundles/binding/org.openhab.binding.bticino/src/main/java/be/devlaminck/openwebnet/MonitorSessionThread.java +++ b/bundles/binding/org.openhab.binding.bticino/src/main/java/be/devlaminck/openwebnet/MonitorSessionThread.java @@ -23,7 +23,7 @@ * openwebnet) and on code of Flavio Fcrisciani * (https://github.com/fcrisciani/java-myhome-library) released under EPL * - * @author Tom De Vlaminck + * @author Tom De Vlaminck, Lago Moreno * @serial 1.0 * @since 1.7.0 */ @@ -66,7 +66,7 @@ public MonitorSessionThread(OpenWebNet pluginReference, String ipAddress, public void buildEventFromFrame(String frame) { logger.info("Received OpenWebNet frame '" + frame - + "' now translate it to an event."); + + "' now translate it to an event."); String who = null; String what = null; String where = null; @@ -77,8 +77,13 @@ public void buildEventFromFrame(String frame) { String[] frameParts = null; ProtocolRead event = null; + if (frame.isEmpty()) { + logger.error("Empty frame"); + return; + } + int length = frame.length(); - if (frame.isEmpty() || !frame.endsWith("##")) { + if (!frame.endsWith("##")) { logger.error("Malformed frame " + frame + " " + frame.substring(length - 2, length)); return; @@ -94,6 +99,7 @@ public void buildEventFromFrame(String frame) { return; } + // Status request frame if (frame.substring(0, 2).equalsIgnoreCase("*#")) { // remove *# and ## frame = frame.substring(2, length - 2); @@ -194,12 +200,12 @@ public void buildEventFromFrame(String frame) { } // TERMOREGULATION if (who.equalsIgnoreCase("4")) { + messageType = "thermoregulation"; objectClass = "Thermo"; objectName = who + "*" + where; - String temperature = null; if (frameParts[2].equalsIgnoreCase("0")) { - temperature = frameParts[3]; + String temperature = frameParts[3]; temperature = OWNUtilities.convertTemperature(temperature); messageDescription = "Temperature value"; if (temperature != null) { @@ -407,9 +413,12 @@ public void buildEventFromFrame(String frame) { // notify event logger.info(OWNUtilities.getDateTime() + " Rx: " + frame + " " + "(" + messageDescription + ")"); - + + // Notify all the listeners an event has been received + pluginReference.notifyEvent(event); } + // Command frame if (!(frame.substring(0, 2).equalsIgnoreCase("*#")) && (frame.substring(0, 1).equalsIgnoreCase("*"))) { // remove delimiter chars * and ## @@ -425,15 +434,8 @@ public void buildEventFromFrame(String frame) { where = ""; event = new ProtocolRead(frame); objectName = who + "*" + where; - - // Virtual configurator support - // where=XXYY (XX = A (01-10), YY = PL (01-15)) - // eg. A=10 and PL=5 the where will be 1005, A=2 and PL=12 the where - // will be 0212 - // split in parts, if 2 parts with riser - // todo - boolean virtual_where = (where.length() == 4); - + boolean virtual_where = false; + String[] what_parts; switch (Integer.parseInt(who)) { // LIGHTING case 1: @@ -442,11 +444,12 @@ public void buildEventFromFrame(String frame) { // For virtual configuration we receive for light on 1000#1 // so assuming the second part is the what - if (virtual_where) { - String[] what_parts = what.split("#"); - // take the last part for the what - what = what_parts[what_parts.length - 1]; - } + what_parts = what.split("#"); + if (what_parts.length > 1) { + virtual_where = true; + // take the last part for the what + what = what_parts[what_parts.length - 1]; + } switch (Integer.parseInt(what)) { // Light OFF @@ -507,7 +510,7 @@ public void buildEventFromFrame(String frame) { // THERMOREGULATION case 4: messageType = "thermoregulation"; - objectClass = "Temperature"; + objectClass = "Thermo"; switch (Integer.parseInt(what)) { case 0: @@ -680,7 +683,7 @@ public void buildEventFromFrame(String frame) { messageType = "CEN Basic and Evolved"; objectClass = "CEN"; - String[] what_parts = what.split("#"); + what_parts = what.split("#"); if (what_parts.length == 1) { // type of pressure @@ -725,11 +728,10 @@ public void buildEventFromFrame(String frame) { if (objectName != null) { event.addProperty("object.name", objectName); } - logger.info("Frame " + frame + " is " + messageType - + " message. Notify it as OpenHab event " - + messageDescription == "No Description set" ? "" - : messageDescription); // for debug + + " message. Notify it as OpenHab event " + + messageDescription == "No Description set" ? "" + : messageDescription); // for debug // Notify all the listeners an event has been received pluginReference.notifyEvent(event); diff --git a/bundles/binding/org.openhab.binding.bticino/src/main/java/org/openhab/binding/bticino/internal/BticinoDevice.java b/bundles/binding/org.openhab.binding.bticino/src/main/java/org/openhab/binding/bticino/internal/BticinoDevice.java index 3204258e1e6..75aa6da3fc3 100644 --- a/bundles/binding/org.openhab.binding.bticino/src/main/java/org/openhab/binding/bticino/internal/BticinoDevice.java +++ b/bundles/binding/org.openhab.binding.bticino/src/main/java/org/openhab/binding/bticino/internal/BticinoDevice.java @@ -17,8 +17,10 @@ import org.openhab.binding.bticino.internal.BticinoGenericBindingProvider.BticinoBindingConfig; import org.openhab.core.events.EventPublisher; import org.openhab.core.items.Item; +import org.openhab.core.library.items.NumberItem; import org.openhab.core.library.items.RollershutterItem; import org.openhab.core.library.items.SwitchItem; +import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.StopMoveType; import org.openhab.core.library.types.UpDownType; @@ -284,7 +286,19 @@ else if (p_protocol_read.getProperty("messageType") UpDownType.DOWN); } } + } else if (l_item instanceof NumberItem) { + logger.debug("Gateway [" + m_gateway_id + "], RECEIVED EVENT FOR NumberItem [" + l_item.getName() + "], TRANSLATE TO OPENHAB BUS EVENT"); + + // THERMOREGULATION + if (p_protocol_read.getProperty("messageType") + .equalsIgnoreCase("thermoregulation")) { + + if (p_protocol_read.getProperty("messageDescription") + .equalsIgnoreCase("Temperature value")) { + eventPublisher.postUpdate(l_item.getName(), DecimalType.valueOf(p_protocol_read.getProperty("temperature"))); + } + } } } } -} \ No newline at end of file +} diff --git a/bundles/binding/org.openhab.binding.bticino/src/main/java/org/openhab/binding/bticino/internal/BticinoGenericBindingProvider.java b/bundles/binding/org.openhab.binding.bticino/src/main/java/org/openhab/binding/bticino/internal/BticinoGenericBindingProvider.java index c3cba908e38..e08b31b1979 100644 --- a/bundles/binding/org.openhab.binding.bticino/src/main/java/org/openhab/binding/bticino/internal/BticinoGenericBindingProvider.java +++ b/bundles/binding/org.openhab.binding.bticino/src/main/java/org/openhab/binding/bticino/internal/BticinoGenericBindingProvider.java @@ -12,6 +12,7 @@ import org.openhab.core.binding.BindingConfig; import org.openhab.core.items.Item; +import org.openhab.core.library.items.NumberItem; import org.openhab.core.library.items.RollershutterItem; import org.openhab.core.library.items.SwitchItem; import org.openhab.core.types.State; @@ -49,17 +50,16 @@ public String getBindingType() { /** * @{inheritDoc */ - public void validateItemType(Item item, String bindingConfig) - throws BindingConfigParseException { + public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException { - if (!(item instanceof SwitchItem || item instanceof RollershutterItem)) { + if (!(item instanceof SwitchItem || item instanceof RollershutterItem || item instanceof NumberItem)) { throw new BindingConfigParseException( "item '" + item.getName() + "' is of type '" + item.getClass().getSimpleName() + "', this Item is not allowed - please check your *.items configuration" - + ", only SwitchItem and RollershutterItem are allowed / supported for now"); + + ", only SwitchItem, RollershutterItem and NumberItem are allowed / supported for now"); } } diff --git a/bundles/binding/org.openhab.binding.comfoair/.classpath b/bundles/binding/org.openhab.binding.comfoair/.classpath index 4033112b349..6d224cd3d0d 100644 --- a/bundles/binding/org.openhab.binding.comfoair/.classpath +++ b/bundles/binding/org.openhab.binding.comfoair/.classpath @@ -4,6 +4,5 @@ - diff --git a/bundles/binding/org.openhab.binding.comfoair/src/main/java/org/openhab/binding/comfoair/handling/ComfoAirCommandType.java b/bundles/binding/org.openhab.binding.comfoair/src/main/java/org/openhab/binding/comfoair/handling/ComfoAirCommandType.java index 3ece22cba42..762fb61c87f 100644 --- a/bundles/binding/org.openhab.binding.comfoair/src/main/java/org/openhab/binding/comfoair/handling/ComfoAirCommandType.java +++ b/bundles/binding/org.openhab.binding.comfoair/src/main/java/org/openhab/binding/comfoair/handling/ComfoAirCommandType.java @@ -146,20 +146,20 @@ public enum ComfoAirCommandType { } }, - EWT_TEMPERATUR_HIGH { + EWT_TEMPERATUR_LOW { { - key = "ewt_temperatur_high"; - data_type = DataTypeTemperature.class; + key = "ewt_temperatur_low"; + data_type = DataTypeNumber.class; read_command = 0xeb; read_reply_command = 0xec; read_reply_data_pos = new int[] { 0 }; } }, - EWT_TEMPERATUR_LOW { + EWT_TEMPERATUR_HIGH { { - key = "ewt_temperatur_low"; - data_type = DataTypeTemperature.class; + key = "ewt_temperatur_high"; + data_type = DataTypeNumber.class; read_command = 0xeb; read_reply_command = 0xec; read_reply_data_pos = new int[] { 1 }; @@ -176,6 +176,17 @@ public enum ComfoAirCommandType { } }, + EWT_MODE { + { + key = "ewt_mode"; + data_type = DataTypeBoolean.class; + read_command = 0x37; + read_reply_command = 0x3c; + read_reply_data_pos = new int[] { 6 }; + read_reply_data_bits = 0x80; + } + }, + BYPASS_MODE { { key = "bypass_mode"; @@ -276,7 +287,7 @@ public enum ComfoAirCommandType { int[] possible_values; /* - * Cmd code to swich properties on the comforair. + * Cmd code to change properties on the comfoair. */ int change_command; /* diff --git a/bundles/binding/org.openhab.binding.davis/.classpath b/bundles/binding/org.openhab.binding.davis/.classpath index d7e6436ffa7..c07429c6760 100644 --- a/bundles/binding/org.openhab.binding.davis/.classpath +++ b/bundles/binding/org.openhab.binding.davis/.classpath @@ -4,6 +4,5 @@ - diff --git a/bundles/binding/org.openhab.binding.dscalarm/.classpath b/bundles/binding/org.openhab.binding.dscalarm/.classpath index ea155b6de37..ca755b29dde 100644 --- a/bundles/binding/org.openhab.binding.dscalarm/.classpath +++ b/bundles/binding/org.openhab.binding.dscalarm/.classpath @@ -3,6 +3,5 @@ - diff --git a/bundles/binding/org.openhab.binding.dscalarm/README.md b/bundles/binding/org.openhab.binding.dscalarm/README.md index 208c56c23f8..7ec1b98bb94 100644 --- a/bundles/binding/org.openhab.binding.dscalarm/README.md +++ b/bundles/binding/org.openhab.binding.dscalarm/README.md @@ -72,7 +72,9 @@ The DSCAlarmItemType maps the binding to an openHAB item type. Here are the sup panel_connectionNumberPanel connection status. panel_messageStringEvent messages received from the DSC Alarm system. panel_system_errorStringDSC Alarm system error. - panel_time_dateDateTimeDSC Alarm system time and date. + panel_timeDateTimeDSC Alarm system time and date. + panel_time_stampSwitchTurn DSC Alarm message time stamping ON/OFF. + panel_time_broadcastSwitchTurn DSC Alarm time broadcasting ON/OFF. panel_fire_key_alarmSwitchA fire key alarm has happened. panel_panic_key_alarmSwitchA panic key alarm has happened. panel_aux_key_alarmSwitchAn auxiliary key alarm has happened. @@ -164,6 +166,10 @@ Number PANEL_COMMAND "Panel Commands" (DSCAlarmPanel) {dscalarm="panel:panel_com String PANEL_MESSAGE "Panel Message: [%s]" <"shield-1"> (DSCAlarmPanel) {dscalarm="panel:panel_message"} String PANEL_SYSTEM_ERROR "Panel System Error: [%s]" <"shield-1"> (DSCAlarmPanel) {dscalarm="panel:panel_system_error"} +DateTime PANEL_TIME "Panel Time [%1$tA, %1$tm/%1$td/%1$tY %1tT]" (DSCAlarmPanel) {dscalarm="panel:panel_time"} +Switch PANEL_TIME_STAMP (DSCAlarmPanel) {dscalarm="panel:panel_time_stamp"} +Switch PANEL_TIME_BROADCAST (DSCAlarmPanel) {dscalarm="panel:panel_time_broadcast"} + Switch PANEL_FIRE_KEY_ALARM (DSCAlarmPanel) {dscalarm="panel:panel_fire_key_alarm"} Switch PANEL_PANIC_KEY_ALARM (DSCAlarmPanel) {dscalarm="panel:panel_panic_key_alarm"} Switch PANEL_AUX_KEY_ALARM (DSCAlarmPanel) {dscalarm="panel:panel_aux_key_alarm"} @@ -290,6 +296,10 @@ Frame label="Alarm System" { Switch item=PANEL_CONNECTION label="Panel Connection" icon="shield-1" mappings=[1="Connected", 0="Disconnected"] Text item=PANEL_MESSAGE icon="shield-1" Selection item=PANEL_COMMAND icon="shield-1" mappings=[0="Poll", 1="Status Report", 2="Labels Request (Serial Only)", 8="Dump Zone Timers (TCP Only)", 10="Set Time/Date", 200="Send User Code"] + Text item=PANEL_TIME { + Switch item=PANEL_TIME_STAMP label="Panel Time Stamp" + Switch item=PANEL_TIME_BROADCAST label="Panel Time Broadcast" + } } Frame label="Partitions" { diff --git a/bundles/binding/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/DSCAlarmActiveBinding.java b/bundles/binding/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/DSCAlarmActiveBinding.java index 3a78caee125..9f4407bc547 100644 --- a/bundles/binding/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/DSCAlarmActiveBinding.java +++ b/bundles/binding/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/DSCAlarmActiveBinding.java @@ -18,6 +18,7 @@ import org.openhab.binding.dscalarm.DSCAlarmBindingConfig; import org.openhab.binding.dscalarm.DSCAlarmBindingProvider; import org.openhab.binding.dscalarm.internal.connector.DSCAlarmConnectorType; +import org.openhab.binding.dscalarm.internal.model.DSCAlarmDeviceProperties; import org.openhab.binding.dscalarm.internal.model.DSCAlarmDeviceType; import org.openhab.binding.dscalarm.internal.protocol.API; import org.openhab.binding.dscalarm.internal.protocol.APICode; @@ -25,6 +26,7 @@ import org.openhab.core.binding.AbstractActiveBinding; import org.openhab.core.binding.BindingProvider; import org.openhab.core.items.Item; +import org.openhab.core.library.types.OnOffType; import org.openhab.core.types.Command; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedService; @@ -88,7 +90,7 @@ public class DSCAlarmActiveBinding extends AbstractActiveBinding 3) { try { if(apiMessage.length() >= 8 && apiMessage.charAt(2) == ':' && apiMessage.charAt(5) == ':') { + timeStamp = apiMessage.substring(0,8); apiMessage = apiMessage.substring(9, apiMessage.length() - 2); } else { @@ -77,7 +80,9 @@ private void parseAPIMessage() { apiCodeReceived = "000"; } - if(APICode.getAPICodeValue(apiCodeReceived) != null) { + APICode apiCode = APICode.getAPICodeValue(apiCodeReceived); + + if(apiCode != null) { switch (APICode.getAPICodeValue(apiCodeReceived)) { case CommandAcknowledge: /*500*/ @@ -91,6 +96,92 @@ private void parseAPIMessage() { case SystemError: /*502*/ apiName = "System Error"; apiDescription = apiCodeReceived + ": An error has been detected."; + int systemErrorCode = 0; + systemErrorCode = Integer.parseInt(data); + switch(systemErrorCode) { + case 1: + error = "Receive Buffer Overrun"; + break; + case 2: + error = "Receive Buffer Overflow"; + break; + case 3: + error = "Transmit Buffer Overflow"; + break; + case 10: + error = "Keybus Transmit Buffer Overrun"; + break; + case 11: + error = "Keybus Transmit Time Timeout"; + break; + case 12: + error = "Keybus Transmit Mode Timeout"; + break; + case 13: + error = "Keybus Transmit Keystring Timeout"; + break; + case 14: + error = "Keybus Interface Not Functioning"; + break; + case 15: + error = "Keybus Busy - Attempting to Disarm or Arm with user code"; + break; + case 16: + error = "Keybus Busy – Lockout"; + break; + case 17: + error = "Keybus Busy – Installers Mode"; + break; + case 18: + error = "Keybus Busy - General Busy"; + break; + case 20: + error = "API Command Syntax Error"; + break; + case 21: + error = "API Command Partition Error - Requested Partition is out of bounds"; + break; + case 22: + error = "API Command Not Supported"; + break; + case 23: + error = "API System Not Armed - Sent in response to a disarm command"; + break; + case 24: + error = "API System Not Ready to Arm - System is either not-secure, in exit-delay, or already armed"; + break; + case 25: + error = "API Command Invalid Length"; + break; + case 26: + error = "API User Code not Required"; + break; + case 27: + error = "API Invalid Characters in Command - No alpha characters are allowed except for checksum"; + break; + case 28: + error = "API Virtual Keypad is Disabled"; + break; + case 29: + error = "API Not Valid Parameter"; + break; + case 30: + error = "API Keypad Does Not Come Out of Blank Mode"; + break; + case 31: + error = "API IT-100 is Already in Thermostat Menu"; + break; + case 32: + error = "API IT-100 is NOT in Thermostat Menu"; + break; + case 33: + error = "API No Response From Thermostat or Escort Module"; + break; + case 0: + default: + error = "No Error"; + break; + } break; case LoginResponse: /*505*/ apiName = "Login Interaction"; @@ -109,7 +200,7 @@ private void parseAPIMessage() { case TimeDateBroadcast: /*550*/ apiName = "Time-Date Broadcast"; apiDescription = apiCodeReceived + ": The current security system time."; - data = apiMessage.substring(4); + data = apiMessage.substring(3); break; case RingDetected: /*560*/ apiName = "Ring Detected"; @@ -588,6 +679,11 @@ public String toString() { sb.append(apiDescription); sb.append("\""); + if (timeStamp != "") { + sb.append(", Time Stamp: "); + sb.append(timeStamp); + } + if (partition != 0) { sb.append(", Partition: "); sb.append(partition); @@ -613,6 +709,11 @@ public String toString() { sb.append(user); } + if (error != "") { + sb.append(", error: "); + sb.append(error); + } + return sb.toString(); } @@ -706,4 +807,22 @@ public String getMode() { public String getUser() { return user; } + + /** + * Returns the error string from the API message + * + * @return user + */ + public String getError() { + return error; + } + + /** + * Returns the time stamp if available + * + * @return timeStamp + */ + public String getTimeStamp() { + return timeStamp; + } } diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRBinding.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRBinding.java index 26112685b93..8da811170bd 100644 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRBinding.java +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRBinding.java @@ -14,6 +14,8 @@ import org.openhab.binding.dsmr.DSMRBindingProvider; import org.openhab.binding.dsmr.internal.cosem.CosemValue; import org.openhab.binding.dsmr.internal.messages.OBISMessage; +import org.openhab.binding.dsmr.internal.messages.OBISMsgFactory; +import org.openhab.binding.dsmr.internal.p1telegram.P1TelegramParser; import org.apache.commons.lang.StringUtils; import org.openhab.core.binding.AbstractActiveBinding; import org.openhab.core.types.State; @@ -31,11 +33,12 @@ *

    * At this moment the binding supports only a single Smart Meter. *

    - * The binding needs 2 necessary configuration parameters from openhab.cfg: + * The binding needs the following configuration parameters from openhab.cfg: *

    *

      *
    • dsmr.port (serial port device) - *
    • dsmr.version {@link DSMRVersion} + *
    • dsmr..chanel (M-Bus channel of the specified meter type gas, + * water, heating, cooling, generic, slaveelectricity) *
    *

    * The implementation of the binding is based on the Dutch Smart Meter @@ -56,8 +59,7 @@ public class DSMRBinding extends AbstractActiveBinding /* Serial port (configurable via openhab.cfg) */ private String port = ""; - /* DSMR Version (configurable via openhab.cfg) */ - private DSMRVersion version = DSMRVersion.NONE; + /* Meter - channel mapping (configurable via openhab.cfg) */ private final List dsmrMeters = new ArrayList(); @@ -125,7 +127,7 @@ protected String getName() { } /** - * @{inhearticDoc + * @{inheritDoc */ @Override protected void execute() { @@ -138,12 +140,15 @@ protected void execute() { // Check if a valid DSMR port exists. Open a new one if necessary if (dsmrPort == null || !dsmrPort.isOpen()) { logger.debug("Creating DSMR Port:" + port); - dsmrPort = new DSMRPort(port, version, dsmrMeters, - DSMR_UPDATE_INTERVAL); + + dsmrPort = new DSMRPort(port, new P1TelegramParser( + new OBISMsgFactory(dsmrMeters)), DSMR_UPDATE_INTERVAL / 2, + DSMR_UPDATE_INTERVAL * 2); } // Read the DSMRPort List messages = dsmrPort.read(); + logger.debug("Received " + messages.size() + " messages"); // Publish messages on the event bus for (OBISMessage msg : messages) { @@ -153,7 +158,8 @@ protected void execute() { String dsmrItemId = provider.getDSMRItemID(itemName); for (CosemValue openHABValue : msg .getOpenHABValues()) { - // DSMR items with an empty dsmrItemId are filtered automatically + // DSMR items with an empty dsmrItemId are filtered + // automatically if (dsmrItemId.equals(openHABValue.getDsmrItemId())) { logger.debug("Publish data(" + dsmrItemId + ") to " + itemName); @@ -168,9 +174,7 @@ protected void execute() { } /** - * Read the following properties: - dsmr:port. Serial port where DSMR can be - * read (e.g. /dev/ttyUSB0) - dsmr:version. Version of the DSMR protocol of - * the meter. See also {@link DSMRVersion} + * Read the dsmr:port and dsmr:.channel properties */ @Override public void updated(Dictionary config) @@ -186,15 +190,6 @@ public void updated(Dictionary config) logger.warn("dsmr:port setting is empty"); } - // Read version string - String versionString = (String) config.get("version"); - logger.debug("dsmr:version=" + versionString); - if (StringUtils.isNotBlank(versionString)) { - version = DSMRVersion.getDSMRVersion(versionString); - } else { - logger.warn("dsmr:version setting is empty"); - } - /* * Read the channel configuration */ @@ -217,8 +212,10 @@ public void updated(Dictionary config) } } else { switch (meterType) { - case NA: break; // Filter special DSMRMeterType - case ELECTRICITY: break; // Always channel 0, configuration not needed + case NA: + break; // Filter special DSMRMeterType + case ELECTRICITY: + break; // Always channel 0, configuration not needed default: logger.info("dsmr:" + meterType.channelConfigKey + " setting is empty"); @@ -227,7 +224,7 @@ public void updated(Dictionary config) } // Validate minimal configuration - if (version != DSMRVersion.NONE && port.length() > 0) { + if (port.length() > 0) { logger.debug("Configuration succeeded"); setProperlyConfigured(true); } else { diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRGenericBindingProvider.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRGenericBindingProvider.java index 64ad923b7bb..c8ce32b4f0f 100644 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRGenericBindingProvider.java +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRGenericBindingProvider.java @@ -34,13 +34,14 @@ public String getBindingType() { } /** - * @{inheritDoc} + * @{inheritDoc */ @Override public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException { // TODO: More advanced checking based on bindingConfig is possible - if (!(item instanceof NumberItem) && !(item instanceof StringItem) && !(item instanceof DateTimeItem)) { + if (!(item instanceof NumberItem) && !(item instanceof StringItem) + && !(item instanceof DateTimeItem)) { throw new BindingConfigParseException( "item '" + item.getName() @@ -84,8 +85,7 @@ public String getDSMRItemID(String itemName) { *

    * The binding configuration consists only of the OBIS item. *

    - * Binding configuration for an openHAB Item looks like: - * dsmr="" + * Binding configuration for an openHAB Item looks like: dsmr="" * * @author M. Volaart * @since 1.7.0 diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRMeter.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRMeter.java index c98abeb10a8..e1ff2f87fe9 100644 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRMeter.java +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRMeter.java @@ -11,7 +11,7 @@ /** * DSMR Meter represents a meter for this binding. *

    - * The main Electricity meter {@link DSMRMeterType}.ELECTRICTY is available + * The main Electricity meter {@link DSMRMeterType}.ELECTRICTY is available * implicit and an instance of this class for this meter is not necessary. * * @author M. Volaart diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRMeterType.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRMeterType.java index bcd6800cba7..5b7639d58c9 100644 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRMeterType.java +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRMeterType.java @@ -30,7 +30,7 @@ public enum DSMRMeterType { /** Generic meter (generic.channel) */ GENERIC("generic.channel"), /** Slave electricity meter (slaveelectricity.channel) */ - SLAVE_ELECTRICITY("slavelectricity.channel"); + SLAVE_ELECTRICITY("slaveelectricity.channel"); /** Channel configuration key for openhab.cfg */ public final String channelConfigKey; diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRPort.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRPort.java index 3172a78ad62..d44e4370a35 100644 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRPort.java +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRPort.java @@ -8,10 +8,9 @@ */ package org.openhab.binding.dsmr.internal; -import java.io.BufferedReader; +import java.io.BufferedInputStream; import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import gnu.io.CommPort; import gnu.io.CommPortIdentifier; @@ -21,7 +20,7 @@ import gnu.io.UnsupportedCommOperationException; import org.openhab.binding.dsmr.internal.messages.OBISMessage; -import org.openhab.binding.dsmr.internal.messages.OBISMsgFactory; +import org.openhab.binding.dsmr.internal.p1telegram.P1TelegramParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,30 +66,35 @@ * @since 1.7.0 */ public class DSMRPort { - /* Internal state based on DSMR specification */ - private enum ReadState { - WAIT_FOR_START, IDENTIFICATION, DATA, END - }; - /* logger */ private static final Logger logger = LoggerFactory .getLogger(DSMRPort.class); + private enum PortState { + CLOSED, AUTO_DETECT, OPENED; + } + + private enum PortSpeed { + LOW_SPEED, HIGH_SPEED + } + /* private object variables */ private final String portName; - private final DSMRVersion version; - private final int timeoutMSec; + private final int readTimeoutMSec; + private final int autoDetectTimeoutMSec; + private long autoDetectTS; /* serial port resources */ private SerialPort serialPort; - private BufferedReader reader; + private BufferedInputStream bis; + private byte[] buffer = new byte[1024]; // 1K /* state variables */ - private ReadState readerState; - private boolean isOpen = false; + private PortState portState; + private PortSpeed portSpeed; /* helpers */ - private OBISMsgFactory factory; + private P1TelegramParser p1Parser; /* * The portLock is used for the shared data used when opening and closing @@ -106,20 +110,23 @@ private enum ReadState { * * @param portName * Device identifier of the post (e.g. /dev/ttyUSB0) - * @param version - * Version of the DSMR Specification. See {@link DSMRVersion} - * @param dsmrMeters - * List of available {@link DSMRMeter} in the binding - * @param timeoutMSec + * @param p1Parser + * {@link P1TelegramParser} + * @param readTimeoutMSec * communication timeout in milliseconds + * @param autoDetectTimeoutMSec + * timeout for auto detection in milliseconds (after this period + * the Serial Port speed will be changed) */ - public DSMRPort(String portName, DSMRVersion version, - List dsmrMeters, int timeoutMSec) { + public DSMRPort(String portName, P1TelegramParser p1Parser, + int readTimeoutMSec, int autoDetectTimeoutMSec) { this.portName = portName; - this.version = version; - this.timeoutMSec = timeoutMSec; + this.readTimeoutMSec = readTimeoutMSec; + this.autoDetectTimeoutMSec = autoDetectTimeoutMSec; + this.p1Parser = p1Parser; - factory = new OBISMsgFactory(version, dsmrMeters); + portSpeed = PortSpeed.HIGH_SPEED; + portState = PortState.CLOSED; } /** @@ -128,7 +135,7 @@ public DSMRPort(String portName, DSMRVersion version, * @return true if the DSMRPort is open, false otherwise */ public boolean isOpen() { - return isOpen; + return portState != PortState.CLOSED; } /** @@ -138,11 +145,12 @@ public void close() { synchronized (portLock) { logger.info("Closing DSMR port"); - isOpen = false; + portState = PortState.CLOSED; + // Close resources - if (reader != null) { + if (bis != null) { try { - reader.close(); + bis.close(); } catch (IOException ioe) { logger.debug("Failed to close reader", ioe); } @@ -152,7 +160,7 @@ public void close() { } // Release resources - reader = null; + bis = null; serialPort = null; } } @@ -170,67 +178,41 @@ public void close() { * @return List of {@link OBISMessage} with 0 or more entries */ public List read() { - List messages = new ArrayList(); - long startTime = System.currentTimeMillis(); + List receivedMessages = new LinkedList(); + + handlePortState(); // open port if it is not open - if (!open()) { + if (portState == PortState.CLOSED) { logger.warn("Could not open DSMRPort, no values will be read"); close(); - return messages; + return receivedMessages; } - // Initialize readerState - readerState = ReadState.WAIT_FOR_START; - try { - // wait till we reached the end of the telegram or a timeout - while (readerState != ReadState.END - && ((System.currentTimeMillis() - startTime) < (2 * timeoutMSec))) { - String line = reader.readLine(); - logger.trace(line); - logger.debug("Reader state: " + readerState); - - switch (readerState) { - case WAIT_FOR_START: - if (line.startsWith("/")) { - readerState = ReadState.IDENTIFICATION; - } - break; - case IDENTIFICATION: - if (line.length() == 0) { - readerState = ReadState.DATA; - } - break; - case DATA: - if (line.startsWith("!")) { - readerState = ReadState.END; - } else { - OBISMessage msg = factory.getMessage(line); - if (msg != null) { - messages.add(msg); - } - } - break; - case END: - break; - default: - logger.warn("Unsupported state:" + readerState); - break; + // Read without block + int bytesAvailable = bis.available(); + while (bytesAvailable > 0) { + int bytesRead = bis.read(buffer, 0, + Math.min(bytesAvailable, buffer.length)); + + if (bytesRead > 0) { + receivedMessages.addAll(p1Parser.parseData(buffer, 0, + bytesRead)); + } else { + logger.debug("Expected bytes " + bytesAvailable + + " to read, but " + bytesRead + " bytes were read"); } - } - if (readerState != ReadState.END) { - logger.error("Reading took too long and is aborted (readingtime: " - + (System.currentTimeMillis() - startTime) + " ms)"); + bytesAvailable = bis.available(); } } catch (IOException ioe) { /* * Read is interrupted. This can be due to a broken connection or * closing the port */ - if (!isOpen) { + if (portState == PortState.CLOSED) { // Closing on purpose logger.info("Read aborted: DSMRPort is closed"); } else { @@ -242,7 +224,7 @@ public List read() { close(); } } catch (NullPointerException npe) { - if (!isOpen) { + if (portState == PortState.CLOSED) { // Port was closed logger.info("Read aborted: DSMRPort is closed"); } else { @@ -252,8 +234,56 @@ public List read() { } } - // Return all received messages - return messages; + if (portState == PortState.AUTO_DETECT && receivedMessages.size() > 0) { + portState = PortState.OPENED; + } + return receivedMessages; + } + + /** + * Checks the current port state and initiate actions based on it. + *

      + *
    • CLOSED --> Port will be opened + *
    • AUTO_DETECT --> Auto detect period will be evaluated + *
    • OPENED --> Nothing has to be done + *
    + */ + private void handlePortState() { + switch (portState) { + case CLOSED: + if (open()) { + portState = PortState.AUTO_DETECT; + autoDetectTS = System.currentTimeMillis(); + } + break; + case AUTO_DETECT: + if ((System.currentTimeMillis() - autoDetectTS) > autoDetectTimeoutMSec) { + switchPortSpeed(); + close(); + if (open()) { + portState = PortState.AUTO_DETECT; + autoDetectTS = System.currentTimeMillis(); + } + } + break; + case OPENED: + /* do nothing */ + break; + } + } + + /** + * Switch the Serial Port speed (LOW --> HIGH and vice versa). + */ + private void switchPortSpeed() { + switch (portSpeed) { + case HIGH_SPEED: + portSpeed = PortSpeed.LOW_SPEED; + break; + case LOW_SPEED: + portSpeed = PortSpeed.HIGH_SPEED; + break; + } } /** @@ -276,7 +306,7 @@ public List read() { private boolean open() { synchronized (portLock) { // Sanity check - if (isOpen) { + if (portState != PortState.CLOSED) { return true; } @@ -287,34 +317,30 @@ private boolean open() { .getPortIdentifier(portName); logger.debug("Opening CommPortIdentifier"); CommPort commPort = portIdentifier.open( - "org.openhab.binding.dsmr", 2000); + "org.openhab.binding.dsmr", readTimeoutMSec); logger.debug("Configure serial port"); serialPort = (SerialPort) commPort; serialPort.enableReceiveThreshold(1); - serialPort.enableReceiveTimeout(timeoutMSec); - - // Configure Serial Port based on specified DSMR version - logger.debug("Configure serial port based on version " - + version); - switch (version) { - case V21: - case V22: - case V30: + serialPort.enableReceiveTimeout(readTimeoutMSec); + + // Configure Serial Port based on specified port speed + logger.debug("Configure serial port speed " + portSpeed); + switch (portSpeed) { + case LOW_SPEED: serialPort.setSerialPortParams(9600, SerialPort.DATABITS_7, SerialPort.STOPBITS_1, SerialPort.PARITY_EVEN); serialPort.setDTR(false); serialPort.setRTS(true); break; - case V40: - case V404: + case HIGH_SPEED: serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); break; default: - logger.error("Invalid version, closing port"); + logger.error("Invalid speed, closing port"); return false; } @@ -335,8 +361,7 @@ private boolean open() { // SerialPort is ready, open the reader logger.info("SerialPort opened successful"); try { - reader = new BufferedReader(new InputStreamReader( - serialPort.getInputStream())); + bis = new BufferedInputStream(serialPort.getInputStream()); } catch (IOException ioe) { logger.error( "Failed to get inputstream for serialPort. Closing port", @@ -346,9 +371,7 @@ private boolean open() { } logger.info("DSMR Port opened successful"); - isOpen = true; - - return isOpen; + return true; } } } diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRVersion.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRVersion.java deleted file mode 100644 index 226de29024f..00000000000 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/DSMRVersion.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.dsmr.internal; - -/** - * The DSMRVersion specifies the DSMR specification version - *

    - * The following versions are special versions: - *

    - *

      - *
    • NONE - This can be used for filtering purposes - *
    • ALL - This can be used to identify all versions - *

      - * This enumeration also has some convenience arrays for grouping versions - * - * @author M. Volaart - * @since 1.7.0 - */ -public enum DSMRVersion { - /** Special version for filtering purposes */ - NONE("None"), - /** Special version that indicates all versions */ - ALL("All"), - /** DSMR Specification v2.1 */ - V21("v2.1"), - /** DSMR Specification v2.2 */ - V22("v2.2"), - /** DSMR Specification v3.0 */ - V30("v3.0"), - /** DSMR Specification v4.0 */ - V40("v4.0"), - /** DSMR Specification v4.04 */ - V404("v4.04"); - - /** String representation of the DSMR version */ - public final String version; - - /** - * Construct a new Enum type - * - * @param version - * String representation of the Enum - */ - private DSMRVersion(String version) { - this.version = version; - } - - /** Compatibility for all versions */ - public static final DSMRVersion[] ALL_VERSIONS = new DSMRVersion[] { V21, - V22, V30, V40, V404 }; - /** Compatibility for versions v2.1 and later */ - public static final DSMRVersion[] V21_UP = new DSMRVersion[] { V21, V22, - V30, V40, V404 }; - /** Compatibility for versions v2.2 and later */ - public static final DSMRVersion[] V22_UP = new DSMRVersion[] { V22, V30, - V40, V404 }; - /** Compatibility for versions v3.0 and later */ - public static final DSMRVersion[] V30_UP = new DSMRVersion[] { V30, V40, - V404 }; - /** Compatibility for versions v4.0 and later */ - public static final DSMRVersion[] V40_UP = new DSMRVersion[] { V40 }; - /** Compatibility for versions v4.04 and later */ - public static final DSMRVersion[] V404_UP = new DSMRVersion[] { V404 }; - /** Compatibility for all v2.x versions */ - public static final DSMRVersion[] V2_VERSIONS = new DSMRVersion[] { V21, - V22 }; - /** Compatibility for all v3.x versions */ - public static final DSMRVersion[] V3_VERSIONS = new DSMRVersion[] { V30 }; - /** Compatibility for all v4.x versions */ - public static final DSMRVersion[] V4_VERSIONS = new DSMRVersion[] { V40, - V404 }; - - /** - * Returns the DSMRVersion object for the specified version. If the version - * is not found the NONE version is returned - * - * @param version - * String containing the version - * @return corresponding {@link DMSRVersion} or NONE if a unknown version is - * specified - */ - public static DSMRVersion getDSMRVersion(String version) { - for (DSMRVersion t : DSMRVersion.values()) { - if (t.version.equalsIgnoreCase(version)) { - return t; - } - } - return NONE; - } -} diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemFloat.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemFloat.java index 2143b393945..5d1d61200cf 100644 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemFloat.java +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemFloat.java @@ -46,7 +46,8 @@ protected DecimalType parse(String cosemValue) throws ParseException { try { return new DecimalType(Float.parseFloat(cosemValue)); } catch (NumberFormatException nfe) { - throw new ParseException("Failed to parse value " + value + " as float", 0); + throw new ParseException("Failed to parse value " + value + + " as float", 0); } } } diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemString.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemString.java index 2fae2a3cd54..9bc00b588e6 100644 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemString.java +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemString.java @@ -32,7 +32,8 @@ public CosemString(String unit, String bindingSuffix) { } /** - * Parses a String value (that represents an integer) to an openHAB StringType + * Parses a String value (that represents an integer) to an openHAB + * StringType * * @param cosemValue * the value to parse diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemValueDescriptor.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemValueDescriptor.java index 18120009718..c9d24a7e2bd 100644 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemValueDescriptor.java +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/cosem/CosemValueDescriptor.java @@ -47,6 +47,7 @@ public CosemValueDescriptor( /** * Returns the class of the CosemValue + * * @return the class of the CosemValue */ public Class> getCosemValueClass() { @@ -55,6 +56,7 @@ public Class> getCosemValueClass() { /** * Returns the unit + * * @return the unit */ public String getUnit() { @@ -62,7 +64,7 @@ public String getUnit() { } /** - * Returns the DSMR item id + * Returns the DSMR item id * * @return the DSMR item id */ diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISIdentifier.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISIdentifier.java new file mode 100644 index 00000000000..2087b949c9e --- /dev/null +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISIdentifier.java @@ -0,0 +1,250 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.dsmr.internal.messages; + +import java.text.ParseException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Class representing an OBISIdentifier + * + * @author M. Volaart + * @since 1.7.0 + */ +public class OBISIdentifier implements Comparable { + /* String representing a.b.c.d.e.f OBIS ID */ + private static final String OBISID_REGEX = "((\\d+)\\-)?((\\d+):)?((\\d+)\\.)(\\d+)(\\.(\\d+))?(\\*(\\d+))?"; + + /* OBIS ID pattern */ + private static final Pattern obisIdPattern = Pattern.compile(OBISID_REGEX); + + /* the six individual group values of the OBIS ID */ + private Integer groupA; + private Integer groupB; + private Integer groupC; + private Integer groupD; + private Integer groupE; + private Integer groupF; + + /** + * Constructs a new OBIS Identifier (A.B.C.D.E.F) + * + * @param groupA + * A value + * @param groupB + * B value + * @param groupC + * C value + * @param groupD + * D value + * @param groupE + * E value + * @param groupF + * F value + */ + public OBISIdentifier(Integer groupA, Integer groupB, Integer groupC, + Integer groupD, Integer groupE, Integer groupF) { + this.groupA = groupA; + this.groupB = groupB; + this.groupC = groupC; + this.groupD = groupD; + this.groupE = groupE; + this.groupF = groupF; + } + + /** + * Creates a new OBISIdentifier of the specified String + * + * @param obisIDString + * the OBIS String ID + * @throws ParseException + * if obisIDString is not a valid OBIS Identifier + */ + public OBISIdentifier(String obisIDString) throws ParseException { + Matcher m = obisIdPattern.matcher(obisIDString); + + if (m.matches()) { + // Optional value A + if (m.group(2) != null) { + this.groupA = Integer.parseInt(m.group(2)); + } + + // Optional value B + if (m.group(4) != null) { + this.groupB = Integer.parseInt(m.group(4)); + } + + // Required value C & D + this.groupC = Integer.parseInt(m.group(6)); + this.groupD = Integer.parseInt(m.group(7)); + + // Optional value E + if (m.group(9) != null) { + this.groupE = Integer.parseInt(m.group(9)); + } + + // Optional value F + if (m.group(11) != null) { + this.groupF = Integer.parseInt(m.group(11)); + } + } else { + throw new ParseException("Invalis OBIS identifier:" + obisIDString, + 0); + } + } + + /** + * @return the groupA + */ + public Integer getGroupA() { + return groupA; + } + + /** + * @return the groupB + */ + public Integer getGroupB() { + return groupB; + } + + /** + * @return the groupC + */ + public Integer getGroupC() { + return groupC; + } + + /** + * @return the groupD + */ + public Integer getGroupD() { + return groupD; + } + + /** + * @return the groupE + */ + public Integer getGroupE() { + return groupE; + } + + /** + * @return the groupF + */ + public Integer getGroupF() { + return groupF; + } + + @Override + public String toString() { + return (groupA != null ? (groupA + "-") : "") + + (groupB != null ? (groupB + ":") : "") + groupC + "." + + groupD + (groupE != null ? ("." + groupE) : "") + + (groupF != null ? ("*" + groupF) : ""); + } + + @Override + public boolean equals(Object other) { + OBISIdentifier o; + if (other != null && other instanceof OBISIdentifier) { + o = (OBISIdentifier) other; + } else { + return false; + } + boolean result = true; + + if (groupA != null && o.groupA != null) { + result &= (groupA.equals(o.groupA)); + } + if (groupB != null && o.groupB != null) { + result &= (groupB.equals(o.groupB)); + } + result &= (groupC.equals(o.groupC)); + result &= (groupD.equals(o.groupD)); + if (groupE != null && o.groupE != null) { + result &= (groupE.equals(o.groupE)); + } + if (groupF != null && o.groupF != null) { + result &= (groupF.equals(o.groupF)); + } + + return result; + } + + @Override + public int compareTo(OBISIdentifier o) { + if (o == null) { + throw new NullPointerException("Compared OBISIdentifier is null"); + } + if (groupA != o.groupA) { + if (groupA == null) { + return 1; + } else if (o.groupA == null) { + return -1; + } else { + return groupA.compareTo(o.groupA); + } + } + if (groupB != o.groupB) { + if (groupB == null) { + return 1; + } else if (o.groupB == null) { + return -1; + } else { + return groupB.compareTo(o.groupB); + } + } + if (groupC != o.groupC) { + return groupC.compareTo(o.groupC); + } + if (groupD != o.groupD) { + return groupD.compareTo(o.groupD); + } + if (groupE != o.groupE) { + if (groupE == null) { + return 1; + } else if (o.groupE == null) { + return -1; + } else { + return groupE.compareTo(o.groupE); + } + } + if (groupF != o.groupF) { + if (groupF == null) { + return 1; + } else if (o.groupF == null) { + return -1; + } else { + return groupF.compareTo(o.groupF); + } + } + + return 0; + } + + @Override + public int hashCode() { + return ((groupA != null) ? groupA.hashCode() : 0) + + ((groupB != null) ? groupB.hashCode() : 0) + + groupC.hashCode() + groupD.hashCode() + + ((groupE != null) ? groupE.hashCode() : 0) + + ((groupF != null) ? groupF.hashCode() : 0); + } + + /** + * Returns an reduced OBIS Identifier. This means group F is set to null + * (.i.e. not applicable) + * + * @return reduced OBIS Identifer + */ + public OBISIdentifier getReducedOBISIdentifier() { + return new OBISIdentifier(groupA, groupB, groupC, groupD, groupE, null); + } +} diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMessage.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMessage.java index f92af7a2756..2cc6a745bbd 100644 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMessage.java +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMessage.java @@ -34,6 +34,11 @@ public class OBISMessage { private static final Logger logger = LoggerFactory .getLogger(OBISMessage.class); + // Identifier of the first power failure date element + public static final int FIRST_POWER_FAILURE_DATE = 2; + // Identifier of the first power failure duration element + public static final int FIRST_POWER_FAILURE_DURATION = 3; + // OBIS Message Type private final OBISMsgType msgType; @@ -98,37 +103,44 @@ public void parseCosemValues(List cosemStringValues) + ", Needed items:" + msgType.cosemValueDescriptors.size()); /* - * It is not necessarily a problem if 'Needed items' > 'Received items'. - * Since some items have a dynamic number of values (e.g. Power Failure Log). - * - * Since the minority of the messages has such features, differences - * between received and needed could indicate problems + * It is not necessarily a problem if 'Needed items' > 'Received items'. + * Since some items have a dynamic number of values (e.g. Power Failure + * Log). + * + * Since the minority of the messages has such features, differences + * between received and needed could indicate problems */ if (cosemStringValues.size() <= msgType.cosemValueDescriptors.size()) { for (int i = 0; i < cosemStringValues.size(); i++) { - - CosemValue cosemValue = getCosemValue(msgType.cosemValueDescriptors.get(i)); + + CosemValue cosemValue = getCosemValue(msgType.cosemValueDescriptors + .get(i)); if (cosemValue != null) { cosemValue.setValue(cosemStringValues.get(i)); cosemValues.add(cosemValue); } else { - logger.error("Failed to parse:" + cosemStringValues.get(i), " for OBISMsgType:" + msgType); + logger.error("Failed to parse:" + cosemStringValues.get(i), + " for OBISMsgType:" + msgType); } } } else { - throw new ParseException("Received items:" + cosemStringValues.size() - + ", Needed items:" + msgType.cosemValueDescriptors.size(), 0); + throw new ParseException("Received items:" + + cosemStringValues.size() + ", Needed items:" + + msgType.cosemValueDescriptors.size(), 0); } - + /* * Here we do a post processing on the values */ - switch(msgType) { - case EMETER_POWER_FAILURE_LOG: postProcessKaifaE0003(); break; - default: break; + switch (msgType) { + case EMETER_POWER_FAILURE_LOG: + postProcessKaifaE0003(); + break; + default: + break; } } - + /** * Creates an empty CosemValue object * @@ -137,9 +149,10 @@ public void parseCosemValues(List cosemStringValues) * @return the instantiated CosemValue based on the specified * CosemValueDescriptor */ - private CosemValue getCosemValue(CosemValueDescriptor cosemValueDescriptor) { - Class> cosemValueClass = - cosemValueDescriptor.getCosemValueClass(); + private CosemValue getCosemValue( + CosemValueDescriptor cosemValueDescriptor) { + Class> cosemValueClass = cosemValueDescriptor + .getCosemValueClass(); String unit = cosemValueDescriptor.getUnit(); String dsmrItemId = cosemValueDescriptor.getDsmrItemId(); @@ -163,18 +176,36 @@ private CosemValue getCosemValue(CosemValueDescriptor cosemValu */ private void postProcessKaifaE0003() { logger.debug("postProcessKaifaE0003"); + + /* + * The list of cosemValues for this OBIS Message is: + * - [0] Number of entries in the list + * - [1] Cosem Identifier + * - [2] power failure date entry 1 [Optional] + * - [3] power failure duration entry 1 [Optional] + * - [entry n * 2] power failure date entry n + * - [entry n * 2 + 1] power failure duration entry n + */ - CosemDate powerFailureDate = (CosemDate)cosemValues.get(1); - CosemInteger powerFailureDuration = (CosemInteger)cosemValues.get(2); - - Calendar epoch = Calendar.getInstance(); - epoch.setTime(new Date(0)); - - if(powerFailureDate.getValue().getCalendar().before(epoch) && - powerFailureDuration.getValue().intValue() == Integer.MAX_VALUE) { - logger.debug("Filter invalid power failure entry"); - cosemValues.remove(2); // powerFailureDuration - cosemValues.remove(1); // powerFailureDate - } + // First check of there is at least one entry of a power failure present + // (i.e. date at idx 2 and duration at idx 3) + if (cosemValues.size() > FIRST_POWER_FAILURE_DURATION) { + CosemDate powerFailureDate = (CosemDate) cosemValues + .get(FIRST_POWER_FAILURE_DATE); + CosemInteger powerFailureDuration = (CosemInteger) cosemValues + .get(FIRST_POWER_FAILURE_DURATION); + + Calendar epoch = Calendar.getInstance(); + epoch.setTime(new Date(0)); + + // Check if the first entry it as epoc and has a 2^32-1 value + // If so, filter this value, since it has no added value + if (powerFailureDate.getValue().getCalendar().before(epoch) + && powerFailureDuration.getValue().intValue() == Integer.MAX_VALUE) { + logger.debug("Filter invalid power failure entry"); + cosemValues.remove(FIRST_POWER_FAILURE_DURATION); + cosemValues.remove(FIRST_POWER_FAILURE_DATE); + } + } } } diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMsgFactory.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMsgFactory.java index 559850f4524..89b65861103 100644 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMsgFactory.java +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMsgFactory.java @@ -9,16 +9,12 @@ package org.openhab.binding.dsmr.internal.messages; import java.text.ParseException; -import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import org.openhab.binding.dsmr.internal.DSMRMeter; import org.openhab.binding.dsmr.internal.DSMRMeterType; -import org.openhab.binding.dsmr.internal.DSMRVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,159 +29,129 @@ public class OBISMsgFactory { private static final Logger logger = LoggerFactory .getLogger(OBISMsgFactory.class); - /* Regular expression for OBIS strings */ - private static final String OBIS_REGEX = "^(\\d{1,3}-\\d{1,3}:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})(\\(.*\\))+$"; - private static final String OBIS_VALUE_REGEX = "\\(([^\\(\\)]*)\\)"; - private static final String OBIS_CONFIGURABLE_CHANNEL_PATTERN = "(\\d+)-(-1):(\\d+)\\.(\\d+)\\.(\\d+)"; - - /* Pattern instances */ - private final Pattern obisPattern; - private final Pattern obisValuePattern; - private final Pattern obisChannelPattern; - /* internal lookup cache */ - private final HashMap obisLookupTable; + private final HashMap> obisLookupTable; /** - * Creates a new OBISMsgFactory for the specified DSMRVersion + * Creates a new OBISMsgFactory * - * @param version - * {@link DMSRVersion} to use for handling input data * @param dsmrMeters * available DSMR meters (see {@link DSMRMeter}) in the binding */ - public OBISMsgFactory(DSMRVersion version, List dsmrMeters) { - obisPattern = Pattern.compile(OBIS_REGEX); - obisValuePattern = Pattern.compile(OBIS_VALUE_REGEX); - obisChannelPattern = Pattern.compile(OBIS_CONFIGURABLE_CHANNEL_PATTERN); - + public OBISMsgFactory(List dsmrMeters) { /* - * Fill a lookup table with OBIS messages belonging to the specified - * DSMR version and channel - MeterType mapping + * Fill a lookup table with OBIS message types based on the specified + * channel - MeterType mapping */ - obisLookupTable = new HashMap(); + obisLookupTable = new HashMap>(); // Create a convenience lookup table for a channel based on meter type Map meterChannelMapping = new HashMap(); for (DSMRMeter meter : dsmrMeters) { meterChannelMapping.put(meter.getMeterType(), meter.getChannel()); } - fillLookupTable(version, meterChannelMapping); + fillLookupTable(meterChannelMapping); } /** * Return OBISMessage from specified string or null if string couldn't be * parsed correctly or no corresponding OBISMessage was found * - * @param obisStr - * a single raw OBIS message string received from the DSMR meter + * @param obisIdString + * String containing the OBIS message identifier + * @param cosemStringValues + * LinkedList of String containing Cosem values * @return OBISMessage or null if parsing failed */ - public OBISMessage getMessage(String obisStr) { - OBISMessage msg = null; - - if (obisStr != null) { - Matcher m = obisPattern.matcher(obisStr); - - if (m.matches()) { - logger.debug("Received valid OBIS String:" + obisStr); + public OBISMessage getMessage(String obisIdString, + LinkedList cosemStringValues) { + OBISIdentifier obisId = null; + OBISIdentifier reducedObisId = null; + + try { + obisId = new OBISIdentifier(obisIdString); + reducedObisId = obisId.getReducedOBISIdentifier(); + } catch (ParseException pe) { + logger.error("Received invalid OBIS identifer:" + obisIdString); + + return null; + } - List cosemStringValues = new ArrayList(); + logger.debug("Received obisIdString " + obisIdString + ", obisId:" + + obisId + ", values:" + cosemStringValues); - // Get identifier and all the values as a single String - OBISMsgType msgType = getOBISMsgType(m.group(1)); + if (obisLookupTable.containsKey(reducedObisId)) { + List compatibleMsgTypes = obisLookupTable.get(reducedObisId); - if (msgType != OBISMsgType.UNKNOWN) { - // Get the individual COSEM String values - String allCosemStringValues = m.group(2); - Matcher valueMatcher = obisValuePattern - .matcher(allCosemStringValues); + OBISMessage msg = null; - while (valueMatcher.find()) { - cosemStringValues.add(valueMatcher.group(1)); - } + logger.debug("Found " + compatibleMsgTypes.size() + + " compatible message type(s)"); + for (OBISMsgType msgType : compatibleMsgTypes) { + msg = new OBISMessage(msgType); - logger.debug("OBIS message type:" + msgType + ", values:" - + cosemStringValues); + try { + logger.debug("Parse values for OBIS Message type:" + + msgType); - msg = new OBISMessage(msgType); + msg.parseCosemValues(cosemStringValues); - try { - msg.parseCosemValues(cosemStringValues); - } catch (ParseException pe) { - logger.error("Failed to parse " + obisStr, pe); - } - } else { - logger.warn("Received OBIS unknown message:" + obisStr); + return msg; + } catch (ParseException pe) { + logger.debug("Failed to parse OBIS identifer " + obisId + + ", values:" + cosemStringValues + " for type" + + msgType, pe); } } - } - - logger.debug("Converted to:" + msg); - - return msg; - } - - /** - * Returns the OBIS message type (See {@link OBISMsgType}) for the specified - * OBIS reduced identifier - * - * @param obisId - * the OBIS reduced identifier - * @return the {@link OBISMsgType} or UNKNOWN if the OBIS reduced identifier - * is unknown - */ - private OBISMsgType getOBISMsgType(String obisId) { - if (obisLookupTable.containsKey(obisId)) { - return obisLookupTable.get(obisId); + logger.error("Failed to parse OBIS identifier " + obisId + + ", values:" + cosemStringValues); } else { - return OBISMsgType.UNKNOWN; + logger.warn("Received OBIS unknown message:" + obisId); } + return null; } /** - * This method fills a lookup table in which the applicable OBIS message - * types are stored based on the {@link DSMRVersion} and mapping channel - - * {@link DSMRMeterType} + * This method fills a lookup table with the OBIS message types based on the + * mapping channel - {@link DSMRMeterType} *

      - * DSMR messages can be interpreted ambiguous if the version or mapping is - * not known. The lookup table makes sure that messages are parsed without - * ambiguity. * - * @param version - * applicable DSMR version * @param mapping * DSMRMeterType - channel mapping */ - private void fillLookupTable(DSMRVersion version, - Map mapping) { + private void fillLookupTable(Map mapping) { for (OBISMsgType t : OBISMsgType.values()) { - if (t.applicableVersions.contains(version)) { - Matcher m = obisChannelPattern.matcher(t.obisId); - if (m.matches()) { - DSMRMeterType meterType = t.meterType; - if (mapping.containsKey(meterType)) { - /* - * OBIS-identifier contains a variable channel Check if - * the configuration contains the mapping for this meter - * type and then make the OBIS-identifier specific - */ - - Integer channel = mapping.get(t.meterType); - logger.debug("Change OBIS-identifier " + t.obisId - + " for meter " + t.meterType + " on channel " - + channel); - - String obisSpecificIdentifier = m.replaceFirst("$1-" - + channel + ":$3.$4.$5"); - obisLookupTable.put(obisSpecificIdentifier, t); - } else { - logger.debug("Mapping does not contain a channel for " - + meterType); - } + OBISIdentifier obisId = t.obisId; + + if (obisId.getGroupB() == null) { + DSMRMeterType meterType = t.meterType; + if (mapping.containsKey(meterType)) { + /* + * OBIS-identifier contains a variable channel Check if the + * configuration contains the mapping for this meter type + * and then make the OBIS-identifier specific + */ + + Integer channel = mapping.get(t.meterType); + logger.debug("Change OBIS-identifier " + t.obisId + + " for meter " + t.meterType + " on channel " + + channel); + + obisId = new OBISIdentifier(obisId.getGroupA(), channel, + obisId.getGroupC(), obisId.getGroupD(), + obisId.getGroupE(), obisId.getGroupF()); } else { - obisLookupTable.put(t.obisId, t); + logger.debug("Mapping does not contain a channel for " + + meterType); + + obisId = null; + } + } + if (obisId != null) { + if (!obisLookupTable.containsKey(obisId)) { + obisLookupTable.put(obisId, new LinkedList()); } + obisLookupTable.get(obisId).add(t); } } } diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMsgType.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMsgType.java index fc199a0b19d..d7117be3449 100644 --- a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMsgType.java +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/messages/OBISMsgType.java @@ -11,7 +11,6 @@ import java.util.Arrays; import java.util.List; import org.openhab.binding.dsmr.internal.DSMRMeterType; -import org.openhab.binding.dsmr.internal.DSMRVersion; import org.openhab.binding.dsmr.internal.cosem.CosemDate; import org.openhab.binding.dsmr.internal.cosem.CosemFloat; import org.openhab.binding.dsmr.internal.cosem.CosemInteger; @@ -26,7 +25,6 @@ *

        *
      • OBIS Identifier (reduced form) *
      • Applicable {@link DSMRMeterType} - *
      • Applicable {@link DSMRVersion} *
      • Description of the values (See {@link CosemValueDescriptor}) *
      • Human readable description *
      @@ -35,111 +33,107 @@ * @since 1.7.0 */ public enum OBISMsgType { - UNKNOWN("", + UNKNOWN(new OBISIdentifier(null, null, -1, -1, null, null), DSMRMeterType.NA, - new CosemValueDescriptor(CosemString.class, "", ""), - DSMRVersion.NONE, + new CosemValueDescriptor(CosemString.class, "", ""), "Unknown OBIS message type"), /* General messages (DSMR V4) */ - P1_VERSION_OUTPUT_V4("1-3:0.2.8", + P1_VERSION_OUTPUT_V4(new OBISIdentifier(1, 3, 0, 2, 8, null), DSMRMeterType.NA, new CosemValueDescriptor(CosemString.class, "", "P1VersionOutput"), - DSMRVersion.V4_VERSIONS, "Version information for P1 output"), - P1_TIMESTAMP("0-0:1.0.0", + P1_TIMESTAMP(new OBISIdentifier(0, 0, 1, 0, 0, null), DSMRMeterType.NA, - new CosemValueDescriptor(CosemDate.class, "", "P1Timestamp"), - DSMRVersion.V4_VERSIONS, + new CosemValueDescriptor(CosemDate.class, "", "P1Timestamp"), "Timestamp of the P1 output"), /* Electricity Meter */ - EMETER_EQUIPMENT_IDENTIFIER_V2_X("0-0:42.0.0", + EMETER_EQUIPMENT_IDENTIFIER_V2_X(new OBISIdentifier(0, 0, 42, 0, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemString.class, "", "eEquipmentId"), - DSMRVersion.V2_VERSIONS, "Equipment identifier DSMR v2.x"), - EMETER_EQUIPMENT_IDENTIFIER("0-0:96.1.1", + EMETER_EQUIPMENT_IDENTIFIER_NTA8130(new OBISIdentifier(0, 0, 96, 1, 0, null), DSMRMeterType.ELECTRICITY, - new CosemValueDescriptor(CosemString.class, "", "eEquipmentId"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemString.class, "", "eEquipmentId"), + "Equipment identifier (NTA8130)"), + EMETER_EQUIPMENT_IDENTIFIER(new OBISIdentifier(0, 0, 96, 1, 1, null), + DSMRMeterType.ELECTRICITY, + new CosemValueDescriptor(CosemString.class, "", "eEquipmentId"), "Equipment identifier"), - EMETER_DELIVERY_TARIFF1("1-0:1.8.1", + EMETER_DELIVERY_TARIFF0(new OBISIdentifier(1, 0, 1, 8, 0, null), DSMRMeterType.ELECTRICITY, - new CosemValueDescriptor(CosemFloat.class, "kWh", "eDeliveryTariff1"), - DSMRVersion.ALL_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "kWh", "eDeliveryTariff0"), + "Total meter delivery tariff 0"), + EMETER_DELIVERY_TARIFF1(new OBISIdentifier(1, 0, 1, 8, 1, null), + DSMRMeterType.ELECTRICITY, + new CosemValueDescriptor(CosemFloat.class, "kWh", "eDeliveryTariff1"), "Total meter delivery tariff 1"), - EMETER_DELIVERY_TARIFF2("1-0:1.8.2", + EMETER_DELIVERY_TARIFF2(new OBISIdentifier(1, 0, 1, 8, 2, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "kWh", "eDeliveryTariff2"), - DSMRVersion.ALL_VERSIONS, "Total meter delivery tariff 2"), - EMETER_PRODUCTION_TARIFF1("1-0:2.8.1", + EMETER_PRODUCTION_TARIFF0(new OBISIdentifier(1, 0, 2, 8, 0, null), + DSMRMeterType.ELECTRICITY, + new CosemValueDescriptor(CosemFloat.class, "kWh", "eProductionTariff0"), + "Total meter production tariff 0"), + EMETER_PRODUCTION_TARIFF1(new OBISIdentifier(1, 0, 2, 8, 1, null), DSMRMeterType.ELECTRICITY, - new CosemValueDescriptor(CosemFloat.class, "kWh", "eProductionTariff1"), - DSMRVersion.ALL_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "kWh", "eProductionTariff1"), "Total meter production tariff 1"), - EMETER_PRODUCTION_TARIFF2("1-0:2.8.2", + EMETER_PRODUCTION_TARIFF2(new OBISIdentifier(1, 0, 2, 8, 2, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "kWh", "eProductionTariff2"), - DSMRVersion.ALL_VERSIONS, "Total meter production tariff 2"), - EMETER_TARIFF_INDICATOR("0-0:96.14.0", + EMETER_TARIFF_INDICATOR(new OBISIdentifier(0, 0, 96, 14, 0, null), DSMRMeterType.ELECTRICITY, - new CosemValueDescriptor(CosemString.class, "", "eTariffIndicator"), - DSMRVersion.ALL_VERSIONS, + new CosemValueDescriptor(CosemString.class, "", "eTariffIndicator"), "Tariff indicator"), - EMETER_ACTUAL_DELIVERY("1-0:1.7.0", + EMETER_ACTIVE_IMPORT_POWER(new OBISIdentifier(1, 0, 15, 7, 0, null), + DSMRMeterType.ELECTRICITY, + new CosemValueDescriptor(CosemFloat.class, "W", "eActualDelivery"), + "Aggregrate active import power"), + EMETER_ACTUAL_DELIVERY(new OBISIdentifier(1, 0, 1, 7, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "kW", "eActualDelivery"), - DSMRVersion.ALL_VERSIONS, "Actual power delivery"), - EMETER_ACTUAL_PRODUCTION("1-0:2.7.0", + EMETER_ACTUAL_PRODUCTION(new OBISIdentifier(1, 0, 2, 7, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "kW", "eActualProduction"), - DSMRVersion.ALL_VERSIONS, "Actual power production"), - EMETER_TRESHOLD_V2_1("1-0:17.0.0", + EMETER_TRESHOLD_V2_1(new OBISIdentifier(1, 0, 17, 0, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemInteger.class, "A", "eTreshold"), - new DSMRVersion[] { DSMRVersion.V21 }, "The actual threshold Electricity in A (DSMR v2.1)"), - EMETER_TRESHOLD("0-0:17.0.0", + EMETER_TRESHOLD(new OBISIdentifier(0, 0, 17, 0, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemInteger.class, "A", "eTreshold"), - new DSMRVersion[] { DSMRVersion.V22, DSMRVersion.V30 }, "The actual threshold Electricity in A (DSMR v2.2 / v3)"), - EMETER_TRESHOLD_V4("0-0:17.0.0", + EMETER_TRESHOLD_V4(new OBISIdentifier(0, 0, 17, 0, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "kW", "eTreshold"), - DSMRVersion.V4_VERSIONS, "The actual threshold Electricity in kW (DSMR v4)"), - EMETER_SWITCH_POSITION_V2_1("1-0:96.3.10", + EMETER_SWITCH_POSITION_V2_1(new OBISIdentifier(1, 0, 96, 3, 10, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemInteger.class, "", "eSwitchPosition"), - new DSMRVersion[] { DSMRVersion.V21 }, "Actual switch position Electricity DSMR v2.1"), - EMETER_SWITCH_POSITION_V2_2("0-0:24.4.0", + EMETER_SWITCH_POSITION_V2_2(new OBISIdentifier(0, 0, 24, 4, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemInteger.class, "", "eSwitchPosition"), - new DSMRVersion[] { DSMRVersion.V22 }, "Actual switch position Electricity DSMR v2.2"), - EMETER_SWITCH_POSITION("0-0:96.3.10", + EMETER_SWITCH_POSITION(new OBISIdentifier(0, 0, 96, 3, 10, null), DSMRMeterType.ELECTRICITY, - new CosemValueDescriptor(CosemInteger.class, "", "eSwitchPosition"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemInteger.class, "", "eSwitchPosition"), "Actual switch position Electricity"), - EMETER_POWER_FAILURES("0-0:96.7.21", + EMETER_POWER_FAILURES(new OBISIdentifier(0, 0, 96, 7, 21, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "", "ePowerFailures"), - DSMRVersion.V4_VERSIONS, "Number of Power failures"), - EMETER_LONG_POWER_FAILURES("0-0:96.7.9", + EMETER_LONG_POWER_FAILURES(new OBISIdentifier(0, 0, 96, 7, 9, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "", "eLongPowerFailures"), - DSMRVersion.V4_VERSIONS, "Number of Long Power failures"), - EMETER_POWER_FAILURE_LOG("1-0:99.97.0", + EMETER_POWER_FAILURE_LOG(new OBISIdentifier(1, 0, 99, 97, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor[] { new CosemValueDescriptor(CosemInteger.class, "", "eNumberOfLogEntries"), @@ -164,121 +158,98 @@ public enum OBISMsgType { new CosemValueDescriptor(CosemInteger.class, "s", "eDurationPowerFailure9"), new CosemValueDescriptor(CosemDate.class, "", "eDatePowerFailure10"), new CosemValueDescriptor(CosemInteger.class, "s", "eDurationPowerFailure10")}, - DSMRVersion.V4_VERSIONS, "Power Failure event log"), - EMETER_VOLTAGE_SAGS_L1("1-0:32.32.0", + EMETER_VOLTAGE_SAGS_L1(new OBISIdentifier(1, 0, 32, 32, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "", "eVoltageSagsL1"), - DSMRVersion.V4_VERSIONS, "Number of voltage sags L1"), - EMETER_VOLTAGE_SAGS_L2("1-0:52.32.0", + EMETER_VOLTAGE_SAGS_L2(new OBISIdentifier(1, 0, 52, 32, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "", "eVoltageSagsL2"), - DSMRVersion.V4_VERSIONS, "Number of voltage sags L2"), - EMETER_VOLTAGE_SAGS_L3("1-0:72.32.0", + EMETER_VOLTAGE_SAGS_L3(new OBISIdentifier(1, 0, 72, 32, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "", "eVoltageSagsL3"), - DSMRVersion.V4_VERSIONS, "Number of voltage sags L3"), - EMETER_VOLTAGE_SWELLS_L1("1-0:32.36.0", + EMETER_VOLTAGE_SWELLS_L1(new OBISIdentifier(1, 0, 32, 36, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "", "eVoltageSwellsL1"), - DSMRVersion.V4_VERSIONS, "Number of voltage swells L1"), - EMETER_VOLTAGE_SWELLS_L2("1-0:52.36.0", + EMETER_VOLTAGE_SWELLS_L2(new OBISIdentifier(1, 0, 52, 36, 0, null), DSMRMeterType.ELECTRICITY, - new CosemValueDescriptor(CosemFloat.class, "", "eVoltageSwellsL2"), - DSMRVersion.V4_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "", "eVoltageSwellsL2"), "Number of voltage swells L2"), - EMETER_VOLTAGE_SWELLS_L3("1-0:72.36.0", + EMETER_VOLTAGE_SWELLS_L3(new OBISIdentifier(1, 0, 72, 36, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "", "eVoltageSwellsL3"), - DSMRVersion.V4_VERSIONS, "Number of voltage swells L3"), - EMETER_TEXT_CODE("0-0:96.13.1", + EMETER_TEXT_CODE(new OBISIdentifier(0, 0, 96, 13, 1, null), DSMRMeterType.ELECTRICITY, - new CosemValueDescriptor(CosemString.class, "", "eTextCode"), - DSMRVersion.ALL_VERSIONS, + new CosemValueDescriptor(CosemString.class, "", "eTextCode"), "Text message code (8 digits)"), - EMETER_TEXT_STRING("0-0:96.13.0", + EMETER_TEXT_STRING(new OBISIdentifier(0, 0, 96, 13, 0, null), DSMRMeterType.ELECTRICITY, - new CosemValueDescriptor(CosemString.class, "", "eTextMessage"), - DSMRVersion.ALL_VERSIONS, + new CosemValueDescriptor(CosemString.class, "", "eTextMessage"), "Text message"), - EMETER_INSTANT_CURRENT_L1("1-0:31.7.0", + EMETER_INSTANT_CURRENT_L1(new OBISIdentifier(1, 0, 31, 7, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "A", "eInstantCurrentL1"), - DSMRVersion.V404, "Instantenous current L1"), - EMETER_INSTANT_CURRENT_L2("1-0:51.7.0", + EMETER_INSTANT_CURRENT_L2(new OBISIdentifier(1, 0, 51, 7, 0, null), DSMRMeterType.ELECTRICITY, - new CosemValueDescriptor(CosemFloat.class, "A", "eInstantCurrentL2"), - DSMRVersion.V404, + new CosemValueDescriptor(CosemFloat.class, "A", "eInstantCurrentL2"), "Instantenous current L2"), - EMETER_INSTANT_CURRENT_L3("1-0:71.7.0", + EMETER_INSTANT_CURRENT_L3(new OBISIdentifier(1, 0, 71, 7, 0, null), DSMRMeterType.ELECTRICITY, - new CosemValueDescriptor(CosemFloat.class, "A", "eInstantCurrentL3"), - DSMRVersion.V404, + new CosemValueDescriptor(CosemFloat.class, "A", "eInstantCurrentL3"), "Instantenous current L3"), - EMETER_INSTANT_POWER_DELIVERY_L1("1-0:21.7.0", + EMETER_INSTANT_POWER_DELIVERY_L1(new OBISIdentifier(1, 0, 21, 7, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "kW", "eInstantPowerDeliveryL1"), - DSMRVersion.V404, "Instantenous active power delivery L1"), - EMETER_INSTANT_POWER_DELIVERY_L2("1-0:41.7.0", + EMETER_INSTANT_POWER_DELIVERY_L2(new OBISIdentifier(1, 0, 41, 7, 0, null), DSMRMeterType.ELECTRICITY, - new CosemValueDescriptor(CosemFloat.class, "kW", "eInstantPowerDeliveryL2"), - DSMRVersion.V404, + new CosemValueDescriptor(CosemFloat.class, "kW", "eInstantPowerDeliveryL2"), "Instantenous active power delivery L2"), - EMETER_INSTANT_POWER_DELIVERY_L3("1-0:61.7.0", + EMETER_INSTANT_POWER_DELIVERY_L3(new OBISIdentifier(1, 0, 61, 7, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "kW", "eInstantPowerDeliveryL3"), - DSMRVersion.V404, "Instantenous active power delivery L3"), - EMETER_INSTANT_POWER_PRODUCTION_L1("1-0:22.7.0", + EMETER_INSTANT_POWER_PRODUCTION_L1(new OBISIdentifier(1, 0, 22, 7, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "kW", "eInstantPowerProductionL1"), - DSMRVersion.V404, "Instantenous active power production L1"), - EMETER_INSTANT_POWER_PRODUCTION_L2("1-0:42.7.0", + EMETER_INSTANT_POWER_PRODUCTION_L2(new OBISIdentifier(1, 0, 42, 7, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "kW", "eInstantPowerProductionL2"), - DSMRVersion.V404, "Instantenous active power production L2"), - EMETER_INSTANT_POWER_PRODUCTION_L3("1-0:62.7.0", + EMETER_INSTANT_POWER_PRODUCTION_L3(new OBISIdentifier(1, 0, 62, 7, 0, null), DSMRMeterType.ELECTRICITY, new CosemValueDescriptor(CosemFloat.class, "kW", "eInstantPowerProductionL3"), - DSMRVersion.V404, "Instantenous active power production L3"), /* Gas Meter */ - GMETER_DEVICE_TYPE("0--1:24.1.0", + GMETER_DEVICE_TYPE(new OBISIdentifier(0, null, 24, 1, 0, null), DSMRMeterType.GAS, - new CosemValueDescriptor(CosemString.class, "", "gDeviceType"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemString.class, "", "gDeviceType"), "Device Type"), - GMETER_EQUIPMENT_IDENTIFIER_V2_X("7-0:0.0.0", + GMETER_EQUIPMENT_IDENTIFIER_V2_X(new OBISIdentifier(7, 0, 0, 0, 0, null), DSMRMeterType.GAS, new CosemValueDescriptor(CosemString.class, "", "gEquipmentId"), - DSMRVersion.V2_VERSIONS, "Equipment identifier"), - GMETER_EQUIPMENT_IDENTIFIER("0--1:96.1.0", + GMETER_EQUIPMENT_IDENTIFIER(new OBISIdentifier(0, null, 96, 1, 0, null), DSMRMeterType.GAS, - new CosemValueDescriptor(CosemString.class, "", "gEquipmentId"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemString.class, "", "gEquipmentId"), "Equipment identifier"), - GMETER_24H_DELIVERY_V2_X("7-0:23.1.0", + GMETER_24H_DELIVERY_V2_X(new OBISIdentifier(7, 0, 23, 1, 0, null), DSMRMeterType.GAS, new CosemValueDescriptor(CosemString.class, "m3", "gValue"), - DSMRVersion.V2_VERSIONS, "Delivery of the past hour(v3.0 and up) or 24 hours (v2.1 / v2.2)"), - GMETER_24H_DELIVERY_COMPENSATED_V2_X("7-0:23.2.0", + GMETER_24H_DELIVERY_COMPENSATED_V2_X(new OBISIdentifier(7, 0, 23, 2, 0, null), DSMRMeterType.GAS, new CosemValueDescriptor(CosemString.class, "m3", "gValueCompensated"), - DSMRVersion.V2_VERSIONS, "Temperature compensated delivery of the past 24 hours"), - GMETER_VALUE_V3("0--1:24.3.0", + GMETER_VALUE_V3(new OBISIdentifier(0, null, 24, 3, 0, null), DSMRMeterType.GAS, new CosemValueDescriptor[]{ new CosemValueDescriptor(CosemDate.class, "", "gValueTS"), @@ -287,268 +258,178 @@ public enum OBISMsgType { new CosemValueDescriptor(CosemInteger.class, "", "gNumberOfValues"), new CosemValueDescriptor(CosemString.class, "", ""), new CosemValueDescriptor(CosemString.class, "", "gUnit"), - new CosemValueDescriptor(CosemInteger.class, "", "gValue"), - new CosemValueDescriptor(CosemInteger.class, "", "gValue2"), - new CosemValueDescriptor(CosemInteger.class, "", "gValue3"), - new CosemValueDescriptor(CosemInteger.class, "", "gValue4"), - new CosemValueDescriptor(CosemInteger.class, "", "gValue5"), - new CosemValueDescriptor(CosemInteger.class, "", "gValue6"), - new CosemValueDescriptor(CosemInteger.class, "", "gValue7"), - new CosemValueDescriptor(CosemInteger.class, "", "gValue8"), - new CosemValueDescriptor(CosemInteger.class, "", "gValue9"), - new CosemValueDescriptor(CosemInteger.class, "", "gValue10")}, - DSMRVersion.V3_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "", "gValue"), + new CosemValueDescriptor(CosemFloat.class, "", "gValue2"), + new CosemValueDescriptor(CosemFloat.class, "", "gValue3"), + new CosemValueDescriptor(CosemFloat.class, "", "gValue4"), + new CosemValueDescriptor(CosemFloat.class, "", "gValue5"), + new CosemValueDescriptor(CosemFloat.class, "", "gValue6"), + new CosemValueDescriptor(CosemFloat.class, "", "gValue7"), + new CosemValueDescriptor(CosemFloat.class, "", "gValue8"), + new CosemValueDescriptor(CosemFloat.class, "", "gValue9"), + new CosemValueDescriptor(CosemFloat.class, "", "gValue10")}, "Delivery of the past 24 hours"), - GMETER_VALUE_V4("0--1:24.2.1", + GMETER_VALUE_V4(new OBISIdentifier(0, null, 24, 2, 1, null), DSMRMeterType.GAS, new CosemValueDescriptor[]{ new CosemValueDescriptor(CosemDate.class, "", "gValueTS"), new CosemValueDescriptor(CosemFloat.class, "m3", "gValue")}, - DSMRVersion.V4_VERSIONS, "Delivery of the past 24 hours"), - GMETER_VALVE_POSITION_V2_1("7-0:96.3.10", + GMETER_VALVE_POSITION_V2_1(new OBISIdentifier(7, 0, 96, 3, 10, null), DSMRMeterType.GAS, new CosemValueDescriptor(CosemInteger.class, "", "gValvePosition"), - DSMRVersion.V2_VERSIONS, "Valve position"), - GMETER_VALVE_POSITION_V2_2("7-0:24.4.0", + GMETER_VALVE_POSITION_V2_2(new OBISIdentifier(7, 0, 24, 4, 0, null), DSMRMeterType.GAS, - new CosemValueDescriptor(CosemInteger.class, "", "gValvePosition"), - DSMRVersion.V2_VERSIONS, + new CosemValueDescriptor(CosemInteger.class, "", "gValvePosition"), "Valve position"), - GMETER_VALVE_POSITION("0--1:24.4.0", + GMETER_VALVE_POSITION(new OBISIdentifier(0, null, 24, 4, 0, null), DSMRMeterType.GAS, - new CosemValueDescriptor(CosemInteger.class, "", "gValvePosition"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemInteger.class, "", "gValvePosition"), "Valve position"), /* Heating Meter */ - HMETER_DEVICE_TYPE("0--1:24.1.0", + HMETER_DEVICE_TYPE(new OBISIdentifier(0, null, 24, 1, 0, null), DSMRMeterType.HEATING, - new CosemValueDescriptor(CosemString.class, "", "hDeviceType"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemString.class, "", "hDeviceType"), "Device Type"), - HMETER_EQUIPMENT_IDENTIFIER_V2_X("5-0:0.0.0", + HMETER_EQUIPMENT_IDENTIFIER_V2_X(new OBISIdentifier(5, 0, 0, 0, 0, null), DSMRMeterType.HEATING, - new CosemValueDescriptor(CosemString.class, "", "hEquipmentId"), - DSMRVersion.V2_VERSIONS, + new CosemValueDescriptor(CosemString.class, "", "hEquipmentId"), "Equipment identifier"), - HMETER_EQUIPMENT_IDENTIFIER("0--1:96.1.0", + HMETER_EQUIPMENT_IDENTIFIER(new OBISIdentifier(0, null, 96, 1, 0, null), DSMRMeterType.HEATING, - new CosemValueDescriptor(CosemString.class, "", "hEquipmentId"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemString.class, "", "hEquipmentId"), "Equipment identifier"), - HMETER_VALUE_V2_X("5-0:1.0.0", + HMETER_VALUE_V2_X(new OBISIdentifier(5, 0, 1, 0, 0, null), DSMRMeterType.HEATING, - new CosemValueDescriptor(CosemFloat.class, "GJ", "hValue"), - DSMRVersion.V2_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "GJ", "hValue"), "Last hour delivery"), - HMETER_VALUE_HEAT_V3("0--1:24.3.0", + HMETER_VALUE_HEAT_V3(new OBISIdentifier(0, null, 24, 3, 0, null), DSMRMeterType.HEATING, - new CosemValueDescriptor(CosemFloat.class, "GJ", "hValue"), - DSMRVersion.V3_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "GJ", "hValue"), "Last hour delivery"), - HMETER_VALUE_HEAT_V4("0--1:24.2.1", + HMETER_VALUE_HEAT_V4(new OBISIdentifier(0, null, 24, 2, 1, null), DSMRMeterType.HEATING, new CosemValueDescriptor[] { new CosemValueDescriptor(CosemDate.class, "", "hValueTS"), - new CosemValueDescriptor(CosemFloat.class, "GJ", "hValue")}, - DSMRVersion.V4_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "GJ", "hValue")}, "Last hour delivery"), - HMETER_VALVE_POSITION("0--1:24.4.0", + HMETER_VALVE_POSITION(new OBISIdentifier(0, null, 24, 4, 0, null), DSMRMeterType.HEATING, - new CosemValueDescriptor(CosemInteger.class, "", "hValvePosition"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemInteger.class, "", "hValvePosition"), "Valve position"), /* Cooling Meter */ - CMETER_DEVICE_TYPE("0--1:24.1.0", + CMETER_DEVICE_TYPE(new OBISIdentifier(0, null, 24, 1, 0, null), DSMRMeterType.COOLING, - new CosemValueDescriptor(CosemString.class, "", "cDeviceType"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemString.class, "", "cDeviceType"), "Device Type"), - CMETER_EQUIPMENT_IDENTIFIER_V2_X("6-0:0.0.0", + CMETER_EQUIPMENT_IDENTIFIER_V2_X(new OBISIdentifier(6, 0, 0, 0, 0, null), DSMRMeterType.COOLING, - new CosemValueDescriptor(CosemString.class, "", "cEquipmentId"), - DSMRVersion.V2_VERSIONS, + new CosemValueDescriptor(CosemString.class, "", "cEquipmentId"), "Equipment identifier"), - CMETER_EQUIPMENT_IDENTIFIER("0--1:96.1.0", + CMETER_EQUIPMENT_IDENTIFIER(new OBISIdentifier(0, null, 96, 1, 0, null), DSMRMeterType.COOLING, - new CosemValueDescriptor(CosemString.class, "", "cEquipmentId"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemString.class, "", "cEquipmentId"), "Equipment identifier"), - CMETER_VALUE_V2_X("6-0:1.0.0", + CMETER_VALUE_V2_X(new OBISIdentifier(6, 0, 1, 0, 0, null), DSMRMeterType.COOLING, - new CosemValueDescriptor(CosemFloat.class, "GJ", "cValue"), - DSMRVersion.V2_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "GJ", "cValue"), "Value"), - CMETER_VALUE_COLD_V3("0--1:24.3.1", + CMETER_VALUE_COLD_V3(new OBISIdentifier(0, null, 24, 3, 1, null), DSMRMeterType.COOLING, - new CosemValueDescriptor(CosemFloat.class, "GJ", "cValue"), - DSMRVersion.V3_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "GJ", "cValue"), "Last hour delivery"), - CMETER_VALUE_COLD_V4("0--1:24.2.1", + CMETER_VALUE_COLD_V4(new OBISIdentifier(0, null, 24, 2, 1, null), DSMRMeterType.COOLING, new CosemValueDescriptor[]{ new CosemValueDescriptor(CosemDate.class, "", "cValueTS"), - new CosemValueDescriptor(CosemFloat.class, "GJ", "cValue")}, - DSMRVersion.V4_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "GJ", "cValue")}, "Last hour delivery"), - CMETER_VALVE_POSITION("0--1:24.4.0", + CMETER_VALVE_POSITION(new OBISIdentifier(0, null, 24, 4, 0, null), DSMRMeterType.COOLING, - new CosemValueDescriptor(CosemInteger.class, "", "cValvePosition"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemInteger.class, "", "cValvePosition"), "Valve position"), /* Water Meter */ - WMETER_DEVICE_TYPE("0--1:24.1.0", + WMETER_DEVICE_TYPE(new OBISIdentifier(0, null, 24, 1, 0, null), DSMRMeterType.WATER, - new CosemValueDescriptor(CosemString.class, "", "wDeviceType"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemString.class, "", "wDeviceType"), "Device Type"), - WMETER_EQUIPMENT_IDENTIFIER_V2_X("8-0:0.0.0", + WMETER_EQUIPMENT_IDENTIFIER_V2_X(new OBISIdentifier(8, 0, 0, 0, 0, null), DSMRMeterType.WATER, - new CosemValueDescriptor(CosemString.class, "", "wEquipmentId"), - DSMRVersion.V2_VERSIONS, + new CosemValueDescriptor(CosemString.class, "", "wEquipmentId"), "Equipment identifier"), - WMETER_EQUIPMENT_IDENTIFIER("0--1:96.1.0", + WMETER_EQUIPMENT_IDENTIFIER(new OBISIdentifier(0, null, 96, 1, 0, null), DSMRMeterType.WATER, - new CosemValueDescriptor(CosemString.class, "", "wEquipmentId"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemString.class, "", "wEquipmentId"), "Equipment identifier"), - WMETER_VALUE_V2_X("8-0:1.0.0", + WMETER_VALUE_V2_X(new OBISIdentifier(8, 0, 1, 0, 0, null), DSMRMeterType.WATER, - new CosemValueDescriptor(CosemFloat.class, "m3", "wValue"), - DSMRVersion.V2_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "m3", "wValue"), "Last hour delivery"), - WMETER_VALUE_V3("0--1:24.3.0", + WMETER_VALUE_V3(new OBISIdentifier(0, null, 24, 3, 0, null), DSMRMeterType.WATER, new CosemValueDescriptor(CosemFloat.class, "m3", "wValue"), - DSMRVersion.V3_VERSIONS, "Last hourly meter reading"), - WMETER_VALUE_V4("0--1:24.2.1", + "Last hourly meter reading"), + WMETER_VALUE_V4(new OBISIdentifier(0, null, 24, 2, 1, null), DSMRMeterType.WATER, new CosemValueDescriptor[]{ new CosemValueDescriptor(CosemDate.class, "", "wValueTS"), - new CosemValueDescriptor(CosemFloat.class, "m3", "wValue")}, - DSMRVersion.V4_VERSIONS, + new CosemValueDescriptor(CosemFloat.class, "m3", "wValue")}, "Last hourly meter reading"), - WMETER_VALVE_POSITION("0--1:24.4.0", + WMETER_VALVE_POSITION(new OBISIdentifier(0, null, 24, 4, 0, null), DSMRMeterType.WATER, - new CosemValueDescriptor(CosemInteger.class, "", "wValvePosition"), - DSMRVersion.V30_UP, + new CosemValueDescriptor(CosemInteger.class, "", "wValvePosition"), "Water valve position"), /* Generic Meter (DSMR v3 only) */ - GENMETER_DEVICE_TYPE("0--1:24.1.0", + GENMETER_DEVICE_TYPE(new OBISIdentifier(0, null, 24, 1, 0, null), DSMRMeterType.GENERIC, - new CosemValueDescriptor(CosemString.class, "", "genericDeviceType"), - DSMRVersion.V3_VERSIONS, + new CosemValueDescriptor(CosemString.class, "", "genericDeviceType"), "Device Type"), - GENMETER_EQUIPMENT_IDENTIFIER("0--1:96.1.0", + GENMETER_EQUIPMENT_IDENTIFIER(new OBISIdentifier(0, null, 96, 1, 0, null), DSMRMeterType.GENERIC, new CosemValueDescriptor(CosemString.class, "", "genericEquipmentId"), - DSMRVersion.V3_VERSIONS, "Equipment identifier"), - GENMETER_VALUE_V3("0--1:24.3.0", + GENMETER_VALUE_V3(new OBISIdentifier(0, null, 24, 3, 0, null), DSMRMeterType.GENERIC, new CosemValueDescriptor(CosemFloat.class, "", "genericValue"), - DSMRVersion.V3_VERSIONS, "Last hourly meter reading"), /* Slave E Meter (DSMR v4) */ - SEMETER_DEVICE_TYPE("0--1:24.1.0", + SEMETER_DEVICE_TYPE(new OBISIdentifier(0, null, 24, 1, 0, null), DSMRMeterType.SLAVE_ELECTRICITY, new CosemValueDescriptor(CosemString.class, "", "seDeviceType"), - DSMRVersion.V4_VERSIONS, "Slave Electricity Device Type"), - SEMETER_EQUIPMENT_IDENTIFIER("0--1:96.1.0", + SEMETER_EQUIPMENT_IDENTIFIER(new OBISIdentifier(0, null, 96, 1, 0, null), DSMRMeterType.SLAVE_ELECTRICITY, new CosemValueDescriptor(CosemString.class, "", "seEquipmentId"), - DSMRVersion.V4_VERSIONS, "Slave Electricity Equipment identifier"), - SEMETER_VALUE_V4("0--1:24.2.1", + SEMETER_VALUE_V4(new OBISIdentifier(0, null, 24, 2, 1, null), DSMRMeterType.SLAVE_ELECTRICITY, new CosemValueDescriptor[]{ new CosemValueDescriptor(CosemDate.class, "", "seValueTS"), new CosemValueDescriptor(CosemFloat.class, "kWh", "seValue")}, - DSMRVersion.V4_VERSIONS, "Slave Electricity last hourly meter reading"), - SEMETER_SWITCH_POSITION("0--1:24.4.0", + SEMETER_SWITCH_POSITION(new OBISIdentifier(0, null, 24, 4, 0, null), DSMRMeterType.SLAVE_ELECTRICITY, - new CosemValueDescriptor(CosemInteger.class, "", "seSwitchPosition"), - DSMRVersion.V4_VERSIONS, + new CosemValueDescriptor(CosemInteger.class, "", "seSwitchPosition"), "Slave Electricity switch position"); /** OBIS reduced identifier */ - public String obisId; + public OBISIdentifier obisId; /** COSEM value descriptors */ public final List cosemValueDescriptors; /** Description of this message type */ public final String description; - - /** Applicable DSMR versions for this message type */ - public final List applicableVersions; - + /** Applicable meter type for this message type*/ public final DSMRMeterType meterType; - /** - * Constructor - * - * @param obisId - * OBIS Identifier for the OBIS message - * @param meterType - * the {@link DSMRMeterType} that this message is applicable for - * @param cosemValueDescriptors - * array of {@link CosemValueDescriptor} that describe the values - * of the message - * @param applicableVersions - * array of {@link DSMRVersion} that this message is applicable - * for - * @param description - * human readable description of the OBIS message - */ - private OBISMsgType( - String obisId, - DSMRMeterType meterType, - CosemValueDescriptor[] cosemValueDescriptors, - DSMRVersion[] applicableVersions, - String description) { - this.obisId = obisId; - this.meterType = meterType; - this.cosemValueDescriptors = Arrays.asList(cosemValueDescriptors); - this.applicableVersions = Arrays.asList(applicableVersions); - this.description = description; - } - - /** - * Constructor - * - * @param obisId - * OBIS Identifier for the OBIS message - * @param meterType - * the {@link DSMRMeterType} that this message is applicable for - * @param cosemValueDescriptor - * {@link CosemValueDescriptor} that describes the value of the - * message - * @param applicableVersion - * {@link DSMRVersion} that this message is applicable for - * @param description - * human readable description of the OBIS message - */ - private OBISMsgType( - String obisId, - DSMRMeterType meterType, - CosemValueDescriptor cosemValueDescriptor, - DSMRVersion applicableVersion, - String description) { - this(obisId, meterType, new CosemValueDescriptor[] { cosemValueDescriptor }, - new DSMRVersion[] { applicableVersion }, - description); - } - /** * Constructor * @@ -559,20 +440,15 @@ private OBISMsgType( * @param cosemValueDescriptor * {@link CosemValueDescriptor} that describes the value * of the message - * @param applicableVersions - * array of {@link DSMRVersion} that this message is applicable - * for * @param description * human readable description of the OBIS message */ private OBISMsgType( - String obisId, + OBISIdentifier obisId, DSMRMeterType meterType, CosemValueDescriptor cosemValueDescriptor, - DSMRVersion[] applicableVersions, String description) { this(obisId, meterType, new CosemValueDescriptor[] { cosemValueDescriptor }, - applicableVersions, description); } @@ -586,20 +462,17 @@ private OBISMsgType( * @param cosemValueDescriptors * array of {@link CosemValueDescriptor} that describe the values * of the message - * @param applicableVersions - * {@link DSMRVersion} that this message is applicable - * for * @param description * human readable description of the OBIS message */ private OBISMsgType( - String obisId, + OBISIdentifier obisId, DSMRMeterType meterType, CosemValueDescriptor[] cosemValueDescriptors, - DSMRVersion applicableVersion, String description) { - this(obisId, meterType, cosemValueDescriptors, - new DSMRVersion[] { applicableVersion }, - description); + this.obisId = obisId; + this.meterType = meterType; + this.cosemValueDescriptors = Arrays.asList(cosemValueDescriptors); + this.description = description; } } diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/p1telegram/P1TelegramParser.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/p1telegram/P1TelegramParser.java new file mode 100644 index 00000000000..428c85dabcc --- /dev/null +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/p1telegram/P1TelegramParser.java @@ -0,0 +1,295 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.dsmr.internal.p1telegram; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import org.openhab.binding.dsmr.internal.messages.OBISMessage; +import org.openhab.binding.dsmr.internal.messages.OBISMsgFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The P1TelegramParser is a class that will read P1-port data create a full P1 + * telegram. + * + * This class parses data via the public method parseData. It will parse the + * received data. If a complete P1 telegram is received the OBIS messages are + * returned. Otherwise it will continue parsing with the next call op parseData. + * + * @author mvolaart + * @since 1.7.0 + */ +public class P1TelegramParser { + // Logger + public static final Logger logger = LoggerFactory + .getLogger(P1TelegramParser.class); + + // Helper classers + private OBISMsgFactory factory; + + // Reader state + private P1TelegramParserState parserState; + + // Current P1Telegram values + private LinkedList obisDataLines; + private OBISDataLine currentLine = null; + + /** + * Creates a new P1TelegramParser + * + * @param factory + * OBISMsgFactory object + */ + public P1TelegramParser(OBISMsgFactory factory) { + this.factory = factory; + + obisDataLines = new LinkedList(); + parserState = new P1TelegramParserState(); + } + + /** + * Parses data. If parsing is not ready yet nothing will be returned. If + * parsing fails completely nothing will be returned. If parsing succeeds + * (partial) the received OBIS messages will be returned. + * + * @param data + * byte data + * @param offset + * offset tot start in the data buffer + * @param length + * number of bytes to parse + * @return List of {@link OBISMessage} if a full P1 telegram is received, + * empty list if parsing is not ready or failed completely. + */ + public List parseData(byte[] data, int offset, int length) { + List receivedMessages = new LinkedList(); + + logger.trace("Data:" + + Arrays.toString(Arrays.copyOfRange(data, offset, length)) + + ", state before parsing:" + parserState); + for (int i = offset; i < (offset + length); i++) { + char c = (char) data[i]; + + switch (parserState.getState()) { + case WAIT_FOR_START: + if (c == '/') { + parserState.setState(P1TelegramParserState.State.STARTED); + + handleNewP1Telegram(); + } + break; + case STARTED: + parserState.setState(P1TelegramParserState.State.HEADER); + break; + + case HEADER: + if (c == '\r') { + parserState.setState(P1TelegramParserState.State.CRLF); + } + break; + case CRLF: + if (Character.isWhitespace(c)) { + // do nothing + } else if (Character.isDigit(c)) { + parserState + .setState(P1TelegramParserState.State.DATA_OBIS_ID); + + finishObisLine(); + } else { + handleUnexpectedCharacter(c); + + parserState + .setState(P1TelegramParserState.State.WAIT_FOR_START); + } + break; + case DATA_OBIS_ID: + if (Character.isWhitespace(c)) { + // ignore + } else if (Character.isDigit(c) || c == ':' || c == '-' + || c == '.' || c == '*') { + // do nothing + } else if (c == '(') { + parserState + .setState(P1TelegramParserState.State.DATA_OBIS_VALUE_START); + } else if (c == '!') { + logger.warn("Unexpected character '!'. Going to state:" + + P1TelegramParserState.State.CRC_VALUE); + + parserState.setState(P1TelegramParserState.State.CRC_VALUE); + } else { + handleUnexpectedCharacter(c); + + parserState + .setState(P1TelegramParserState.State.WAIT_FOR_START); + } + break; + case DATA_OBIS_VALUE_START: + if (c == ')') { + handleObisValueReady(); + + parserState + .setState(P1TelegramParserState.State.DATA_OBIS_VALUE_END); + } else { + parserState + .setState(P1TelegramParserState.State.DATA_OBIS_VALUE); + } + break; + + case DATA_OBIS_VALUE: + if (c == ')') { + handleObisValueReady(); + + parserState + .setState(P1TelegramParserState.State.DATA_OBIS_VALUE_END); + } + break; + case DATA_OBIS_VALUE_END: + if (Character.isWhitespace(c)) { + // ignore + } else if (Character.isDigit(c)) { + finishObisLine(); + + parserState + .setState(P1TelegramParserState.State.DATA_OBIS_ID); + } else if (c == '(') { + parserState + .setState(P1TelegramParserState.State.DATA_OBIS_VALUE_START); + } else if (c == '!') { + parserState.setState(P1TelegramParserState.State.CRC_VALUE); + } else { + handleUnexpectedCharacter(c); + + parserState + .setState(P1TelegramParserState.State.WAIT_FOR_START); + } + break; + + case CRC_VALUE: + if (c == '\r') { + if (parserState.getCrcValue().length() > 0) { + // TODO: Handle CRC here + } + + receivedMessages.addAll(handleEndP1Telegram()); + + parserState + .setState(P1TelegramParserState.State.WAIT_FOR_START); + } + break; + } + parserState.handleCharacter(c); + } + logger.trace("State after parsing:" + parserState); + + return receivedMessages; + } + + /** + * Handles the start of a new P1 telegram This method will clear internal + * state + */ + private void handleNewP1Telegram() { + obisDataLines.clear(); + currentLine = null; + } + + /** + * Handles the end of a P1 telegram. This method will parse the raw data to + * a list of {@link OBISMessage} + */ + private List handleEndP1Telegram() { + finishObisLine(); + + List obisMessages = new LinkedList(); + + for (OBISDataLine obisDataLine : obisDataLines) { + OBISMessage obisMessage = factory.getMessage(obisDataLine.obisId, + obisDataLine.obisStringValues); + logger.debug("Parsed:" + obisDataLine + ", to:" + obisMessage); + if (obisMessage != null) { + obisMessages.add(obisMessage); + } else { + logger.warn("Failed to parse:" + obisDataLine); + } + } + + return obisMessages; + } + + /** + * Handles an unexpected character. The character will be logged and the P1 + * telegram will be finished. + * + * @param c + * the unexpected character + */ + private void handleUnexpectedCharacter(char c) { + logger.warn("Unexpected character '" + c + "' in state:" + parserState + + ". Publishing partial P1Telegram and wait for new P1Telegram"); + + handleEndP1Telegram(); + } + + /** + * Handle if a full OBIS value is parsed. This method will store the OBIS + * value in the current OBISDataLine + */ + private void handleObisValueReady() { + if (currentLine == null) { + currentLine = new OBISDataLine(parserState.getObisId()); + } + currentLine.obisStringValues.add(parserState.getObisValue()); + } + + /** + * Handle the end of a OBIS Line (i.e. all values are parsed) + */ + private void finishObisLine() { + if (currentLine != null) { + obisDataLines.add(currentLine); + + currentLine = null; + } + } + + /** + * Class representing a OBISDataLine, e.g. '0-0:96.3.10(1)' + * + * @author mvolaart + * @since 1.7.0 + */ + class OBISDataLine { + // OBIS identifier + final String obisId; + + // List of OBIS values + final LinkedList obisStringValues; + + /** + * Creates a new OBISDataLine + * + * @param obisId + * OBISIdentifer + */ + OBISDataLine(String obisId) { + this.obisId = obisId; + + obisStringValues = new LinkedList(); + } + + @Override + public String toString() { + return "OBISDataLine [OBIS id:" + obisId + ", obis values:" + + obisStringValues; + } + } +} diff --git a/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/p1telegram/P1TelegramParserState.java b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/p1telegram/P1TelegramParserState.java new file mode 100644 index 00000000000..03d78964fb3 --- /dev/null +++ b/bundles/binding/org.openhab.binding.dsmr/src/main/java/org/openhab/binding/dsmr/internal/p1telegram/P1TelegramParserState.java @@ -0,0 +1,205 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.dsmr.internal.p1telegram; + +/** + * P1TelegramParserState stores the state of the P1TelegramParser The state + * consists of the following attributes: + *
        + *
      • receivedData (all parsed data of a single P1 telegram) + *
      • header (the header string of a single P1 telegram) + *
      • obisId (the last OBIS Identifier seen or parsing) + *
      • obisValue (the last OBIS value seen or parsing) + *
      • crcValue (the last crc value seen or parsing) + *
      • state (state in the P1 telegram) + *
      + * + * @author mvolaart + * @since 1.7.0 + */ +class P1TelegramParserState { + static enum State { + // Wait for the '/' character + WAIT_FOR_START, + // '/' character seen + STARTED, + // Parsing data after the '/' character + HEADER, + // Waiting for the header to end with a CR & LF + CRLF, + // Handling OBIS Identifier + DATA_OBIS_ID, + // OBIS value start seen '(' + DATA_OBIS_VALUE_START, + // Parsing OBIS value + DATA_OBIS_VALUE, + // OBIS value end seen ')' + DATA_OBIS_VALUE_END, + // Parsing CRC value following '!' + CRC_VALUE + }; + + /* internal state variables */ + private String receivedData = ""; + private String header = ""; + private String obisId = ""; + private String obisValue = ""; + private String crcValue = ""; + private State state = State.WAIT_FOR_START; + + /** + * Creates a new P1TelegramParser object + */ + P1TelegramParserState() { + } + + /** + * Stores a single character + * + * @param c + * the character to store + */ + void handleCharacter(char c) { + + switch (state) { + case WAIT_FOR_START: + // ignore the data + break; + case STARTED: + header += c; + receivedData += c; + break; + case HEADER: + header += c; + receivedData += c; + break; + case CRLF: + receivedData += c; + break; + case DATA_OBIS_ID: + obisId += c; + receivedData += c; + break; + case DATA_OBIS_VALUE_START: + receivedData += c; + break; + case DATA_OBIS_VALUE: + obisValue += c; + receivedData += c; + break; + case DATA_OBIS_VALUE_END: + receivedData += c; + break; + case CRC_VALUE: + crcValue += c; + // CRC data is not part of received data + break; + default: + break; + } + } + + /** + * Clear internal state + */ + private void clearInternalData() { + header = ""; + obisId = ""; + obisValue = ""; + receivedData = ""; + crcValue = ""; + } + + /** + * Clears the received OBIS Identifer + */ + private void clearObisId() { + obisId = ""; + } + + /** + * Clears the current OBIS value + */ + private void clearObisValue() { + obisValue = ""; + } + + /** + * @return the state + */ + State getState() { + return state; + } + + /** + * @param state + * the state to set + */ + void setState(State newState) { + switch (newState) { + case WAIT_FOR_START: + clearInternalData(); + break; + case DATA_OBIS_ID: + clearObisId(); + clearObisValue(); + break; + case DATA_OBIS_VALUE_START: + break; + case DATA_OBIS_VALUE: + clearObisValue(); + break; + default: + break; + } + + state = newState; + } + + /** + * @return the meterId + */ + String getHeader() { + return header; + } + + /** + * @return the obisId + */ + String getObisId() { + return obisId; + } + + /** + * @return the obisValue + */ + String getObisValue() { + return obisValue; + } + + /** + * @return the crcValue + */ + String getCrcValue() { + return crcValue; + } + + /** + * @return the receivedData + */ + String getReceivedData() { + return receivedData; + } + + @Override + public String toString() { + return state + ", header = " + header + ", obisId = " + obisId + + ", obisValue = " + obisValue; + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/.classpath b/bundles/binding/org.openhab.binding.ecobee/.classpath new file mode 100644 index 00000000000..577bac87a26 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/bundles/library/org.openhab.library.tel/bin/.project b/bundles/binding/org.openhab.binding.ecobee/.project similarity index 84% rename from bundles/library/org.openhab.library.tel/bin/.project rename to bundles/binding/org.openhab.binding.ecobee/.project index 2cfeb09c548..69237326c6d 100644 --- a/bundles/library/org.openhab.library.tel/bin/.project +++ b/bundles/binding/org.openhab.binding.ecobee/.project @@ -1,7 +1,7 @@ - org.openhab.library.tel - This is the runtime component of the open Home Automation Bus (openHAB) + org.openhab.binding.ecobee + This is the Ecobee binding of the open Home Automation Bus (openHAB) diff --git a/bundles/binding/org.openhab.binding.ecobee/.settings/org.eclipse.jdt.core.prefs b/bundles/binding/org.openhab.binding.ecobee/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..f42de363afa --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/bundles/binding/org.openhab.binding.ecobee/.settings/org.eclipse.jdt.ui.prefs b/bundles/binding/org.openhab.binding.ecobee/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000000..243459222cb --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.ui.javadoc=false +org.eclipse.jdt.ui.text.custom_code_templates= diff --git a/bundles/binding/org.openhab.binding.ecobee/META-INF/MANIFEST.MF b/bundles/binding/org.openhab.binding.ecobee/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..256fc1768ac --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/META-INF/MANIFEST.MF @@ -0,0 +1,43 @@ +Manifest-Version: 1.0 +Private-Package: org.openhab.binding.ecobee.internal +Ignore-Package: org.openhab.binding.ecobee.internal +Bundle-License: http://www.eclipse.org/legal/epl-v10.html +Bundle-Name: openHAB Ecobee Binding +Bundle-SymbolicName: org.openhab.binding.ecobee +Bundle-Vendor: openHAB.org +Bundle-Version: 1.7.0.qualifier +Bundle-Activator: org.openhab.binding.ecobee.internal.EcobeeActivator +Bundle-ManifestVersion: 2 +Bundle-Description: This is the Ecobee binding of the open Home Aut + omation Bus (openHAB) +Import-Package: com.google.common.base, + com.google.common.io, + org.apache.commons.httpclient, + org.apache.commons.httpclient.util, + org.apache.commons.lang, + org.apache.commons.lang.builder, + org.apache.commons.logging, + org.codehaus.jackson, + org.codehaus.jackson.annotate, + org.codehaus.jackson.map, + org.openhab.binding.ecobee, + org.openhab.core.binding, + org.openhab.core.events, + org.openhab.core.items, + org.openhab.core.library.items, + org.openhab.core.library.types, + org.openhab.core.types, + org.openhab.io.net.http, + org.openhab.model.item.binding, + org.osgi.framework, + org.osgi.service.cm, + org.osgi.service.component, + org.osgi.service.event, + org.slf4j +Export-Package: org.openhab.binding.ecobee +Bundle-DocURL: http://www.openhab.org +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Service-Component: OSGI-INF/binding.xml, OSGI-INF/genericbindingprovider.xml +Bundle-ClassPath: lib/commons-beanutils-1.8.3.jar, + . +Require-Bundle: org.openhab.io.rest.lib diff --git a/bundles/binding/org.openhab.binding.ecobee/OSGI-INF/binding.xml b/bundles/binding/org.openhab.binding.ecobee/OSGI-INF/binding.xml new file mode 100644 index 00000000000..18c43772a58 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/OSGI-INF/binding.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.ecobee/OSGI-INF/genericbindingprovider.xml b/bundles/binding/org.openhab.binding.ecobee/OSGI-INF/genericbindingprovider.xml new file mode 100644 index 00000000000..4044a8f4ac8 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/OSGI-INF/genericbindingprovider.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.ecobee/README.md b/bundles/binding/org.openhab.binding.ecobee/README.md new file mode 100644 index 00000000000..8a0b03853b2 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/README.md @@ -0,0 +1,89 @@ +org.openhab.binding.ecobee +========================== + +openHAB Ecobee Binding + +Installation +------------ + +* Add an appkey and scope to openhab.cfg + +``` +ecobee:refresh=60000 +ecobee:appkey=ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHI +ecobee:scope=smartWrite +``` + +* Login to your Ecobee portal and navigate to My Apps + +* Install the binding bundle by copying the appropriate JAR file to your addons directory. + +* Monitor the openhab.log for INFO messages from this binding that instruct you to enter + the supplied four-letter PIN into the My Apps, and follow those instructions. + +* Configure items and rules. Examples: + +``` +Number Ecobee_Name "Room [%s]" {ecobee="<[123456789#name]" +``` +Return the name of the thermostat whose ID is 123456789 using the default Ecobee app instance (configured in openhab.cfg). + +``` +Number Dining_Humidity "Humidity [%d %%]" {ecobee="<[123456789#runtime.actualHumidity]"} +``` +Example item for retrieving the relative humidity. + +``` +Number Condo_Temperature "Condo Temperature [%d ºF]" {ecobee="<[condo.987654321#runtime.actualTemperature]"} +``` +Return the current temperature read by the thermostat using the condo account at ecobee.com. If you want to instead have Celsius temperatures reported, add the setting `ecobee:tempscale=C` to your openhab.cfg. + +``` +Number Dining_FanMinOnTime "Fan Min On Time [%d min/hour]" {ecobee="=[543212345#settings.fanMinOnTime]"} +``` +Set the minimum number of minutes per hour the fan will run on thermostat ID 543212345. + +``` +String All_HVAC_Modes "[%s]" {ecobee=">[*#settings.hvacMode]"} +``` +Change the HVAC mode to one of `"auto"`, `"auxHeatOnly"`, `"cool"`, `"heat"`, or +`"off"` on all thermostats registered in the default app instance. + +``` +Number Lakehouse_Backlights "[%d]" {ecobee=">[lakehouse.*#settings.backlightSleepIntensity]"} +``` +Changes the backlight sleep intensity on all thermostats at the lake house (meaning, all thermostats registered to the lakehouse Ecobee account). + +Supported are a long list of runtime and configuration values (see below). + +Example rule to send a mail if humidity reaches a certain threshold: +``` +var boolean humHighWarning = false +var boolean humVeryHighWarning = false + +rule "Monitor humidity level" + when + Item Dining_Humidity changed + then + if(Dining_Humidity.state > 60) { + if(humHighWarning == false) { + sendMail("example@example.com", + "High humidity level!", + "Humidity level is " + Dining_Humidity.state + " %%.") + humHighWarning = true + } + } else if(Dining_Humidity.state > 75) { + if(humVeryHighWarning == false) { + sendMail("example@example.com", + "Very high humidity level!", + "Humidity level is " + Dining_Humidity.state + " %%.") + humVeryHighWarning = true + } + } else { + humHighWarning = false + humVeryHighWarning = false + } +end +``` + +TBD diff --git a/bundles/binding/org.openhab.binding.ecobee/build.properties b/bundles/binding/org.openhab.binding.ecobee/build.properties new file mode 100644 index 00000000000..008e33bdc67 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/build.properties @@ -0,0 +1,7 @@ +source.. = src/main/java/,\ + src/main/resources/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/,\ + lib/commons-beanutils-1.8.3.jar +output.. = target/classes/ diff --git a/bundles/binding/org.openhab.binding.ecobee/lib/commons-beanutils-1.8.3.jar b/bundles/binding/org.openhab.binding.ecobee/lib/commons-beanutils-1.8.3.jar new file mode 100644 index 00000000000..218510bc5d6 Binary files /dev/null and b/bundles/binding/org.openhab.binding.ecobee/lib/commons-beanutils-1.8.3.jar differ diff --git a/bundles/binding/org.openhab.binding.ecobee/pom.xml b/bundles/binding/org.openhab.binding.ecobee/pom.xml new file mode 100644 index 00000000000..5394100b3f4 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/pom.xml @@ -0,0 +1,35 @@ + + + + + org.openhab.bundles + binding + 1.7.0-SNAPSHOT + + + + org.openhab.binding.ecobee + org.openhab.binding.ecobee + openhab-addon-binding-Ecobee + openhab addon binding Ecobee + + + 4.0.0 + org.openhab.binding + org.openhab.binding.ecobee + + openHAB Ecobee Binding + + eclipse-plugin + + + + + org.vafer + jdeb + + + + + diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/EcobeeBindingProvider.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/EcobeeBindingProvider.java new file mode 100644 index 00000000000..c2ca31c0ac0 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/EcobeeBindingProvider.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee; + +import org.openhab.core.binding.BindingProvider; + +/** + * This interface is implemented by classes that can provide mapping information between openHAB items and Ecobee items. + * + * Implementing classes should register themselves as a service in order to be taken into account. + * + * @author John Cocula + * @since 1.7.0 + */ +public interface EcobeeBindingProvider extends BindingProvider { + + /** + * Returns an Id of the user the settings refer to. + * + * @param itemName + * the itemName to query + * @return the ID of the user the settings refer to. + */ + String getUserid(String itemName); + + /** + * Queries the Ecobee thermostat identifier of the given {@code itemName}. + * + * @param itemName + * the itemName to query + * @return the Ecobee thermostat identifier of the Item identified by {@code itemName} if it has an Ecobee binding, + * null otherwise + */ + String getThermostatIdentifier(String itemName); + + /** + * Queries the Ecobee property of the given {@code itemName}. + * + * @param itemName + * the itemName to query + * @return the Ecobee property of the Item identified by {@code itemName} if it has an Ecobee binding, + * null otherwise + */ + String getProperty(String itemName); + + /** + * Queries whether this item can be read from the Ecobee API, for the given {@code itemName}. + * + * @param itemName + * the itemName to query + * @return true if this property can be read from the Ecobee API. + */ + boolean isInBound(String itemName); + + /** + * Queries whether this item can be written to the Ecobee API, for the given {@code itemName}. + * + * @param itemName + * the itemName to query + * @return true if this property can be written to the Ecobee API. + */ + boolean isOutBound(String itemName); +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeActivator.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeActivator.java new file mode 100644 index 00000000000..c209c4adf86 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeActivator.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Extension of the default OSGi bundle activator + * + * @author John Cocula + * @since 1.7.0 + */ +public final class EcobeeActivator implements BundleActivator { + + private static Logger logger = LoggerFactory.getLogger(EcobeeActivator.class); + + private static BundleContext context; + + /** + * Called whenever the OSGi framework starts our bundle + */ + public void start(BundleContext bc) throws Exception { + context = bc; + logger.debug("Ecobee binding has been started."); + } + + /** + * Called whenever the OSGi framework stops our bundle + */ + public void stop(BundleContext bc) throws Exception { + context = null; + logger.debug("Ecobee binding has been stopped."); + } + + /** + * Returns the bundle context of this bundle + * + * @return the bundle context + */ + public static BundleContext getContext() { + return context; + } + +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeBinding.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeBinding.java new file mode 100644 index 00000000000..aa49a52ff66 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeBinding.java @@ -0,0 +1,1009 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.prefs.Preferences; + +import org.apache.commons.beanutils.ConvertUtils; +import org.apache.commons.beanutils.Converter; +import org.openhab.binding.ecobee.EcobeeBindingProvider; +import org.openhab.binding.ecobee.internal.messages.AbstractFunction; +import org.openhab.binding.ecobee.internal.messages.ApiResponse; +import org.openhab.binding.ecobee.internal.messages.AuthorizeRequest; +import org.openhab.binding.ecobee.internal.messages.AuthorizeResponse; +import org.openhab.binding.ecobee.internal.messages.Request; +import org.openhab.binding.ecobee.internal.messages.Selection; +import org.openhab.binding.ecobee.internal.messages.Selection.SelectionType; +import org.openhab.binding.ecobee.internal.messages.Status; +import org.openhab.binding.ecobee.internal.messages.Temperature; +import org.openhab.binding.ecobee.internal.messages.Thermostat; +import org.openhab.binding.ecobee.internal.messages.Thermostat.HvacMode; +import org.openhab.binding.ecobee.internal.messages.Thermostat.VentilatorMode; +import org.openhab.binding.ecobee.internal.messages.ThermostatRequest; +import org.openhab.binding.ecobee.internal.messages.ThermostatResponse; +import org.openhab.binding.ecobee.internal.messages.ThermostatSummaryRequest; +import org.openhab.binding.ecobee.internal.messages.ThermostatSummaryResponse; +import org.openhab.binding.ecobee.internal.messages.ThermostatSummaryResponse.Revision; +import org.openhab.binding.ecobee.internal.messages.RefreshTokenRequest; +import org.openhab.binding.ecobee.internal.messages.TokenRequest; +import org.openhab.binding.ecobee.internal.messages.TokenResponse; +import org.openhab.binding.ecobee.internal.messages.UpdateThermostatRequest; + +import static org.apache.commons.lang.StringUtils.isNotBlank; + +import org.openhab.core.binding.AbstractActiveBinding; +import org.openhab.core.binding.BindingProvider; +import org.openhab.core.items.ItemRegistry; +import org.openhab.core.library.types.DateTimeType; +import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.StringType; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Binding that retrieves information about thermostats we're interested in every few minutes, and sends updates and + * commands to Ecobee as they are made. Reviewed lots of other binding implementations, particularly Netatmo and XBMC. + * + * @author John Cocula + * @since 1.7.0 + */ +public class EcobeeBinding extends AbstractActiveBinding implements ManagedService { + + private static final String DEFAULT_USER_ID = "DEFAULT_USER"; + + private static final Logger logger = LoggerFactory.getLogger(EcobeeBinding.class); + + protected static final String CONFIG_REFRESH = "refresh"; + protected static final String CONFIG_APP_KEY = "appkey"; + protected static final String CONFIG_SCOPE = "scope"; + protected static final String CONFIG_TEMP_SCALE = "tempscale"; + + static { + // Register bean type converters + ConvertUtils.register(new Converter() { + + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof DecimalType) { + return Temperature.fromLocalTemperature(((DecimalType) value).toBigDecimal()); + } else { + return null; + } + } + }, Temperature.class); + ConvertUtils.register(new Converter() { + + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof StringType) { + return HvacMode.forValue(value.toString()); + } else { + return null; + } + } + }, HvacMode.class); + ConvertUtils.register(new Converter() { + + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof DecimalType) { + return ((DecimalType) value).intValue(); + } else { + return null; + } + } + }, Integer.class); + ConvertUtils.register(new Converter() { + + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof StringType) { + return VentilatorMode.forValue(value.toString()); + } else { + return null; + } + } + }, VentilatorMode.class); + ConvertUtils.register(new Converter() { + + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof OnOffType) { + return ((OnOffType) value) == OnOffType.ON; + } else { + return null; + } + } + }, Boolean.class); + ConvertUtils.register(new Converter() { + + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + return value.toString(); + } + }, String.class); + } + + /** + * the refresh interval which is used to poll values from the Ecobee server (optional, defaults to 60000ms) + */ + private long refreshInterval = 60000; + + /** + * A map of userids from the openhab.cfg file to OAuth credentials used to communicate with each app instance. + */ + private Map credentialsCache = new HashMap(); + + /** + * used to store events that we have sent ourselves; we need to remember them for not reacting to them + */ + private List ignoreEventList = Collections.synchronizedList(new ArrayList()); + + /** + * The most recently received list of revisions, or an empty Map if none have been retrieved yet. + */ + private Map lastRevisionMap = new HashMap(); + + // Injected by the OSGi Container through the setItemRegistry and + // unsetItemRegistry methods. + private ItemRegistry itemRegistry; + + public EcobeeBinding() { + } + + /** + * Invoked by the OSGi Framework. + * + * This method is invoked by OSGi during the initialization of the EcobeeBinding, so we have subsequent access to + * the ItemRegistry (needed to get values from Items in openHAB) + */ + public void setItemRegistry(ItemRegistry itemRegistry) { + this.itemRegistry = itemRegistry; + } + + /** + * Invoked by the OSGi Framework. + * + * This method is invoked by OSGi during the initialization of the EcobeeBinding, so we have subsequent access to + * the ItemRegistry (needed to get values from Items in openHAB) + */ + public void unsetItemRegistry(ItemRegistry itemRegistry) { + this.itemRegistry = null; + } + + /** + * {@inheritDoc} + */ + @Override + public void activate() { + super.activate(); + } + + /** + * {@inheritDoc} + */ + @Override + public void deactivate() { + // deallocate resources here that are no longer needed and + // should be reset when activating this binding again + } + + /** + * {@inheritDoc} + */ + @Override + protected long getRefreshInterval() { + return refreshInterval; + } + + /** + * {@inheritDoc} + */ + @Override + protected String getName() { + return "Ecobee Refresh Service"; + } + + /** + * {@inheritDoc} + */ + @Override + protected void execute() { + logger.trace("Querying Ecobee API"); + + try { + for (String userid : credentialsCache.keySet()) { + OAuthCredentials oauthCredentials = getOAuthCredentials(userid); + + Selection selection = createSelection(oauthCredentials); + if (selection == null) { + logger.debug("Nothing to retrieve for '{}'; skipping thermostat retrieval.", + oauthCredentials.userid); + continue; + } + + if (oauthCredentials.noAccessToken()) { + if (!oauthCredentials.refreshTokens()) { + logger.warn("Periodic poll skipped for '{}'.", oauthCredentials.userid); + continue; + } + } + + readEcobee(oauthCredentials, selection); + } + } catch (Exception e) { + logger.error("Error reading from Ecobee:", e); + } + } + + /** + * Given the credentials to use and what to select from the Ecobee API, read any changed information from Ecobee and + * update the affected items. + * + * @param oauthCredentials + * the credentials to use + * @param selection + * the selection of data to retrieve + */ + private void readEcobee(OAuthCredentials oauthCredentials, Selection selection) throws Exception { + + logger.debug("Requesting summaries for {}", selection); + + ThermostatSummaryRequest request = new ThermostatSummaryRequest(oauthCredentials.accessToken, selection); + ThermostatSummaryResponse response = request.execute(); + if (response.isError()) { + final Status status = response.getStatus(); + + if (status.isAccessTokenExpired()) { + logger.debug("Access token has expired: {}", status); + if (oauthCredentials.refreshTokens()) + readEcobee(oauthCredentials, selection); + } else { + logger.error(status.getMessage()); + } + + return; // abort processing + } + + logger.debug("Retrieved summaries for {} thermostat(s).", response.getRevisionList().size()); + + // Identify which thermostats have changed since the last fetch + + Map newRevisionMap = new HashMap(); + for (Revision r : response.getRevisionList()) { + newRevisionMap.put(r.getThermostatIdentifier(), r); + } + + // Accumulate the thermostat IDs for thermostats that have updated + // since the last fetch. + Set thermostatIdentifiers = new HashSet(); + + for (Revision newRevision : newRevisionMap.values()) { + Revision lastRevision = this.lastRevisionMap.get(newRevision.getThermostatIdentifier()); + + // If this thermostat's values have changed, + // add it to the list for full retrieval + + /* + * NOTE: The following tests may be more eager than they should be, because we may have a settings binding + * for one thermostat and not another, and a runtime binding for another thermostat but not this one, but we + * will now retrieve both thermostats. A small sin. If the Ecobee binding is only working with a single + * thermostat, these tests will be perfectly accurate. + */ + + boolean changed = false; + + changed = changed + || (newRevision.hasRuntimeChanged(lastRevision) && (selection.includeRuntime() || selection + .includeExtendedRuntime())); + changed = changed + || (newRevision.hasThermostatChanged(lastRevision) && (selection.includeSettings() || selection + .includeProgram())); + + if (changed) { + thermostatIdentifiers.add(newRevision.getThermostatIdentifier()); + } + } + + // Remember the new revisions for the next execute() call. + this.lastRevisionMap = newRevisionMap; + + if (0 == thermostatIdentifiers.size()) { + logger.debug("No changes detected."); + return; + } + + logger.debug("Requesting full retrieval for {} thermostat(s).", thermostatIdentifiers.size()); + + // Potentially decrease the number of thermostats for the full + // retrieval. + + selection.setSelectionMatch(thermostatIdentifiers); + + // TODO loop through possibly multiple pages (@watou) + ThermostatRequest treq = new ThermostatRequest(oauthCredentials.accessToken, selection, null); + ThermostatResponse tres = treq.execute(); + + if (tres.isError()) { + logger.error("Error retrieving thermostats: {}", tres.getStatus()); + return; + } + + // Create a ID-based map of the thermostats we retrieved. + Map thermostats = new HashMap(); + + for (Thermostat t : tres.getThermostatList()) { + thermostats.put(t.getIdentifier(), t); + } + + // Iterate through bindings and update all inbound values. + for (final EcobeeBindingProvider provider : this.providers) { + for (final String itemName : provider.getItemNames()) { + if (provider.isInBound(itemName)) { + final State newState = getState(provider, thermostats, itemName); + State oldState = (itemRegistry == null) ? null : itemRegistry.getItem(itemName).getState(); + + if ((oldState == null && newState != null) + || (UnDefType.UNDEF.equals(oldState) && !UnDefType.UNDEF.equals(newState)) + || !oldState.equals(newState)) { + logger.debug("readEcobee: Updating itemName '{}' with newState '{}', oldState '{}'", itemName, + newState, oldState); + + /* + * we need to make sure that we won't send out this event to Ecobee again, when receiving it on + * the openHAB bus + */ + ignoreEventList.add(itemName + newState.toString()); + logger.trace("Added event (item='{}', newState='{}') to the ignore event list", itemName, + newState); + this.eventPublisher.postUpdate(itemName, newState); + } else { + logger.trace("readEcobee: Ignoring item='{}' with newState='{}', oldState='{}'", itemName, + newState, oldState); + } + } + } + } + } + + /** + * Give a binding provider, a map of thermostats, and an item name, return the corresponding state object. + * + * @param provider + * the Ecobee binding provider + * @param thermostats + * a map of thermostat identifiers to {@link Thermostat} objects + * @param itemName + * the item name from the items file. + * @return the State object for the named item + */ + private State getState(EcobeeBindingProvider provider, Map thermostats, String itemName) { + + final String thermostatIdentifier = provider.getThermostatIdentifier(itemName); + final String property = provider.getProperty(itemName); + final Thermostat thermostat = thermostats.get(thermostatIdentifier); + + if (thermostat == null) { + logger.error("Did not receive thermostat '{}' for item '{}'; skipping.", thermostatIdentifier, itemName); + } else { + try { + return createState(thermostat.getProperty(property)); + } catch (Exception e) { + logger.error("Unable to get state from thermostat", e); + } + } + return UnDefType.NULL; + } + + /** + * Creates an openHAB {@link State} in accordance to the class of the given {@code propertyValue}. Currently + * {@link Date}, {@link BigDecimal}, {@link Temperature} and {@link Boolean} are handled explicitly. All other + * {@code dataTypes} are mapped to {@link StringType}. + *

      + * If {@code propertyValue} is {@code null}, {@link UnDefType#NULL} will be returned. + * + * Copied/adapted from the Koubachi binding. + * + * @param propertyValue + * + * @return the new {@link State} in accordance with {@code dataType}. Will never be {@code null}. + */ + private State createState(Object propertyValue) { + if (propertyValue == null) { + return UnDefType.NULL; + } + + Class dataType = propertyValue.getClass(); + + if (Date.class.isAssignableFrom(dataType)) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime((Date) propertyValue); + return new DateTimeType(calendar); + } else if (Integer.class.isAssignableFrom(dataType)) { + return new DecimalType((Integer) propertyValue); + } else if (BigDecimal.class.isAssignableFrom(dataType)) { + return new DecimalType((BigDecimal) propertyValue); + } else if (Boolean.class.isAssignableFrom(dataType)) { + if ((Boolean) propertyValue) { + return OnOffType.ON; + } else { + return OnOffType.OFF; + } + } else if (Temperature.class.isAssignableFrom(dataType)) { + return new DecimalType(((Temperature) propertyValue).toLocalTemperature()); + } else { + return new StringType(propertyValue.toString()); + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void internalReceiveCommand(String itemName, Command command) { + logger.trace("internalReceiveCommand(item='{}', command='{}')", itemName, command); + commandEcobee(itemName, command); + } + + /** + * {@inheritDoc} + */ + @Override + protected void internalReceiveUpdate(final String itemName, final State newState) { + logger.trace("Received update (item='{}', state='{}')", itemName, newState.toString()); + if (!isEcho(itemName, newState)) { + updateEcobee(itemName, newState); + } + } + + /** + * Perform the given {@code command} against all targets referenced in {@code itemName}. + * + * @param command + * the command to execute + * @param the + * target(s) against which to execute this command + */ + private void commandEcobee(final String itemName, final Command command) { + if (command instanceof State) { + updateEcobee(itemName, (State) command); + } + } + + private boolean isEcho(String itemName, State state) { + String ignoreEventListKey = itemName + state.toString(); + if (ignoreEventList.remove(ignoreEventListKey)) { + logger.trace( + "We received this event (item='{}', state='{}') from Ecobee, so we don't send it back again -> ignore!", + itemName, state.toString()); + return true; + } else { + return false; + } + } + + /** + * Send the {@code newState} for the given {@code itemName} to Ecobee. + * + * @param itemName + * @param newState + */ + private void updateEcobee(final String itemName, final State newState) { + + // Find the first binding provider for this itemName. + EcobeeBindingProvider provider = null; + String selectionMatch = null; + for (EcobeeBindingProvider p : this.providers) { + selectionMatch = p.getThermostatIdentifier(itemName); + if (selectionMatch != null) { + provider = p; + break; + } + } + + if (provider == null) { + logger.warn("no matching binding provider found [itemName={}, newState={}]", itemName, newState); + return; + } else { + final Selection selection = new Selection(selectionMatch); + List functions = null; + logger.debug("Selection for update: {}", selection); + + String property = provider.getProperty(itemName); + + try { + final Thermostat thermostat = new Thermostat(null); + + logger.debug("About to set property '{}' to '{}'", property, newState); + + thermostat.setProperty(property, newState); + + logger.debug("Thermostat for update: {}", thermostat); + + OAuthCredentials oauthCredentials = getOAuthCredentials(provider.getUserid(itemName)); + + if (oauthCredentials == null) { + logger.warn("Unable to locate credentials for item {}; aborting update.", itemName); + return; + } + + if (oauthCredentials.noAccessToken()) { + if (!oauthCredentials.refreshTokens()) { + logger.warn("Sending update skipped."); + return; + } + } + + UpdateThermostatRequest request = new UpdateThermostatRequest(oauthCredentials.accessToken, selection, + functions, thermostat); + ApiResponse response = request.execute(); + if (response.isError()) { + final Status status = response.getStatus(); + if (status.isAccessTokenExpired()) { + if (oauthCredentials.refreshTokens()) { + updateEcobee(itemName, newState); + } + } else { + logger.error("Error updating thermostat(s): {}", response); + } + } + } catch (Exception e) { + logger.error("Unable to update thermostat(s)", e); + } + } + } + + /** + * {@inheritDoc} + */ + public void bindingChanged(BindingProvider provider, String itemName) { + + // Forget prior revisions because we may be concerned with + // different thermostats or properties than before. + if (provider instanceof EcobeeBindingProvider) { + this.lastRevisionMap.clear(); + } + } + + /** + * {@inheritDoc} + */ + public void allBindingsChanged(BindingProvider provider) { + + // Forget prior revisions because we may be concerned with + // different thermostats or properties than before. + if (provider instanceof EcobeeBindingProvider) { + this.lastRevisionMap.clear(); + } + } + + /** + * Returns the cached {@link OAuthCredentials} for the given {@code userid}. If their is no such cached + * {@link OAuthCredentials} element, the cache is searched with the {@code DEFAULT_USER}. If there is still no + * cached element found {@code NULL} is returned. + * + * @param userid + * the userid to find the {@link OAuthCredentials} + * @return the cached {@link OAuthCredentials} or {@code NULL} + */ + private OAuthCredentials getOAuthCredentials(String userid) { + if (credentialsCache.containsKey(userid)) { + return credentialsCache.get(userid); + } else { + return credentialsCache.get(DEFAULT_USER_ID); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void updated(Dictionary config) throws ConfigurationException { + if (config != null) { + + // to override the default refresh interval one has to add a + // parameter to openhab.cfg like ecobee:refresh=120000 + String refreshIntervalString = (String) config.get(CONFIG_REFRESH); + if (isNotBlank(refreshIntervalString)) { + refreshInterval = Long.parseLong(refreshIntervalString); + } + // to override the default usage of Fahrenheit one has to add a + // parameter to openhab.cfg, as in ecobee:tempscale=C + String tempScaleString = (String) config.get(CONFIG_TEMP_SCALE); + if (isNotBlank(tempScaleString)) { + try { + Temperature.setLocalScale(Temperature.Scale.forValue(tempScaleString)); + } catch (IllegalArgumentException iae) { + throw new ConfigurationException(CONFIG_TEMP_SCALE, "Unsupported temperature scale '" + + tempScaleString + "'."); + } + } + + Enumeration configKeys = config.keys(); + while (configKeys.hasMoreElements()) { + String configKey = (String) configKeys.nextElement(); + + // the config-key enumeration contains additional keys that we + // don't want to process here ... + if (CONFIG_REFRESH.equals(configKey) || CONFIG_TEMP_SCALE.equals(configKey) + || "service.pid".equals(configKey)) { + continue; + } + + String userid; + String configKeyTail; + + if (configKey.contains(".")) { + String[] keyElements = configKey.split("\\."); + userid = keyElements[0]; + configKeyTail = keyElements[1]; + + } else { + userid = DEFAULT_USER_ID; + configKeyTail = configKey; + } + + OAuthCredentials credentials = credentialsCache.get(userid); + if (credentials == null) { + credentials = new OAuthCredentials(userid); + credentialsCache.put(userid, credentials); + } + + String value = (String) config.get(configKey); + + if (CONFIG_APP_KEY.equals(configKeyTail)) { + credentials.appKey = value; + } else if (CONFIG_SCOPE.equals(configKeyTail)) { + credentials.scope = value; + } else { + throw new ConfigurationException(configKey, "the given configKey '" + configKey + "' is unknown"); + } + } + + // Verify the completeness of each OAuthCredentials entry + // to make sure we can get started. + + boolean properlyConfigured = true; + + for (String userid : credentialsCache.keySet()) { + OAuthCredentials oauthCredentials = getOAuthCredentials(userid); + String userString = (DEFAULT_USER_ID.equals(userid)) ? "" : (userid + "."); + if (oauthCredentials.appKey == null) { + logger.error("Required ecobee:{}{} is missing.", userString, CONFIG_APP_KEY); + properlyConfigured = false; + break; + } + if (oauthCredentials.scope == null) { + logger.error("Required ecobee:{}{} is missing.", userString, CONFIG_SCOPE); + properlyConfigured = false; + break; + } + } + + setProperlyConfigured(properlyConfigured); + } + } + + /** + * Creates the necessary {@link Selection} object to request all information required from the Ecobee API for all + * thermostats and sub-objects that have a binding, per set of credentials configured in openhab.cfg. One + * {@link ThermostatRequest} can then query all information in one go. + * + * @param oauthCredentials + * constrain the resulting Selection object to only select the thermostats which the configuration + * indicates can be reached using these credentials. + * @returns the Selection object, or null if only an unsuitable Selection is possible. + */ + private Selection createSelection(OAuthCredentials oauthCredentials) { + final Selection selection = new Selection(SelectionType.THERMOSTATS, null); + final Set thermostatIdentifiers = new HashSet(); + + for (final EcobeeBindingProvider provider : this.providers) { + for (final String itemName : provider.getItemNames()) { + + final String thermostatIdentifier = provider.getThermostatIdentifier(itemName); + final String property = provider.getProperty(itemName); + + /* + * We are only concerned with inbound items, so there would be no point to including the criteria for + * this item. + * + * We are also only concerned with items that can be reached by the given credentials. + */ + + if (!provider.isInBound(itemName) + || oauthCredentials != getOAuthCredentials(provider.getUserid(itemName))) { + continue; + } + + thermostatIdentifiers.add(thermostatIdentifier); + + if (property.startsWith("settings")) { + selection.setIncludeSettings(true); + } else if (property.startsWith("runtime")) { + selection.setIncludeRuntime(true); + } else if (property.startsWith("extendedRuntime")) { + selection.setIncludeExtendedRuntime(true); + } else if (property.startsWith("electricity")) { + selection.setIncludeElectricity(true); + } else if (property.startsWith("devices")) { + selection.setIncludeDevice(true); + } else if (property.startsWith("electricity")) { + selection.setIncludeElectricity(true); + } else if (property.startsWith("location")) { + selection.setIncludeLocation(true); + } else if (property.startsWith("technician")) { + selection.setIncludeTechnician(true); + } else if (property.startsWith("utility")) { + selection.setIncludeUtility(true); + } else if (property.startsWith("management")) { + selection.setIncludeManagement(true); + } else if (property.startsWith("weather")) { + selection.setIncludeWeather(true); + } else if (property.startsWith("events")) { + selection.setIncludeEvents(true); + } else if (property.startsWith("program")) { + selection.setIncludeProgram(true); + } else if (property.startsWith("houseDetails")) { + selection.setIncludeHouseDetails(true); + } else if (property.startsWith("oemCfg")) { + selection.setIncludeOemCfg(true); + } else if (property.startsWith("equipmentStatus")) { + selection.setIncludeEquipmentStatus(true); + } else if (property.startsWith("notificationSettings")) { + selection.setIncludeNotificationSettings(true); + } else if (property.startsWith("privacy")) { + selection.setIncludePrivacy(true); + } else if (property.startsWith("version")) { + selection.setIncludeVersion(true); + } + } + } + + if (thermostatIdentifiers.isEmpty()) { + logger.info("No Ecobee in-bindings have been found for selection."); + return null; + } + + // include all the thermostats we found in the bindings + selection.setSelectionMatch(thermostatIdentifiers); + + return selection; + } + + /** + * This internal class holds the different credentials necessary for the OAuth2 flow to work. It also provides basic + * methods to refresh the tokens. + * + *

      + * OAuth States + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      authTokenrefreshTokenaccessTokenState
      nullauthorize
      non-nullnullrequest tokens
      non-nullnon-nullnullrefresh tokens
      non-nullnon-nullnon-nullif expired, refresh if any error, authorize
      + * + * @author John Cocula + * @since 1.7.0 + */ + static class OAuthCredentials { + + private static final String AUTH_TOKEN = "authToken"; + private static final String REFRESH_TOKEN = "refreshToken"; + private static final String ACCESS_TOKEN = "accessToken"; + + private String userid; + + /** + * The private app key needed in order to interact with the Ecobee API. This must be provided in the + * openhab.cfg file. + */ + private String appKey; + + /** + * The scope needed when authorizing this client to the Ecobee API. + * + * @see AuthorizeRequest + */ + private String scope; + + /** + * The authorization token needed to request the refresh and access tokens. Obtained and persisted when + * {@code authorize()} is called. + * + * @see AuthorizeRequest + * @see #authorize() + */ + private String authToken; + + /** + * The refresh token to access the Ecobee API. Initial token is received using the authToken, + * periodically refreshed using the previous refreshToken, and saved in persistent storage so it can be used + * across activations. + * + * @see TokenRequest + * @see RefreshTokenRequest + */ + private String refreshToken; + + /** + * The access token to access the Ecobee API. Automatically renewed from the API using the refresh token and + * persisted for use across activations. + * + * @see #refreshTokens() + */ + private String accessToken; + + public OAuthCredentials(String userid) { + + try { + this.userid = userid; + load(); + } catch (Exception e) { + throw new EcobeeException("Cannot create OAuthCredentials.", e); + } + } + + private Preferences getPrefsNode() { + return Preferences.userRoot().node("org.openhab.ecobee." + userid); + } + + private void load() { + Preferences prefs = getPrefsNode(); + this.authToken = prefs.get(AUTH_TOKEN, null); + this.refreshToken = prefs.get(REFRESH_TOKEN, null); + this.accessToken = prefs.get(ACCESS_TOKEN, null); + } + + private void save() { + Preferences prefs = getPrefsNode(); + if (this.authToken != null) { + prefs.put(AUTH_TOKEN, this.authToken); + } else { + prefs.remove(AUTH_TOKEN); + } + + if (this.refreshToken != null) { + prefs.put(REFRESH_TOKEN, this.refreshToken); + } else { + prefs.remove(REFRESH_TOKEN); + } + + if (this.accessToken != null) { + prefs.put(ACCESS_TOKEN, this.accessToken); + } else { + prefs.remove(ACCESS_TOKEN); + } + } + + public boolean noAccessToken() { + return this.accessToken == null; + } + + public void authorize() { + logger.trace("Authorizing this binding with the Ecobee API."); + + final AuthorizeRequest request = new AuthorizeRequest(this.appKey, this.scope); + logger.trace("Request: {}", request); + + final AuthorizeResponse response = request.execute(); + logger.trace("Response: {}", response); + + this.authToken = response.getAuthToken(); + this.refreshToken = null; + this.accessToken = null; + save(); + + logger.info("#########################################################################################"); + logger.info("# Ecobee-Integration: U S E R I N T E R A C T I O N R E Q U I R E D !!"); + logger.info("# 1. Login to www.ecobee.com using your '{}' account", this.userid); + logger.info("# 2. Enter the PIN '{}' in My Apps within the next {} minutes.", response.getEcobeePin(), + response.getExpiresIn()); + logger.info("# NOTE: Any API attempts will fail in the meantime."); + logger.info("#########################################################################################"); + } + + /** + * This method attempts to advance the authorization process by retrieving the tokens needed to use the API. It + * returns true if there is reason to believe that an immediately subsequent API call would + * succeed. + *

      + * This method requests access and refresh tokens to use the Ecobee API. If there is a refreshToken + * , it will be used to obtain the tokens, but if there is only an authToken, that will be used + * instead. + * + * @return true if there is reason to believe that an immediately subsequent API call would + * succeed. + */ + public boolean refreshTokens() { + if (this.authToken == null) { + authorize(); + return false; + } else { + logger.trace("Refreshing tokens."); + + Request request; + + if (this.refreshToken == null) { + request = new TokenRequest(this.authToken, this.appKey); + } else { + request = new RefreshTokenRequest(this.refreshToken, this.appKey); + } + logger.trace("Request: {}", request); + + final TokenResponse response = (TokenResponse) request.execute(); + logger.trace("Response: {}", response); + + if (response.isError()) { + logger.error("Error retrieving tokens: {}", response.getError()); + return false; + } else { + this.refreshToken = response.getRefreshToken(); + this.accessToken = response.getAccessToken(); + save(); + return true; + } + } + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeException.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeException.java new file mode 100644 index 00000000000..6561ab829ba --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeException.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal; + +/** + * @author John Cocula + * @since 1.7.0 + */ +public class EcobeeException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public EcobeeException(final String message, final Throwable cause) { + super(message, cause); + } + + public EcobeeException(final Throwable cause) { + super(cause); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeGenericBindingProvider.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeGenericBindingProvider.java new file mode 100644 index 00000000000..011b80c1493 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/EcobeeGenericBindingProvider.java @@ -0,0 +1,268 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.openhab.binding.ecobee.EcobeeBindingProvider; +import org.openhab.binding.ecobee.internal.messages.Selection; +import org.openhab.core.binding.BindingConfig; +import org.openhab.core.items.Item; +import org.openhab.model.item.binding.AbstractGenericBindingProvider; +import org.openhab.model.item.binding.BindingConfigParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is responsible for parsing the binding configuration. + * + *

      + * Ecobee bindings start with a <, > or =, to indicate if the item receives values from the API (in binding), + * sends values to the API (out binding), or both (bidirectional binding), respectively. + * + *

      + * The first character is then followed by a section between square brackets ([ and ] characters): + * + *

      + * [<thermostat>#<property>] + * + *

      + * Where thermostat is a decimal thermostat identifier for in, out and bidirectional bindings. + * + *

      + * For out bindings only, thermostat can instead be selection criteria that specify which thermostats to + * change. You can use either a comma-separated list of thermostat identifiers, or, for non-EMS thermostats only, a + * wildcard (the * character). + * + *

      + * In the case of out bindings for EMS or Utility accounts, the thermostat criteria can be a path to a + * management set (for example, /Toronto/Campus/BuildingA). + * + *

      + * The thermostat specification can be optionally prepended with a specific app instance name as specified + * in openhab.cfg, as in condo.123456789 when you have specified + * ecobee:condo.scope and ecobee:condo.appkey properties in openhab.cfg. + * + *

      + * property is one of a long list of thermostat properties than you can read and optionally change. See the + * list below, and peruse this binding's JavaDoc for all specifics as to their meanings. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      PropertyInOut + *
      nameXX
      runtime.actualTemperatureX
      runtime.actualHumidityX
      settings.hvacModeXX
      + * + *

      + * Example bindings: + *

        + *
      • { ecobee="<[123456789#name]" } + *

        + * Return the name of the thermostat whose ID is 123456789 using the default Ecobee app instance (configured in + * openhab.cfg).

      • + *
      • { ecobee="<[condo.987654321#runtime.actualTemperature]" } + *

        + * Return the current temperature read by the thermostat using the condo account at ecobee.com.

      • + *
      • { ecobee=">[543212345#settings.fanMinOnTime]" } + *

        + * Set the minimum number of minutes per hour the fan will run on thermostat ID 543212345.

      • + *
      • { ecobee=">[*#settings.hvacMode]" } + *

        + * Change the HVAC mode to one of "auto", "auxHeatOnly", "cool", + * "heat", or "off" on all thermostats registered in the default app instance.

      • + *
      • + * { ecobee=">[lakehouse.*#settings.backlightSleepIntensity]" } + *

        + * Changes the backlight sleep intensity on all thermostats at the lake house (meaning, all thermostats registered to + * the lakehouse Ecobee account).

      • + *
      + * + * @author John Cocula + * @since 1.7.0 + */ +public class EcobeeGenericBindingProvider extends AbstractGenericBindingProvider implements EcobeeBindingProvider { + + private static class EcobeeBindingConfig implements BindingConfig { + String userid; + String thermostatIdentifier; + String property; + boolean inBound = false; + boolean outBound = false; + + public EcobeeBindingConfig(final String userid, final String thermostatIdentifier, final String property, + final boolean inBound, final boolean outBound) { + this.userid = userid; + this.thermostatIdentifier = thermostatIdentifier; + this.property = property; + this.inBound = inBound; + this.outBound = outBound; + } + + @Override + public String toString() { + return "EcobeeBindingConfig [userid=" + this.userid + "thermostatIdentifier=" + this.thermostatIdentifier + + ", property=" + this.property + ", inBound=" + this.inBound + ", outBound=" + this.outBound + "]"; + } + } + + private static Logger logger = LoggerFactory.getLogger(EcobeeGenericBindingProvider.class); + + private static final Pattern CONFIG_PATTERN = Pattern.compile(".\\[(.*)#(.*)\\]"); + + // the first character in the above pattern + private static final String IN_BOUND = "<"; + private static final String OUT_BOUND = ">"; + private static final String BIDIRECTIONAL = "="; + + /** + * {@inheritDoc} + */ + public String getBindingType() { + return "ecobee"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getUserid(final String itemName) { + final EcobeeBindingConfig config = (EcobeeBindingConfig) this.bindingConfigs.get(itemName); + return config != null ? config.userid : null; + } + + /** + * {@inheritDoc} + */ + @Override + public String getThermostatIdentifier(final String itemName) { + EcobeeBindingConfig config = (EcobeeBindingConfig) this.bindingConfigs.get(itemName); + return config != null ? config.thermostatIdentifier : null; + } + + /** + * {@inheritDoc} + */ + @Override + public String getProperty(final String itemName) { + EcobeeBindingConfig config = (EcobeeBindingConfig) this.bindingConfigs.get(itemName); + return config != null ? config.property : null; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isInBound(final String itemName) { + EcobeeBindingConfig config = (EcobeeBindingConfig) this.bindingConfigs.get(itemName); + return config != null ? config.inBound : false; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isOutBound(final String itemName) { + EcobeeBindingConfig config = (EcobeeBindingConfig) this.bindingConfigs.get(itemName); + return config != null ? config.outBound : false; + } + + /** + * {@inheritDoc} + */ + @Override + public void processBindingConfiguration(final String context, final Item item, final String bindingConfig) + throws BindingConfigParseException { + logger.debug("Processing binding configuration: '{}'", bindingConfig); + + super.processBindingConfiguration(context, item, bindingConfig); + + boolean inBound = false; + boolean outBound = false; + + if (bindingConfig.startsWith(IN_BOUND)) { + inBound = true; + } else if (bindingConfig.startsWith(OUT_BOUND)) { + outBound = true; + } else if (bindingConfig.startsWith(BIDIRECTIONAL)) { + inBound = true; + outBound = true; + } else { + throw new BindingConfigParseException("Item \"" + item.getName() + "\" does not start with " + IN_BOUND + + ", " + OUT_BOUND + " or " + BIDIRECTIONAL + "."); + } + + Matcher matcher = CONFIG_PATTERN.matcher(bindingConfig); + + if (!matcher.matches() || matcher.groupCount() != 2) + throw new BindingConfigParseException("Config for item '" + item.getName() + "' could not be parsed."); + + String userid = null; + String thermostatIdentifier = matcher.group(1); + if (thermostatIdentifier.contains(".")) { + String[] parts = thermostatIdentifier.split("\\."); + userid = parts[0]; + thermostatIdentifier = parts[1]; + } + + if (inBound && !Selection.isThermostatIdentifier(thermostatIdentifier)) { + throw new BindingConfigParseException( + "Only a single thermostat identifier is permitted in an in binding or bidirectional binding."); + } + + String property = matcher.group(2); + + EcobeeBindingConfig config = new EcobeeBindingConfig(userid, thermostatIdentifier, property, inBound, outBound); + + addBindingConfig(item, config); + } + + /** + * {@inheritDoc} + */ + @Override + public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException { + + logger.trace("validateItemType called with bindingConfig={}", bindingConfig); + + Matcher matcher = CONFIG_PATTERN.matcher(bindingConfig); + + if (!matcher.matches() || matcher.groupCount() != 2) + throw new BindingConfigParseException("Config for item '" + item.getName() + "' could not be parsed."); + + String property = matcher.group(2); + + logger.trace("validateItemType called with property={}", property); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractAuthResponse.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractAuthResponse.java new file mode 100644 index 00000000000..42acf6b3556 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractAuthResponse.java @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * Base class for all Ecobee authorization responses. The members of this abstract class will de-serialize to + * nulls if there was no error, but the concrete subclasses will instead be filled in. + * + * @see Authorization + * Requests and Errors + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class AbstractAuthResponse extends AbstractMessage implements Response { + + @JsonProperty("error") + private String error; + @JsonProperty("error_description") + private String errorDescription; + @JsonProperty("error_uri") + private String errorURI; + + /** + * @return the error type + */ + @JsonProperty("error") + public String getError() { + return this.error; + } + + /** + * @return the error description + */ + @JsonProperty("error_description") + public String getErrorDescription() { + return this.errorDescription; + } + + /** + * @return the error URI, explaining why this error may have occurred. + */ + @JsonProperty("error_uri") + public String getErrorURI() { + return this.errorURI; + } + + @Override + public String getResponseMessage() { + return this.error; + } + + @Override + public boolean isError() { + return this.error != null; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + if (this.error != null) { + builder.append("error", this.error); + } + if (this.errorDescription != null) { + builder.append("errorDescription", this.errorDescription); + } + if (this.errorURI != null) { + builder.append("errorURI", this.errorURI); + } + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractFunction.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractFunction.java new file mode 100644 index 00000000000..b78ef4d604b --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractFunction.java @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * The function object is defined by its functionType and one or more additional properties. The property list is + * variable depending on the type of function. + * + *

      + * Functions are used to perform more complex operations on a thermostat or user which are too complex with simple + * property modifications. Functions are used to modify read-only objects where appropriate. + * + *

      + * Each function takes different parameters. + * + * @see Function + * @author John Cocula + * @since 1.7.0 + */ +public abstract class AbstractFunction extends AbstractMessagePart { + + // TODO needs to be in specific thermostat's local timezone (@watou) + protected final static DateFormat ymd = new SimpleDateFormat("yyyy-MM-dd"); + protected final static DateFormat hms = new SimpleDateFormat("HH:mm:ss"); + + private String type; + private Map params; + + /** + * Construct a function of given type with zero params. + * + * @param type + * the function type name + */ + protected AbstractFunction(String type) { + this.type = type; + } + + protected final Map makeParams() { + if (params == null) + params = new HashMap(); + return params; + } + + /** + * @return the function type name See the type name in the function documentation + */ + @JsonProperty("type") + public String getType() { + return this.type; + } + + /** + * @return a map of key=value pairs as the parameters to the function. See individual function + * documentation for the properties. + */ + @JsonProperty("params") + public Map getParams() { + return this.params; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("type", this.type); + builder.append("params", this.params); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractMessage.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractMessage.java new file mode 100644 index 00000000000..1eb384aa752 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractMessage.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import static org.apache.commons.lang.builder.ToStringStyle.SHORT_PREFIX_STYLE; + +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * Base class for all messages. + * + * @author John Cocula + * @since 1.7.0 + */ +public class AbstractMessage { + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + + return builder.toString(); + } + + protected final ToStringBuilder createToStringBuilder() { + return new ToStringBuilder(this, SHORT_PREFIX_STYLE); + } + +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractMessagePart.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractMessagePart.java new file mode 100644 index 00000000000..d4ffb6d88b6 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractMessagePart.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import static org.apache.commons.lang.builder.ToStringStyle.SHORT_PREFIX_STYLE; + +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * Base class for all message parts; i.e., objects within a response. + * + * @author John Cocula + * @since 1.7.0 + */ +public class AbstractMessagePart { + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + + return builder.toString(); + } + + protected final ToStringBuilder createToStringBuilder() { + return new ToStringBuilder(this, SHORT_PREFIX_STYLE); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractRequest.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractRequest.java new file mode 100644 index 00000000000..335b087d8cd --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AbstractRequest.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.text.SimpleDateFormat; +import java.util.Properties; + +import org.codehaus.jackson.map.JsonMappingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion; +import org.openhab.binding.ecobee.internal.EcobeeException; + +/** + * Base class for all Ecobee API requests. + * + * @author John Cocula + * @since 1.7.0 + */ +public abstract class AbstractRequest extends AbstractMessage implements Request { + + protected static final String HTTP_GET = "GET"; + + protected static final String HTTP_POST = "POST"; + + protected static final String API_BASE_URL = "https://api.ecobee.com/"; + + protected static final Properties HTTP_HEADERS; + + protected static final int HTTP_REQUEST_TIMEOUT = 10000; + + protected static final ObjectMapper JSON = new ObjectMapper(); + + static { + HTTP_HEADERS = new Properties(); + HTTP_HEADERS.put("Content-Type", "application/json;charset=UTF-8"); + HTTP_HEADERS.put("User-Agent", "ecobee-openhab-api/1.0"); + + // do not serialize null values + JSON.setSerializationInclusion(Inclusion.NON_NULL); + + // *most* dates in the JSON are in this format + JSON.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); + } + + protected final RuntimeException newException(final String message, final Exception cause, final String url, + final String json) { + if (cause instanceof JsonMappingException) { + return new EcobeeException("Could not parse JSON from URL '" + url + "': " + json, cause); + } + + return new EcobeeException(message, cause); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AcknowledgeFunction.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AcknowledgeFunction.java new file mode 100644 index 00000000000..93f9511f6e0 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AcknowledgeFunction.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import org.codehaus.jackson.annotate.JsonValue; + +/** + * The acknowledge function allows an alert to be acknowledged. + * + * @see Acknowledge + * @author John Cocula + * @since 1.7.0 + */ +public final class AcknowledgeFunction extends AbstractFunction { + + /** + * The type of acknowledgment. + */ + public static enum AckType { + ACCEPT("accept"), DECLINE("decline"), DEFER("defer"), UNACKNOWLEDGED("unacknowledged"); + + private final String type; + + private AckType(String type) { + this.type = type; + } + + @Override + @JsonValue + public String toString() { + return this.type; + } + } + + public AcknowledgeFunction(String thermostatIdentifier, String ackRef, AckType ackType, Boolean remindMeLater) { + super("acknowledge"); + + if (thermostatIdentifier == null || ackRef == null || ackType == null) { + throw new IllegalArgumentException("thermostatIdentifier, ackRef and ackType are required."); + } + + makeParams().put("thermostatIdentifier", thermostatIdentifier); + makeParams().put("ackRef", ackRef); + makeParams().put("ackType", ackType); + if (remindMeLater != null) { + makeParams().put("remindMeLater", remindMeLater); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ApiResponse.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ApiResponse.java new file mode 100644 index 00000000000..06c48e6ddaa --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ApiResponse.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * Base class for all Ecobee API responses. + * + * @author John Cocula + * @since 1.7.0 + */ +public class ApiResponse extends AbstractMessage implements Response { + + private Status status; + + @JsonProperty("status") + public Status getStatus() { + return this.status; + } + + @Override + public String getResponseMessage() { + return status.toString(); + } + + @Override + public boolean isError() { + return status.getCode() != 0; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + if (this.status != null) { + builder.append("status", this.status); + } + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AuthorizeRequest.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AuthorizeRequest.java new file mode 100644 index 00000000000..44c8f9fe74d --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AuthorizeRequest.java @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import static org.openhab.io.net.http.HttpUtil.executeUrl; + +import org.apache.commons.httpclient.util.URIUtil; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.openhab.binding.ecobee.internal.EcobeeException; + +/** + * The ecobee PIN authorization method is designed to support any 3rd party device, be it a mobile phone, tablet, + * desktop widget or remote server. This authorization method allows a 3rd party application to obtain an authorization + * code and a 4 byte alphabetic string which can be displayed to the user. The user then logs into the ecobee Portal and + * registers the application using the PIN provided. Once this step is completed, the 3rd party application is able to + * request the access and refresh tokens. + * + * @see AuthorizeResponse + * @see PIN + * Authorization Strategy + * @author John Cocula + * @since 1.7.0 + */ +public class AuthorizeRequest extends AbstractRequest { + + private static final String RESOURCE_URL = API_BASE_URL + "authorize"; + + private String appKey; + private String scope; + + /** + * Construct an authorization request. + * + * @param appKey + * the application key for your application (this binding) + * @param scope + * the scope the application requests from the user + */ + public AuthorizeRequest(final String appKey, final String scope) { + assert appKey != null : "appKey must not be null!"; + assert scope != null : "scope must not be null!"; + + this.appKey = appKey; + this.scope = scope; + } + + @Override + public AuthorizeResponse execute() { + final String url = buildQueryString(); + String json = null; + + try { + json = executeQuery(url); + + final AuthorizeResponse response = JSON.readValue(json, AuthorizeResponse.class); + + return response; + } catch (final Exception e) { + throw newException("Could not get authorization.", e, url, json); + } + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("appKey", this.appKey); + builder.append("scope", this.scope); + return builder.toString(); + } + + protected String executeQuery(final String url) { + return executeUrl(HTTP_GET, url, HTTP_HEADERS, null, null, HTTP_REQUEST_TIMEOUT); + } + + private String buildQueryString() { + final StringBuilder urlBuilder = new StringBuilder(RESOURCE_URL); + + try { + urlBuilder.append("?response_type=ecobeePin"); + urlBuilder.append("&client_id="); + urlBuilder.append(appKey); + urlBuilder.append("&scope="); + urlBuilder.append(scope); + return URIUtil.encodeQuery(urlBuilder.toString()); + } catch (final Exception e) { + throw new EcobeeException(e); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AuthorizeResponse.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AuthorizeResponse.java new file mode 100644 index 00000000000..6e20b4ec744 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/AuthorizeResponse.java @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * This class represents the response to the /authorize endpoint. Upon success, the PIN, authorization + * token, scope, the PIN expiration and minimum polling interval for PINs is returned. + * + *

      + * At this point, the application should display the PIN to the user and request that they log into their web portal and + * register the application using the PIN in their My Apps widget. + * + * @see AuthorizeRequest + * @see PIN + * Authorization Strategy + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class AuthorizeResponse extends AbstractAuthResponse { + + @JsonProperty("ecobeePin") + private String ecobeePin; + @JsonProperty("code") + private String authToken; + @JsonProperty("scope") + private String scope; + @JsonProperty("expires_in") + private Integer expiresIn; + @JsonProperty("interval") + private Integer interval; + + /** + * @return the PIN a user enters in the web portal + */ + @JsonProperty("ecobeePin") + public String getEcobeePin() { + return this.ecobeePin; + } + + /** + * @return the authorization token needed to request the access and refresh tokens + */ + @JsonProperty("code") + public String getAuthToken() { + return this.authToken; + } + + /** + * @return the requested Scope from the original request. This must match the original request. + */ + @JsonProperty("scope") + public String getScope() { + return this.scope; + } + + /** + * @return the number of minutes until the PIN expires. Ensure you inform the user how much time they have. + */ + @JsonProperty("expires_in") + public Integer getExpiresIn() { + return this.expiresIn; + } + + /** + * @return the minimum amount of seconds which must pass between polling attempts for a token. + */ + @JsonProperty("interval") + public Integer getInterval() { + return this.interval; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("ecobeePin", this.ecobeePin); + builder.append("authToken", this.authToken); + builder.append("scope", this.scope); + builder.append("expiresIn", this.expiresIn); + builder.append("interval", this.interval); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ControlPlugFunction.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ControlPlugFunction.java new file mode 100644 index 00000000000..ab45110dd0a --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ControlPlugFunction.java @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.util.Date; + +import org.codehaus.jackson.annotate.JsonValue; + +/** + * Control the on/off state of a plug by setting a hold on the plug. Creates a hold for the on or off state of the plug + * for the specified duration. Note that an event is created regardless of whether the program is in the same state as + * the requested state. + * + * @see ControlPlug + * @author John Cocula + * @since 1.7.0 + */ +public final class ControlPlugFunction extends AbstractFunction { + + /** + * The state to put the plug into. Valid values: on, off, resume. + */ + public static enum PlugState { + + /** + * Sets the plug into the on state for the start/end period specified. Creates a plug hold in the on state. + */ + ON("on"), + + /** + * Sets the plug into the off state for the start/end period specified. Creates a plug hold in the off state. + */ + OFF("off"), + + /** + * Causes the plug to resume its regular program and to follow it. Removes the currently active plug hold, if no + * hold is currently running, nothing happens. No other optional properties are used. + */ + RESUME("resume"); + + private final String state; + + private PlugState(String state) { + this.state = state; + } + + @Override + @JsonValue + public String toString() { + return this.state; + } + } + + /** + * Construct a ControlPlug function. + * + * @param plugName + * the name of the plug. Ensure each plug has a unique name. Required. + * @param plugState + * the state to put the plug into. Valid values: on, off, resume. Required. + * @param startDateTime + * the start date and time in thermostat time + * @param endDateTime + * the end date and time in thermostat time + * @param holdType + * the hold duration type + * @param holdHours + * the number of hours to hold for, used and required if holdType='holdHours' + * @throws IllegalArgumentException + * if the parameters are incorrect. + */ + public ControlPlugFunction(final String plugName, final PlugState plugState, final Date startDateTime, + final Date endDateTime, final HoldType holdType, final Integer holdHours) { + super("controlPlug"); + + if (plugName == null || plugState == null) { + throw new IllegalArgumentException("plugName and plugState arguments are required."); + } + if (holdType == HoldType.DATE_TIME && endDateTime == null) { + throw new IllegalArgumentException("End date/time is required for dateTime hold type."); + } + if (holdType == HoldType.HOLD_HOURS && holdHours == null) { + throw new IllegalArgumentException("holdHours must be specified when using holdHours hold type."); + } + + makeParams().put("plugName", plugName); + makeParams().put("plugState", plugState); + if (startDateTime != null) { + makeParams().put("startDate", ymd.format(startDateTime)); + makeParams().put("startTime", hms.format(startDateTime)); + } + if (endDateTime != null) { + makeParams().put("endDate", ymd.format(endDateTime)); + makeParams().put("endTime", hms.format(endDateTime)); + } + if (holdType != null) { + makeParams().put("holdType", holdType); + } + if (holdHours != null) { + makeParams().put("holdHours", holdHours); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/CreateVacationFunction.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/CreateVacationFunction.java new file mode 100644 index 00000000000..db0b00a90f5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/CreateVacationFunction.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.util.Date; + +/** + * The create vacation function creates a vacation event on the thermostat. If the start/end date/times are not provided + * for the vacation event, the vacation event will begin immediately and last 14 days. + * + *

      + * If both the coolHoldTemp and heatHoldTemp parameters provided to this function have the + * same value, and the {@link Thermostat} is in auto mode, then the two values will be adjusted during processing to be + * separated by the value stored in {@link Thermostat.Settings#heatCoolMinDelta}. + * + * @see CreateVacation + * @author John Cocula + * @author Ecobee + * @since 1.7.0 + */ +public final class CreateVacationFunction extends AbstractFunction { + + public CreateVacationFunction(final String name, final Temperature coolHoldTemp, final Temperature heatHoldTemp, + final Date startDateTime, final Date endDateTime, final FanMode fan, final Integer fanMinOnTime) { + // TODO doc says String not Integer for fanMinOnTime parameter (@watou) + super("createVacation"); + + if (name == null || coolHoldTemp == null || heatHoldTemp == null) { + throw new IllegalArgumentException("name, coolHoldTemp and heatHoldTemp arguments are required."); + } + + makeParams().put("name", name); + makeParams().put("coolHoldTemp", coolHoldTemp); + makeParams().put("heatHoldTemp", heatHoldTemp); + if (startDateTime != null) { + makeParams().put("startDate", ymd.format(startDateTime)); + makeParams().put("startTime", hms.format(startDateTime)); + } + if (endDateTime != null) { + makeParams().put("endDate", ymd.format(endDateTime)); + makeParams().put("endTime", hms.format(endDateTime)); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/DeleteVacationFunction.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/DeleteVacationFunction.java new file mode 100644 index 00000000000..cf57936e976 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/DeleteVacationFunction.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +/** + * The delete vacation function deletes a vacation event from a thermostat. This is the only way to cancel a vacation + * event. This method is able to remove vacation events not yet started and scheduled in the future. + * + * @see DeleteVacation + * @author John Cocula + * @author Ecobee + * @since 1.7.0 + */ +public class DeleteVacationFunction extends AbstractFunction { + + /** + * @param name + * the vacation event name to delete + */ + public DeleteVacationFunction(String name) { + super("deleteVacation"); + if (name == null) { + throw new IllegalArgumentException("name argument is required."); + } + + makeParams().put("name", name); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/FanMode.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/FanMode.java new file mode 100644 index 00000000000..ea44f42c95f --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/FanMode.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonValue; + +/** + * Possible values for fan mode + * + * @see Event + * @author John Cocula + * @since 1.7.0 + */ +public enum FanMode { + AUTO("auto"), ON("on"); + + private final String mode; + + private FanMode(final String mode) { + this.mode = mode; + } + + @JsonValue + public String value() { + return mode; + } + + @JsonCreator + public static FanMode forValue(String v) { + for (FanMode fm : FanMode.values()) { + if (fm.mode.equals(v)) { + return fm; + } + } + throw new IllegalArgumentException("Invalid fan mode: " + v); + } + + @Override + public String toString() { + return this.mode; + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Group.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Group.java new file mode 100644 index 00000000000..ff0b1767895 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Group.java @@ -0,0 +1,353 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.util.List; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * A Group object defines the group (and the related Group settings) which a thermostat may belong to. There could be a + * number of Groups and also a number of thermostats in each Group. The Group object allows the caller to define the + * Group name, which user preferences are shared across all thermostats in that Group, and indeed which Thermostats are + * part of that Group. + * + *

      + * The result is that if you modify the Group settings, for example set the synchronizeAlerts flag to true, + * any {@link Thermostat.Alert} changes made to any thermostat in that group will be shared with the remaining + * thermostats in the same group. + * + *

      + * The Grouping algorithm uses a "first group wins" strategy when a {@link Thermostat} is referenced in multiple groups. + * What this means in practice is that when the API request is processed and a Thermostat is referenced in more than one + * group, that Thermostat will only be added to the first Group (at head of array) and not to the others. + * + *

      + * If any of the synchronizeXXX fields are not supplied they will default to false. So to set all to false + * where previously some were set to true the caller can either pass all the synchronizeXXX fields + * explicitly, or pass none and the default will be set for each. + * + *

      + * The Group object may be modified. However, it is important to note that if the groupRef is not sent by the caller it + * is assumed that this is a new group, even if the groupName has not changed, and a new groupRef will be generated and + * returned. Therefore when updating a Group the groupRef must always be sent. + * + *

      + * Also note that if the thermostats list is not sent, or an empty list is sent, the Group will effectively be deleted + * as it will no longer contain any thermostats and any group information will be lost. + * + * @see Group + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Group extends AbstractMessagePart { + private String groupRef; + private String groupName; + private Boolean synchronizeAlerts; + private Boolean synchronizeSystemMode; + private Boolean synchronizeSchedule; + private Boolean synchronizeQuickSave; + private Boolean synchronizeReminders; + private Boolean synchronizeContractorInfo; + private Boolean synchronizeUserPreferences; + private Boolean synchronizeUtilityInfo; + private Boolean synchronizeLocation; + private Boolean synchronizeReset; + private Boolean synchronizeVacation; + private List thermostats; + + /** + * Construct a Group. + * + * @param groupName + * the name for the Group + */ + public Group(@JsonProperty("groupName") final String groupName) { + this.groupName = groupName; + } + + /** + * @return the unique reference Id for the Group. + */ + @JsonProperty("groupRef") + public String getGroupRef() { + return this.groupRef; + } + + /** + * @param groupRef + * the unique reference Id for the Group. If not supplied in the POST call, and new groupRef will be + * generated. + */ + @JsonProperty("groupRef") + public void setGroupRef(final String groupRef) { + this.groupRef = groupRef; + } + + /** + * @return the name for the Group + */ + @JsonProperty("groupName") + public String getGroupName() { + return this.groupName; + } + + /** + * @return flag for whether to synchronize {@link Thermostat.Alert}s with all other {@link Thermostat}s in the + * Group. Default is false. + */ + @JsonProperty("synchronizeAlerts") + public Boolean getSynchronizeAlerts() { + return this.synchronizeAlerts; + } + + /** + * @param synchronizeAlerts + * flag for whether to synchronize {@link Thermostat.Alert}s with all other {@link Thermostat}s in the + * Group. Default is false. + */ + @JsonProperty("synchronizeAlerts") + public void setSynchronizeAlerts(final Boolean synchronizeAlerts) { + this.synchronizeAlerts = synchronizeAlerts; + } + + /** + * @return flag for whether to synchronize the Thermostat mode with all other Thermostats in the Group. Default is + * false. + */ + @JsonProperty("synchronizeSystemMode") + public Boolean getSynchronizeSystemMode() { + return this.synchronizeSystemMode; + } + + /** + * @param synchronizeSystemMode + * flag for whether to synchronize the Thermostat mode with all other Thermostats in the Group. Default + * is false. + */ + @JsonProperty("synchronizeSystemMode") + public void setSynchronizeSystemMode(final Boolean synchronizeSystemMode) { + this.synchronizeSystemMode = synchronizeSystemMode; + } + + /** + * @return flag for whether to synchronize the Thermostat schedule/Program details with all other Thermostats in the + * Group. Default is false. + */ + @JsonProperty("synchronizeSchedule") + public Boolean getSynchronizeSchedule() { + return this.synchronizeSchedule; + } + + /** + * @param synchronizeSchedule + * flag for whether to synchronize the Thermostat schedule/Program details with all other Thermostats in + * the Group. Default is false. + */ + @JsonProperty("synchronizeSchedule") + public void setSynchronizeSchedule(final Boolean synchronizeSchedule) { + this.synchronizeSchedule = synchronizeSchedule; + } + + /** + * @return flag for whether to synchronize the Thermostat quick save settings with all other Thermostats in the + * Group. Default is false. + */ + @JsonProperty("synchronizeQuickSave") + public Boolean getSynchronizeQuickSave() { + return this.synchronizeQuickSave; + } + + /** + * @param synchronizeQuickSave + * flag for whether to synchronize the Thermostat quick save settings with all other Thermostats in the + * Group. Default is false. + */ + @JsonProperty("synchronizeQuickSave") + public void setSynchronizeQuickSave(final Boolean synchronizeQuickSave) { + this.synchronizeQuickSave = synchronizeQuickSave; + } + + /** + * @return flag for whether to synchronize the Thermostat reminders with all other Thermostats in the Group. Default + * is false. + */ + @JsonProperty("synchronizeReminders") + public Boolean getSynchronizeReminders() { + return this.synchronizeReminders; + } + + /** + * @param synchronizeReminders + * flag for whether to synchronize the Thermostat reminders with all other Thermostats in the Group. + * Default is false. + */ + @JsonProperty("synchronizeReminders") + public void setSynchronizeReminders(final Boolean synchronizeReminders) { + this.synchronizeReminders = synchronizeReminders; + } + + /** + * @return flag for whether to synchronize the Thermostat Technician/Contractor Information with all other + * Thermostats in the Group. Default is false. + */ + @JsonProperty("synchronizeContractorInfo") + public Boolean getSynchronizeContractorInfo() { + return this.synchronizeContractorInfo; + } + + /** + * @param synchronizeContractorInfo + * flag for whether to synchronize the Thermostat Technician/Contractor Information with all other + * Thermostats in the Group. Default is false. + */ + @JsonProperty("synchronizeContractorInfo") + public void setSynchronizeContractorInfo(final Boolean synchronizeContractorInfo) { + this.synchronizeContractorInfo = synchronizeContractorInfo; + } + + /** + * @return flag for whether to synchronize the Thermostat user preferences with all other Thermostats in the Group. + * Default is false. + */ + @JsonProperty("synchronizeUserPreferences") + public Boolean getSynchronizeUserPreferences() { + return this.synchronizeUserPreferences; + } + + /** + * @param synchronizeUserPreferences + * tflag for whether to synchronize the Thermostat user preferences with all other Thermostats in the + * Group. Default is false. + */ + @JsonProperty("synchronizeUserPreferences") + public void setSynchronizeUserPreferences(final Boolean synchronizeUserPreferences) { + this.synchronizeUserPreferences = synchronizeUserPreferences; + } + + /** + * @return flag for whether to synchronize the Thermostat utility information with all other Thermostats in the + * Group. Default is false. + */ + @JsonProperty("synchronizeUtilityInfo") + public Boolean getSynchronizeUtilityInfo() { + return this.synchronizeUtilityInfo; + } + + /** + * @param synchronizeUtilityInfo + * flag for whether to synchronize the Thermostat utility information with all other Thermostats in the + * Group. Default is false. + */ + @JsonProperty("synchronizeUtilityInfo") + public void setSynchronizeUtilityInfo(final Boolean synchronizeUtilityInfo) { + this.synchronizeUtilityInfo = synchronizeUtilityInfo; + } + + /** + * @return flag for whether to synchronize the Thermostat Location with all other Thermostats in the Group. Default + * is false. + */ + @JsonProperty("synchronizeLocation") + public Boolean getSynchronizeLocation() { + return this.synchronizeLocation; + } + + /** + * @param synchronizeLocation + * flag for whether to synchronize the Thermostat Location with all other Thermostats in the Group. + * Default is false. + */ + @JsonProperty("synchronizeLocation") + public void setSynchronizeLocation(final Boolean synchronizeLocation) { + this.synchronizeLocation = synchronizeLocation; + } + + /** + * @return flag for whether to synchronize the Thermostat reset with all other Thermostats in the Group. Default is + * false. + */ + @JsonProperty("synchronizeReset") + public Boolean getSynchronizeReset() { + return this.synchronizeReset; + } + + /** + * @param synchronizeReset + * flag for whether to synchronize the Thermostat reset with all other Thermostats in the Group. Default + * is false. + */ + @JsonProperty("synchronizeReset") + public void setSynchronizeReset(final Boolean synchronizeReset) { + this.synchronizeReset = synchronizeReset; + } + + /** + * @return flag for whether to synchronize the Thermostat vacation Program with all other Thermostats in the Group. + * Default is false. + */ + @JsonProperty("synchronizeVacation") + public Boolean getSynchronizeVacation() { + return this.synchronizeVacation; + } + + /** + * @param synchronizeVacation + * flag for whether to synchronize the Thermostat vacation Program with all other Thermostats in the + * Group. Default is false. + */ + @JsonProperty("synchronizeVacation") + public void setSynchronizeVacation(final Boolean synchronizeVacation) { + this.synchronizeVacation = synchronizeVacation; + } + + /** + * @return the list of Thermostat identifiers which belong to the group. If an empty list is sent the Group will be + * deleted. + */ + @JsonProperty("thermostats") + public List getThermostats() { + return this.thermostats; + } + + /** + * @param thermostats + * the list of Thermostat identifiers which belong to the group. If an empty list is sent the Group will + * be deleted. + */ + @JsonProperty("thermostats") + public void setThermostats(final List thermostats) { + this.thermostats = thermostats; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("groupRef", this.groupRef); + builder.append("groupName", this.groupName); + builder.append("synchronizeAlerts", this.synchronizeAlerts); + builder.append("synchronizeSystemMode", this.synchronizeSystemMode); + builder.append("synchronizeSchedule", this.synchronizeSchedule); + builder.append("synchronizeQuickSave", this.synchronizeQuickSave); + builder.append("synchronizeReminders", this.synchronizeReminders); + builder.append("synchronizeContractorInfo", this.synchronizeContractorInfo); + builder.append("synchronizeUserPreferences", this.synchronizeUserPreferences); + builder.append("synchronizeUtilityInfo", this.synchronizeUtilityInfo); + builder.append("synchronizeLocation", this.synchronizeLocation); + builder.append("synchronizeReset", this.synchronizeReset); + builder.append("synchronizeVacation", this.synchronizeVacation); + builder.append("thermostats", this.thermostats); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/HoldType.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/HoldType.java new file mode 100644 index 00000000000..4dbf0113818 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/HoldType.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import org.codehaus.jackson.annotate.JsonValue; + +/** + * Hold types ease the calculation of end times for holds. You are always free to provide the startDate and + * startTime for the hold and it will be honoured, except where documented. The endDate and + * endTime depend on the hold type chosen. Default is indefinite. Valid values: + * dateTime, nextTransition, indefinite, holdHours. + * + * @see SetHold + * @author John Cocula + * @since 1.7.0 + */ +public enum HoldType { + + /** + * Use the provided startDate, startTime, endDate and endTime + * for the event. If start date/time is not provided, it will be assumed to be right now. End date/time is required. + */ + DATE_TIME("dateTime"), + + /** + * The end date/time will be set to the next climate transition in the program. + */ + NEXT_TRANSITION("nextTransition"), + + /** + * The hold will not end and require to be cancelled explicitly. + */ + INDEFINITE("indefinite"), + + /** + * Use the value in the holdHours parameter to set the end date/time for the event. + */ + HOLD_HOURS("holdHours"); + + private final String type; + + private HoldType(final String type) { + this.type = type; + } + + @Override + @JsonValue + public String toString() { + return this.type; + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Page.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Page.java new file mode 100644 index 00000000000..4af960409e6 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Page.java @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * The Page object contains the response page information. + * + * @see Page + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Page extends AbstractMessagePart { + private Integer page; + private Integer totalPages; + private Integer pageSize; + private Integer total; + + /** + * Construct a Page. + * + * @param page + * the specific page requested + */ + public Page(@JsonProperty("page") final Integer page) { + this.page = page; + } + + /** + * @return the page retrieved or, in the case of a request parameter, the specific page requested + */ + @JsonProperty("page") + public Integer getPage() { + return this.page; + } + + /** + * @return the total pages available + */ + @JsonProperty("totalPages") + public Integer getTotalPages() { + return this.totalPages; + } + + /** + * @return the number of objects on this page + */ + @JsonProperty("pageSize") + public Integer getPageSize() { + return this.pageSize; + } + + /** + * @return the total number of objects available + */ + @JsonProperty("total") + public Integer getTotal() { + return this.total; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("page", this.page); + builder.append("totalPages", this.totalPages); + builder.append("pageSize", this.pageSize); + builder.append("total", this.total); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/RefreshTokenRequest.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/RefreshTokenRequest.java new file mode 100644 index 00000000000..72a3a3a6551 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/RefreshTokenRequest.java @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import static org.openhab.io.net.http.HttpUtil.executeUrl; + +import org.apache.commons.httpclient.util.URIUtil; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.openhab.binding.ecobee.internal.EcobeeException; + +/** + * All access tokens must be refreshed periodically. Token refresh reduces the potential and benefit of token theft. + * Since all tokens expire, stolen tokens may only be used for a limited time. A token refresh immediately expires the + * previously issued access and refresh tokens and issues brand new tokens. + * + * @see TokenResponse + * @see Refreshing Your + * Tokens + * @author John Cocula + * @author Ecobee + * @since 1.7.0 + */ +public class RefreshTokenRequest extends AbstractRequest { + + private static final String RESOURCE_URL = API_BASE_URL + "token"; + + private String refreshToken; + private String appKey; + + /** + * Construct a refresh token request. + * + * @param refreshToken + * the refresh token you were issued + * @param appKey + * the application key for your application (this binding) + */ + public RefreshTokenRequest(final String refreshToken, final String appKey) { + assert refreshToken != null : "refreshToken must not be null!"; + assert appKey != null : "appKey must not be null!"; + + this.refreshToken = refreshToken; + this.appKey = appKey; + } + + @Override + public TokenResponse execute() { + final String url = buildQueryString(); + String json = null; + + try { + json = executeQuery(url); + + final TokenResponse response = JSON.readValue(json, TokenResponse.class); + + return response; + } catch (final Exception e) { + throw newException("Could not get refresh token.", e, url, json); + } + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("refreshToken", this.refreshToken); + builder.append("appKey", this.appKey); + return builder.toString(); + } + + protected String executeQuery(final String url) { + return executeUrl(HTTP_POST, url, HTTP_HEADERS, null, null, HTTP_REQUEST_TIMEOUT); + } + + private String buildQueryString() { + final StringBuilder urlBuilder = new StringBuilder(RESOURCE_URL); + + try { + urlBuilder.append("?grant_type=refresh_token"); + urlBuilder.append("&code="); + urlBuilder.append(refreshToken); + urlBuilder.append("&client_id="); + urlBuilder.append(appKey); + return URIUtil.encodeQuery(urlBuilder.toString()); + } catch (final Exception e) { + throw new EcobeeException(e); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Request.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Request.java new file mode 100644 index 00000000000..c0cc14a88ae --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Request.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +/** + * Base interface for all Ecobee API requests. + * + * @author John Cocula + * @since 1.7.0 + */ +public interface Request { + + /** + * Send this request to the Ecobee API. Implementations specify a more concrete {@link Request} class. + * + * @return a {@link Response} containing the requested data or an error + */ + Response execute(); +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Response.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Response.java new file mode 100644 index 00000000000..a0413eda1fa --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Response.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +/** + * Base interface for all Ecobee API responses. + * + * @author John Cocula + * @since 1.7.0 + */ +public interface Response { + + /** + * Return the response message, or null if there is none. + * + * @return the response message + * + * @see #isError() + */ + String getResponseMessage(); + + /** + * Checks if this response contained an error. + * + * @return true if the response contained an error instead of actual data. + */ + boolean isError(); +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ResumeProgramFunction.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ResumeProgramFunction.java new file mode 100644 index 00000000000..54b3e17c9ab --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ResumeProgramFunction.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +/** + * The resume program function removes the currently running event providing the event is not a mandatory demand + * response event. The top active event is removed from the stack and the thermostat resumes its program, or enters the + * next event in the stack if one exists. This function may need to be called multiple times in order to resume all + * events. Sending 3 resume functions in a row will resume the thermostat to its program in all instances. + * + *

      + * Note that vacation events cannot be resumed, you must delete the vacation event using the + * {@link DeleteVacationFunction}. + * + * @see ResumeProgram + * @author John Cocula + * @since 1.7.0 + */ +public final class ResumeProgramFunction extends AbstractFunction { + + public ResumeProgramFunction() { + super("resumeProgram"); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Selection.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Selection.java new file mode 100644 index 00000000000..d774a2cedc2 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Selection.java @@ -0,0 +1,771 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.util.Set; + +import org.apache.commons.lang.builder.ToStringBuilder; +import static org.apache.commons.lang.StringUtils.join; +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.annotate.JsonValue; + +/** + * The selection object defines the resources and information to return as part of a response. The selection is required + * in all requests however meaning of some selection fields is only meaningful to certain types of requests. + * + *

      + * The selectionType parameter defines the type of selection to perform. The selectionMatch + * specifies the matching criteria for the type specified. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      Selection TypeAccount TypeSelection Match ExampleDescription
      registeredSmart only.match is not used.When this is set the thermostats registered to the current user will be returned. This is only usable with Smart + * thermostats registered to a user. It does not work on EMS thermostats and may not be used by a Utility who is not the + * owner of thermostats.
      thermostatsAll accountsidentifier1,identifier2,etc...Select only those thermostats listed in the CSV match criteria. No spaces in the CSV string. There is a limit of + * 25 identifiers per request.
      managementSetEMS/Utility only./Toronto/Campus/BuildingASelects all thermostats for a given management set defined by the Management/Utility account. This is only + * available to Management/Utility accounts. "/" is the root, represented by the "My Sets" set.
      + * + * @see Selection + * @author John Cocula + * @author Ecobee + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Selection extends AbstractMessagePart { + public static final String REGISTERED_WILDCARD = "*"; + public static final String MANAGEMENT_SET_DELIMITER = "/"; + + private SelectionType selectionType; + private String selectionMatch; + private Boolean includeRuntime; + private Boolean includeExtendedRuntime; + private Boolean includeElectricity; + private Boolean includeSettings; + private Boolean includeLocation; + private Boolean includeProgram; + private Boolean includeEvents; + private Boolean includeDevice; + private Boolean includeTechnician; + private Boolean includeUtility; + private Boolean includeManagement; + private Boolean includeAlerts; + private Boolean includeWeather; + private Boolean includeHouseDetails; + private Boolean includeOemCfg; + private Boolean includeEquipmentStatus; + private Boolean includeNotificationSettings; + private Boolean includePrivacy; + private Boolean includeVersion; + + /** + * The SelectionType defines the type of selection to perform. + * + * @see Selection + * Object + * @author John Cocula + * @author Ecobee + */ + public static enum SelectionType { + + /** + * No doc found. + */ + NONE("none"), + + /** + * All accounts. + * + *

      + * Select only those thermostats listed in the CSV match criteria. No spaces in the CSV string. There is a limit + * of 25 identifiers per request. + */ + THERMOSTATS("thermostats"), + + /** + * Smart only. + * + *

      + * When this is set the thermostats registered to the current user will be returned. This is only usable with + * Smart thermostats registered to a user. It does not work on EMS thermostats and may not be used by a Utility + * who is not the owner of thermostats. + */ + REGISTERED("registered"), + + /** + * No doc found. + */ + USER("user"), + + /** + * EMS/Utility only. + * + *

      + * Selects all thermostats for a given management set defined by the Management/Utility account. This is only + * available to Management/Utility accounts. "/" is the root, represented by the "My Sets" set. + */ + MANAGEMENT_SET("managementSet"); + + private final String type; + + private SelectionType(final String type) { + this.type = type; + } + + @JsonCreator + public static SelectionType forValue(String v) { + for (SelectionType st : SelectionType.values()) { + if (st.type.equals(v)) { + return st; + } + } + throw new IllegalArgumentException("Invalid selection type: " + v); + } + + @Override + @JsonValue + public String toString() { + return this.type; + } + } + + /** + * Give a selectionMatch string, infer what kind of selectionType should be used. + * + * @param selectionMatch + * the match string to inspect + * @returns the selectionType to be used with the selectionMatch + */ + private SelectionType inferSelectionType(String selectionMatch) { + SelectionType selectionType; + + if (REGISTERED_WILDCARD.equals(selectionMatch)) { + selectionType = SelectionType.REGISTERED; + } else if (selectionMatch.startsWith(MANAGEMENT_SET_DELIMITER)) { + selectionType = SelectionType.MANAGEMENT_SET; + } else { + selectionType = SelectionType.THERMOSTATS; + } + return selectionType; + } + + /** + * Return true if the given string matches the known format for thermostat identifiers. + * + * @param thermostatIdentifier + * the string to test + * @return true if the given string matches the known format for thermostat identifiers. + */ + public static boolean isThermostatIdentifier(String thermostatIdentifier) { + return thermostatIdentifier.matches("[0-9]+"); + } + + /** + * Construct a Selection object using a single selectionMatch, and inferring the + * selectionType from the selectionMatch. + * + * @param selectionMatch + * based on the syntax, infer the selectionType + */ + public Selection(@JsonProperty("selectionMatch") final String selectionMatch) { + this.selectionType = inferSelectionType(selectionMatch); + this.selectionMatch = selectionMatch; + } + + /** + * Construct a Selection object. + * + * @param selectionType + * the type of match data supplied. + * @param selectionMatch + */ + public Selection(@JsonProperty("selectionType") final SelectionType selectionType, + @JsonProperty("selectionMatch") final String selectionMatch) { + this.selectionType = selectionType; + this.selectionMatch = selectionMatch; + } + + /** + * @return the type of match data supplied. + */ + @JsonProperty("selectionType") + public SelectionType getSelectionType() { + return this.selectionType; + } + + /** + * @param selectionType + * the type of match data supplied. + */ + @JsonProperty("selectionType") + public void setSelectionType(final SelectionType selectionType) { + this.selectionType = selectionType; + } + + /** + * @return the match data based on selectionType (e.g. a list of thermostat identifiers in the case of a + * selectionType of thermostats) + */ + @JsonProperty("selectionMatch") + public String getSelectionMatch() { + return this.selectionMatch; + } + + /** + * @param selectionMatch + * the match data based on selectionType (e.g. a list of thermostat identifiers in the case of a + * selectionType of "thermostats") + */ + @JsonProperty("selectionMatch") + public void setSelectionMatch(final String selectionMatch) { + this.selectionMatch = selectionMatch; + } + + /** + * @param thermostatIdentifiers + * set a list of thermostat identifiers as the selectionMatch and set the + * selectionType to {@code SelectionType.THERMOSTATS}. + */ + public void setSelectionMatch(final Set thermostatIdentifiers) { + this.selectionType = SelectionType.THERMOSTATS; + this.selectionMatch = join(thermostatIdentifiers, ','); + } + + /** + * @return include the {@link Thermostat.Runtime} object. If not specified, defaults to false. + */ + @JsonProperty("includeRuntime") + public Boolean getIncludeRuntime() { + return this.includeRuntime; + } + + /** + * @return true if we would like runtime values returned from this Selection. + */ + public boolean includeRuntime() { + return (this.includeRuntime == null) ? false : this.includeRuntime; + } + + /** + * @param includeRuntime + * include the thermostat {@link Thermostat.Runtime} object. If not specified, defaults to + * false. + */ + @JsonProperty("includeRuntime") + public void setIncludeRuntime(final Boolean includeRuntime) { + this.includeRuntime = includeRuntime; + } + + /** + * @return include the extended thermostat runtime object. If not specified, defaults to false. + */ + @JsonProperty("includeExtendedRuntime") + public Boolean getIncludeExtendedRuntime() { + return this.includeExtendedRuntime; + } + + /** + * @return true if we would like extended runtime values returned from this Selection. + */ + public boolean includeExtendedRuntime() { + return (this.includeExtendedRuntime == null) ? false : this.includeExtendedRuntime; + } + + /** + * @param includeExtendedRuntime + * include the @{link Thermostat.ExtendedRuntime} object. If not specified, defaults to + * false. + */ + @JsonProperty("includeExtendedRuntime") + public void setIncludeExtendedRuntime(final Boolean includeExtendedRuntime) { + this.includeExtendedRuntime = includeExtendedRuntime; + } + + /** + * @return include the {@link Thermostat.Electricity} readings object. If not specified, defaults to + * false. + */ + @JsonProperty("includeElectricity") + public Boolean getIncludeElectricity() { + return this.includeElectricity; + } + + /** + * @return true if we would like electricity values returned from this Selection. + */ + public boolean includeElectricity() { + return (this.includeElectricity == null) ? false : this.includeElectricity; + } + + /** + * @param includeElectricity + * include the {@link Thermostat.Electricity} readings object. If not specified, defaults to + * false. + */ + @JsonProperty("includeElectricity") + public void setIncludeElectricity(final Boolean includeElectricity) { + this.includeElectricity = includeElectricity; + } + + /** + * @return include the {@link Thermostat.Settings} object. If not specified, defaults to false. + */ + @JsonProperty("includeSettings") + public Boolean getIncludeSettings() { + return this.includeSettings; + } + + /** + * @return true if we would like settings values returned from this Selection. + */ + public boolean includeSettings() { + return (this.includeSettings == null) ? false : this.includeSettings; + } + + /** + * @param includeSettings + * include the {@link Thermostat.Settings} object. If not specified, defaults to false. + */ + @JsonProperty("includeSettings") + public void setIncludeSettings(final Boolean includeSettings) { + this.includeSettings = includeSettings; + } + + /** + * @return include the {@link Thermostat.Location} object. If not specified, defaults to false. + */ + @JsonProperty("includeLocation") + public Boolean getIncludeLocation() { + return this.includeLocation; + } + + /** + * @return true if we would like location values returned from this Selection. + */ + public boolean includeLocation() { + return (this.includeLocation == null) ? false : this.includeLocation; + } + + /** + * @param includeLocation + * include the {@link Thermostat.Location} object. If not specified, defaults to false. + */ + @JsonProperty("includeLocation") + public void setIncludeLocation(final Boolean includeLocation) { + this.includeLocation = includeLocation; + } + + /** + * @return include the {@link Thermostat.Program} object. If not specified, defaults to false. + */ + @JsonProperty("includeProgram") + public Boolean getIncludeProgram() { + return this.includeProgram; + } + + /** + * @return true if we would like program values returned from this Selection. + */ + public boolean includeProgram() { + return (this.includeProgram == null) ? false : this.includeProgram; + } + + /** + * @param includeProgram + * include the {@link Thermostat.Program} object. If not specified, defaults to false. + */ + @JsonProperty("includeProgram") + public void setIncludeProgram(final Boolean includeProgram) { + this.includeProgram = includeProgram; + } + + /** + * @return include the {@link Thermostat.Event}s calendar objects. If not specified, defaults to false. + */ + @JsonProperty("includeEvents") + public Boolean getIncludeEvents() { + return this.includeEvents; + } + + /** + * @return true if we would like events returned from this Selection. + */ + public boolean includeEvents() { + return (this.includeEvents == null) ? false : this.includeEvents; + } + + /** + * @param includeEvents + * include the {@link Thermostat.Event}s calendar objects. If not specified, defaults to + * false. + */ + @JsonProperty("includeEvents") + public void setIncludeEvents(final Boolean includeEvents) { + this.includeEvents = includeEvents; + } + + /** + * @return include the {@link Thermostat.Device} configuration objects. If not specified, defaults to + * false. + */ + @JsonProperty("includeDevice") + public Boolean getIncludeDevice() { + return this.includeDevice; + } + + /** + * @return true if we would like device values returned from this Selection. + */ + public boolean includeDevice() { + return (this.includeDevice == null) ? false : this.includeDevice; + } + + /** + * @param includeDevice + * include the {@link Thermostat.Device} configuration objects. If not specified, defaults to false. + */ + @JsonProperty("includeDevice") + public void setIncludeDevice(final Boolean includeDevice) { + this.includeDevice = includeDevice; + } + + /** + * @return include the {@link Thermostat.Technician} object. If not specified, defaults to false. + */ + @JsonProperty("includeTechnician") + public Boolean getIncludeTechnician() { + return this.includeTechnician; + } + + /** + * @return true if we would like technician values returned from this Selection. + */ + public boolean includeTechnician() { + return (this.includeTechnician == null) ? false : this.includeTechnician; + } + + /** + * @param includeTechnician + * include the {@link Thermostat.Technician} object. If not specified, defaults to false. + */ + @JsonProperty("includeTechnician") + public void setIncludeTechnician(final Boolean includeTechnician) { + this.includeTechnician = includeTechnician; + } + + /** + * @return include the {@link Thermostat.Utility} company object. If not specified, defaults to false. + */ + @JsonProperty("includeUtility") + public Boolean getIncludeUtility() { + return this.includeUtility; + } + + /** + * @return true if we would like utility values returned from this Selection. + */ + public boolean includeUtility() { + return (this.includeUtility == null) ? false : this.includeUtility; + } + + /** + * @param includeUtility + * include the {@link Thermostat.Utility} company object. If not specified, defaults to + * false. + */ + @JsonProperty("includeUtility") + public void setIncludeUtility(final Boolean includeUtility) { + this.includeUtility = includeUtility; + } + + /** + * @return include the {@link Thermostat.Management} company object. If not specified, defaults to + * false. + */ + @JsonProperty("includeManagement") + public Boolean getIncludeManagement() { + return this.includeManagement; + } + + /** + * @return true if we would like management values returned from this Selection. + */ + public boolean includeManagement() { + return (this.includeManagement == null) ? false : this.includeManagement; + } + + /** + * @param includeManagement + * include the {@link Thermostat.Management} company object. If not specified, defaults to + * false. + */ + @JsonProperty("includeManagement") + public void setIncludeManagement(final Boolean includeManagement) { + this.includeManagement = includeManagement; + } + + /** + * @return include the unacknowledged {@link Thermostat.Alert} objects. If not specified, defaults to + * false. + */ + @JsonProperty("includeAlerts") + public Boolean getIncludeAlerts() { + return this.includeAlerts; + } + + /** + * @return true if we would like alerts returned from this Selection. + */ + public boolean includeAlerts() { + return (this.includeAlerts == null) ? false : this.includeAlerts; + } + + /** + * @param includeAlerts + * include the unacknowledged {@link Thermostat.Alert} objects. If not specified, defaults to + * false. + */ + @JsonProperty("includeAlerts") + public void setIncludeAlerts(final Boolean includeAlerts) { + this.includeAlerts = includeAlerts; + } + + /** + * @return include the current {@link Thermostat.Weather} forecast object. If not specified, defaults to + * false. + */ + @JsonProperty("includeWeather") + public Boolean getIncludeWeather() { + return this.includeWeather; + } + + /** + * @return true if we would like weather returned from this Selection. + */ + public boolean includeWeather() { + return (this.includeWeather == null) ? false : this.includeWeather; + } + + /** + * @param includeWeather + * include the current {@link Thermostat.Weather} forecast object. If not specified, defaults to + * false. + */ + @JsonProperty("includeWeather") + public void setIncludeWeather(final Boolean includeWeather) { + this.includeWeather = includeWeather; + } + + /** + * @return include the current {@link Thermostat.HouseDetails} object. If not specified, defaults to + * false. + */ + @JsonProperty("includeHouseDetails") + public Boolean getIncludeHouseDetails() { + return this.includeHouseDetails; + } + + /** + * @return true if we would like house details returned from this Selection. + */ + public boolean includeHouseDetails() { + return (this.includeHouseDetails == null) ? false : this.includeHouseDetails; + } + + /** + * @param includeHouseDetails + * include the current {@link Thermostat.HouseDetails} object. If not specified, defaults to + * false. + */ + @JsonProperty("includeHouseDetails") + public void setIncludeHouseDetails(final Boolean includeHouseDetails) { + this.includeHouseDetails = includeHouseDetails; + } + + /** + * @return include the current thermostat OemCfg object. If not specified, defaults to false. + */ + @JsonProperty("includeOemCfg") + public Boolean getIncludeOemCfg() { + return this.includeOemCfg; + } + + /** + * @return true if we would like OemCfg values returned from this Selection. + */ + public boolean includeOemCfg() { + return (this.includeOemCfg == null) ? false : this.includeOemCfg; + } + + /** + * @param includeOemCfg + * include the current thermostat OemCfg object. If not specified, defaults to false. + */ + @JsonProperty("includeOemCfg") + public void setIncludeOemCfg(final Boolean includeOemCfg) { + this.includeOemCfg = includeOemCfg; + } + + /** + * @return include the current thermostat equipment status information. If not specified, defaults to + * false. + */ + @JsonProperty("includeEquipmentStatus") + public Boolean getIncludeEquipmentStatus() { + return this.includeEquipmentStatus; + } + + /** + * @return true if we would like equipment status returned from this Selection. + */ + public boolean includeEquipmentStatus() { + return (this.includeEquipmentStatus == null) ? false : this.includeEquipmentStatus; + } + + /** + * @param includeEquipmentStatus + * include the current thermostat equipment status information. If not specified, defaults to + * false. + */ + @JsonProperty("includeEquipmentStatus") + public void setIncludeEquipmentStatus(final Boolean includeEquipmentStatus) { + this.includeEquipmentStatus = includeEquipmentStatus; + } + + /** + * @return include the current alert and reminders {@link Thermostat.NotificationSettings}. If not specified, + * defaults to false. + */ + @JsonProperty("includeNotificationSettings") + public Boolean getIncludeNotificationSettings() { + return this.includeNotificationSettings; + } + + /** + * @return true if we would like notification settings returned from this Selection. + */ + public boolean includeNotificationSettings() { + return (this.includeNotificationSettings == null) ? false : this.includeNotificationSettings; + } + + /** + * @param includeNotificationSettings + * include the current alert and reminders {@link Thermostat.NotificationSettings}. If not specified, + * defaults to false. + */ + @JsonProperty("includeNotificationSettings") + public void setIncludeNotificationSettings(final Boolean includeNotificationSettings) { + this.includeNotificationSettings = includeNotificationSettings; + } + + /** + * @return include the current thermostat privacy settings. Note: access to this object is restricted to callers + * with implicit authentication, setting this value to true without proper credentials will result in an + * authentication exception. + */ + @JsonProperty("includePrivacy") + public Boolean getIncludePrivacy() { + return this.includePrivacy; + } + + /** + * @return true if we would like privacy settings returned from this Selection. + */ + public boolean includePrivacy() { + return (this.includePrivacy == null) ? false : this.includePrivacy; + } + + /** + * @param includePrivacy + * include the current thermostat privacy settings. Note: access to this object is restricted to callers + * with implicit authentication, setting this value to true without proper credentials will result in an + * authentication exception. + */ + @JsonProperty("includePrivacy") + public void setIncludePrivacy(final Boolean includePrivacy) { + this.includePrivacy = includePrivacy; + } + + /** + * @return include the {@link Thermostat.Version}. If not specified, defaults to false. + */ + @JsonProperty("includeVersion") + public Boolean getIncludeVersion() { + return this.includeVersion; + } + + /** + * @return true if we would like version information returned from this Selection. + */ + public boolean includeVersion() { + return (this.includeVersion == null) ? false : this.includeVersion; + } + + /** + * @param includeVersion + * include the {@link Thermostat.Version}. If not specified, defaults to false. + */ + @JsonProperty("includeVersion") + public void setIncludeVersion(final Boolean includeVersion) { + this.includeVersion = includeVersion; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("selectionType", this.selectionType); + builder.append("selectionMatch", this.selectionMatch); + builder.append("includeRuntime", this.includeRuntime); + builder.append("includeExtendedRuntime", this.includeExtendedRuntime); + builder.append("includeElectricity", this.includeElectricity); + builder.append("includeSettings", this.includeSettings); + builder.append("includeLocation", this.includeLocation); + builder.append("includeProgram", this.includeProgram); + builder.append("includeEvents", this.includeEvents); + builder.append("includeDevice", this.includeDevice); + builder.append("includeTechnician", this.includeTechnician); + builder.append("includeUtility", this.includeUtility); + builder.append("includeManagement", this.includeManagement); + builder.append("includeAlerts", this.includeAlerts); + builder.append("includeWeather", this.includeWeather); + builder.append("includeHouseDetails", this.includeHouseDetails); + builder.append("includeOemCfg", this.includeOemCfg); + builder.append("includeEquipmentStatus", this.includeEquipmentStatus); + builder.append("includeNotificationSettings", this.includeNotificationSettings); + builder.append("includePrivacy", this.includePrivacy); + builder.append("includeVersion", this.includeVersion); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/SendMessageFunction.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/SendMessageFunction.java new file mode 100644 index 00000000000..77821f65a4f --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/SendMessageFunction.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +/** + * The send message function allows an alert message to be sent to the thermostat. The message properties are same + * as those of the {@link Thermostat.Alert} object. + * + * @see SendMessage + * @author John Cocula + * @since 1.7.0 + */ +public final class SendMessageFunction extends AbstractFunction { + + /** + * @param text + * the message text to send. Text will be truncated to 500 characters if longer. + * @throws IllegalArgumentException + * is text is null. + */ + public SendMessageFunction(String text) { + super("sendMessage"); + if (text == null) { + throw new IllegalArgumentException("text is required."); + } + + makeParams().put("text", text); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/SetHoldFunction.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/SetHoldFunction.java new file mode 100644 index 00000000000..938c6d9d3fe --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/SetHoldFunction.java @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.util.Date; + +/** + * The set hold function sets the thermostat into a hold with the specified temperature. Creates a hold for the + * specified duration. Note that an event is created regardless of whether the program is in the same state as the + * requested state. + * + *

      + * There is also support for creating a hold by passing a holdClimateRef request parameter/value pair to + * this function (See {@link Thermostat.Event}). When an existing and valid {@link Thermostat.Climate#climateRef} value + * is passed to this function, the coolHoldTemp, heatHoldTemp and fan mode from + * that {@link Thermostat.Climate} are used in the creation of the hold event. The values from that Climate will take + * precedence over any coolHoldTemp, heatHoldTemp and fan mode parameters passed + * into this function separately. + * + *

      + * To resume from a hold and return to the program, use the {@link ResumeProgramFunction}. + * + * @see SetHold + * @author John Cocula + * @since 1.7.0 + */ +public final class SetHoldFunction extends AbstractFunction { + + /** + * Construct a SetHoldFunction. + * + * @param coolHoldTemp + * the temperature to set the cool hold at + * @param heatHoldTemp + * the temperature to set the heat hold at + * @param holdClimateRef + * the Climate to use as reference for setting the coolHoldTemp, heatHoldTemp and fan settings for this + * hold. If this value is passed, the coolHoldTemp and heatHoldTemp are not required. + * @param startDateTime + * the start date and time in thermostat time + * @param endDateTime + * the end date and time in thermostat time + * @param holdType + * the hold duration type + * @param holdHours + * the number of hours to hold for, used and required if holdType='holdHours' + */ + public SetHoldFunction(Temperature coolHoldTemp, Temperature heatHoldTemp, String holdClimateRef, + Date startDateTime, Date endDateTime, HoldType holdType, Integer holdHours) { + super("setHold"); + + if (holdClimateRef == null && (coolHoldTemp == null || heatHoldTemp == null)) { + throw new IllegalArgumentException( + "coolHoldTemp and heatHoldTemp are required when holdClimateRef is not supplied."); + } + if (holdType == HoldType.HOLD_HOURS && holdHours == null) { + throw new IllegalArgumentException("holdHours must be specified when holdType='holdHours'"); + } + if (holdType == HoldType.DATE_TIME && endDateTime == null) { + throw new IllegalArgumentException("endDateTime must be specific when holdType='dateTime'"); + } + + if (coolHoldTemp != null) { + makeParams().put("coolHoldTemp", coolHoldTemp); + } + if (heatHoldTemp != null) { + makeParams().put("heatHoldTemp", heatHoldTemp); + } + if (holdClimateRef != null) { + makeParams().put("holdClimateRef", holdClimateRef); + } + if (startDateTime != null) { + makeParams().put("startDate", ymd.format(startDateTime)); + makeParams().put("startTime", hms.format(startDateTime)); + } + if (endDateTime != null) { + makeParams().put("endDate", ymd.format(endDateTime)); + makeParams().put("endTime", hms.format(endDateTime)); + } + if (holdType != null) { + makeParams().put("holdType", holdType); + } + if (holdHours != null) { + makeParams().put("holdHours", holdHours); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/SetOccupiedFunction.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/SetOccupiedFunction.java new file mode 100644 index 00000000000..176129efb8e --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/SetOccupiedFunction.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.util.Date; + +/** + * The set occupied function may only be used by EMS thermostats. + * + *

      + * The function switches a thermostat from occupied mode to unoccupied, or vice versa. If used on a Smart thermostat, + * the function will throw an error. Switch occupancy events are treated as Holds. There may only be one Switch + * Occupancy at one time, and the new event will replace any previous event. + * + *

      + * Note that an occupancy event is created regardless what the program on the thermostat is set to. For example, if the + * program is currently unoccupied and you set occupied=false, an occupancy event will be created using the + * heat/cool settings of the unoccupied program climate. If your intent is to go back to the program and remove the + * occupancy event, use {@link ResumeProgramFunction} instead. + * + * @see SetOccupied + * @author John Cocula + * @since 1.7.0 + */ +public final class SetOccupiedFunction extends AbstractFunction { + + /** + * Construct a SetOccupiedFunction. + * + * @param occupied + * the climate to use for the temperature, occupied (true) or unoccupied (false) + * @param startDateTime + * the start date and time in thermostat time + * @param endDateTime + * the end date and time in thermostat time + * @param holdType + * the hold duration type + * @param holdHours + * the number of hours to hold for, used and required if holdType='holdHours' + */ + public SetOccupiedFunction(Boolean occupied, Date startDateTime, Date endDateTime, HoldType holdType, + Integer holdHours) { + super("setOccupied"); // not in doc; assuming + + if (occupied == null) { + throw new IllegalArgumentException("occupied state is required."); + } + if (holdType == HoldType.HOLD_HOURS && holdHours == null) { + throw new IllegalArgumentException("holdHours must be specified when holdType='holdHours'"); + } + if (holdType == HoldType.DATE_TIME && endDateTime == null) { + throw new IllegalArgumentException("endDateTime must be specific when holdType='dateTime'"); + } + + makeParams().put("occupied", occupied); + if (startDateTime != null) { + makeParams().put("startDate", ymd.format(startDateTime)); + makeParams().put("startTime", hms.format(startDateTime)); + } + if (endDateTime != null) { + makeParams().put("endDate", ymd.format(endDateTime)); + makeParams().put("endTime", hms.format(endDateTime)); + } + if (holdType != null) { + makeParams().put("holdType", holdType); + } + if (holdHours != null) { + makeParams().put("holdHours", holdHours); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Status.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Status.java new file mode 100644 index 00000000000..ace95d5e050 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Status.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * The response status object contains the processing status of the request. It will contain any relevant error + * information should an error occur. The status object is returned with every response regardless of success or failure + * status. It is suitable for logging request failures. + * + * @see Status + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Status extends AbstractMessagePart { + private Integer code; + private String message; + + /** + * @return the status code for this status + */ + @JsonProperty("code") + public Integer getCode() { + return this.code; + } + + /** + * @return the detailed message for this status + */ + @JsonProperty("message") + public String getMessage() { + return this.message; + } + + /** + * @return true if we know this error indicates that the access token has expired. + */ + public boolean isAccessTokenExpired() { + return this.code != null && this.code == 14; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("code", this.code); + builder.append("message", this.message); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Temperature.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Temperature.java new file mode 100644 index 00000000000..9138231b91e --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Temperature.java @@ -0,0 +1,169 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.math.BigDecimal; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonValue; + +/** + * Temperature values are expressed as degrees Fahrenheit, multiplied by 10. For example, a temperature of 72F would be + * expressed as the value 720. If the user preferences indicate the use of Celsius values, it is the responsibility of + * the caller to convert values to and from Celsius. + * + *

      + * Where specified explicitly Degrees F indicates that the temperature will be returned in degrees Fahrenheit accurate + * to one decimal place (i.e. 18.5F). + * + *

      + * Methods are included to construct Temperature objects from Celsius, Fahrenheit, or whichever the local temperature + * scale is. + * + * @see Values + * and Representation + * @author John Cocula + * @since 1.7.0 + */ +public class Temperature { + + /** + * Enum for representing the temperature scale that will be reported. + */ + public static enum Scale { + CELSIUS("C"), FAHRENHEIT("F"); + + private final String scale; + + private Scale(final String scale) { + this.scale = scale; + } + + public String value() { + return scale; + } + + public static Scale forValue(String v) { + for (Scale s : Scale.values()) { + if (s.scale.equals(v)) { + return s; + } + } + throw new IllegalArgumentException("Invalid temperature scale: " + v); + } + } + + /** + * The local temperature scale used throughout this JVM. Defaults to Fahrenheit. + */ + private static Scale localScale = Scale.FAHRENHEIT; + + public static void setLocalScale(final Scale localScale) { + Temperature.localScale = localScale; + } + + private BigDecimal temp; + + @JsonValue + public int value() { + return temp.intValue(); + } + + /** + * Construct a Temperature from the Ecobee-style temperature value (Fahrenheit times 10). + * + * @param temp + * Ecobee-style temperature value (Fahrenheit times 10) + */ + @JsonCreator + public Temperature(int temp) { + this.temp = new BigDecimal(temp); + } + + /** + * Construct a Temperature from the Ecobee-style temperature value (Fahrenheit times 10). + * + * @param temp + * Ecobee-style temperature value (Fahrenheit times 10) + */ + public Temperature(BigDecimal temp) { + this.temp = temp; + } + + /** + * Factory method to construct a Temperature from the local temperature scale. + * + * @param localTemp + * the temperature in the local temperature scale. + * @return a new Temperature object + */ + public static Temperature fromLocalTemperature(BigDecimal localTemp) { + if (localScale.equals(Scale.CELSIUS)) { + return fromCelsius(localTemp); + } else { + return fromFahrenheit(localTemp); + } + } + + /** + * Factory method to construct a Temperature from Fahrenheit. + * + * @param fahrenheit + * the Fahrenheit temperature + */ + public static Temperature fromFahrenheit(BigDecimal fahrenheit) { + return new Temperature(fahrenheit.movePointRight(1)); + } + + private static BigDecimal NINE = new BigDecimal("9"); + private static BigDecimal FIVE = new BigDecimal("5"); + private static BigDecimal THIRTY_TWO = new BigDecimal("32"); + + /** + * Factory method to construct a Temperature from Celsius. + * + * @param celsius + * the Celsius temperature + */ + public static Temperature fromCelsius(BigDecimal celsius) { + return new Temperature(celsius.multiply(NINE).divide(FIVE).add(THIRTY_TWO).movePointRight(1)); + } + + /** + * Convert this temperature to a temperature in the local temperature scale. + * + * @return temperarure in the local temperature scale + */ + public final BigDecimal toLocalTemperature() { + return localScale == Scale.CELSIUS ? toCelsius() : toFahrenheit(); + } + + /** + * Convert this Temperature to Fahrenheit. + * + * @return temperature in Fahrenheit + */ + public final BigDecimal toFahrenheit() { + return temp.movePointLeft(1); + } + + /** + * Convert this Temperature to Celsius. + * + * @return temperature in Celsius + */ + public final BigDecimal toCelsius() { + return temp.movePointLeft(1).subtract(THIRTY_TWO).divide(NINE.divide(FIVE)); + } + + @Override + public String toString() { + return temp.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Thermostat.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Thermostat.java new file mode 100644 index 00000000000..292f1984d4d --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/Thermostat.java @@ -0,0 +1,6016 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.lang.reflect.InvocationTargetException; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; +import org.apache.commons.beanutils.BeanUtils; +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.annotate.JsonValue; + +/** + * The Thermostat Java Bean is the central piece of the ecobee API. All objects relate in one way or another to a real + * thermostat. The Thermostat class and its component classes define the real thermostat device. + * + * @see Thermostat + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Thermostat extends AbstractMessagePart { + + /** + * Numeric values whose value is not known are expressed as -5002. This is the numeric equivalent to a null value. + * The value of -5002 had been chosen as an unknown value because the representation of -500.2F is below absolute + * zero when representing temperatures. + * + * @see Core Concepts + */ + public static final int UNKNOWN_VALUE = -5002; + + /** + * There is a concept of dates "before time began" which is equivalent to a NULL time and "end of time" which + * represents infinite durations (i.e. events). The API represents these as: + * + * Before Time Began Date: 2008-01-02 + * + * End of Time Date: 2035-01-01 + * + * @see Core Concepts + */ + public static final Date BEFORE_TIME_BEGAN = new GregorianCalendar(2008, 1, 2).getTime(); + public static final Date END_OF_TIME = new GregorianCalendar(2035, 1, 1).getTime(); + + private String identifier; + private String name; + private String thermostatRev; + private Boolean isRegistered; + private String modelNumber; + private Date lastModified; + private Date thermostatTime; + private Date utcTime; + private List alerts; + private Settings settings; + private Runtime runtime; + private ExtendedRuntime extendedRuntime; + private Electricity electricity; + private List devices; + private Location location; + private Technician technician; + private Utility utility; + private Management management; + private Weather weather; + private List events; + private Program program; + private HouseDetails houseDetails; + private ThermostatOemCfg oemCfg; + private String equipmentStatus; + private NotificationSettings notificationSettings; + private ThermostatPrivacy privacy; + private Version version; + + public Thermostat(@JsonProperty("identifier") String identifier) { + this.identifier = identifier; + } + + /** + * Return a JavaBean property by name. + * + * @param name + * the named property to return + * @return the named property's value + * @see BeanUtils#getProperty() + * @throws IllegalAccessException + * if the caller does not have access to the property accessor method + * @throws InvocationTargetException + * if the property accessor method throws an exception + * @throws NoSuchMethodException + * if the accessor method for this property cannot be found + */ + public Object getProperty(String name) throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + + return PropertyUtils.getProperty(this, name); + } + + /** + * Set the specified property value, performing type conversions as required to conform to the type of the + * destination property. Nest beans are created if they are currently null. + * + * @param name + * property name (can be nested/indexed/mapped/combo) + * @param value + * value to be set + * @throws IllegalAccessException + * if the caller does not have access to the property accessor method + * @throws InvocationTargetException + * if the property accessor method throws an exception + */ + public void setProperty(String name, Object value) throws IllegalAccessException, InvocationTargetException { + + if (name.startsWith("settings") && this.settings == null) { + this.settings = new Settings(); + } else if (name.startsWith("location") && this.location == null) { + this.location = new Location(); + } else if (name.startsWith("program") && this.program == null) { + this.program = new Program(); + } else if (name.startsWith("houseDetails") && this.houseDetails == null) { + this.houseDetails = new HouseDetails(); + } else if (name.startsWith("notificationSettings") && this.notificationSettings == null) { + this.notificationSettings = new NotificationSettings(); + } + + BeanUtils.setProperty(this, name, value); + } + + /** + * @return the unique thermostat serial number. + */ + @JsonProperty("identifier") + public String getIdentifier() { + return this.identifier; + } + + /** + * @return the user defined name for a thermostat + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @param name + * the user defined name for a thermostat + */ + @JsonProperty("name") + public void setName(String name) { + this.name = name; + } + + /** + * @return current thermostat configuration revision + */ + @JsonProperty("thermostatRev") + public String getThermostatRev() { + return this.thermostatRev; + } + + /** + * @return whether the user registered the thermostat + */ + @JsonProperty("isRegistered") + public Boolean getIsRegistered() { + return this.isRegistered; + } + + /** + * @return the thermostat model number. Values: idtSmart, idtEms, siSmart, siEms + */ + @JsonProperty("modelNumber") + public String getModelNumber() { + return this.modelNumber; + } + + /** + * @return the last modified date time for the thermostat configuration. + */ + @JsonProperty("lastModified") + public Date getLastModified() { + return this.lastModified; + } + + /** + * @return the current time in the thermostat's time zone TODO time zone adjust (@watou) + * http://wiki.fasterxml.com/JacksonFAQDateHandling + */ + @JsonProperty("thermostatTime") + public Date getThermostatTime() { + return this.thermostatTime; + } + + /** + * @return the current time in UTC + */ + @JsonProperty("utcTime") + public Date getUtcTime() { + return this.utcTime; + } + + /** + * @return the list of Alert objects tied to the thermostat + */ + @JsonProperty("alerts") + public List getAlerts() { + return this.alerts; + } + + /** + * @return the thermostat Setting object linked to the thermostat + */ + @JsonProperty("settings") + public Settings getSettings() { + return this.settings; + } + + /** + * @param settings + * the thermostat Setting object linked to the thermostat + */ + @JsonProperty("settings") + public void setSettings(Settings settings) { + this.settings = settings; + } + + /** + * @return the Runtime state object for the thermostat + */ + @JsonProperty("runtime") + public Runtime getRuntime() { + return this.runtime; + } + + /** + * @return the ExtendedRuntime object for the thermostat + */ + @JsonProperty("extendedRuntime") + public ExtendedRuntime getExtendedRuntime() { + return this.extendedRuntime; + } + + /** + * @return the Electricity object for the thermostat + */ + @JsonProperty("electricity") + public Electricity getElectricity() { + return this.electricity; + } + + /** + * @return the list of Device objects linked to the thermostat + */ + @JsonProperty("devices") + public List getDevices() { + return this.devices; + } + + /** + * @return the Location object for the thermostat + */ + @JsonProperty("location") + public Location getLocation() { + return this.location; + } + + /** + * @param location + * the Location object for the thermostat + */ + @JsonProperty("location") + public void setLocation(Location location) { + this.location = location; + } + + /** + * @return the Technician object associated with the thermostat containing the technician contact information + */ + @JsonProperty("technician") + public Technician getTechnician() { + return this.technician; + } + + /** + * @return the Utility object associated with the thermostat containing the utility company information + */ + @JsonProperty("utility") + public Utility getUtility() { + return this.utility; + } + + /** + * @return the Management object associated with the thermostat containing the management company information + */ + @JsonProperty("management") + public Management getManagement() { + return this.management; + } + + /** + * @return the Weather object linked to the thermostat representing the current weather on the thermostat + */ + @JsonProperty("weather") + public Weather getWeather() { + return this.weather; + } + + /** + * @return the list of Event objects linked to the thermostat representing any events that are active or scheduled. + */ + @JsonProperty("events") + public List getEvents() { + return this.events; + } + + /** + * @return the Program object for the thermostat + */ + @JsonProperty("program") + public Program getProgram() { + return this.program; + } + + /** + * @param program + * the Program object for the thermostat + */ + @JsonProperty("program") + public void setProgram(Program program) { + this.program = program; + } + + /** + * @return the HouseDetails object that contains the information about the house the thermostat is installed in + */ + @JsonProperty("houseDetails") + public HouseDetails getHouseDetails() { + return this.houseDetails; + } + + /** + * @param houseDetails + * the HouseDetails object that contains the information about the house the thermostat is installed in + */ + @JsonProperty("houseDetails") + public void setHouseDetails(HouseDetails houseDetails) { + this.houseDetails = houseDetails; + } + + /** + * @return the ThermostatOemCfg object that contains information about the OEM specific thermostat + */ + @JsonProperty("oemCfg") + public ThermostatOemCfg getOemCfg() { + return this.oemCfg; + } + + /** + * @param oemCfg + * the ThermostatOemCfg object that contains information about the OEM specific thermostat + */ + @JsonProperty("oemCfg") + public void setOemCfg(ThermostatOemCfg oemCfg) { + this.oemCfg = oemCfg; + } + + /** + * The status of all equipment controlled by this Thermostat. Only running equipment is listed in the CSV String. If + * no equipment is currently running an empty string is returned. + * + * Values: heatPump, heatPump2, heatPump3, compCool1, compCool2, auxHeat1, auxHeat2, auxHeat3, fan, humidifier, + * dehumidifier, ventilator, economizer, compHotWater, auxHotWater. + * + * @return the equipmentStatus + */ + @JsonProperty("equipmentStatus") + public String getEquipmentStatus() { + return this.equipmentStatus; + } + + /** + * @return the NotificationSettings object containing the configuration for Alert and Reminders for the Thermostat + */ + @JsonProperty("notificationSettings") + public NotificationSettings getNotificationSettings() { + return this.notificationSettings; + } + + /** + * @param notificationSettings + * the NotificationSettings object containing the configuration for Alert and Reminders for the + * Thermostat + */ + @JsonProperty("notificationSettings") + public void setNotificationSettings(NotificationSettings notificationSettings) { + this.notificationSettings = notificationSettings; + } + + /** + * @return the Privacy object containing the privacy settings for the Thermostat. Note: access to this object is + * restricted to callers with implicit authentication. + */ + @JsonProperty("privacy") + public ThermostatPrivacy getPrivacy() { + return this.privacy; + } + + /** + * @param privacy + * the Privacy object containing the privacy settings for the Thermostat. Note: access to this object is + * restricted to callers with implicit authentication. + */ + @JsonProperty("privacy") + public void setPrivacy(ThermostatPrivacy privacy) { + this.privacy = privacy; + } + + /** + * @return the version information about the thermostat + */ + @JsonProperty("version") + public Version getVersion() { + return version; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("identifier", this.identifier); + builder.append("name", this.name); + builder.append("thermostatRev", this.thermostatRev); + builder.append("isRegistered", this.isRegistered); + builder.append("modelNumber", this.modelNumber); + builder.append("lastModified", this.lastModified); + builder.append("thermostatTime", this.thermostatTime); + builder.append("utcTime", this.utcTime); + builder.append("alerts", this.alerts); + builder.append("settings", this.settings); + builder.append("runtime", this.runtime); + builder.append("extendedRuntime", this.extendedRuntime); + builder.append("electricity", this.electricity); + builder.append("devices", this.devices); + builder.append("location", this.location); + builder.append("technician", this.technician); + builder.append("utility", this.utility); + builder.append("management", this.management); + builder.append("weather", this.weather); + builder.append("events", this.events); + builder.append("program", this.program); + builder.append("houseDetails", this.houseDetails); + builder.append("oemCfg", this.oemCfg); + builder.append("equipmentStatus", this.equipmentStatus); + builder.append("notificationSettings", this.notificationSettings); + builder.append("privacy", this.privacy); + builder.append("version", this.version); + + return builder.toString(); + } + + /** + * The Alert object represents an alert generated either by a thermostat or user which requires user attention. It + * may be an error, or a reminder for a filter change. Alerts may not be modified directly but rather they must be + * acknowledged using the Acknowledge Function. + * + * @see Alert + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Alert extends AbstractMessagePart { + private String acknowledgeRef; + private String date; + private String time; + private String severity; + private String text; + private Integer alertNumber; + private String alertType; + @JsonProperty("isOperatorAlert") + private Boolean _isOperatorAlert; + private String reminder; + @JsonProperty("showIdt") + private Boolean _showIdt; + @JsonProperty("showWeb") + private Boolean _showWeb; + @JsonProperty("sendEmail") + private Boolean _sendEmail; + private String acknowledgement; + @JsonProperty("remindMeLater") + private Boolean _remindMeLater; + private String thermostatIdentifier; + private String notificationType; + + /** + * @return the acknowledgeRef + */ + @JsonProperty("acknowledgeRef") + public String getAcknowledgeRef() { + return this.acknowledgeRef; + } + + /** + * @return the date + */ + @JsonProperty("date") + public String getDate() { + return this.date; + } + + /** + * @return the time + */ + @JsonProperty("time") + public String getTime() { + return this.time; + } + + /** + * @return the severity + */ + @JsonProperty("severity") + public String getSeverity() { + return this.severity; + } + + /** + * @return the text + */ + @JsonProperty("text") + public String getText() { + return this.text; + } + + /** + * @return the alertNumber + */ + @JsonProperty("alertNumber") + public Integer getAlertNumber() { + return this.alertNumber; + } + + /** + * @return the alertType + */ + @JsonProperty("alertType") + public String getAlertType() { + return this.alertType; + } + + /** + * @return the isOperatorAlert + */ + @JsonProperty("isOperatorAlert") + public Boolean isOperatorAlert() { + return this._isOperatorAlert; + } + + /** + * @return the reminder + */ + @JsonProperty("reminder") + public String getReminder() { + return this.reminder; + } + + /** + * @return the showIdt + */ + @JsonProperty("showIdt") + public Boolean showIdt() { + return this._showIdt; + } + + /** + * @return the showWeb + */ + @JsonProperty("showWeb") + public Boolean showWeb() { + return this._showWeb; + } + + /** + * @return the sendEmail + */ + @JsonProperty("sendEmail") + public Boolean sendEmail() { + return this._sendEmail; + } + + /** + * @return the acknowledgement + */ + @JsonProperty("acknowledgement") + public String getAcknowledgement() { + return this.acknowledgement; + } + + /** + * @return the remindMeLater + */ + @JsonProperty("remindMeLater") + public Boolean remindMeLater() { + return this._remindMeLater; + } + + /** + * @return the thermostatIdentifier + */ + @JsonProperty("thermostatIdentifier") + public String getThermostatIdentifier() { + return this.thermostatIdentifier; + } + + /** + * @return the notificationType + */ + @JsonProperty("notificationType") + public String getNotificationType() { + return this.notificationType; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + + builder.append("acknowledgeRef", this.acknowledgeRef); + builder.append("date", this.date); + builder.append("time", this.time); + builder.append("severity", this.severity); + builder.append("text", this.text); + builder.append("alertNumber", this.alertNumber); + builder.append("alertType", this.alertType); + builder.append("isOperatorAlert", this._isOperatorAlert); + builder.append("reminder", this.reminder); + builder.append("showIdt", this._showIdt); + builder.append("showWeb", this._showWeb); + builder.append("sendEmail", this._sendEmail); + builder.append("acknowledgement", this.acknowledgement); + builder.append("remindMeLater", this._remindMeLater); + builder.append("thermostatIdentifier", this.thermostatIdentifier); + builder.append("notificationType", this.notificationType); + + return builder.toString(); + } + } + + /** + * The Settings Java Bean contains all the configuration properties of the thermostat in which it is contained. + * + * @see Settings + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Settings extends AbstractMessagePart { + private HvacMode hvacMode; + private String lastServiceDate; // TODO Jackson 1.9 dates (@watou) + private Boolean serviceRemindMe; + private Integer monthsBetweenService; + private String remindMeDate; // TODO Jackson 1.9 dates (@watou) + private VentilatorMode vent; + private Integer ventilatorMinOnTime; + private Boolean serviceRemindTechnician; + private String eiLocation; + private Temperature coldTempAlert; + private Boolean coldTempAlertEnabled; + private Temperature hotTempAlert; + private Boolean hotTempAlertEnabled; + private Integer coolStages; + private Integer heatStages; + private Temperature maxSetBack; + private Temperature maxSetForward; + private Temperature quickSaveSetBack; + private Temperature quickSaveSetForward; + private Boolean hasHeatPump; + private Boolean hasForcedAir; + private Boolean hasBoiler; + private Boolean hasHumidifier; + private Boolean hasErv; + private Boolean hasHrv; + private Boolean condensationAvoid; + private Boolean useCelsius; + private Boolean useTimeFormat12; + private String locale; + private String humidity; + private String humidifierMode; + private Integer backlightOnIntensity; + private Integer backlightSleepIntensity; + private Integer backlightOffTime; + private Integer soundTickVolume; + private Integer soundAlertVolume; + private Integer compressorProtectionMinTime; + private Temperature compressorProtectionMinTemp; + private Temperature stage1HeatingDifferentialTemp; + private Temperature stage1CoolingDifferentialTemp; + private Integer stage1HeatingDissipationTime; + private Integer stage1CoolingDissipationTime; + private Boolean heatPumpReversalOnCool; + private Boolean fanControlRequired; + private Integer fanMinOnTime; + private Temperature heatCoolMinDelta; + private Temperature tempCorrection; + private String holdAction; + private Boolean heatPumpGroundWater; + private Boolean hasElectric; + private Boolean hasDehumidifier; + private String dehumidifierMode; + private Integer dehumidifierLevel; + private Boolean dehumidifyWithAC; + private Integer dehumidifyOvercoolOffset; + private Boolean autoHeatCoolFeatureEnabled; + private Boolean wifiOfflineAlert; + private Temperature heatMinTemp; + private Temperature heatMaxTemp; + private Temperature coolMinTemp; + private Temperature coolMaxTemp; + private Temperature heatRangeHigh; + private Temperature heatRangeLow; + private Temperature coolRangeHigh; + private Temperature coolRangeLow; + private String userAccessCode; + private Integer userAccessSetting; + private Temperature auxRuntimeAlert; + private Temperature auxOutdoorTempAlert; + private Temperature auxMaxOutdoorTemp; + private Boolean auxRuntimeAlertNotify; + private Boolean auxOutdoorTempAlertNotify; + private Boolean auxRuntimeAlertNotifyTechnician; + private Boolean auxOutdoorTempAlertNotifyTechnician; + private Boolean disablePreHeating; + private Boolean disablePreCooling; + private Boolean installerCodeRequired; + private String drAccept; + private Boolean isRentalProperty; + private Boolean useZoneController; + private Integer randomStartDelayCool; + private Integer randomStartDelayHeat; + private Integer humidityHighAlert; + private Integer humidityLowAlert; + private Boolean disableHeatPumpAlerts; + private Boolean disableAlertsOnIdt; + private Boolean humidityAlertNotify; + private Boolean humidityAlertNotifyTechnician; + private Boolean tempAlertNotify; + private Boolean tempAlertNotifyTechnician; + private Integer monthlyElectricityBillLimit; + private Boolean enableElectricityBillAlert; + private Boolean enableProjectedElectricityBillAlert; + private Integer electricityBillingDayOfMonth; + private Integer electricityBillCycleMonths; + private Integer electricityBillStartMonth; + private Integer ventilatorMinOnTimeHome; + private Integer ventilatorMinOnTimeAway; + private Boolean backlightOffDuringSleep; + private Boolean autoAway; + private Boolean smartCirculation; + private Boolean followMeComfort; + private String ventilatorType; + private Boolean isVentilatorTimerOn; + private Date ventilatorOffDateTime; + private Boolean hasUVFilter; + private Boolean coolingLockout; + private Boolean ventilatorFreeCooling; + private Boolean dehumidifyWhenHeating; + private String groupRef; + private String groupName; + private Integer groupSetting; + + /** + * @return the current HVAC mode the thermostat is in. Values: auto, auxHeatOnly, cool, heat, off. + */ + @JsonProperty("hvacMode") + public HvacMode getHvacMode() { + return this.hvacMode; + } + + /** + * @param hvacMode + * the current HVAC mode the thermostat is in. Values: auto, auxHeatOnly, cool, heat, off. + */ + @JsonProperty("hvacMode") + public void setHvacMode(HvacMode hvacMode) { + this.hvacMode = hvacMode; + } + + /** + * @return the last service date of the HVAC equipment + */ + @JsonProperty("lastServiceDate") + public String getLastServiceDate() { + return this.lastServiceDate; + } + + /** + * @param lastServiceDate + * the last service date of the HVAC equipment + */ + @JsonProperty("lastServiceDate") + public void setLastServiceDate(String lastServiceDate) { + this.lastServiceDate = lastServiceDate; + } + + /** + * @return whether to send an alert when service is required again + */ + @JsonProperty("serviceRemindMe") + public Boolean getServiceRemindMe() { + return this.serviceRemindMe; + } + + /** + * @param serviceRemindMe + * whether to send an alert when service is required again + */ + @JsonProperty("serviceRemindMe") + public void setServiceRemindMe(Boolean serviceRemindMe) { + this.serviceRemindMe = serviceRemindMe; + } + + /** + * @return the user configured monthly interval between HVAC service reminders + */ + @JsonProperty("monthsBetweenService") + public Integer getMonthsBetweenService() { + return this.monthsBetweenService; + } + + /** + * @param monthsBetweenService + * the user configured monthly interval between HVAC service reminders + */ + @JsonProperty("monthsBetweenService") + public void setMonthsBetweenService(Integer monthsBetweenService) { + this.monthsBetweenService = monthsBetweenService; + } + + /** + * @return the date to be reminded about the next HVAC service date + */ + @JsonProperty("remindMeDate") + public String getRemindMeDate() { + return this.remindMeDate; + } + + /** + * @param remindMeDate + * the date to be reminded about the next HVAC service date + */ + @JsonProperty("remindMeDate") + public void setRemindMeDate(String remindMeDate) { + this.remindMeDate = remindMeDate; + } + + /** + * @return the ventilator mode. Values: auto, minontime, on, off + */ + @JsonProperty("vent") + public VentilatorMode getVent() { + return this.vent; + } + + /** + * @param vent + * the ventilator mode. Values: auto, minontime, on, off + */ + @JsonProperty("vent") + public void setVent(VentilatorMode vent) { + this.vent = vent; + } + + /** + * @return the minimum time in minutes the ventilator is configured to run. The thermostat will always guarantee + * that the ventilator runs for this minimum duration whenever engaged. + */ + @JsonProperty("ventilatorMinOnTime") + public Integer getVentilatorMinOnTime() { + return this.ventilatorMinOnTime; + } + + /** + * @param ventilatorMinOnTime + * the minimum time in minutes the ventilator is configured to run. The thermostat will always + * guarantee that the ventilator runs for this minimum duration whenever engaged. + */ + @JsonProperty("ventilatorMinOnTime") + public void setVentilatorMinOnTime(Integer ventilatorMinOnTime) { + this.ventilatorMinOnTime = ventilatorMinOnTime; + } + + /** + * @return whether the technician associated with this thermostat should receive the HVAC service reminders as + * well + */ + @JsonProperty("serviceRemindTechnician") + public Boolean getServiceRemindTechnician() { + return this.serviceRemindTechnician; + } + + /** + * @param serviceRemindTechnician + * whether the technician associated with this thermostat should receive the HVAC service reminders + * as well + */ + @JsonProperty("serviceRemindTechnician") + public void setServiceRemindTechnician(Boolean serviceRemindTechnician) { + this.serviceRemindTechnician = serviceRemindTechnician; + } + + /** + * @return a note about the physical location where the SMART or EMS Equipment Interface module is located + */ + @JsonProperty("eiLocation") + public String getEiLocation() { + return this.eiLocation; + } + + /** + * @param eiLocation + * a note about the physical location where the SMART or EMS Equipment Interface module is located + */ + @JsonProperty("eiLocation") + public void setEiLocation(String eiLocation) { + this.eiLocation = eiLocation; + } + + /** + * @return the temperature at which a cold temp alert is triggered + */ + @JsonProperty("coldTempAlert") + public Temperature getColdTempAlert() { + return this.coldTempAlert; + } + + /** + * @param coldTempAlert + * the temperature at which a cold temp alert is triggered + */ + @JsonProperty("coldTempAlert") + public void setColdTempAlert(Temperature coldTempAlert) { + this.coldTempAlert = coldTempAlert; + } + + /** + * @return whether cold temperature alerts are enabled + */ + @JsonProperty("coldTempAlertEnabled") + public Boolean getColdTempAlertEnabled() { + return this.coldTempAlertEnabled; + } + + /** + * @param coldTempAlertEnabled + * whether cold temperature alerts are enabled + */ + @JsonProperty("coldTempAlertEnabled") + public void setColdTempAlertEnabled(Boolean coldTempAlertEnabled) { + this.coldTempAlertEnabled = coldTempAlertEnabled; + } + + /** + * @return the temperature at which a hot temp alert is triggered + */ + @JsonProperty("hotTempAlert") + public Temperature getHotTempAlert() { + return this.hotTempAlert; + } + + /** + * @param hotTempAlert + * the temperature at which a hot temp alert is triggered + */ + @JsonProperty("hotTempAlert") + public void setHotTempAlert(Temperature hotTempAlert) { + this.hotTempAlert = hotTempAlert; + } + + /** + * @return whether hot temperature alerts are enabled + */ + @JsonProperty("hotTempAlertEnabled") + public Boolean getHotTempAlertEnabled() { + return this.hotTempAlertEnabled; + } + + /** + * @param hotTempAlertEnabled + * whether hot temperature alerts are enabled + */ + @JsonProperty("hotTempAlertEnabled") + public void setHotTempAlertEnabled(Boolean hotTempAlertEnabled) { + this.hotTempAlertEnabled = hotTempAlertEnabled; + } + + /** + * @return the number of cool stages the connected HVAC equipment supports + */ + @JsonProperty("coolStages") + public Integer getCoolStages() { + return this.coolStages; + } + + /** + * @return the number of heat stages the connected HVAC equipment supports + */ + @JsonProperty("heatStages") + public Integer getHeatStages() { + return this.heatStages; + } + + /** + * @return the maximum automated set point set back offset allowed in degrees + */ + @JsonProperty("maxSetBack") + public Temperature getMaxSetBack() { + return this.maxSetBack; + } + + /** + * @param maxSetBack + * the maximum automated set point set back offset allowed in degrees + */ + @JsonProperty("maxSetBack") + public void setMaxSetBack(Temperature maxSetBack) { + this.maxSetBack = maxSetBack; + } + + /** + * @return the maximum automated set point set forward offset allowed in degrees + */ + @JsonProperty("maxSetForward") + public Temperature getMaxSetForward() { + return this.maxSetForward; + } + + /** + * @param maxSetForward + * the maximum automated set point set forward offset allowed in degrees + */ + @JsonProperty("maxSetForward") + public void setMaxSetForward(Temperature maxSetForward) { + this.maxSetForward = maxSetForward; + } + + /** + * @return the set point set back offset, in degrees, configured for a quick save event + */ + @JsonProperty("quickSaveSetBack") + public Temperature getQuickSaveSetBack() { + return this.quickSaveSetBack; + } + + /** + * @param quickSaveSetBack + * the set point set back offset, in degrees, configured for a quick save event + */ + @JsonProperty("quickSaveSetBack") + public void setQuickSaveSetBack(Temperature quickSaveSetBack) { + this.quickSaveSetBack = quickSaveSetBack; + } + + /** + * @return the set point set forward offset, in degrees, configured for a quick save event + */ + @JsonProperty("quickSaveSetForward") + public Temperature getQuickSaveSetForward() { + return this.quickSaveSetForward; + } + + /** + * @param quickSaveSetForward + * the set point set forward offset, in degrees, configured for a quick save event + */ + @JsonProperty("quickSaveSetForward") + public void setQuickSaveSetForward(Temperature quickSaveSetForward) { + this.quickSaveSetForward = quickSaveSetForward; + } + + /** + * @return whether the thermostat is controlling a heat pump + */ + @JsonProperty("hasHeatPump") + public Boolean getHasHeatPump() { + return this.hasHeatPump; + } + + /** + * @return whether the thermostat is controlling a forced air furnace + */ + @JsonProperty("hasForcedAir") + public Boolean getHasForcedAir() { + return this.hasForcedAir; + } + + /** + * @return whether the thermostat is controlling a boiler + */ + @JsonProperty("hasBoiler") + public Boolean getHasBoiler() { + return this.hasBoiler; + } + + /** + * @return whether the thermostat is controlling a humidifier + */ + @JsonProperty("hasHumidifier") + public Boolean getHasHumidifier() { + return this.hasHumidifier; + } + + /** + * @return whether the thermostat is controlling an energy recovery ventilator + */ + @JsonProperty("hasErv") + public Boolean getHasErv() { + return this.hasErv; + } + + /** + * @return whether the thermostat is controlling a heat recovery ventilator + */ + @JsonProperty("hasHrv") + public Boolean getHasHrv() { + return this.hasHrv; + } + + /** + * @return whether the thermostat is in frost control mode + */ + @JsonProperty("condensationAvoid") + public Boolean getCondensationAvoid() { + return this.condensationAvoid; + } + + /** + * @param condensationAvoid + * whether the thermostat is in frost control mode + */ + @JsonProperty("condensationAvoid") + public void setCondensationAvoid(Boolean condensationAvoid) { + this.condensationAvoid = condensationAvoid; + } + + /** + * @return whether the thermostat is configured to report in degrees Celsius + */ + @JsonProperty("useCelsius") + public Boolean getUseCelsius() { + return this.useCelsius; + } + + /** + * @param useCelsius + * whether the thermostat is configured to report in degrees Celsius + */ + @JsonProperty("useCelsius") + public void setUseCelsius(Boolean useCelsius) { + this.useCelsius = useCelsius; + } + + /** + * @return whether the thermostat is using 12hr time format + */ + @JsonProperty("useTimeFormat12") + public Boolean getUseTimeFormat12() { + return this.useTimeFormat12; + } + + /** + * @param useTimeFormat12 + * whether the thermostat is using 12hr time format + */ + @JsonProperty("useTimeFormat12") + public void setUseTimeFormat12(Boolean useTimeFormat12) { + this.useTimeFormat12 = useTimeFormat12; + } + + /** + * @return the locale + */ + @JsonProperty("locale") + public String getLocale() { + return this.locale; + } + + /** + * @param locale + * the locale to set + */ + @JsonProperty("locale") + public void setLocale(String locale) { + this.locale = locale; + } + + /** + * @return the minimum humidity level (in percent) set point for the humidifier + */ + @JsonProperty("humidity") + public String getHumidity() { + return this.humidity; + } + + /** + * @param humidity + * the minimum humidity level (in percent) set point for the humidifier + */ + @JsonProperty("humidity") + public void setHumidity(String humidity) { + this.humidity = humidity; + } + + /** + * @return the humidifier mode. Values: auto, manual, off + */ + @JsonProperty("humidifierMode") + public String getHumidifierMode() { + return this.humidifierMode; + } + + /** + * @param humidifierMode + * the humidifier mode. Values: auto, manual, off + */ + @JsonProperty("humidifierMode") + public void setHumidifierMode(String humidifierMode) { + this.humidifierMode = humidifierMode; + } + + /** + * @return the thermostat backlight intensity when on. A value between 1 and 10. + */ + @JsonProperty("backlightOnIntensity") + public Integer getBacklightOnIntensity() { + return this.backlightOnIntensity; + } + + /** + * @param backlightOnIntensity + * the thermostat backlight intensity when on. A value between 1 and 10. + */ + @JsonProperty("backlightOnIntensity") + public void setBacklightOnIntensity(Integer backlightOnIntensity) { + this.backlightOnIntensity = backlightOnIntensity; + } + + /** + * @return the thermostat backlight intensity when asleep. A value between 1 and 10. + */ + @JsonProperty("backlightSleepIntensity") + public Integer getBacklightSleepIntensity() { + return this.backlightSleepIntensity; + } + + /** + * @param backlightSleepIntensity + * the thermostat backlight intensity when asleep. A value between 1 and 10. + */ + @JsonProperty("backlightSleepIntensity") + public void setBacklightSleepIntensity(Integer backlightSleepIntensity) { + this.backlightSleepIntensity = backlightSleepIntensity; + } + + /** + * @return the time in seconds before the thermostat screen goes into sleep mode + */ + @JsonProperty("backlightOffTime") + public Integer getBacklightOffTime() { + return this.backlightOffTime; + } + + /** + * @param backlightOffTime + * the time in seconds before the thermostat screen goes into sleep mode + */ + @JsonProperty("backlightOffTime") + public void setBacklightOffTime(Integer backlightOffTime) { + this.backlightOffTime = backlightOffTime; + } + + /** + * @return the volume level for key presses on the thermostat. A value between 1 and 10. + */ + @JsonProperty("soundTickVolume") + public Integer getSoundTickVolume() { + return this.soundTickVolume; + } + + /** + * @param soundTickVolume + * the volume level for key presses on the thermostat. A value between 1 and 10. + */ + @JsonProperty("soundTickVolume") + public void setSoundTickVolume(Integer soundTickVolume) { + this.soundTickVolume = soundTickVolume; + } + + /** + * @return the volume level for alerts on the thermostat. A value between 1 and 10. + */ + @JsonProperty("soundAlertVolume") + public Integer getSoundAlertVolume() { + return this.soundAlertVolume; + } + + /** + * @param soundAlertVolume + * the volume level for alerts on the thermostat. A value between 1 and 10. + */ + @JsonProperty("soundAlertVolume") + public void setSoundAlertVolume(Integer soundAlertVolume) { + this.soundAlertVolume = soundAlertVolume; + } + + /** + * @return the compressorProtectionMinTime + */ + @JsonProperty("compressorProtectionMinTime") + public Integer getCompressorProtectionMinTime() { + return this.compressorProtectionMinTime; + } + + /** + * @param compressorProtectionMinTime + * the compressorProtectionMinTime to set + */ + @JsonProperty("compressorProtectionMinTime") + public void setCompressorProtectionMinTime(Integer compressorProtectionMinTime) { + this.compressorProtectionMinTime = compressorProtectionMinTime; + } + + /** + * @return the compressorProtectionMinTemp + */ + @JsonProperty("compressorProtectionMinTemp") + public Temperature getCompressorProtectionMinTemp() { + return this.compressorProtectionMinTemp; + } + + /** + * @param compressorProtectionMinTemp + * the compressorProtectionMinTemp to set + */ + @JsonProperty("compressorProtectionMinTemp") + public void setCompressorProtectionMinTemp(Temperature compressorProtectionMinTemp) { + this.compressorProtectionMinTemp = compressorProtectionMinTemp; + } + + /** + * @return the stage1HeatingDifferentialTemp + */ + @JsonProperty("stage1HeatingDifferentialTemp") + public Temperature getStage1HeatingDifferentialTemp() { + return this.stage1HeatingDifferentialTemp; + } + + /** + * @param stage1HeatingDifferentialTemp + * the stage1HeatingDifferentialTemp to set + */ + @JsonProperty("stage1HeatingDifferentialTemp") + public void setStage1HeatingDifferentialTemp(Temperature stage1HeatingDifferentialTemp) { + this.stage1HeatingDifferentialTemp = stage1HeatingDifferentialTemp; + } + + /** + * @return the stage1CoolingDifferentialTemp + */ + @JsonProperty("stage1CoolingDifferentialTemp") + public Temperature getStage1CoolingDifferentialTemp() { + return this.stage1CoolingDifferentialTemp; + } + + /** + * @param stage1CoolingDifferentialTemp + * the stage1CoolingDifferentialTemp to set + */ + @JsonProperty("stage1CoolingDifferentialTemp") + public void setStage1CoolingDifferentialTemp(Temperature stage1CoolingDifferentialTemp) { + this.stage1CoolingDifferentialTemp = stage1CoolingDifferentialTemp; + } + + /** + * @return the stage1HeatingDissipationTime + */ + @JsonProperty("stage1HeatingDissipationTime") + public Integer getStage1HeatingDissipationTime() { + return this.stage1HeatingDissipationTime; + } + + /** + * @param stage1HeatingDissipationTime + * the stage1HeatingDissipationTime to set + */ + @JsonProperty("stage1HeatingDissipationTime") + public void setStage1HeatingDissipationTime(Integer stage1HeatingDissipationTime) { + this.stage1HeatingDissipationTime = stage1HeatingDissipationTime; + } + + /** + * @return the stage1CoolingDissipationTime + */ + @JsonProperty("stage1CoolingDissipationTime") + public Integer getStage1CoolingDissipationTime() { + return this.stage1CoolingDissipationTime; + } + + /** + * @param stage1CoolingDissipationTime + * the stage1CoolingDissipationTime to set + */ + @JsonProperty("stage1CoolingDissipationTime") + public void setStage1CoolingDissipationTime(Integer stage1CoolingDissipationTime) { + this.stage1CoolingDissipationTime = stage1CoolingDissipationTime; + } + + /** + * @return the heatPumpReversalOnCool + */ + @JsonProperty("heatPumpReversalOnCool") + public Boolean getHeatPumpReversalOnCool() { + return this.heatPumpReversalOnCool; + } + + /** + * @param heatPumpReversalOnCool + * the heatPumpReversalOnCool to set + */ + @JsonProperty("heatPumpReversalOnCool") + public void setHeatPumpReversalOnCool(Boolean heatPumpReversalOnCool) { + this.heatPumpReversalOnCool = heatPumpReversalOnCool; + } + + /** + * @return the fanControlRequired + */ + @JsonProperty("fanControlRequired") + public Boolean getFanControlRequired() { + return this.fanControlRequired; + } + + /** + * @param fanControlRequired + * the fanControlRequired to set + */ + @JsonProperty("fanControlRequired") + public void setFanControlRequired(Boolean fanControlRequired) { + this.fanControlRequired = fanControlRequired; + } + + /** + * @return the minimum time, in minutes, to run the fan each hour. Value from 1 to 60. + */ + @JsonProperty("fanMinOnTime") + public Integer getFanMinOnTime() { + return this.fanMinOnTime; + } + + /** + * @param fanMinOnTime + * the minimum time, in minutes, to run the fan each hour. Value from 1 to 60. + */ + @JsonProperty("fanMinOnTime") + public void setFanMinOnTime(Integer fanMinOnTime) { + this.fanMinOnTime = fanMinOnTime; + } + + /** + * @return the minimum temperature difference between the heat and cool values. Used to ensure that when + * thermostat is in auto mode, the heat and cool values are separated by at least this value. + */ + @JsonProperty("heatCoolMinDelta") + public Temperature getHeatCoolMinDelta() { + return this.heatCoolMinDelta; + } + + /** + * @param heatCoolMinDelta + * the minimum temperature difference between the heat and cool values. Used to ensure that when + * thermostat is in auto mode, the heat and cool values are separated by at least this value. + */ + @JsonProperty("heatCoolMinDelta") + public void setHeatCoolMinDelta(Temperature heatCoolMinDelta) { + this.heatCoolMinDelta = heatCoolMinDelta; + } + + /** + * @return the tempCorrection + */ + @JsonProperty("tempCorrection") + public Temperature getTempCorrection() { + return this.tempCorrection; + } + + /** + * @param tempCorrection + * the tempCorrection to set + */ + @JsonProperty("tempCorrection") + public void setTempCorrection(Temperature tempCorrection) { + this.tempCorrection = tempCorrection; + } + + /** + * @return the default end time setting the thermostat applies to user temperature holds. Values + * useEndTime4hour, useEndTime2hour (EMS Only), nextPeriod, indefinite, askMe + */ + @JsonProperty("holdAction") + public String getHoldAction() { + return this.holdAction; + } + + /** + * @param holdAction + * the default end time setting the thermostat applies to user temperature holds. Values + * useEndTime4hour, useEndTime2hour (EMS Only), nextPeriod, indefinite, askMe + */ + @JsonProperty("holdAction") + public void setHoldAction(String holdAction) { + this.holdAction = holdAction; + } + + /** + * @return the heatPumpGroundWater + */ + @JsonProperty("heatPumpGroundWater") + public Boolean getHeatPumpGroundWater() { + return this.heatPumpGroundWater; + } + + /** + * @return whether the thermostat is connected to an electric HVAC system + */ + @JsonProperty("hasElectric") + public Boolean getHasElectric() { + return this.hasElectric; + } + + /** + * @return whether the thermostat is connected to a dehumidifier + */ + @JsonProperty("hasDehumidifier") + public Boolean getHasDehumidifier() { + return this.hasDehumidifier; + } + + /** + * @return the dehumidifier mode. Values: on, off. + */ + @JsonProperty("dehumidifierMode") + public String getDehumidifierMode() { + return this.dehumidifierMode; + } + + /** + * @param dehumidifierMode + * the dehumidifier mode. Values: on, off. + */ + @JsonProperty("dehumidifierMode") + public void setDehumidifierMode(String dehumidifierMode) { + this.dehumidifierMode = dehumidifierMode; + } + + /** + * @return the dehumidification set point in percentage + */ + @JsonProperty("dehumidifierLevel") + public Integer getDehumidifierLevel() { + return this.dehumidifierLevel; + } + + /** + * @param dehumidifierLevel + * the dehumidification set point in percentage + */ + @JsonProperty("dehumidifierLevel") + public void setDehumidifierLevel(Integer dehumidifierLevel) { + this.dehumidifierLevel = dehumidifierLevel; + } + + /** + * @return whether the thermostat should use AC overcool to dehumidify. + */ + @JsonProperty("dehumidifyWithAC") + public Boolean getDehumidifyWithAC() { + return this.dehumidifyWithAC; + } + + /** + * @param dehumidifyWithAC + * whether the thermostat should use AC overcool to dehumidify. When set to true a positive integer + * value must be supplied for dehumidifyOvercoolOffset otherwise an API validation exception will be + * thrown. TODO implement constraint here (@watou). + */ + @JsonProperty("dehumidifyWithAC") + public void setDehumidifyWithAC(Boolean dehumidifyWithAC) { + this.dehumidifyWithAC = dehumidifyWithAC; + } + + /** + * @return whether the thermostat should use AC overcool to dehumidify and what that temperature offset should + * be. A value of 0 means this feature is disabled and dehumidifyWithAC will be set to false. Value + * represents the value in F to subtract from the current set point. + */ + @JsonProperty("dehumidifyOvercoolOffset") + public Integer getDehumidifyOvercoolOffset() { + return this.dehumidifyOvercoolOffset; + } + + /** + * @param dehumidifyOvercoolOffset + * whether the thermostat should use AC overcool to dehumidify and what that temperature offset + * should be. A value of 0 means this feature is disabled and dehumidifyWithAC will be set to false. + * Value represents the value in F to subtract from the current set point. Values should be in the + * range 0 - 50 and be divisible by 5. + */ + @JsonProperty("dehumidifyOvercoolOffset") + public void setDehumidifyOvercoolOffset(Integer dehumidifyOvercoolOffset) { + this.dehumidifyOvercoolOffset = dehumidifyOvercoolOffset; + } + + /** + * @return the autoHeatCoolFeatureEnabled + */ + @JsonProperty("autoHeatCoolFeatureEnabled") + public Boolean getAutoHeatCoolFeatureEnabled() { + return this.autoHeatCoolFeatureEnabled; + } + + /** + * @param autoHeatCoolFeatureEnabled + * the autoHeatCoolFeatureEnabled to set + */ + @JsonProperty("autoHeatCoolFeatureEnabled") + public void setAutoHeatCoolFeatureEnabled(Boolean autoHeatCoolFeatureEnabled) { + this.autoHeatCoolFeatureEnabled = autoHeatCoolFeatureEnabled; + } + + /** + * @return the wifiOfflineAlert + */ + @JsonProperty("wifiOfflineAlert") + public Boolean getWifiOfflineAlert() { + return this.wifiOfflineAlert; + } + + /** + * @param wifiOfflineAlert + * the wifiOfflineAlert to set + */ + @JsonProperty("wifiOfflineAlert") + public void setWifiOfflineAlert(Boolean wifiOfflineAlert) { + this.wifiOfflineAlert = wifiOfflineAlert; + } + + /** + * @return the minimum heat set point allowed by the thermostat firmware + */ + @JsonProperty("heatMinTemp") + public Temperature getHeatMinTemp() { + return this.heatMinTemp; + } + + /** + * @return the maximum heat set point allowed by the thermostat firmware + */ + @JsonProperty("heatMaxTemp") + public Temperature getHeatMaxTemp() { + return this.heatMaxTemp; + } + + /** + * @return the minimum cool set point allowed by the thermostat firmware + */ + @JsonProperty("coolMinTemp") + public Temperature getCoolMinTemp() { + return this.coolMinTemp; + } + + /** + * @return the maximum cool set point allowed by the thermostat firmware + */ + @JsonProperty("coolMaxTemp") + public Temperature getCoolMaxTemp() { + return this.coolMaxTemp; + } + + /** + * @return the maximum heat set point configured by the user's preferences + */ + @JsonProperty("heatRangeHigh") + public Temperature getHeatRangeHigh() { + return this.heatRangeHigh; + } + + /** + * @param heatRangeHigh + * the maximum heat set point configured by the user's preferences + */ + @JsonProperty("heatRangeHigh") + public void setHeatRangeHigh(Temperature heatRangeHigh) { + this.heatRangeHigh = heatRangeHigh; + } + + /** + * @return the minimum heat set point configured by the user's preferences + */ + @JsonProperty("heatRangeLow") + public Temperature getHeatRangeLow() { + return this.heatRangeLow; + } + + /** + * @param heatRangeLow + * the minimum heat set point configured by the user's preferences + */ + @JsonProperty("heatRangeLow") + public void setHeatRangeLow(Temperature heatRangeLow) { + this.heatRangeLow = heatRangeLow; + } + + /** + * @return the maximum cool set point configured by the user's preferences + */ + @JsonProperty("coolRangeHigh") + public Temperature getCoolRangeHigh() { + return this.coolRangeHigh; + } + + /** + * @param coolRangeHigh + * the maximum cool set point configured by the user's preferences + */ + @JsonProperty("coolRangeHigh") + public void setCoolRangeHigh(Temperature coolRangeHigh) { + this.coolRangeHigh = coolRangeHigh; + } + + /** + * @return the minimum heat set point configured by the user's preferences + */ + @JsonProperty("coolRangeLow") + public Temperature getCoolRangeLow() { + return this.coolRangeLow; + } + + /** + * @param coolRangeLow + * the minimum heat set point configured by the user's preferences + */ + @JsonProperty("coolRangeLow") + public void setCoolRangeLow(Temperature coolRangeLow) { + this.coolRangeLow = coolRangeLow; + } + + /** + * @return the userAccessCode + */ + @JsonProperty("userAccessCode") + public String getUserAccessCode() { + return this.userAccessCode; + } + + /** + * @param userAccessCode + * the userAccessCode to set + */ + @JsonProperty("userAccessCode") + public void setUserAccessCode(String userAccessCode) { + this.userAccessCode = userAccessCode; + } + + /** + * @return the userAccessSetting + */ + @JsonProperty("userAccessSetting") + public Integer getUserAccessSetting() { + return this.userAccessSetting; + } + + /** + * @param userAccessSetting + * the userAccessSetting to set + */ + @JsonProperty("userAccessSetting") + public void setUserAccessSetting(Integer userAccessSetting) { + this.userAccessSetting = userAccessSetting; + } + + /** + * @return the auxRuntimeAlert + */ + @JsonProperty("auxRuntimeAlert") + public Temperature getAuxRuntimeAlert() { + return this.auxRuntimeAlert; + } + + /** + * @param auxRuntimeAlert + * the auxRuntimeAlert to set + */ + @JsonProperty("auxRuntimeAlert") + public void setAuxRuntimeAlert(Temperature auxRuntimeAlert) { + this.auxRuntimeAlert = auxRuntimeAlert; + } + + /** + * @return the auxOutdoorTempAlert + */ + @JsonProperty("auxOutdoorTempAlert") + public Temperature getAuxOutdoorTempAlert() { + return this.auxOutdoorTempAlert; + } + + /** + * @param auxOutdoorTempAlert + * the auxOutdoorTempAlert to set + */ + @JsonProperty("auxOutdoorTempAlert") + public void setAuxOutdoorTempAlert(Temperature auxOutdoorTempAlert) { + this.auxOutdoorTempAlert = auxOutdoorTempAlert; + } + + /** + * @return the auxMaxOutdoorTemp + */ + @JsonProperty("auxMaxOutdoorTemp") + public Temperature getAuxMaxOutdoorTemp() { + return this.auxMaxOutdoorTemp; + } + + /** + * @param auxMaxOutdoorTemp + * the auxMaxOutdoorTemp to set + */ + @JsonProperty("auxMaxOutdoorTemp") + public void setAuxMaxOutdoorTemp(Temperature auxMaxOutdoorTemp) { + this.auxMaxOutdoorTemp = auxMaxOutdoorTemp; + } + + /** + * @return the auxRuntimeAlertNotify + */ + @JsonProperty("auxRuntimeAlertNotify") + public Boolean getAuxRuntimeAlertNotify() { + return this.auxRuntimeAlertNotify; + } + + /** + * @param auxRuntimeAlertNotify + * the auxRuntimeAlertNotify to set + */ + @JsonProperty("auxRuntimeAlertNotify") + public void setAuxRuntimeAlertNotify(Boolean auxRuntimeAlertNotify) { + this.auxRuntimeAlertNotify = auxRuntimeAlertNotify; + } + + /** + * @return the auxOutdoorTempAlertNotify + */ + @JsonProperty("auxOutdoorTempAlertNotify") + public Boolean getAuxOutdoorTempAlertNotify() { + return this.auxOutdoorTempAlertNotify; + } + + /** + * @param auxOutdoorTempAlertNotify + * the auxOutdoorTempAlertNotify to set + */ + @JsonProperty("auxOutdoorTempAlertNotify") + public void setAuxOutdoorTempAlertNotify(Boolean auxOutdoorTempAlertNotify) { + this.auxOutdoorTempAlertNotify = auxOutdoorTempAlertNotify; + } + + /** + * @return the auxRuntimeAlertNotifyTechnician + */ + @JsonProperty("auxRuntimeAlertNotifyTechnician") + public Boolean getAuxRuntimeAlertNotifyTechnician() { + return this.auxRuntimeAlertNotifyTechnician; + } + + /** + * @param auxRuntimeAlertNotifyTechnician + * the auxRuntimeAlertNotifyTechnician to set + */ + @JsonProperty("auxRuntimeAlertNotifyTechnician") + public void setAuxRuntimeAlertNotifyTechnician(Boolean auxRuntimeAlertNotifyTechnician) { + this.auxRuntimeAlertNotifyTechnician = auxRuntimeAlertNotifyTechnician; + } + + /** + * @return the auxOutdoorTempAlertNotifyTechnician + */ + @JsonProperty("auxOutdoorTempAlertNotifyTechnician") + public Boolean getAuxOutdoorTempAlertNotifyTechnician() { + return this.auxOutdoorTempAlertNotifyTechnician; + } + + /** + * @param auxOutdoorTempAlertNotifyTechnician + * the auxOutdoorTempAlertNotifyTechnician to set + */ + @JsonProperty("auxOutdoorTempAlertNotifyTechnician") + public void setAuxOutdoorTempAlertNotifyTechnician(Boolean auxOutdoorTempAlertNotifyTechnician) { + this.auxOutdoorTempAlertNotifyTechnician = auxOutdoorTempAlertNotifyTechnician; + } + + /** + * @return whether the thermostat should use pre heating to reach the set point on time + */ + @JsonProperty("disablePreHeating") + public Boolean getDisablePreHeating() { + return this.disablePreHeating; + } + + /** + * @param disablePreHeating + * whether the thermostat should use pre heating to reach the set point on time + */ + @JsonProperty("disablePreHeating") + public void setDisablePreHeating(Boolean disablePreHeating) { + this.disablePreHeating = disablePreHeating; + } + + /** + * @return whether the thermostat should use pre cooling to reach the set point on time + */ + @JsonProperty("disablePreCooling") + public Boolean getDisablePreCooling() { + return this.disablePreCooling; + } + + /** + * @param disablePreCooling + * whether the thermostat should use pre cooling to reach the set point on time + */ + @JsonProperty("disablePreCooling") + public void setDisablePreCooling(Boolean disablePreCooling) { + this.disablePreCooling = disablePreCooling; + } + + /** + * @return whether an installer code is required + */ + @JsonProperty("installerCodeRequired") + public Boolean getInstallerCodeRequired() { + return this.installerCodeRequired; + } + + /** + * @param installerCodeRequired + * whether an installer code is required + */ + @JsonProperty("installerCodeRequired") + public void setInstallerCodeRequired(Boolean installerCodeRequired) { + this.installerCodeRequired = installerCodeRequired; + } + + /** + * @return whether Demand Response requests are accepted by this thermostat. Possible values are: always, askMe, + * customerSelect, defaultAccept, defaultDecline, never. + */ + @JsonProperty("drAccept") + public String getDrAccept() { + return this.drAccept; + } + + /** + * @param drAccept + * whether Demand Response requests are accepted by this thermostat. Possible values are: always, + * askMe, customerSelect, defaultAccept, defaultDecline, never. + */ + @JsonProperty("drAccept") + public void setDrAccept(String drAccept) { + this.drAccept = drAccept; + } + + /** + * @return whether the property is a rental or not + */ + @JsonProperty("isRentalProperty") + public Boolean getIsRentalProperty() { + return this.isRentalProperty; + } + + /** + * @param isRentalProperty + * whether the property is a rental or not + */ + @JsonProperty("isRentalProperty") + public void setIsRentalProperty(Boolean isRentalProperty) { + this.isRentalProperty = isRentalProperty; + } + + /** + * @return whether to use a zone controller or not + */ + @JsonProperty("useZoneController") + public Boolean getUseZoneController() { + return this.useZoneController; + } + + /** + * @param useZoneController + * whether to use a zone controller or not + */ + @JsonProperty("useZoneController") + public void setUseZoneController(Boolean useZoneController) { + this.useZoneController = useZoneController; + } + + /** + * @return whether random start delay is enabled for cooling + */ + @JsonProperty("randomStartDelayCool") + public Integer getRandomStartDelayCool() { + return this.randomStartDelayCool; + } + + /** + * @param randomStartDelayCool + * whether random start delay is enabled for cooling + */ + @JsonProperty("randomStartDelayCool") + public void setRandomStartDelayCool(Integer randomStartDelayCool) { + this.randomStartDelayCool = randomStartDelayCool; + } + + /** + * @return whether random start delay is enabled for heating + */ + @JsonProperty("randomStartDelayHeat") + public Integer getRandomStartDelayHeat() { + return this.randomStartDelayHeat; + } + + /** + * @param randomStartDelayHeat + * whether random start delay is enabled for heating + */ + @JsonProperty("randomStartDelayHeat") + public void setRandomStartDelayHeat(Integer randomStartDelayHeat) { + this.randomStartDelayHeat = randomStartDelayHeat; + } + + /** + * @return the humidity level to trigger a high humidity alert + */ + @JsonProperty("humidityHighAlert") + public Integer getHumidityHighAlert() { + return this.humidityHighAlert; + } + + /** + * @param humidityHighAlert + * the humidity level to trigger a high humidity alert + */ + @JsonProperty("humidityHighAlert") + public void setHumidityHighAlert(Integer humidityHighAlert) { + this.humidityHighAlert = humidityHighAlert; + } + + /** + * @return the humidity level to trigger a low humidity alert + */ + @JsonProperty("humidityLowAlert") + public Integer getHumidityLowAlert() { + return this.humidityLowAlert; + } + + /** + * @param humidityLowAlert + * the humidity level to trigger a low humidity alert + */ + @JsonProperty("humidityLowAlert") + public void setHumidityLowAlert(Integer humidityLowAlert) { + this.humidityLowAlert = humidityLowAlert; + } + + /** + * @return whether heat pump alerts are disabled + */ + @JsonProperty("disableHeatPumpAlerts") + public Boolean getDisableHeatPumpAlerts() { + return this.disableHeatPumpAlerts; + } + + /** + * @param disableHeatPumpAlerts + * whether heat pump alerts are disabled + */ + @JsonProperty("disableHeatPumpAlerts") + public void setDisableHeatPumpAlerts(Boolean disableHeatPumpAlerts) { + this.disableHeatPumpAlerts = disableHeatPumpAlerts; + } + + /** + * @return whether alerts are disabled from showing on the thermostat + */ + @JsonProperty("disableAlertsOnIdt") + public Boolean getDisableAlertsOnIdt() { + return this.disableAlertsOnIdt; + } + + /** + * @param disableAlertsOnIdt + * whether alerts are disabled from showing on the thermostat + */ + @JsonProperty("disableAlertsOnIdt") + public void setDisableAlertsOnIdt(Boolean disableAlertsOnIdt) { + this.disableAlertsOnIdt = disableAlertsOnIdt; + } + + /** + * @return whether humidification alerts are enabled to the thermostat owner + */ + @JsonProperty("humidityAlertNotify") + public Boolean getHumidityAlertNotify() { + return this.humidityAlertNotify; + } + + /** + * @param humidityAlertNotify + * whether humidification alerts are enabled to the thermostat owner + */ + @JsonProperty("humidityAlertNotify") + public void setHumidityAlertNotify(Boolean humidityAlertNotify) { + this.humidityAlertNotify = humidityAlertNotify; + } + + /** + * @return whether humidification alerts are enabled to the technician associated with the thermostat + */ + @JsonProperty("humidityAlertNotifyTechnician") + public Boolean getHumidityAlertNotifyTechnician() { + return this.humidityAlertNotifyTechnician; + } + + /** + * @param humidityAlertNotifyTechnician + * whether humidification alerts are enabled to the technician associated with the thermostat + */ + @JsonProperty("humidityAlertNotifyTechnician") + public void setHumidityAlertNotifyTechnician(Boolean humidityAlertNotifyTechnician) { + this.humidityAlertNotifyTechnician = humidityAlertNotifyTechnician; + } + + /** + * @return whether temperature alerts are enabled to the thermostat owner + */ + @JsonProperty("tempAlertNotify") + public Boolean getTempAlertNotify() { + return this.tempAlertNotify; + } + + /** + * @param tempAlertNotify + * whether temperature alerts are enabled to the thermostat owner + */ + @JsonProperty("tempAlertNotify") + public void setTempAlertNotify(Boolean tempAlertNotify) { + this.tempAlertNotify = tempAlertNotify; + } + + /** + * @return hether temperature alerts are enabled to the technician associated with the thermostat + */ + @JsonProperty("tempAlertNotifyTechnician") + public Boolean getTempAlertNotifyTechnician() { + return this.tempAlertNotifyTechnician; + } + + /** + * @param tempAlertNotifyTechnician + * hether temperature alerts are enabled to the technician associated with the thermostat + */ + @JsonProperty("tempAlertNotifyTechnician") + public void setTempAlertNotifyTechnician(Boolean tempAlertNotifyTechnician) { + this.tempAlertNotifyTechnician = tempAlertNotifyTechnician; + } + + /** + * @return the dollar amount the owner specifies for their desired maximum electricity bill + */ + @JsonProperty("monthlyElectricityBillLimit") + public Integer getMonthlyElectricityBillLimit() { + return this.monthlyElectricityBillLimit; + } + + /** + * @param monthlyElectricityBillLimit + * the dollar amount the owner specifies for their desired maximum electricity bill + */ + @JsonProperty("monthlyElectricityBillLimit") + public void setMonthlyElectricityBillLimit(Integer monthlyElectricityBillLimit) { + this.monthlyElectricityBillLimit = monthlyElectricityBillLimit; + } + + /** + * @return whether electricity bill alerts are enabled + */ + @JsonProperty("enableElectricityBillAlert") + public Boolean getEnableElectricityBillAlert() { + return this.enableElectricityBillAlert; + } + + /** + * @param enableElectricityBillAlert + * whether electricity bill alerts are enabled + */ + @JsonProperty("enableElectricityBillAlert") + public void setEnableElectricityBillAlert(Boolean enableElectricityBillAlert) { + this.enableElectricityBillAlert = enableElectricityBillAlert; + } + + /** + * @return whether electricity bill projection alerts are enabled + */ + @JsonProperty("enableProjectedElectricityBillAlert") + public Boolean getEnableProjectedElectricityBillAlert() { + return this.enableProjectedElectricityBillAlert; + } + + /** + * @param enableProjectedElectricityBillAlert + * whether electricity bill projection alerts are enabled + */ + @JsonProperty("enableProjectedElectricityBillAlert") + public void setEnableProjectedElectricityBillAlert(Boolean enableProjectedElectricityBillAlert) { + this.enableProjectedElectricityBillAlert = enableProjectedElectricityBillAlert; + } + + /** + * @return the electricityBillingDayOfMonth + */ + @JsonProperty("electricityBillingDayOfMonth") + public Integer getElectricityBillingDayOfMonth() { + return this.electricityBillingDayOfMonth; + } + + /** + * @param electricityBillingDayOfMonth + * the electricityBillingDayOfMonth to set + */ + @JsonProperty("electricityBillingDayOfMonth") + public void setElectricityBillingDayOfMonth(Integer electricityBillingDayOfMonth) { + this.electricityBillingDayOfMonth = electricityBillingDayOfMonth; + } + + /** + * @return the owner's billing cycle duration in months + */ + @JsonProperty("electricityBillCycleMonths") + public Integer getElectricityBillCycleMonths() { + return this.electricityBillCycleMonths; + } + + /** + * @param electricityBillCycleMonths + * the owner's billing cycle duration in months + */ + @JsonProperty("electricityBillCycleMonths") + public void setElectricityBillCycleMonths(Integer electricityBillCycleMonths) { + this.electricityBillCycleMonths = electricityBillCycleMonths; + } + + /** + * @return the annual start month of the owner's billing cycle + */ + @JsonProperty("electricityBillStartMonth") + public Integer getElectricityBillStartMonth() { + return this.electricityBillStartMonth; + } + + /** + * @param electricityBillStartMonth + * the annual start month of the owner's billing cycle + */ + @JsonProperty("electricityBillStartMonth") + public void setElectricityBillStartMonth(Integer electricityBillStartMonth) { + this.electricityBillStartMonth = electricityBillStartMonth; + } + + /** + * @return the number of minutes to run ventilator per hour when home + */ + @JsonProperty("ventilatorMinOnTimeHome") + public Integer getVentilatorMinOnTimeHome() { + return this.ventilatorMinOnTimeHome; + } + + /** + * @param ventilatorMinOnTimeHome + * the number of minutes to run ventilator per hour when home + */ + @JsonProperty("ventilatorMinOnTimeHome") + public void setVentilatorMinOnTimeHome(Integer ventilatorMinOnTimeHome) { + this.ventilatorMinOnTimeHome = ventilatorMinOnTimeHome; + } + + /** + * @return the number of minutes to run ventilator per hour when away + */ + @JsonProperty("ventilatorMinOnTimeAway") + public Integer getVentilatorMinOnTimeAway() { + return this.ventilatorMinOnTimeAway; + } + + /** + * @param ventilatorMinOnTimeAway + * the number of minutes to run ventilator per hour when away + */ + @JsonProperty("ventilatorMinOnTimeAway") + public void setVentilatorMinOnTimeAway(Integer ventilatorMinOnTimeAway) { + this.ventilatorMinOnTimeAway = ventilatorMinOnTimeAway; + } + + /** + * @return whether or not to turn the backlight off during sleep + */ + @JsonProperty("backlightOffDuringSleep") + public Boolean getBacklightOffDuringSleep() { + return this.backlightOffDuringSleep; + } + + /** + * @param backlightOffDuringSleep + * whether or not to turn the backlight off during sleep + */ + @JsonProperty("backlightOffDuringSleep") + public void setBacklightOffDuringSleep(Boolean backlightOffDuringSleep) { + this.backlightOffDuringSleep = backlightOffDuringSleep; + } + + /** + * @return when set to true if no occupancy motion detected thermostat will go into indefinite away hold, until + * either the user presses resume schedule or motion is detected. + */ + @JsonProperty("autoAway") + public Boolean getAutoAway() { + return this.autoAway; + } + + /** + * @return when set to true if a larger than normal delta is found between sensors the fan will be engaged for + * 15min/hour. + */ + @JsonProperty("smartCirculation") + public Boolean getSmartCirculation() { + return this.smartCirculation; + } + + /** + * @param smartCirculation + * when set to true if a larger than normal delta is found between sensors the fan will be engaged + * for 15min/hour. + */ + @JsonProperty("smartCirculation") + public void setSmartCirculation(Boolean smartCirculation) { + this.smartCirculation = smartCirculation; + } + + /** + * @return true if a sensor has detected presence for more than 10 minutes then include that sensor in temp + * average. If no activity has been seen on a sensor for more than 1 hour then remove this sensor from + * temperature average. + */ + @JsonProperty("followMeComfort") + public Boolean getFollowMeComfort() { + return this.followMeComfort; + } + + /** + * @param followMeComfort + * set to true if a sensor has detected presence for more than 10 minutes then include that sensor in + * temp average. If no activity has been seen on a sensor for more than 1 hour then remove this + * sensor from temperature average. + */ + @JsonProperty("followMeComfort") + public void setFollowMeComfort(Boolean followMeComfort) { + this.followMeComfort = followMeComfort; + } + + /** + * @return the type of ventilator present for the Thermostat. The possible values are none, ventilator, hrv, and + * erv. + */ + @JsonProperty("ventilatorType") + public String getVentilatorType() { + return this.ventilatorType; + } + + /** + * @return whether the ventilator timer is on or off. The default value is false. If set to true the + * ventilatorOffDateTime is set to now() + 20 minutes. If set to false the ventilatorOffDateTime is set + * to its default value. + */ + @JsonProperty("isVentilatorTimerOn") + public Boolean getIsVentilatorTimerOn() { + return this.isVentilatorTimerOn; + } + + /** + * @param isVentilatorTimerOn + * whether the ventilator timer is on or off. The default value is false. If set to true the + * ventilatorOffDateTime is set to now() + 20 minutes. If set to false the ventilatorOffDateTime is + * set to its default value. + */ + @JsonProperty("isVentilatorTimerOn") + public void setIsVentilatorTimerOn(Boolean isVentilatorTimerOn) { + this.isVentilatorTimerOn = isVentilatorTimerOn; + } + + /** + * @return the date and time the ventilator will run until. The default value is 2014-01-01 00:00:00. + */ + @JsonProperty("ventilatorOffDateTime") + public Date getVentilatorOffDateTime() { + return this.ventilatorOffDateTime; + } + + /** + * @return whether the HVAC system has a UV filter. The default value is true. + */ + @JsonProperty("hasUVFilter") + public Boolean getHasUVFilter() { + return this.hasUVFilter; + } + + /** + * @param hasUVFilter + * whether the HVAC system has a UV filter. The default value is true. + */ + @JsonProperty("hasUVFilter") + public void setHasUVFilter(Boolean hasUVFilter) { + this.hasUVFilter = hasUVFilter; + } + + /** + * @return whether to permit the cooling to operate when the outdoor temperature is under a specific threshold, + * currently 55F. The default value is false. + */ + @JsonProperty("coolingLockout") + public Boolean getCoolingLockout() { + return this.coolingLockout; + } + + /** + * @param coolingLockout + * whether to permit the cooling to operate when the outdoor temperature is under a specific + * threshold, currently 55F. The default value is false. + */ + @JsonProperty("coolingLockout") + public void setCoolingLockout(Boolean coolingLockout) { + this.coolingLockout = coolingLockout; + } + + /** + * @return the ventilatorFreeCooling + */ + @JsonProperty("ventilatorFreeCooling") + public Boolean getVentilatorFreeCooling() { + return this.ventilatorFreeCooling; + } + + /** + * @param ventilatorFreeCooling + * the ventilatorFreeCooling to set + */ + @JsonProperty("ventilatorFreeCooling") + public void setVentilatorFreeCooling(Boolean ventilatorFreeCooling) { + this.ventilatorFreeCooling = ventilatorFreeCooling; + } + + /** + * @return whether to permit dehumidifier to operate when the heating is running. The default value is false. + */ + @JsonProperty("dehumidifyWhenHeating") + public Boolean getDehumidifyWhenHeating() { + return this.dehumidifyWhenHeating; + } + + /** + * @param dehumidifyWhenHeating + * whether to permit dehumidifier to operate when the heating is running. The default value is false. + */ + @JsonProperty("dehumidifyWhenHeating") + public void setDehumidifyWhenHeating(Boolean dehumidifyWhenHeating) { + this.dehumidifyWhenHeating = dehumidifyWhenHeating; + } + + /** + * @return the unique reference to the group this thermostat belongs to, if any. See GET Group request and POST + * Group request for more information. + */ + @JsonProperty("groupRef") + public String getGroupRef() { + return this.groupRef; + } + + /** + * @param groupRef + * the unique reference to the group this thermostat belongs to, if any. See GET Group request and + * POST Group request for more information. + */ + @JsonProperty("groupRef") + public void setGroupRef(String groupRef) { + this.groupRef = groupRef; + } + + /** + * @return the name of the the group this thermostat belongs to, if any. See GET Group request and POST Group + * request for more information. + */ + @JsonProperty("groupName") + public String getGroupName() { + return this.groupName; + } + + /** + * @param groupName + * the name of the the group this thermostat belongs to, if any. See GET Group request and POST Group + * request for more information. + */ + @JsonProperty("groupName") + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + /** + * @return the setting value for the group this thermostat belongs to, if any. See GET Group request and POST + * Group request for more information. + */ + @JsonProperty("groupSetting") + public Integer getGroupSetting() { + return this.groupSetting; + } + + /** + * @param groupSetting + * the setting value for the group this thermostat belongs to, if any. See GET Group request and POST + * Group request for more information. + */ + @JsonProperty("groupSetting") + public void setGroupSetting(Integer groupSetting) { + this.groupSetting = groupSetting; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("hvacMode", this.hvacMode); + builder.append("lastServiceDate", this.lastServiceDate); + builder.append("serviceRemindMe", this.serviceRemindMe); + builder.append("monthsBetweenService", this.monthsBetweenService); + builder.append("remindMeDate", this.remindMeDate); + builder.append("vent", this.vent); + builder.append("ventilatorMinOnTime", this.ventilatorMinOnTime); + builder.append("serviceRemindTechnician", this.serviceRemindTechnician); + builder.append("eiLocation", this.eiLocation); + builder.append("coldTempAlert", this.coldTempAlert); + builder.append("coldTempAlertEnabled", this.coldTempAlertEnabled); + builder.append("hotTempAlert", this.hotTempAlert); + builder.append("hotTempAlertEnabled", this.hotTempAlertEnabled); + builder.append("coolStages", this.coolStages); + builder.append("heatStages", this.heatStages); + builder.append("maxSetBack", this.maxSetBack); + builder.append("maxSetForward", this.maxSetForward); + builder.append("quickSaveSetBack", this.quickSaveSetBack); + builder.append("quickSaveSetForward", this.quickSaveSetForward); + builder.append("hasHeatPump", this.hasHeatPump); + builder.append("hasForcedAir", this.hasForcedAir); + builder.append("hasBoiler", this.hasBoiler); + builder.append("hasHumidifier", this.hasHumidifier); + builder.append("hasErv", this.hasErv); + builder.append("hasHrv", this.hasHrv); + builder.append("condensationAvoid", this.condensationAvoid); + builder.append("useCelsius", this.useCelsius); + builder.append("useTimeFormat12", this.useTimeFormat12); + builder.append("locale", this.locale); + builder.append("humidity", this.humidity); + builder.append("humidifierMode", this.humidifierMode); + builder.append("backlightOnIntensity", this.backlightOnIntensity); + builder.append("backlightSleepIntensity", this.backlightSleepIntensity); + builder.append("backlightOffTime", this.backlightOffTime); + builder.append("soundTickVolume", this.soundTickVolume); + builder.append("soundAlertVolume", this.soundAlertVolume); + builder.append("compressorProtectionMinTime", this.compressorProtectionMinTime); + builder.append("compressorProtectionMinTemp", this.compressorProtectionMinTemp); + builder.append("stage1HeatingDifferentialTemp", this.stage1HeatingDifferentialTemp); + builder.append("stage1CoolingDifferentialTemp", this.stage1CoolingDifferentialTemp); + builder.append("stage1HeatingDissipationTime", this.stage1HeatingDissipationTime); + builder.append("stage1CoolingDissipationTime", this.stage1CoolingDissipationTime); + builder.append("heatPumpReversalOnCool", this.heatPumpReversalOnCool); + builder.append("fanControlRequired", this.fanControlRequired); + builder.append("fanMinOnTime", this.fanMinOnTime); + builder.append("heatCoolMinDelta", this.heatCoolMinDelta); + builder.append("tempCorrection", this.tempCorrection); + builder.append("holdAction", this.holdAction); + builder.append("heatPumpGroundWater", this.heatPumpGroundWater); + builder.append("hasElectric", this.hasElectric); + builder.append("hasDehumidifier", this.hasDehumidifier); + builder.append("humidifierMode", this.humidifierMode); + builder.append("dehumidifierLevel", this.dehumidifierLevel); + builder.append("dehumidifyWithAC", this.dehumidifyWithAC); + builder.append("dehumidifyOvercoolOffset", this.dehumidifyOvercoolOffset); + builder.append("autoHeatCoolFeatureEnabled", this.autoHeatCoolFeatureEnabled); + builder.append("wifiOfflineAlert", this.wifiOfflineAlert); + builder.append("heatMinTemp", this.heatMinTemp); + builder.append("heatMaxTemp", this.heatMaxTemp); + builder.append("coolMinTemp", this.coolMinTemp); + builder.append("coolMaxTemp", this.coolMaxTemp); + builder.append("heatRangeHigh", this.heatRangeHigh); + builder.append("heatRangeLow", this.heatRangeLow); + builder.append("coolRangeHigh", this.coolRangeHigh); + builder.append("coolRangeLow", this.coolRangeLow); + builder.append("userAccessCode", this.userAccessCode); + builder.append("userAccessSetting", this.userAccessSetting); + builder.append("auxRuntimeAlert", this.auxRuntimeAlert); + builder.append("auxOutdoorTempAlert", this.auxOutdoorTempAlert); + builder.append("auxMaxOutdoorTemp", this.auxMaxOutdoorTemp); + builder.append("auxRuntimeAlertNotify", this.auxRuntimeAlertNotify); + builder.append("auxOutdoorTempAlertNotify", this.auxOutdoorTempAlertNotify); + builder.append("auxRuntimeAlertNotifyTechnician", this.auxRuntimeAlertNotifyTechnician); + builder.append("auxOutdoorTempAlertNotifyTechnician", this.auxOutdoorTempAlertNotifyTechnician); + builder.append("disablePreHeating", this.disablePreHeating); + builder.append("disablePreCooling", this.disablePreCooling); + builder.append("installerCodeRequired", this.installerCodeRequired); + builder.append("drAccept", this.drAccept); + builder.append("isRentalProperty", this.isRentalProperty); + builder.append("useZoneController", this.useZoneController); + builder.append("randomStartDelayCool", this.randomStartDelayCool); + builder.append("randomStartDelayHeat", this.randomStartDelayHeat); + builder.append("humidityHighAlert", this.humidityHighAlert); + builder.append("humidityLowAlert", this.humidityLowAlert); + builder.append("disableHeatPumpAlerts", this.disableHeatPumpAlerts); + builder.append("disableAlertsOnIdt", this.disableAlertsOnIdt); + builder.append("humidityAlertNotify", this.humidityAlertNotify); + builder.append("humidityAlertNotifyTechnician", this.humidityAlertNotifyTechnician); + builder.append("tempAlertNotify", this.tempAlertNotify); + builder.append("tempAlertNotifyTechnician", this.tempAlertNotifyTechnician); + builder.append("monthlyElectricityBillLimit", this.monthlyElectricityBillLimit); + builder.append("enableElectricityBillAlert", this.enableElectricityBillAlert); + builder.append("enableProjectedElectricityBillAlert", this.enableProjectedElectricityBillAlert); + builder.append("electricityBillingDayOfMonth", this.electricityBillingDayOfMonth); + builder.append("electricityBillCycleMonths", this.electricityBillCycleMonths); + builder.append("electricityBillStartMonth", this.electricityBillStartMonth); + builder.append("ventilatorMinOnTimeHome", this.ventilatorMinOnTimeHome); + builder.append("ventilatorMinOnTimeAway", this.ventilatorMinOnTimeAway); + builder.append("backlightOffDuringSleep", this.backlightOffDuringSleep); + builder.append("autoAway", this.autoAway); + builder.append("smartCirculation", this.smartCirculation); + builder.append("followMeComfort", this.followMeComfort); + builder.append("ventilatorType", this.ventilatorType); + builder.append("isVentilatorTimerOn", this.isVentilatorTimerOn); + builder.append("ventilatorOffDateTime", this.ventilatorOffDateTime); + builder.append("hasUVFilter", this.hasUVFilter); + builder.append("coolingLockout", this.coolingLockout); + builder.append("ventilatorFreeCooling", this.ventilatorFreeCooling); + builder.append("dehumidifyWhenHeating", this.dehumidifyWhenHeating); + builder.append("groupRef", this.groupRef); + builder.append("groupName", this.groupName); + builder.append("groupSetting", this.groupSetting); + + return builder.toString(); + } + } + + /** + * Possible values for hvacMode + */ + public static enum HvacMode { + AUTO("auto"), AUX_HEAT_ONLY("auxHeatOnly"), COOL("cool"), HEAT("heat"), OFF("off"); + + private final String mode; + + private HvacMode(String mode) { + this.mode = mode; + } + + @JsonValue + public String value() { + return mode; + } + + @JsonCreator + public static HvacMode forValue(String v) { + for (HvacMode hm : HvacMode.values()) { + if (hm.mode.equals(v)) { + return hm; + } + } + throw new IllegalArgumentException("Invalid hvacMode: " + v); + } + + @Override + public String toString() { + return this.mode; + } + } + + /** + * Possible values for vent + */ + public static enum VentilatorMode { + AUTO("auto"), MIN_ON_TIME("minontime"), ON("on"), OFF("off"); + + private final String mode; + + private VentilatorMode(String mode) { + this.mode = mode; + } + + @JsonValue + public String value() { + return mode; + } + + @JsonCreator + public static VentilatorMode forValue(String v) { + for (VentilatorMode vm : VentilatorMode.values()) { + if (vm.mode.equals(v)) { + return vm; + } + } + throw new IllegalArgumentException("Invalid vent: " + v); + } + + @Override + public String toString() { + return this.mode; + } + } + + /** + * The Runtime Java Bean represents the last known thermostat running state. This state is composed from the last + * interval status message received from a thermostat. It is also updated each time the thermostat posts + * configuration changes to the server. + * + *

      + * The runtime object contains the last 5 minute interval value sent by the thermostat for the past 15 minutes of + * runtime. The thermostat updates the server every 15 minutes with the last three 5 minute readings. + * + *

      + * The actual temperature and humidity will also be updated when the equipment state changes by the thermostat, this + * may occur at a frequency of 3 minutes, however it is only transmitted when there is an equipment state change on + * the thermostat. + * + *

      + * See Thermostat Interval Report Data for additional information about the interval readings. + * + *

      + * The Runtime class is read-only. + * + * @see Runtime + * @see Thermostat + * Interval Report Data + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Runtime extends AbstractMessagePart { + private String runtimeRev; + private Boolean connected; + private Date firstConnected; + private Date connectDateTime; + private String disconnectDateTime; // TODO: Jackson 1.9 can't handle + // date only (no time) (@watou) + private Date lastModified; + private Date lastStatusModified; + private String runtimeDate; // TODO: Jackson 1.9 can't handle date only + // (no time) (@watou) + private Integer runtimeInterval; + private Temperature actualTemperature; + private Integer actualHumidity; + private Temperature desiredHeat; + private Temperature desiredCool; + private Integer desiredHumidity; + private Integer desiredDehumidity; + private String desiredFanMode; + + /** + * @return the current runtime revision. Equivalent in meaning to the runtime revision number in the thermostat + * summary call. + */ + @JsonProperty("runtimeRev") + public String getRuntimeRev() { + return this.runtimeRev; + } + + /** + * @return whether the thermostat is currently connected to the server + */ + @JsonProperty("connected") + public Boolean getConnected() { + return this.connected; + } + + /** + * @return the UTC date/time stamp of when the thermostat first connected to the ecobee server + */ + @JsonProperty("firstConnected") + public Date getFirstConnected() { + return this.firstConnected; + } + + /** + * @return the last recorded connection date and time + */ + @JsonProperty("connectDateTime") + public Date getConnectDateTime() { + return this.connectDateTime; + } + + /** + * @return the last recorded disconnection date and time + */ + @JsonProperty("disconnectDateTime") + public String getDisconnectDateTime() { + return this.disconnectDateTime; + } + + /** + * @return the UTC date/time stamp of when the thermostat was updated. Format: YYYY-MM-DD HH:MM:SS + */ + @JsonProperty("lastModified") + public Date getLastModified() { + return this.lastModified; + } + + /** + * @return the UTC date/time stamp of when the thermostat last posted its runtime information. Format: + * YYYY-MM-DD HH:MM:SS + */ + @JsonProperty("lastStatusModified") + public Date getLastStatusModified() { + return this.lastStatusModified; + } + + /** + * @return the UTC date of the last runtime reading. Format: YYYY-MM-DD + */ + @JsonProperty("runtimeDate") + public String getRuntimeDate() { + return this.runtimeDate; + } + + /** + * @return the last 5 minute interval which was updated by the thermostat telemetry update. Subtract 2 from this + * interval to obtain the beginning interval for the last 3 readings. Multiply by 5 mins to obtain the + * minutes of the day. Range: 0-287 + */ + @JsonProperty("runtimeInterval") + public Integer getRuntimeInterval() { + return this.runtimeInterval; + } + + /** + * @return the current temperature displayed on the thermostat + */ + @JsonProperty("actualTemperature") + public Temperature getActualTemperature() { + return this.actualTemperature; + } + + /** + * @return the current humidity % shown on the thermostat + */ + @JsonProperty("actualHumidity") + public Integer getActualHumidity() { + return this.actualHumidity; + } + + /** + * @return the desired heat temperature as per the current running program or active event + */ + @JsonProperty("desiredHeat") + public Temperature getDesiredHeat() { + return this.desiredHeat; + } + + /** + * @return the desired cool temperature as per the current running program or active event. + */ + @JsonProperty("desiredCool") + public Temperature getDesiredCool() { + return this.desiredCool; + } + + /** + * @return the desired humidity set point + */ + @JsonProperty("desiredHumidity") + public Integer getDesiredHumidity() { + return this.desiredHumidity; + } + + /** + * @return the desired dehumidification set point + */ + @JsonProperty("desiredDehumidity") + public Integer getDesiredDehumidity() { + return this.desiredDehumidity; + } + + /** + * @return the desired fan mode. Values: auto, on or null if the HVAC system is off. TODO handle null as valid + * value (@watou). + */ + @JsonProperty("desiredFanMode") + public String getDesiredFanMode() { + return this.desiredFanMode; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("runtimeRev", this.runtimeRev); + builder.append("connected", this.connected); + builder.append("firstConnected", this.firstConnected); + builder.append("connectDateTime", this.connectDateTime); + builder.append("disconnectDateTime", this.disconnectDateTime); + builder.append("lastModified", this.lastModified); + builder.append("lastStatusModified", this.lastStatusModified); + builder.append("runtimeDate", this.runtimeDate); + builder.append("runtimeInterval", this.runtimeInterval); + builder.append("actualTemperature", this.actualTemperature); + builder.append("actualHumidity", this.actualHumidity); + builder.append("desiredHeat", this.desiredHeat); + builder.append("desiredCool", this.desiredCool); + builder.append("desiredHumidity", this.desiredHumidity); + builder.append("desiredDehumidity", this.desiredDehumidity); + builder.append("desiredFanMode", this.desiredFanMode); + + return builder.toString(); + } + } + + /** + * The ExtendedRuntime Java Bean contains the last three 5 minute interval values sent by the thermostat for the + * past 15 minutes of runtime. The interval values are valuable when you are interested in analyzing the runtime + * data in a more granular fashion, at 5 minute increments rather than the more general 15 minute value from the + * Runtime Object. + * + *

      + * For the runtime values (i.e. heatPump, auxHeat, cool, etc.) refer to the {@link Thermostat#settings} values ( + * {@link Settings#hasHeatPump}, {@link Settings#heatStages}, {@link Settings#coolStages}) to determine whether a + * heat pump exists and how many stages the thermostat supports. + * + *

      + * The actual temperature and humidity will also be updated when the equipment state changes by the thermostat, this + * may occur at a frequency of 3 minutes, however it is only transmitted when there is an equipment state change on + * the thermostat. + * + *

      + * The extended runtime object is read-only. + * + * @see ExtendedRuntime + * @see Thermostat + * Interval Report Data + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class ExtendedRuntime extends AbstractMessagePart { + private Date lastReadingTimestamp; + private String runtimeDate; // TODO Jackson 1.9 can't also deal with date-only dates (@watou) + private Integer runtimeInterval; + private List actualTemperature; + private List actualHumidity; + private List desiredHeat; + private List desiredCool; + private List desiredHumidity; + private List desiredDehumidity; + private List dmOffset; + private List hvacMode; + private List heatPump1; + private List heatPump2; + private List auxHeat1; + private List auxHeat2; + private List auxHeat3; + private List cool1; + private List cool2; + private List fan; + private List humidifier; + private List dehumidifier; + private List economizer; + private List ventilator; + private Integer currentElectricityBill; + private Integer projectedElectricityBill; + + /** + * @return the UTC timestamp of the last value read. This timestamp is updated at a 15 min interval by the + * thermostat. For the 1st value, it is timestamp - 10 mins, for the 2nd value it is timestamp - 5 mins. + * Consider day boundaries being straddled when using these values. + */ + @JsonProperty("lastReadingTimestamp") + public Date getLastReadingTimestamp() { + return this.lastReadingTimestamp; + } + + /** + * @return the UTC date of the last runtime reading. Format: YYYY-MM-DD + */ + @JsonProperty("runtimeDate") + public String getRuntimeDate() { + return this.runtimeDate; + } + + /** + * @return the last 5 minute interval which was updated by the thermostat telemetry update. Subtract 2 from this + * interval to obtain the beginning interval for the last 3 readings. Multiply by 5 mins to obtain the + * minutes of the day. Range: 0-287 + */ + @JsonProperty("runtimeInterval") + public Integer getRuntimeInterval() { + return this.runtimeInterval; + } + + /** + * @return the last three 5 minute actual temperature readings + */ + @JsonProperty("actualTemperature") + public List getActualTemperature() { + return this.actualTemperature; + } + + /** + * @return the last three 5 minute actual humidity readings + */ + @JsonProperty("actualHumidity") + public List getActualHumidity() { + return this.actualHumidity; + } + + /** + * @return the last three 5 minute desired heat temperature readings + */ + @JsonProperty("desiredHeat") + public List getDesiredHeat() { + return this.desiredHeat; + } + + /** + * @return the last three 5 minute desired cool temperature readings + */ + @JsonProperty("desiredCool") + public List getDesiredCool() { + return this.desiredCool; + } + + /** + * @return the last three 5 minute desired humidity readings + */ + @JsonProperty("desiredHumidity") + public List getDesiredHumidity() { + return this.desiredHumidity; + } + + /** + * @return the last three 5 minute desired dehumidification readings + */ + @JsonProperty("desiredDehumidity") + public List getDesiredDehumidity() { + return this.desiredDehumidity; + } + + /** + * @return the last three 5 minute desired Demand Management temperature offsets. This value is Demand + * Management adjustment value which was applied by the thermostat. If the thermostat decided not to + * honor the adjustment, it will send 0 for the interval. Compare these values with the values sent in + * the DM message to determine whether the thermostat applied the adjustment. + */ + @JsonProperty("dmOffset") + public List getDmOffset() { + return this.dmOffset; + } + + /** + * @return the last three 5 minute HVAC Mode reading. These values indicate which stage was energized in the 5 + * minute interval. Values: heatStage1On, heatStage2On, heatStage3On, heatOff, compressorCoolStage1On, + * compressorCoolStage2On, compressorCoolOff, compressorHeatStage1On, compressorHeatStage2On, + * compressorHeatOff, economyCycle. + */ + @JsonProperty("hvacMode") + public List getHvacMode() { + return this.hvacMode; + } + + /** + * @return the last three 5 minute HVAC Runtime values in seconds (0-300 seconds) per interval. This value + * corresponds to the heat pump stage 1 runtime. + */ + @JsonProperty("heatPump1") + public List getHeatPump1() { + return this.heatPump1; + } + + /** + * @return the last three 5 minute HVAC Runtime values in seconds (0-300 seconds) per interval. This value + * corresponds to the heat pump stage 2 runtime. + */ + @JsonProperty("heatPump2") + public List getHeatPump2() { + return this.heatPump2; + } + + /** + * @return the last three 5 minute HVAC Runtime values in seconds (0-300 seconds) per interval. This value + * corresponds to the auxiliary heat stage 1. If the thermostat does not have a heat pump, this is heat + * stage 1. + */ + @JsonProperty("auxHeat1") + public List getAuxHeat1() { + return this.auxHeat1; + } + + /** + * @return the last three 5 minute HVAC Runtime values in seconds (0-300 seconds) per interval. This value + * corresponds to the auxiliary heat stage 2. If the thermostat does not have a heat pump, this is heat + * stage 2. + */ + @JsonProperty("auxHeat2") + public List getAuxHeat2() { + return this.auxHeat2; + } + + /** + * @return the last three 5 minute HVAC Runtime values in seconds (0-300 seconds) per interval. This value + * corresponds to the heat stage 3 if the thermostat does not have a heat pump. Auxiliary stage 3 is not + * supported. + */ + @JsonProperty("auxHeat3") + public List getAuxHeat3() { + return this.auxHeat3; + } + + /** + * @return the last three 5 minute HVAC Runtime values in seconds (0-300 seconds) per interval. This value + * corresponds to the cooling stage 1. + */ + @JsonProperty("cool1") + public List getCool1() { + return this.cool1; + } + + /** + * @return the last three 5 minute HVAC Runtime values in seconds (0-300 seconds) per interval. This value + * corresponds to the cooling stage 2. + */ + @JsonProperty("cool2") + public List getCool2() { + return this.cool2; + } + + /** + * @return the last three 5 minute fan Runtime values in seconds (0-300 seconds) per interval. + */ + @JsonProperty("fan") + public List getFan() { + return this.fan; + } + + /** + * @return the last three 5 minute humidifier Runtime values in seconds (0-300 seconds) per interval. + */ + @JsonProperty("humidifier") + public List getHumidifier() { + return this.humidifier; + } + + /** + * @return the last three 5 minute dehumidifier Runtime values in seconds (0-300 seconds) per interval. + */ + @JsonProperty("dehumidifier") + public List getDehumidifier() { + return this.dehumidifier; + } + + /** + * @return the last three 5 minute economizer Runtime values in seconds (0-300 seconds) per interval. + */ + @JsonProperty("economizer") + public List getEconomizer() { + return this.economizer; + } + + /** + * @return the last three 5 minute ventilator Runtime values in seconds (0-300 seconds) per interval. + */ + @JsonProperty("ventilator") + public List getVentilator() { + return this.ventilator; + } + + /** + * @return the latest value of the current electricity bill as interpolated from the thermostat's readings from + * a paired electricity meter. + */ + @JsonProperty("currentElectricityBill") + public Integer getCurrentElectricityBill() { + return this.currentElectricityBill; + } + + /** + * @return the latest estimate of the projected electricity bill as interpolated from the thermostat's readings + * from a paired electricity meter. + */ + @JsonProperty("projectedElectricityBill") + public Integer getProjectedElectricityBill() { + return this.projectedElectricityBill; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("lastReadingTimestamp", this.lastReadingTimestamp); + builder.append("runtimeDate", this.runtimeDate); + builder.append("runtimeInterval", this.runtimeInterval); + builder.append("actualTemperature", this.actualTemperature); + builder.append("actualHumidity", this.actualHumidity); + builder.append("desiredHeat", this.desiredHeat); + builder.append("desiredCool", this.desiredCool); + builder.append("desiredHumidity", this.desiredHumidity); + builder.append("desiredDehumidity", this.desiredDehumidity); + builder.append("dmOffset", this.dmOffset); + builder.append("hvacMode", this.hvacMode); + builder.append("heatPump1", this.heatPump1); + builder.append("heatPump2", this.heatPump2); + builder.append("auxHeat1", this.auxHeat1); + builder.append("auxHeat2", this.auxHeat2); + builder.append("auxHeat3", this.auxHeat3); + builder.append("cool1", this.cool1); + builder.append("cool2", this.cool2); + builder.append("fan", this.fan); + builder.append("humidifier", this.humidifier); + builder.append("dehumidifier", this.dehumidifier); + builder.append("economizer", this.economizer); + builder.append("ventilator", this.ventilator); + builder.append("currentElectricityBill", this.currentElectricityBill); + builder.append("projectedElectricityBill", this.projectedElectricityBill); + + return builder.toString(); + } + } + + /** + * The Electricity class contains the last collected electricity usage measurements for the thermostat. An + * electricity object is composed of ElectricityDevices, each of which contains readings from an ElectricityTier. + * + * @see Electricity + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Electricity extends AbstractMessagePart { + private List devices; + + Electricity(@JsonProperty("devices") List devices) { + this.devices = devices; + } + + /** + * @return the list of ElectricityDevice objects associated with the thermostat, each representing a device such + * as an electric meter or remote load control. + */ + @JsonProperty("devices") + public List getDevices() { + return this.devices; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("devices", this.devices); + + return builder.toString(); + } + } + + /** + * An ElectricityDevice represents an energy recording device. At this time, only meters are supported by the API. + * + * @see ElectricityDevice + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class ElectricityDevice extends AbstractMessagePart { + private List tiers; + private List lastUpdate; + private List cost; + private List consumption; + + /** + * @return the list of ElectricityTiers containing the break down of daily electricity consumption of the device + * for the day, broken down per pricing tier + */ + @JsonProperty("tiers") + public List getTiers() { + return this.tiers; + } + + /** + * @return the last date/time the reading was updated in UTC time + */ + @JsonProperty("lastUpdate") + public List getLastUpdate() { + return this.lastUpdate; + } + + /** + * @return the last three daily electricity cost reads from the device in cents with a three decimal place + * precision. + */ + @JsonProperty("cost") + public List getCost() { + return this.cost; + } + + /** + * @return the last three daily electricity consumption reads from the device in KWh with a three decimal place + * precision. + */ + @JsonProperty("consumption") + public List getConsumption() { + return this.consumption; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("tiers", this.tiers); + builder.append("lastUpdate", this.lastUpdate); + builder.append("cost", this.cost); + builder.append("consumption", this.consumption); + + return builder.toString(); + } + } + + /** + * An ElectricityTier object represents the last reading from a given pricing tier if the utility provides such + * information. If there are no pricing tiers defined, than an unnamed tier will represent the total reading. The + * values represented here are a daily cumulative total in kWh. The cost is likewise a cumulative total in cents. + * + * @see ElectricityTier + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class ElectricityTier extends AbstractMessagePart { + private String name; + private String consumption; + private String cost; + + /** + * @return the tier name as defined by the {@link Utility}. May be an empty string if the tier is undefined or + * the usage falls outside the defined tiers. + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @return the last daily consumption reading collected. The reading format and precision is to three decimal + * places in kWh. + */ + @JsonProperty("consumption") + public String getConsumption() { + return this.consumption; + } + + /** + * @return the daily cumulative tier cost in dollars if defined by the Utility. May be an empty string if + * undefined. + */ + @JsonProperty("cost") + public String getCost() { + return this.cost; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("name", this.name); + builder.append("consumption", this.consumption); + builder.append("cost", this.cost); + + return builder.toString(); + } + } + + /** + * Represents a device attached to the thermostat. Devices may not be modified remotely; all changes must occur on + * the thermostat. + * + * @see Device + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Device extends AbstractMessagePart { + private Integer deviceId; + private String name; + private List sensors; + private List outputs; + + /** + * @return a unique ID for the device + */ + @JsonProperty("deviceId") + public Integer getDeviceId() { + return this.deviceId; + } + + /** + * @return the user supplied device name + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @return the list of {@link Sensor} objects associated with the device + */ + @JsonProperty("sensors") + public List getSensors() { + return this.sensors; + } + + /** + * @return the list of {@link Output} objects associated with the device + */ + @JsonProperty("outputs") + public List getOutputs() { + return this.outputs; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("deviceId", this.deviceId); + builder.append("name", this.name); + builder.append("sensors", this.sensors); + builder.append("outputs", this.outputs); + + return builder.toString(); + } + } + + /** + * The Sensor class represents a sensor connected to the thermostat. Sensors may not be modified using the API, + * however some configuration may occur through the web portal. + * + * @see Sensor + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Sensor extends AbstractMessagePart { + private String name; + private String manufacturer; + private String model; + private Integer zone; + private Integer sensorId; + private String type; + private String usage; + private Integer numberOfBits; + private Integer bconstant; + private Integer thermistorSize; + private Integer tempCorrection; + private Integer gain; + private Integer maxVoltage; + private Integer multiplier; + private List states; + + /** + * @return the sensor name + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @return the sensor manufacturer + */ + @JsonProperty("manufacturer") + public String getManufacturer() { + return this.manufacturer; + } + + /** + * @return the sensor model + */ + @JsonProperty("model") + public String getModel() { + return this.model; + } + + /** + * @return the thermostat zone the sensor is associated with + */ + @JsonProperty("zone") + public Integer getZone() { + return this.zone; + } + + /** + * @return the unique sensor identifier + */ + @JsonProperty("sensorId") + public Integer getSensorId() { + return this.sensorId; + } + + /** + * @return the type of sensor. Values: adc, co2, dryCOntact, humidity, temperature, unknown + */ + @JsonProperty("type") + public String getType() { + return this.type; + } + + /** + * @return the sensor usage type. Values: dischargeAir, indoor, monitor, outdoor + */ + @JsonProperty("usage") + public String getUsage() { + return this.usage; + } + + /** + * @return the numberOfBits + */ + @JsonProperty("numberOfBits") + public Integer getNumberOfBits() { + return this.numberOfBits; + } + + /** + * @return the bconstant + */ + @JsonProperty("bconstant") + public Integer getBconstant() { + return this.bconstant; + } + + /** + * @return the thermistorSize + */ + @JsonProperty("thermistorSize") + public Integer getThermistorSize() { + return this.thermistorSize; + } + + /** + * @return the tempCorrection + */ + @JsonProperty("tempCorrection") + public Integer getTempCorrection() { + return this.tempCorrection; + } + + /** + * @return the gain + */ + @JsonProperty("gain") + public Integer getGain() { + return this.gain; + } + + /** + * @return the maxVoltage + */ + @JsonProperty("maxVoltage") + public Integer getMaxVoltage() { + return this.maxVoltage; + } + + /** + * @return the multiplier + */ + @JsonProperty("multiplier") + public Integer getMultiplier() { + return this.multiplier; + } + + /** + * @return a list of {@link SensorState} objects + */ + @JsonProperty("states") + public List getStates() { + return this.states; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("name", this.name); + builder.append("manufacturer", this.manufacturer); + builder.append("model", this.model); + builder.append("zone", this.zone); + builder.append("sensorId", this.sensorId); + builder.append("type", this.type); + builder.append("usage", this.usage); + builder.append("numberOfBits", this.numberOfBits); + builder.append("bconstant", this.bconstant); + builder.append("thermistorSize", this.thermistorSize); + builder.append("tempCorrection", this.tempCorrection); + builder.append("gain", this.gain); + builder.append("maxVoltage", this.maxVoltage); + builder.append("multiplier", this.multiplier); + builder.append("states", this.states); + + return builder.toString(); + } + } + + /** + * A sensor state is a configurable trigger for a number of {@link StateAction}s. + * + * @see State + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class SensorState extends AbstractMessagePart { + private Integer maxValue; + private Integer minValue; + private String type; + private List actions; + + /** + * @return the maximum value the sensor can generate + */ + @JsonProperty("maxValue") + public Integer getMaxValue() { + return this.maxValue; + } + + /** + * @return the minimum value the sensor can generate + */ + @JsonProperty("minValue") + public Integer getMinValue() { + return this.minValue; + } + + /** + * @return the type Values: coolHigh, coolLow, heatHigh, heatLow, high, low, transitionCount, normal + */ + @JsonProperty("type") + public String getType() { + return this.type; + } + + /** + * @return the list of {@link StateAction} objects associated with the sensor + */ + @JsonProperty("actions") + public List getActions() { + return this.actions; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("maxValue", this.maxValue); + builder.append("minValue", this.minValue); + builder.append("type", this.type); + builder.append("actions", this.actions); + + return builder.toString(); + } + } + + /** + * A StateAction defines an action to take when a {@link SensorState} is triggered. + * + * @see Action + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class StateAction extends AbstractMessagePart { + private String type; + private Boolean sendAlert; + private Boolean sendUpdate; + private Integer activationDelay; + private Integer deactivationDelay; + private Integer minActionDuration; + private Temperature heatAdjustTemp; + private Temperature coolAdjustTemp; + private String activateRelay; + private Boolean activateRelayOpen; + + /** + * @return the type Values: activateRelay, adjustTemp, doNothing, shutdownAC, shutdownAuxHeat, shutdownSystem, + * shutdownCompression, switchToOccupied, switchToUnoccupied, turnOffDehumidifer, turnOffHumidifier, + * turnOnCool, turnOnDehumidifier, turnOnFan, turnOnHeat, turnOnHumidifier. + */ + @JsonProperty("type") + public String getType() { + return this.type; + } + + /** + * @return flag to enable an alert to be generated when the state is triggered + */ + @JsonProperty("sendAlert") + public Boolean getSendAlert() { + return this.sendAlert; + } + + /** + * @return the sendUpdate + */ + @JsonProperty("sendUpdate") + public Boolean getSendUpdate() { + return this.sendUpdate; + } + + /** + * @return delay in seconds before the action is triggered by the state change + */ + @JsonProperty("activationDelay") + public Integer getActivationDelay() { + return this.activationDelay; + } + + /** + * @return the deactivationDelay + */ + @JsonProperty("deactivationDelay") + public Integer getDeactivationDelay() { + return this.deactivationDelay; + } + + /** + * @return the minActionDuration + */ + @JsonProperty("minActionDuration") + public Integer getMinActionDuration() { + return this.minActionDuration; + } + + /** + * @return the heatAdjustTemp + */ + @JsonProperty("heatAdjustTemp") + public Temperature getHeatAdjustTemp() { + return this.heatAdjustTemp; + } + + /** + * @return the coolAdjustTemp + */ + @JsonProperty("coolAdjustTemp") + public Temperature getCoolAdjustTemp() { + return this.coolAdjustTemp; + } + + /** + * @return the activateRelay + */ + @JsonProperty("activateRelay") + public String getActivateRelay() { + return this.activateRelay; + } + + /** + * @return the activateRelayOpen + */ + @JsonProperty("activateRelayOpen") + public Boolean isActivateRelayOpen() { + return this.activateRelayOpen; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("type", this.type); + builder.append("sendAlert", this.sendAlert); + builder.append("sendUpdate", this.sendUpdate); + builder.append("activationDelay", this.activationDelay); + builder.append("deactivationDelay", this.deactivationDelay); + builder.append("minActionDuration", this.minActionDuration); + builder.append("heatAdjustTemp", this.heatAdjustTemp); + builder.append("coolAdjustTemp", this.coolAdjustTemp); + builder.append("activateRelay", this.activateRelay); + builder.append("activateRelayOpen", this.activateRelayOpen); + + return builder.toString(); + } + } + + /** + * An output is a relay connected to the thermostat. + * + * @see Output + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Output extends AbstractMessagePart { + private String name; + private Integer zone; + private Integer outputId; + private String type; + private Boolean sendUpdate; + private Boolean activeClosed; + private Integer activationTime; + private Integer deactivationTime; + + /** + * @return the name of the output + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @return the thermostat zone the output is associated with + */ + @JsonProperty("zone") + public Integer getZone() { + return this.zone; + } + + /** + * @return the unique output identifier number + */ + @JsonProperty("outputId") + public Integer getOutputId() { + return this.outputId; + } + + /** + * @return the type of output. Values: compressor1, compressor2, dehumidifier, economizer, fan, heat1, heat2, + * heat3, heatPumpReversal, humidifer, none, occupancy, userDefined, ventilator, zoneCool, zoneFan, + * zoneHeat + */ + @JsonProperty("type") + public String getType() { + return this.type; + } + + /** + * @return the sendUpdate + */ + @JsonProperty("sendUpdate") + public Boolean getSendUpdate() { + return this.sendUpdate; + } + + /** + * @return the activeClosed + */ + @JsonProperty("activeClosed") + public Boolean getActiveClosed() { + return this.activeClosed; + } + + /** + * @return the activationTime + */ + @JsonProperty("activationTime") + public Integer getActivationTime() { + return this.activationTime; + } + + /** + * @return the deactivationTime + */ + @JsonProperty("deactivationTime") + public Integer getDeactivationTime() { + return this.deactivationTime; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("name", this.name); + builder.append("zone", this.zone); + builder.append("outputId", this.outputId); + builder.append("type", this.type); + builder.append("sendUpdate", this.sendUpdate); + builder.append("activeClosed", this.activeClosed); + builder.append("activationTime", this.activationTime); + builder.append("deactivationTime", this.deactivationTime); + + return builder.toString(); + } + } + + /** + * The Location describes the physical location and coordinates of the thermostat as entered by the thermostat + * owner. The address information is used in a geocode look up to obtain the thermostat coordinates. The coordinates + * are used to obtain accurate weather information. + * + * @see Location + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Location extends AbstractMessagePart { + private Integer timeZoneOffsetMinutes; + private String timeZone; + private Boolean isDaylightSaving; + private String streetAddress; + private String city; + private String provinceState; + private String country; + private String postalCode; + private String phoneNumber; + private String mapCoordinates; + + /** + * @return the timezone offset in minutes from UTC + */ + @JsonProperty("timeZoneOffsetMinutes") + public Integer getTimeZoneOffsetMinutes() { + return this.timeZoneOffsetMinutes; + } + + /** + * @return the Olson timezone the thermostat resides in (e.g America/Toronto) + */ + @JsonProperty("timeZone") + public String getTimeZone() { + return this.timeZone; + } + + /** + * @param timeZone + * the Olson timezone the thermostat resides in (e.g America/Toronto) + */ + @JsonProperty("timeZone") + public void setTimeZone(String timeZone) { + this.timeZone = timeZone; + } + + /** + * @return whether the thermostat should factor in daylight savings when displaying the date and time + */ + @JsonProperty("isDaylightSaving") + public Boolean getIsDaylightSaving() { + return this.isDaylightSaving; + } + + /** + * @param isDaylightSaving + * whether the thermostat should factor in daylight savings when displaying the date and time + */ + @JsonProperty("isDaylightSaving") + public void setIsDaylightSaving(Boolean isDaylightSaving) { + this.isDaylightSaving = isDaylightSaving; + } + + /** + * @return the thermostat location street address + */ + @JsonProperty("streetAddress") + public String getStreetAddress() { + return this.streetAddress; + } + + /** + * @param streetAddress + * the thermostat location street address + */ + @JsonProperty("streetAddress") + public void setStreetAddress(String streetAddress) { + this.streetAddress = streetAddress; + } + + /** + * @return the thermostat location city + */ + @JsonProperty("city") + public String getCity() { + return this.city; + } + + /** + * @param city + * the thermostat location city + */ + @JsonProperty("city") + public void setCity(String city) { + this.city = city; + } + + /** + * @return the thermostat location state or province + */ + @JsonProperty("provinceState") + public String getProvinceState() { + return this.provinceState; + } + + /** + * @param provinceState + * the thermostat location state or province + */ + @JsonProperty("provinceState") + public void setProvinceState(String provinceState) { + this.provinceState = provinceState; + } + + /** + * @return the thermostat location country + */ + @JsonProperty("country") + public String getCountry() { + return this.country; + } + + /** + * @param country + * the thermostat location country + */ + @JsonProperty("country") + public void setCountry(String country) { + this.country = country; + } + + /** + * @return the thermostat location ZIP or postal code + */ + @JsonProperty("postalCode") + public String getPostalCode() { + return this.postalCode; + } + + /** + * @param postalCode + * the thermostat location ZIP or postal code + */ + @JsonProperty("postalCode") + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + /** + * @return the thermostat owner's phone number + */ + @JsonProperty("phoneNumber") + public String getPhoneNumber() { + return this.phoneNumber; + } + + /** + * @param phoneNumber + * the thermostat owner's phone number + */ + @JsonProperty("phoneNumber") + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + /** + * @return the lat/long geographic coordinates of the thermostat location + */ + @JsonProperty("mapCoordinates") + public String getMapCoordinates() { + return this.mapCoordinates; + } + + /** + * @param mapCoordinates + * the lat/long geographic coordinates of the thermostat location + */ + @JsonProperty("mapCoordinates") + public void setMapCoordinates(String mapCoordinates) { + this.mapCoordinates = mapCoordinates; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("timeZoneOffsetMinutes", this.timeZoneOffsetMinutes); + builder.append("timeZone", this.timeZone); + builder.append("isDaylightSaving", this.isDaylightSaving); + builder.append("streetAddress", this.streetAddress); + builder.append("city", this.city); + builder.append("provinceState", this.provinceState); + builder.append("country", this.country); + builder.append("postalCode", this.postalCode); + builder.append("phoneNumber", this.phoneNumber); + builder.append("mapCoordinates", this.mapCoordinates); + + return builder.toString(); + } + } + + /** + * The Technician object contains information pertaining to the technician associated with a thermostat. The + * technician may not be modified through the API. + * + * @see Technician + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Technician extends AbstractMessagePart { + private String contractorRef; + private String name; + private String phone; + private String streetAddress; + private String city; + private String provinceState; + private String country; + private String postalCode; + private String email; + private String web; + + /** + * @return the internal ecobee unique identifier for this contractor + */ + @JsonProperty("contractorRef") + public String getContractorRef() { + return this.contractorRef; + } + + /** + * @return the company name of the technician + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @return the technician's contact phone number + */ + @JsonProperty("phone") + public String getPhone() { + return this.phone; + } + + /** + * @return the technician's street address + */ + @JsonProperty("streetAddress") + public String getStreetAddress() { + return this.streetAddress; + } + + /** + * @return the technician's city + */ + @JsonProperty("city") + public String getCity() { + return this.city; + } + + /** + * @return the technician's State or province + */ + @JsonProperty("provinceState") + public String getProvinceState() { + return this.provinceState; + } + + /** + * @return the technician's country + */ + @JsonProperty("country") + public String getCountry() { + return this.country; + } + + /** + * @return the technician's ZIP or postal code + */ + @JsonProperty("postalCode") + public String getPostalCode() { + return this.postalCode; + } + + /** + * @return the technician's email address + */ + @JsonProperty("email") + public String getEmail() { + return this.email; + } + + /** + * @return the technician's web site + */ + @JsonProperty("web") + public String getWeb() { + return this.web; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("contractorRef", this.contractorRef); + builder.append("name", this.name); + builder.append("phone", this.phone); + builder.append("streetAddress", this.streetAddress); + builder.append("city", this.city); + builder.append("provinceState", this.provinceState); + builder.append("country", this.country); + builder.append("postalCode", this.postalCode); + builder.append("email", this.email); + builder.append("web", this.web); + + return builder.toString(); + } + } + + /** + * The Utility information the {@link Thermostat} belongs to. The utility may not be modified through the API. + * + * @see Utility + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Utility extends AbstractMessagePart { + private String name; + private String phone; + private String email; + private String web; + + /** + * @return the Utility company name + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @return the Utility company contact phone number + */ + @JsonProperty("phone") + public String getPhone() { + return this.phone; + } + + /** + * @return the Utility company email address + */ + @JsonProperty("email") + public String getEmail() { + return this.email; + } + + /** + * @return the Utility company web site + */ + @JsonProperty("web") + public String getWeb() { + return this.web; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("name", this.name); + builder.append("phone", this.phone); + builder.append("email", this.email); + builder.append("web", this.web); + + return builder.toString(); + } + } + + /** + * The Management object contains information about the management company the thermostat belongs to. The Management + * object is read-only, it may be modified in the web portal. + * + * @see Management + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Management extends AbstractMessagePart { + private String administrativeContact; + private String billingContact; + private String name; + private String phone; + private String email; + private String web; + private Boolean showAlertIdt; + private Boolean showAlertWeb; + + /** + * @return the administrative contact name + */ + @JsonProperty("administrativeContact") + public String getAdministrativeContact() { + return this.administrativeContact; + } + + /** + * @return the billing contact name + */ + @JsonProperty("billingContact") + public String getBillingContact() { + return this.billingContact; + } + + /** + * @return the company name + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @return the phone number + */ + @JsonProperty("phone") + public String getPhone() { + return this.phone; + } + + /** + * @return the contact email address + */ + @JsonProperty("email") + public String getEmail() { + return this.email; + } + + /** + * @return the company web site + */ + @JsonProperty("web") + public String getWeb() { + return this.web; + } + + /** + * @return the showAlertIdt + */ + @JsonProperty("showAlertIdt") + public Boolean getShowAlertIdt() { + return this.showAlertIdt; + } + + /** + * @return the showAlertWeb + */ + @JsonProperty("showAlertWeb") + public Boolean getShowAlertWeb() { + return this.showAlertWeb; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("administrativeContact", this.administrativeContact); + builder.append("billingContact", this.billingContact); + builder.append("name", this.name); + builder.append("phone", this.phone); + builder.append("email", this.email); + builder.append("web", this.web); + builder.append("showAlertIdt", this.showAlertIdt); + builder.append("showAlertWeb", this.showAlertWeb); + + return builder.toString(); + } + } + + /** + * The Weather object contains the weather and forecast information for the thermostat's location. + * + * @see Weather + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Weather extends AbstractMessagePart { + private Date timestamp; + private String weatherStation; + private List forecasts; + + /** + * @return the time stamp in UTC of the weather forecast + */ + @JsonProperty("timestamp") + public Date getTimestamp() { + return this.timestamp; + } + + /** + * @return the weather station identifier + */ + @JsonProperty("weatherStation") + public String getWeatherStation() { + return this.weatherStation; + } + + /** + * @return the list of latest weather station forecasts + */ + @JsonProperty("forecasts") + public List getForecasts() { + return this.forecasts; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("timestamp", this.timestamp); + builder.append("weatherStation", this.weatherStation); + builder.append("forecasts", this.forecasts); + + return builder.toString(); + } + } + + /** + * The Weather Forecast contains the weather forecast information for the thermostat. The first forecast is the most + * accurate, later forecasts become less accurate in distance and time. + * + * @see WeatherForecast + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class WeatherForecast extends AbstractMessagePart { + private Integer weatherSymbol; + private Date dateTime; + private String condition; + private Temperature temperature; + private Integer pressure; + private Integer relativeHumidity; + private Integer dewpoint; + private Integer visibility; + private Integer windSpeed; + private Integer windGust; + private String windDirection; + private Integer windBearing; + private Integer pop; + private Temperature tempHigh; + private Temperature tempLow; + private Integer sky; + + /** + * @return the weatherSymbol + */ + @JsonProperty("weatherSymbol") + public Integer getWeatherSymbol() { + return this.weatherSymbol; + } + + /** + * @return the time stamp of the weather forecast + */ + @JsonProperty("dateTime") + public Date getDateTime() { + return this.dateTime; + } + + /** + * @return the condition + */ + @JsonProperty("condition") + public String getCondition() { + return this.condition; + } + + /** + * @return the current temperature + */ + @JsonProperty("temperature") + public Temperature getTemperature() { + return this.temperature; + } + + /** + * @return the current barometric pressure + */ + @JsonProperty("pressure") + public Integer getPressure() { + return this.pressure; + } + + /** + * @return the current humidity + */ + @JsonProperty("relativeHumidity") + public Integer getRelativeHumidity() { + return this.relativeHumidity; + } + + /** + * @return the dewpoint + */ + @JsonProperty("dewpoint") + public Integer getDewpoint() { + return this.dewpoint; + } + + /** + * @return the visibility + */ + @JsonProperty("visibility") + public Integer getVisibility() { + return this.visibility; + } + + /** + * @return the wind speed as an integer in mph * 1000 + */ + @JsonProperty("windSpeed") + public Integer getWindSpeed() { + return this.windSpeed; + } + + /** + * @return the windGust + */ + @JsonProperty("windGust") + public Integer getWindGust() { + return this.windGust; + } + + /** + * @return the wind direction + */ + @JsonProperty("windDirection") + public String getWindDirection() { + return this.windDirection; + } + + /** + * @return the wind bearing + */ + @JsonProperty("windBearing") + public Integer getWindBearing() { + return this.windBearing; + } + + /** + * @return the probability of precipitation + */ + @JsonProperty("pop") + public Integer getPop() { + return this.pop; + } + + /** + * @return the predicted high temperature for the day + */ + @JsonProperty("tempHigh") + public Temperature getTempHigh() { + return this.tempHigh; + } + + /** + * @return the predicted low temperature for the day + */ + @JsonProperty("tempLow") + public Temperature getTempLow() { + return this.tempLow; + } + + /** + * @return the cloud cover condition + */ + @JsonProperty("sky") + public Integer getSky() { + return this.sky; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("weatherSymbol", this.weatherSymbol); + builder.append("dateTime", this.dateTime); + builder.append("condition", this.condition); + builder.append("temperature", this.temperature); + builder.append("pressure", this.pressure); + builder.append("relativeHumidity", this.relativeHumidity); + builder.append("dewpoint", this.dewpoint); + builder.append("visibility", this.visibility); + builder.append("windSpeed", this.windSpeed); + builder.append("windGust", this.windGust); + builder.append("windDirection", this.windDirection); + builder.append("windBearing", this.windBearing); + builder.append("pop", this.pop); + builder.append("tempHigh", this.tempHigh); + builder.append("tempLow", this.tempLow); + builder.append("sky", this.sky); + + return builder.toString(); + } + } + + /** + * The event object represents a scheduled thermostat program change. All events have a start and end time during + * which the thermostat runtime settings will be modified. Events may not be directly modified, various Functions + * provide the capability to modify the calendar events and to modify the program. The event list is sorted with + * events ordered by whether they are currently running and the internal priority of each event. It is safe to take + * the first event which is running and show it as the currently running event. When the resume function is used, + * events are removed in the order they are listed here. + * + * Note that the start/end date/time for the event must be in thermostat time and are not specified in UTC. + * + * Event Priorities + * + * The events are listed from top priority first to lowest priority. They will appear in the events list in the same + * order as listed here provided they are active currently. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      TypeEvent Type
      holdHold temperature event.
      demandResponseDemand Response event.
      sensorSensor generated event.
      switchOccupancyEMS only event to flip unoccupied to occupied, and vice versa. Look at name to determine whether "occupied" + * or "unoccupied".
      vacationVacation event.
      quickSaveQuick Save event.
      todayToday widget generated event.
      templateA vacation event that reflects the thermostat owner's default preferences for any created vacation. Template + * events are never active and are only used to store the last used vacation settings of the thermostat owner.
      + * + * @see Event + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Event extends AbstractMessagePart { + private String type; + private String name; + private Boolean running; + // TODO Jackson 1.9 dates (@watou) + private String startDate; + private String startTime; + private String endDate; + private String endTime; + @JsonProperty("isOccupied") + private Boolean _isOccupied; + @JsonProperty("isCoolOff") + private Boolean _isCoolOff; + @JsonProperty("isHeatOff") + private Boolean _isHeatOff; + private Temperature coolHoldTemp; + private Temperature heatHoldTemp; + private FanMode fan; + private VentilatorMode vent; + private Integer ventilatorMinOnTime; + @JsonProperty("isOptional") + private Boolean _isOptional; + @JsonProperty("isTemperatureRelative") + private Boolean _isTemperatureRelative; + private Temperature coolRelativeTemp; + private Temperature heatRelativeTemp; + @JsonProperty("isTemperatureAbsolute") + private Boolean _isTemperatureAbsolute; + private Integer dutyCyclePercentage; + private Integer fanMinOnTime; + private Boolean occupiedSensorActive; + private Boolean unoccupiedSensorActive; + private Temperature drRampUpTemp; + private Integer drRampUpTime; + private String linkRef; + private String holdClimateRef; + + /** + * @return the type of event. Values: hold, demandResponse, sensor, switchOccupancy, vacation, quickSave, today + */ + @JsonProperty("type") + public String getType() { + return this.type; + } + + /** + * @return the unique event name + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @return whether the event is currently active or not + */ + @JsonProperty("running") + public Boolean isRunning() { + return this.running; + } + + /** + * @return the event start date in thermostat local time + */ + @JsonProperty("startDate") + public String getStartDate() { + return this.startDate; + } + + /** + * @return the event start time in thermostat local time + */ + @JsonProperty("startTime") + public String getStartTime() { + return this.startTime; + } + + /** + * @return the event end date in thermostat local time + */ + @JsonProperty("endDate") + public String getEndDate() { + return this.endDate; + } + + /** + * @return the event end time in thermostat local time + */ + @JsonProperty("endTime") + public String getEndTime() { + return this.endTime; + } + + /** + * @return whether there are persons occupying the property during the event + */ + @JsonProperty("isOccupied") + public Boolean isOccupied() { + return this._isOccupied; + } + + /** + * @return whether cooling will be turned off during the event + */ + @JsonProperty("isCoolOff") + public Boolean isCoolOff() { + return this._isCoolOff; + } + + /** + * @return whether heating will be turned off during the event + */ + @JsonProperty("isHeatOff") + public Boolean isHeatOff() { + return this._isHeatOff; + } + + /** + * @return the cooling absolute temperature to set + */ + @JsonProperty("coolHoldTemp") + public Temperature getCoolHoldTemp() { + return this.coolHoldTemp; + } + + /** + * @return the heating absolute temperature to set + */ + @JsonProperty("heatHoldTemp") + public Temperature getHeatHoldTemp() { + return this.heatHoldTemp; + } + + /** + * @return the fan mode during the event. Values: auto, on Default: based on current climate and hvac mode + */ + @JsonProperty("fan") + public FanMode getFan() { + return this.fan; + } + + /** + * @return the ventilator mode during the event. Values: auto, minontime, on, off + */ + @JsonProperty("vent") + public VentilatorMode getVent() { + return this.vent; + } + + /** + * @return the minimum amount of time the ventilator equipment must stay on on each duty cycle + */ + @JsonProperty("ventilatorMinOnTime") + public Integer getVentilatorMinOnTime() { + return this.ventilatorMinOnTime; + } + + /** + * @return whether this event is mandatory or the end user can cancel it + */ + @JsonProperty("isOptional") + public Boolean isOptional() { + return this._isOptional; + } + + /** + * @return whether the event is using a relative temperature setting to the currently active program climate + */ + @JsonProperty("isTemperatureRelative") + public Boolean isTemperatureRelative() { + return this._isTemperatureRelative; + } + + /** + * @return the relative cool temperature adjustment + */ + @JsonProperty("coolRelativeTemp") + public Temperature getCoolRelativeTemp() { + return this.coolRelativeTemp; + } + + /** + * @return the relative heat temperature adjustment + */ + @JsonProperty("heatRelativeTemp") + public Temperature getHeatRelativeTemp() { + return this.heatRelativeTemp; + } + + /** + * @return whether the event uses absolute temperatures to set the values. Default: true for DRs + */ + @JsonProperty("isTemperatureAbsolute") + public Boolean isTemperatureAbsolute() { + return this._isTemperatureAbsolute; + } + + /** + * @return the dutyCyclePercentage + */ + @JsonProperty("dutyCyclePercentage") + public Integer getDutyCyclePercentage() { + return this.dutyCyclePercentage; + } + + /** + * @return the minimum number of minutes to run the fan each hour. Range: 0-60, Default: 0 + */ + @JsonProperty("fanMinOnTime") + public Integer getFanMinOnTime() { + return this.fanMinOnTime; + } + + /** + * @return the occupiedSensorActive + */ + @JsonProperty("occupiedSensorActive") + public Boolean isOccupiedSensorActive() { + return this.occupiedSensorActive; + } + + /** + * @return the unoccupiedSensorActive + */ + @JsonProperty("unoccupiedSensorActive") + public Boolean isUnoccupiedSensorActive() { + return this.unoccupiedSensorActive; + } + + /** + * @return unsupported. Future feature + */ + @JsonProperty("drRampUpTemp") + public Temperature getDrRampUpTemp() { + return this.drRampUpTemp; + } + + /** + * @return unsupported. Future feature + */ + @JsonProperty("drRampUpTime") + public Integer getDrRampUpTime() { + return this.drRampUpTime; + } + + /** + * @return unique identifier set by the server to link one or more events and alerts together + */ + @JsonProperty("linkRef") + public String getLinkRef() { + return this.linkRef; + } + + /** + * @return used for display purposes to indicate what climate (if any) is being used for the hold + */ + @JsonProperty("holdClimateRef") + public String getHoldClimateRef() { + return this.holdClimateRef; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("type", this.type); + builder.append("name", this.name); + builder.append("running", this.running); + builder.append("startDate", this.startDate); + builder.append("startTime", this.startTime); + builder.append("endDate", this.endDate); + builder.append("endTime", this.endTime); + builder.append("isOccupied", this._isOccupied); + builder.append("isCoolOff", this._isCoolOff); + builder.append("isHeatOff", this._isHeatOff); + builder.append("coolHoldTemp", this.coolHoldTemp); + builder.append("heatHoldTemp", this.heatHoldTemp); + builder.append("fan", this.fan); + builder.append("vent", this.vent); + builder.append("ventilatorMinOnTime", this.ventilatorMinOnTime); + builder.append("isOptional", this._isOptional); + builder.append("isTemperatureRelative", this._isTemperatureRelative); + builder.append("coolRelativeTemp", this.coolRelativeTemp); + builder.append("heatRelativeTemp", this.heatRelativeTemp); + builder.append("isTemperatureAbsolute", this._isTemperatureAbsolute); + builder.append("dutyCyclePercentage", this.dutyCyclePercentage); + builder.append("fanMinOnTime", this.fanMinOnTime); + builder.append("occupiedSensorActive", this.occupiedSensorActive); + builder.append("unoccupiedSensorActive", this.unoccupiedSensorActive); + builder.append("drRampUpTemp", this.drRampUpTemp); + builder.append("drRampUpTime", this.drRampUpTime); + builder.append("linkRef", this.linkRef); + builder.append("holdClimateRef", this.holdClimateRef); + + return builder.toString(); + } + } + + /** + * The thermostat Program is a container for the {@link #schedule} and its {@link #climates}. + * + * See Core Concepts for details on how the program is structured. The {@link #schedule} property is a two + * dimensional array containing the climate names. + * + * @see Program + * @see Core Concepts + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Program extends AbstractMessagePart { + private List> schedule; + private List climates; + private String currentClimateRef; + + /** + * @return the schedule object defining the program schedule + */ + @JsonProperty("schedule") + public List> getSchedule() { + return this.schedule; + } + + /** + * @param schedule + * the schedule object defining the program schedule + */ + @JsonProperty("schedule") + public void setSchedule(List> schedule) { + this.schedule = schedule; + } + + /** + * @return the list of {@link Climate} objects defining all the climates in the program schedule + */ + @JsonProperty("climates") + public List getClimates() { + return this.climates; + } + + /** + * @param climates + * the list of {@link Climate} objects defining all the climates in the program schedule + */ + @JsonProperty("climates") + public void setClimates(List climates) { + this.climates = climates; + } + + /** + * @return the currently active climate, identified by its ClimateRef + */ + @JsonProperty("currentClimateRef") + public String getCurrentClimateRef() { + return this.currentClimateRef; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("schedule", this.schedule); + builder.append("climates", this.climates); + builder.append("currentClimateRef", this.currentClimateRef); + + return builder.toString(); + } + } + + /** + * A climate defines a thermostat settings template which is then applied to individual period cells of the + * schedule. The result is that if you modify the Climate, all schedule cells which reference that Climate will + * automatically be changed. + * + *

      + * When adding a Climate it is optional whether you reference the new Climate in the schedule cells in the same + * request or not. However, when deleting a Climate (by omitting that entire Climate object from the POST request) + * it can not be be deleted if it is still referenced in the schedule cells. + * + *

      + * There are three default Climates for each {@link Thermostat}, with possible climateRef values of + * "away", "home", and "sleep". There are two default Climates for the EMS thermostat, with possible + * climateRef values of "occupied" and "unoccupied". None of these defaults can be deleted and trying + * to do so will return an exception. The remaining fields can be modified. + * + *

      + * Climates may be modified (you can add, update or remove climates). However, it is important to note that the + * climateRef is required and read-only for an existing climate and cannot be changed. The + * {@link Climate#name} can be edited so long as it is unique. + * + *

      + * If the climateRef for an existing climate is not included in an API call it is assumed this is a net + * new climate. The climateRef must always be supplied for the default climates. + * + * @see Climate + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Climate extends AbstractMessagePart { + private String name; + private String climateRef; + private Boolean _isOccupied; + private Boolean _isOptimized; + private FanMode coolFan; + private FanMode heatFan; + private VentilatorMode vent; + private Integer ventilatorMinOnTime; + private String owner; + private String type; + private Integer colour; + private Temperature coolTemp; + private Temperature heatTemp; + + public Climate(@JsonProperty("name") String name) { + this.name = name; + } + + /** + * @return the unique climate name. The name may be changed without affecting the program integrity so long as + * uniqueness is maintained. + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @param name + * the unique climate name. The name may be changed without affecting the program integrity so long + * as uniqueness is maintained. + */ + @JsonProperty("name") + public void setName(String name) { + this.name = name; + } + + /** + * @return the unique climate identifier. Changing the identifier is not possible and it is generated on the + * server for each climate. If this value is not supplied a new climate will be created. For the default + * climates and existing user created climates the climateRef should be supplied - see note above. + */ + @JsonProperty("climateRef") + public String getClimateRef() { + return this.climateRef; + } + + /** + * @return a flag indicating whether the property is occupied by persons during this climate + */ + @JsonProperty("isOccupied") + public Boolean isOccupied() { + return this._isOccupied; + } + + /** + * @param isOccupied + * a flag indicating whether the property is occupied by persons during this climate + */ + @JsonProperty("isOccupied") + public void setIsOccupied(Boolean isOccupied) { + this._isOccupied = isOccupied; + } + + /** + * @return a flag indicating whether ecobee optimized climate settings are used by this climate + */ + @JsonProperty("isOptimized") + public Boolean isOptimized() { + return this._isOptimized; + } + + /** + * @param isOptimized + * a flag indicating whether ecobee optimized climate settings are used by this climate + */ + @JsonProperty("isOptimized") + public void setIsOptimized(Boolean isOptimized) { + this._isOptimized = isOptimized; + } + + /** + * @return the cooling fan mode. Default: on Values: auto, on + */ + @JsonProperty("coolFan") + public FanMode getCoolFan() { + return this.coolFan; + } + + /** + * @param coolFan + * the cooling fan mode. Default: on Values: auto, on + */ + @JsonProperty("coolFan") + public void setCoolFan(FanMode coolFan) { + this.coolFan = coolFan; + } + + /** + * @return the heating fan mode. Default: on Values: auto, on + */ + @JsonProperty("heatFan") + public FanMode getHeatFan() { + return this.heatFan; + } + + /** + * @param heatFan + * the heating fan mode. Default: on Values: auto, on + */ + @JsonProperty("heatFan") + public void setHeatFan(FanMode heatFan) { + this.heatFan = heatFan; + } + + /** + * @return the ventilator mode. Default: off Values: auto, minontime, on, off + */ + @JsonProperty("vent") + public VentilatorMode getVent() { + return this.vent; + } + + /** + * @param vent + * the ventilator mode. Default: off Values: auto, minontime, on, off + */ + @JsonProperty("vent") + public void setVent(VentilatorMode vent) { + this.vent = vent; + } + + /** + * @return the minimum time, in minutes, to run the ventilator each hour + */ + @JsonProperty("ventilatorMinOnTime") + public Integer getVentilatorMinOnTime() { + return this.ventilatorMinOnTime; + } + + /** + * @param ventilatorMinOnTime + * the minimum time, in minutes, to run the ventilator each hour + */ + @JsonProperty("ventilatorMinOnTime") + public void setVentilatorMinOnTime(Integer ventilatorMinOnTime) { + this.ventilatorMinOnTime = ventilatorMinOnTime; + } + + /** + * @return the climate owner. Default: system Values: adHoc, demandResponse, quickSave, sensorAction, + * switchOccupancy, system, template, user + */ + @JsonProperty("owner") + public String getOwner() { + return this.owner; + } + + /** + * @param owner + * the climate owner. Default: system Values: adHoc, demandResponse, quickSave, sensorAction, + * switchOccupancy, system, template, user + */ + @JsonProperty("owner") + public void setOwner(String owner) { + this.owner = owner; + } + + /** + * @return the type of climate. Default: program Values: calendarEvent, program + */ + @JsonProperty("type") + public String getType() { + return this.type; + } + + /** + * @param type + * the type of climate. Default: program Values: calendarEvent, program + */ + @JsonProperty("type") + public void setType(String type) { + this.type = type; + } + + /** + * @return the integer conversion of the HEX color value used to display this climate on the thermostat and on + * the web portal + */ + @JsonProperty("colour") + public Integer getColour() { + return this.colour; + } + + /** + * @param colour + * the integer conversion of the HEX color value used to display this climate on the thermostat and + * on the web portal + */ + @JsonProperty("colour") + public void setColour(Integer colour) { + this.colour = colour; + } + + /** + * @return the cool temperature for this climate + */ + @JsonProperty("coolTemp") + public Temperature getCoolTemp() { + return this.coolTemp; + } + + /** + * @param coolTemp + * the cool temperature for this climate + */ + @JsonProperty("coolTemp") + public void setCoolTemp(Temperature coolTemp) { + this.coolTemp = coolTemp; + } + + /** + * @return the heat temperature for this climate + */ + @JsonProperty("heatTemp") + public Temperature getHeatTemp() { + return this.heatTemp; + } + + /** + * @param heatTemp + * the heat temperature for this climate + */ + @JsonProperty("heatTemp") + public void setHeatTemp(Temperature heatTemp) { + this.heatTemp = heatTemp; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("name", this.name); + builder.append("climateRef", this.climateRef); + builder.append("isOccupied", this._isOccupied); + builder.append("isOptimized", this._isOptimized); + builder.append("coolFan", this.coolFan); + builder.append("heatFan", this.heatFan); + builder.append("vent", this.vent); + builder.append("ventilatorMinOnTime", this.ventilatorMinOnTime); + builder.append("owner", this.owner); + builder.append("type", this.type); + builder.append("colour", this.colour); + builder.append("coolTemp", this.coolTemp); + builder.append("heatTemp", this.heatTemp); + + return builder.toString(); + } + } + + /** + * The HouseDetails object contains the information about the house the thermostat is installed in. + * + * @see HouseDetails + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class HouseDetails extends AbstractMessagePart { + private String style; + private Integer size; + private Integer numberOfFloors; + private Integer numberOfRooms; + private Integer numberOfOccupants; + private Integer age; + + /** + * @return the style of house. Values: other, apartment, condominium, detached, loft, multiPlex, rowHouse, + * semiDetached, townhouse, and 0 for unknown + */ + @JsonProperty("style") + public String getStyle() { + return this.style; + } + + /** + * @param style + * the style of house. Values: other, apartment, condominium, detached, loft, multiPlex, rowHouse, + * semiDetached, townhouse, and 0 for unknown + */ + @JsonProperty("style") + public void setStyle(String style) { + this.style = style; + } + + /** + * @return the size of the house in square feet + */ + @JsonProperty("size") + public Integer getSize() { + return this.size; + } + + /** + * @param size + * the size of the house in square feet + */ + @JsonProperty("size") + public void setSize(Integer size) { + this.size = size; + } + + /** + * @return the number of floors or levels in the house + */ + @JsonProperty("numberOfFloors") + public Integer getNumberOfFloors() { + return this.numberOfFloors; + } + + /** + * @param numberOfFloors + * the numberOfFloors to set + */ + @JsonProperty("numberOfFloors") + public void setNumberOfFloors(Integer numberOfFloors) { + this.numberOfFloors = numberOfFloors; + } + + /** + * @return the number of rooms in the house + */ + @JsonProperty("numberOfRooms") + public Integer getNumberOfRooms() { + return this.numberOfRooms; + } + + /** + * @param numberOfRooms + * the number of rooms in the house + */ + @JsonProperty("numberOfRooms") + public void setNumberOfRooms(Integer numberOfRooms) { + this.numberOfRooms = numberOfRooms; + } + + /** + * @return the number of occupants living in the house + */ + @JsonProperty("numberOfOccupants") + public Integer getNumberOfOccupants() { + return this.numberOfOccupants; + } + + /** + * @param numberOfOccupants + * the number of occupants living in the house + */ + @JsonProperty("numberOfOccupants") + public void setNumberOfOccupants(Integer numberOfOccupants) { + this.numberOfOccupants = numberOfOccupants; + } + + /** + * @return the age of house in years + */ + @JsonProperty("age") + public Integer getAge() { + return this.age; + } + + /** + * @param age + * the age of house in years + */ + @JsonProperty("age") + public void setAge(Integer age) { + this.age = age; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("style", this.style); + builder.append("size", this.size); + builder.append("numberOfFloors", this.numberOfFloors); + builder.append("numberOfRooms", this.numberOfRooms); + builder.append("numberOfOccupants", this.numberOfOccupants); + builder.append("age", this.age); + + return builder.toString(); + } + } + + /** + * The OemCfg object contains information about the OEM specific thermostat. + * + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class ThermostatOemCfg extends AbstractMessagePart { + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + + return builder.toString(); + } + } + + /** + * The Thermostat NotificationSettings object is a container for the configuration of the possible alerts and + * reminders which can be generated by the Thermostat. + * + *

      + * The NotificationsSettings supports retrieval through a Thermostat GET call, setting the + * includeNotificationSettings to true in the {@link Selection}. + * + *

      + * The NotificationsSettings object can also be updated using the Thermostat POST method. When POSTing updates to + * this object please take a note of the required fields, allowed values, and notes about the email address below. + * + *

      + * The type corresponds to the {@link Alert#notificationType} returned when alerts are included in the selection. + * See {@link Alert} for more information. When the type is anything other than alert its configuration will be + * listed here as part of the NotificationSettings. + * + * @see NotificationSettings + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class NotificationSettings extends AbstractMessagePart { + private List emailAddresses; + private Boolean emailNotificationsEnabled; + private List equipment; + private List general; + private List limit; + + /** + * @return the list of email addresses alerts and reminders will be sent to. + */ + @JsonProperty("emailAddresses") + public List getEmailAddresses() { + return this.emailAddresses; + } + + /** + * @param emailAddresses + * the list of email addresses alerts and reminders will be sent to. The full list of email addresses + * must be sent in any update request. If any are missing from that list they will be deleted. If an + * empty list is sent, any email addresses will be deleted. + */ + @JsonProperty("emailAddresses") + public void setEmailAddresses(List emailAddresses) { + this.emailAddresses = emailAddresses; + } + + /** + * @return boolean value representing whether or not alerts and reminders will be sent to the email addresses + * listed above when triggered + */ + @JsonProperty("emailNotificationsEnabled") + public Boolean getEmailNotificationsEnabled() { + return this.emailNotificationsEnabled; + } + + /** + * @param emailNotificationsEnabled + * boolean value representing whether or not alerts and reminders will be sent to the email addresses + * listed above when triggered + */ + @JsonProperty("emailNotificationsEnabled") + public void setEmailNotificationsEnabled(Boolean emailNotificationsEnabled) { + this.emailNotificationsEnabled = emailNotificationsEnabled; + } + + /** + * @return the list of equipment specific alert and reminder settings + */ + @JsonProperty("equipment") + public List getEquipment() { + return this.equipment; + } + + /** + * @param equipment + * the list of equipment specific alert and reminder settings + */ + @JsonProperty("equipment") + public void setEquipment(List equipment) { + this.equipment = equipment; + } + + /** + * @return the list of general alert and reminder settings + */ + @JsonProperty("general") + public List getGeneral() { + return this.general; + } + + /** + * @param general + * the list of general alert and reminder settings + */ + @JsonProperty("general") + public void setGeneral(List general) { + this.general = general; + } + + /** + * @return the list of limit specific alert and reminder settings + */ + @JsonProperty("limit") + public List getLimit() { + return this.limit; + } + + /** + * @param limit + * the list of limit specific alert and reminder settings + */ + @JsonProperty("limit") + public void setLimit(List limit) { + this.limit = limit; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("emailAddresses", this.emailAddresses); + builder.append("emailNotificationsEnabled", this.emailNotificationsEnabled); + builder.append("equipment", this.equipment); + builder.append("general", this.general); + builder.append("limit", this.limit); + + return builder.toString(); + } + } + + /** + * The EquipmentSetting object represents the alert/reminder type which is associated with and dependent upon + * specific equipment controlled by the Thermostat. It is used when getting/setting the Thermostat + * NotificationSettings object. + * + *

      + * Note: Only the notification settings for the equipment/devices currently controlled by the Thermostat are + * returned during GET request, and only those same settings can be updated using the POST request. + * + *

      + * The type corresponds to the {@link Alert#notificationType} returned when alerts are also included in the + * selection. See {@link Alert} for more information. + * + * @see EquipmentSetting + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class EquipmentSetting extends AbstractMessagePart { + private String filterLastChanged; // TODO Jackson 1.9 date handling (@watou) + private Integer filterLife; + private String filterLifeUnits; + private String remindMeDate; // TODO Jackson 1.9 date handling (@watou) + private Boolean enabled; + private String type; + private Boolean remindTechnician; + + public EquipmentSetting(@JsonProperty("type") String type) { + this.type = type; + } + + /** + * @return the date the filter was last changed for this equipment. String format: YYYY-MM-DD + */ + @JsonProperty("filterLastChanged") + public String getFilterLastChanged() { + return this.filterLastChanged; + } + + /** + * @param filterLastChanged + * the date the filter was last changed for this equipment. String format: YYYY-MM-DD + */ + @JsonProperty("filterLastChanged") + public void setFilterLastChanged(String filterLastChanged) { + this.filterLastChanged = filterLastChanged; + } + + /** + * @return the value representing the life of the filter. This value is expressed in month or hour, which is + * specified in the the {@link #filterLifeUnits} property. + */ + @JsonProperty("filterLife") + public Integer getFilterLife() { + return this.filterLife; + } + + /** + * @param filterLife + * the value representing the life of the filter. This value is expressed in month or hour, which is + * specified in the the {@link #filterLifeUnits} property. + */ + @JsonProperty("filterLife") + public void setFilterLife(Integer filterLife) { + this.filterLife = filterLife; + } + + /** + * @return the units the {@link #filterLife} field is measured in. Possible values are: month, hour. month has a + * range of 1 - 12. hour has a range of 100 - 1000. + */ + @JsonProperty("filterLifeUnits") + public String getFilterLifeUnits() { + return this.filterLifeUnits; + } + + /** + * @param filterLifeUnits + * the units the {@link #filterLife} field is measured in. Possible values are: month, hour. month + * has a range of 1 - 12. hour has a range of 100 - 1000. + */ + @JsonProperty("filterLifeUnits") + public void setFilterLifeUnits(String filterLifeUnits) { + this.filterLifeUnits = filterLifeUnits; + } + + /** + * @return the date the reminder will be triggered. This is a read-only field and cannot be modified through the + * API. The value is calculated and set by the thermostat. + */ + @JsonProperty("remindMeDate") + public String getRemindMeDate() { + return this.remindMeDate; + } + + /** + * @return boolean value representing whether or not alerts/reminders are enabled for this notification type or + * not + */ + @JsonProperty("enabled") + public Boolean isEnabled() { + return this.enabled; + } + + /** + * @param enabled + * boolean value representing whether or not alerts/reminders are enabled for this notification type + * or not + */ + @JsonProperty("enabled") + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + /** + * @return boolean value representing whether or not alerts/reminders should be sent to the + * technician/contractor associated with the thermostat + */ + @JsonProperty("remindTechnician") + public Boolean getRemindTechnician() { + return this.remindTechnician; + } + + /** + * @param remindTechnician + * boolean value representing whether or not alerts/reminders should be sent to the + * technician/contractor associated with the thermostat. + */ + @JsonProperty("remindTechnician") + public void setRemindTechnician(Boolean remindTechnician) { + this.remindTechnician = remindTechnician; + } + + /** + * @return the type of notification. Possible values are: hvac, furnaceFilter, humidifierFilter, + * dehumidifierFilter, ventilator, ac, airFilter, airCleaner, uvLamp + */ + @JsonProperty("type") + public String getType() { + return this.type; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("filterLastChanged", this.filterLastChanged); + builder.append("filterLife", this.filterLife); + builder.append("filterLifeUnits", this.filterLifeUnits); + builder.append("remindMeDate", this.remindMeDate); + builder.append("enabled", this.enabled); + builder.append("type", this.type); + builder.append("remindTechnician", this.remindTechnician); + + return builder.toString(); + } + } + + /** + * The GeneralSetting object represent the General alert/reminder type. It is used when getting/setting the + * Thermostat {@link NotificationSettings} object. + * + *

      + * The type corresponds to the {@link Alert#notificationType} returned when alerts are included in the + * selection. See {@link Alert} for more information. + * + * @see GeneralSetting + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class GeneralSetting extends AbstractMessagePart { + private Boolean enabled; + private String type; + private Boolean remindTechnician; + + /** + * @param type + * the type of notification. Possible values are: temp + */ + public GeneralSetting(@JsonProperty("type") String type) { + this.type = type; + } + + /** + * @return boolean value representing whether or not alerts/reminders are enabled for this notification type or + * not + */ + @JsonProperty("enabled") + public Boolean isEnabled() { + return this.enabled; + } + + /** + * @param enabled + * boolean value representing whether or not alerts/reminders are enabled for this notification type + * or not + */ + @JsonProperty("enabled") + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + /** + * @return boolean value representing whether or not alerts/reminders should be sent to the + * technician/contractor associated with the thermostat + */ + @JsonProperty("remindTechnician") + public Boolean getRemindTechnician() { + return this.remindTechnician; + } + + /** + * @param remindTechnician + * boolean value representing whether or not alerts/reminders should be sent to the + * technician/contractor associated with the thermostat + */ + @JsonProperty("remindTechnician") + public void setRemindTechnician(Boolean remindTechnician) { + this.remindTechnician = remindTechnician; + } + + /** + * @return the type of notification. Possible values are: temp + */ + @JsonProperty("type") + public String getType() { + return this.type; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("enabled", this.enabled); + builder.append("type", this.type); + builder.append("remindTechnician", this.remindTechnician); + + return builder.toString(); + } + } + + /** + * The LimitSetting object represents the alert/reminder type which is associated specific values, such as highHeat + * or lowHumidity. It is used when getting/setting the Thermostat NotificationSettings object. + * + * The type corresponds to the {@link Alert#notificationType} returned when alerts are also included in the + * selection. See {@link Alert} for more information. + * + * @see LimitSetting + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class LimitSetting extends AbstractMessagePart { + private Integer limit; + private Boolean enabled; + private String type; + private Boolean remindTechnician; + + /** + * @param type + * the type of notification. Possible values are: lowTemp, highTemp, lowHumidity, highHumidity, + * auxHeat, auxOutdoor + */ + public LimitSetting(@JsonProperty("type") String type) { + this.type = type; + } + + /** + * @return the value of the limit to set. For temperatures the value is expressed as degrees Fahrenheit, + * multipled by 10. For humidity values are expressed as a percentage from 5 to 95. See here for more + * information. + */ + @JsonProperty("limit") + public Integer getLimit() { + return this.limit; + } + + /** + * @param limit + * the value of the limit to set. For temperatures the value is expressed as degrees Fahrenheit, + * multipled by 10. For humidity values are expressed as a percentage from 5 to 95. See here for more + * information. + */ + @JsonProperty("limit") + public void setLimit(Integer limit) { + this.limit = limit; + } + + /** + * @return boolean value representing whether or not alerts/reminders are enabled for this notification type or + * not + */ + @JsonProperty("enabled") + public Boolean isEnabled() { + return this.enabled; + } + + /** + * @param enabled + * boolean value representing whether or not alerts/reminders are enabled for this notification type + * or not + */ + @JsonProperty("enabled") + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + /** + * @return boolean value representing whether or not alerts/reminders should be sent to the + * technician/contractor associated with the thermostat + */ + @JsonProperty("remindTechnician") + public Boolean getRemindTechnician() { + return this.remindTechnician; + } + + /** + * @param remindTechnician + * boolean value representing whether or not alerts/reminders should be sent to the + * technician/contractor associated with the thermostat + */ + @JsonProperty("remindTechnician") + public void setRemindTechnician(Boolean remindTechnician) { + this.remindTechnician = remindTechnician; + } + + /** + * @return the type of notification. Possible values are: lowTemp, highTemp, lowHumidity, highHumidity, auxHeat, + * auxOutdoor + */ + @JsonProperty("type") + public String getType() { + return this.type; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("limit", this.limit); + builder.append("enabled", this.enabled); + builder.append("type", this.type); + builder.append("remindTechnician", this.remindTechnician); + + return builder.toString(); + } + } + + /** + * The ThermostatPrivacy object containing the privacy settings for the Thermostat. Note: access to this object is + * restricted to callers with implicit authentication. + * + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class ThermostatPrivacy extends AbstractMessagePart { + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + + return builder.toString(); + } + } + + /** + * The Version object contains version information about the thermostat. + * + * @see Version + * @author John Cocula + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Version extends AbstractMessagePart { + private String thermostatFirmwareVersion; + + /** + * @return the thermostat firmware version number + */ + @JsonProperty("thermostatFirmwareVersion") + public String getThermostatFirmwareVersion() { + return this.thermostatFirmwareVersion; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("thermostatFirmwareVersion", this.thermostatFirmwareVersion); + + return builder.toString(); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatRequest.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatRequest.java new file mode 100644 index 00000000000..0ed7cb6f79a --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatRequest.java @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import static org.openhab.io.net.http.HttpUtil.executeUrl; + +import java.util.Properties; + +import org.apache.commons.httpclient.util.URIUtil; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnore; +import org.codehaus.jackson.annotate.JsonProperty; +import org.openhab.binding.ecobee.internal.EcobeeException; + +/** + * Queries the Ecobee API for thermostats. + * + * @author John Cocula + * @since 1.7.0 + * @see GET + * Thermostats + */ +public class ThermostatRequest extends AbstractRequest { + + private static final String RESOURCE_URL = API_BASE_URL + "1/thermostat"; + + @JsonIgnore + private final String accessToken; + + @JsonProperty("selection") + private final Selection selection; + + @JsonProperty("page") + private final Page page; + + /** + * Creates a request for the measurements of a device or module. + * + * If you don't specify a moduleId you will retrieve the device's measurements. If you do specify a moduleId you + * will retrieve the module's measurements. + * + * @param accessToken + * @param selection + * @param page + * optional, may be null + */ + public ThermostatRequest(final String accessToken, final Selection selection, final Page page) { + assert accessToken != null : "accessToken must not be null!"; + assert selection != null : "selection must not be null!"; + + this.accessToken = accessToken; + this.selection = selection; + this.page = page; + } + + @Override + public ThermostatResponse execute() { + final String url = buildQueryString(); + String json = null; + + try { + json = executeQuery(url); + + final ThermostatResponse response = JSON.readValue(json, ThermostatResponse.class); + + return response; + } catch (final Exception e) { + throw newException("Could not get thermostats.", e, url, json); + } + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("accessToken", this.accessToken); + builder.append("selection", this.selection); + if (this.page != null) { + builder.append("page", this.page); + } + + return builder.toString(); + } + + protected String executeQuery(final String url) { + Properties headers = new Properties(); + headers.putAll(HTTP_HEADERS); + headers.put("Authorization", "Bearer " + this.accessToken); + return executeUrl(HTTP_GET, url, headers, null, null, HTTP_REQUEST_TIMEOUT); + } + + private String buildQueryString() { + final StringBuilder urlBuilder = new StringBuilder(RESOURCE_URL); + + try { + urlBuilder.append("?json="); + urlBuilder.append(JSON.writeValueAsString(this)); + return URIUtil.encodeQuery(urlBuilder.toString()); + } catch (final Exception e) { + throw new EcobeeException(e); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatResponse.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatResponse.java new file mode 100644 index 00000000000..f7ee7025582 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatResponse.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.util.List; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * Retrieves a selection of thermostat data for one or more thermostats. The type of data retrieved is determined by the + * {@link Selection} object in the request. The include* properties of the selection retrieve specific + * portions of the thermostat. + * + *

      + * When retrieving thermostats, request only the parts of the thermostat you require as the whole thermostat with + * everything can be quite large and generally unnecessary. + * + * @see GET + * Thermostats + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ThermostatResponse extends ApiResponse { + private Page page; + private List thermostatList; + + /** + * @return the page information for the response + */ + @JsonProperty("page") + public Page getPage() { + return this.page; + } + + /** + * @return the list of thermostats returned by the request + */ + @JsonProperty("thermostatList") + public List getThermostatList() { + return this.thermostatList; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("page", this.page); + builder.append("thermostatList", this.thermostatList); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatSummaryRequest.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatSummaryRequest.java new file mode 100644 index 00000000000..6cda3f1858f --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatSummaryRequest.java @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import static org.openhab.io.net.http.HttpUtil.executeUrl; + +import java.util.Properties; + +import org.apache.commons.httpclient.util.URIUtil; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnore; +import org.codehaus.jackson.annotate.JsonProperty; +import org.openhab.binding.ecobee.internal.EcobeeException; + +/** + * This request retrieves a list of thermostat configuration and state revisions. This request is a light-weight polling + * method which will only return the revision numbers for the significant portions of the thermostat data. It is the + * responsibility of the caller to store these revisions for future determination whether changes occurred at the next + * poll interval. + * + *

      + * The intent is to permit the caller to determine whether a thermostat has changed since the last poll. Retrieval of a + * whole thermostat including runtime data is expensive and impractical for large amounts of thermostat such as a + * management set hierarchy, especially if nothing has changed. By storing the retrieved revisions, the caller may + * determine whether to get a thermostat and which sections of the thermostat should be retrieved. + * + * @see GET + * Thermostat Summary (Polling) + * @author John Cocula + * @since 1.7.0 + */ +public class ThermostatSummaryRequest extends AbstractRequest { + + private static final String RESOURCE_URL = API_BASE_URL + "1/thermostatSummary"; + + @JsonIgnore + private final String accessToken; + + @JsonProperty("selection") + private final Selection selection; + + /** + * Creates a request for a summary of thermostats as specified in the selection. + * + * @param accessToken + * the access token that permits this query + * @param selection + * a {@link Selection} object that specifies which thermostats to return in the response. + */ + public ThermostatSummaryRequest(final String accessToken, final Selection selection) { + assert accessToken != null : "accessToken must not be null!"; + assert selection != null : "selection must not be null!"; + + this.accessToken = accessToken; + this.selection = selection; + } + + @Override + public ThermostatSummaryResponse execute() { + final String url = buildQueryString(); + String json = null; + + try { + json = executeQuery(url); + + final ThermostatSummaryResponse response = JSON.readValue(json, ThermostatSummaryResponse.class); + + return response; + } catch (final Exception e) { + throw newException("Could not get thermostat summary.", e, url, json); + } + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("accessToken", this.accessToken); + builder.append("selection", this.selection); + + return builder.toString(); + } + + protected String executeQuery(final String url) { + Properties headers = new Properties(); + headers.putAll(HTTP_HEADERS); + headers.put("Authorization", "Bearer " + this.accessToken); + return executeUrl(HTTP_GET, url, headers, null, null, HTTP_REQUEST_TIMEOUT); + } + + private String buildQueryString() { + final StringBuilder urlBuilder = new StringBuilder(RESOURCE_URL); + + try { + urlBuilder.append("?json="); + urlBuilder.append(JSON.writeValueAsString(this)); + return URIUtil.encodeQuery(urlBuilder.toString()); + } catch (final Exception e) { + throw new EcobeeException(e); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatSummaryResponse.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatSummaryResponse.java new file mode 100644 index 00000000000..1cb02374ee3 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/ThermostatSummaryResponse.java @@ -0,0 +1,450 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * This response contains a list of thermostat configuration and state revisions. This request is a light-weight polling + * method which will only return the revision numbers for the significant portions of the thermostat data. It is the + * responsibility of the caller to store these revisions for future determination whether changes occurred at the next + * poll interval. + * + *

      + * The intent is to permit the caller to determine whether a thermostat has changed since the last poll. Retrieval of a + * whole thermostat including runtime data is expensive and impractical for large amounts of thermostat such as a + * management set hierarchy, especially if nothing has changed. By storing the retrieved revisions, the caller may + * determine whether to get a thermostat and which sections of the thermostat should be retrieved. + * + * @see GET + * Thermostat Summary + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ThermostatSummaryResponse extends ApiResponse { + private List revisionList; + private List statusList; + + /** + * Objects of this class, when compared to previously returned instances, allow you to determine if changes have + * occurred in the thermostat's program, HVAC mode, settings, configuration, alerts, telemetry, or running state of + * connected equipment, and if the thermostat is currently connected to ecobee's servers. + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Revision extends AbstractMessagePart { + + private String thermostatIdentifier; + private String thermostatName; + private boolean connected; + private String thermostatRevision; + private String alertsRevision; + private String runtimeRevision; + private String internalRevision; + + /** + * Construct a Revision object. + * + * @param csv + * a colon separated list of values (in order): + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      ValueTypeDescription
      + * Thermostat IdentifierStringThe thermostat identifier.
      Thermostat NameStringThe thermostat name, otherwise an empty field if one is not set.
      ConnectedBooleanWhether the thermostat is currently connected to the ecobee servers.
      Thermostat RevisionStringCurrent thermostat revision. This revision is incremented whenever the thermostat program, + * hvac mode, settings or configuration change.
      Alerts RevisionStringCurrent revision of the thermostat alerts. This revision is incremented whenever a new alert + * is issued or an alert is modified (acknowledged or deferred).
      Runtime RevisionStringThe current revision of the thermostat runtime settings. This revision is incremented whenever + * the thermostat transmits a new status message, or updates the equipment state. The shortest + * interval this revision may change is 3 minutes.
      Interval RevisionStringThe current revision of the thermostat interval runtime settings. This revision is incremented + * whenever the thermostat transmits a new status message. The thermostat does this on a 15 minute + * interval.
      + * + *

      + * It is the responsibility of the caller to ensure that the sizes of the revisionList and statusList + * are parsed in a flexible manner, as additional revisions and statuses will be added with new + * features and functionality. + */ + @JsonCreator + Revision(final String csv) { + String[] fields = csv.split(":"); + + assert fields.length >= 7 : "unable to parse revision"; + + thermostatIdentifier = fields[0]; + thermostatName = fields[1]; + connected = fields[2].equals("true"); + thermostatRevision = fields[3]; + alertsRevision = fields[4]; + runtimeRevision = fields[5]; + internalRevision = fields[6]; + } + + /** + * @return the thermostat identifier + */ + public String getThermostatIdentifier() { + return this.thermostatIdentifier; + } + + /** + * @return the thermostat name, otherwise an empty string if one is not set. + */ + public String getThermostatName() { + return this.thermostatName; + } + + /** + * Return true if the thermostat is currently connected to the ecobee servers. + * + * @return whether the thermostat is currently connected to the ecobee servers. + */ + public boolean isConnected() { + return this.connected; + } + + /* + * Revisions are UTC date/time stamps in the format: YYMMDDHHMMSS. However, due to possible time drift between + * the API consumer, the server and thermostat, it is recommended that they are treated as a string, rather than + * as a date/time stamp. The recommended method to test for revision changes is to simply do a string comparison + * on the previous and current revision. If the strings match, nothing changed. Otherwise request the thermostat + * including the relevant information which changed. + */ + + /** + * Return true if the thermostat program, HVAC mode, settings or configuration has changed since + * the some previous revision. + * + * @param previous + * the previous status for this thermostat. May be null, in which case this method + * returns true. + * @return true if the thermostat program, HVAC mode, settings or configuration has changed since + * the given revision. + * @throws IllegalArgumentException + * if you are attempting to compare different thermostats. + */ + public boolean hasThermostatChanged(final Revision previous) { + if (previous == null) + return true; + if (!this.thermostatIdentifier.equals(previous.thermostatIdentifier)) + throw new IllegalArgumentException("comparing different thermostats."); + else + return !this.thermostatRevision.equals(previous.thermostatRevision); + } + + /** + * Return true if a new alert has been issued or an alert has been modified (acknowledged or + * deferred) since some previous Revision. + * + * @param previous + * the previous revision for this thermostat. May be null, in which case this method + * returns true. + * @return true if a new alert has been issued or an alert has been modified (acknowledged or + * deferred) since the given revision. + * @throws IllegalArgumentException + * if you are attempting to compare different thermostats. + */ + public boolean hasAlertsChanged(final Revision previous) { + if (previous == null) + return true; + if (!this.thermostatIdentifier.equals(previous.thermostatIdentifier)) + throw new IllegalArgumentException("comparing different thermostats."); + else + return !this.alertsRevision.equals(previous.alertsRevision); + } + + /** + * Return true if the thermostat has transmitted a new status message, or has updated the equipment + * state since some previous revision. The shortest interval this revision may change is 3 minutes. + * + *

      + * {@link #hasTransmittedNewStatus(ThermostatSummaryResponse.Revision)} differs from this method in that this + * method returns true when any thermostat runtime information has changed, whereas + * {@link #hasTransmittedNewStatus(ThermostatSummaryResponse.Revision)} only returns true when the + * thermostat has transmitted its 15 minute interval status message to the server. This method returns + * true when the thermostat has sent the interval status message every 15 minutes as well as + * whenever the equipment state changes on the thermostat, and it has transmitted that information. The + * equipment message can come at a frequency of 3 minutes. When expecting only updates to the thermostat + * telemetry data, use {@link #hasTransmittedNewStatus(ThermostatSummaryResponse.Revision)}. + * + * @param previous + * the previous revision for this thermostat. May be null, in which case this method + * returns true. + * @return true if the thermostat has transmitted a new status message, or has updated the + * equipment state since some previous Revision. The shortest interval this revision may change is 3 + * minutes. + * @throws IllegalArgumentException + * if you are attempting to compare different thermostats. + * @see #hasTransmittedNewStatus(ThermostatSummaryResponse.Revision) + */ + public boolean hasRuntimeChanged(final Revision previous) { + if (previous == null) + return true; + if (!this.thermostatIdentifier.equals(previous.thermostatIdentifier)) + throw new IllegalArgumentException("comparing different thermostats."); + else + return !this.runtimeRevision.equals(previous.runtimeRevision); + } + + /** + * Return true if the thermostat has transmitted a new status message since some previous Revision. + * The thermostat does this on a 15 minute interval. + * + *

      + * This method differs from {@link #hasRuntimeChanged(ThermostatSummaryResponse.Revision)} in that + * {@link #hasRuntimeChanged(ThermostatSummaryResponse.Revision)} returns true when any thermostat + * runtime information has changed, whereas This method is only true when the thermostat has + * transmitted its 15-minute interval status message to the server. + * + * {@link #hasRuntimeChanged(ThermostatSummaryResponse.Revision)} returns true when the thermostat + * has transmitted its interval status message every 15 mins as well as whenever the equipment state changes on + * and it has transmitted that information. The equipment message can come at a frequency of 3 minutes. When + * expecting only updates to the thermostat telemetry data, use this method to detect if changes have occurred. + * + * @param previous + * the previous revision for this thermostat. May be null, in which case this method + * returns true. + * @return true if the thermostat has transmitted a new status message since some previous + * revision. The thermostat does this on a 15 minute interval. + * @throws IllegalArgumentException + * if you are attempting to compare different thermostats. + * @throws IllegalArgumentException + * if you are attempting to compare different thermostats. + * @see #hasRuntimeChanged(ThermostatSummaryResponse.Revision) + */ + public boolean hasTransmittedNewStatus(final Revision previous) { + if (previous == null) + return true; + if (!this.thermostatIdentifier.equals(previous.thermostatIdentifier)) + throw new IllegalArgumentException("comparing different thermostats."); + else + return !this.internalRevision.equals(previous.internalRevision); + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("thermostatIdentifier", this.thermostatIdentifier); + builder.append("thermostatName", this.thermostatName); + builder.append("connected", this.connected ? "true" : "false"); + builder.append("thermostatRevision", this.thermostatRevision); + builder.append("alertsRevision", this.alertsRevision); + builder.append("runtimeRevision", this.runtimeRevision); + builder.append("internalRevision", this.internalRevision); + + return builder.toString(); + } + } + + /** + * A class version of the data returned in each status in the statusList. + * + *

      + * The Thermostat Summary can also return the status of the equipment controlled by the Thermostat. The + * {@link #getRunningEquipment()} lists all equipment which is currently running. If a specific equipment type is + * not present in the set then it is not running, or "OFF". To retrieve this data the {@link Selection} object + * specified in the request should have the {@link Selection#setIncludeEquipmentStatus(Boolean)} set to + * true. The default is false. + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Status extends AbstractMessagePart { + + private String thermostatIdentifier; + private Set runningEquipment; + + /** + * Construct a Status object. + * + * @param csv + * contains a colon separated list of values (in order): + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      ValueTypeDescription
      Thermostat IdentifierStringThe thermostat identifier.
      Equipment StatusStringIf no equipment is currently running no data is returned. Possible values are: heatPump, + * heatPump2, heatPump3, compCool1, compCool2, auxHeat1, auxHeat2, auxHeat3, fan, humidifier, + * dehumidifier, ventilator, economizer, compHotWater, auxHotWater.
      + * + */ + @JsonCreator + Status(final String csv) { + String[] fields = csv.split(":"); + + assert fields.length >= 1 : "unable to parse status"; + + thermostatIdentifier = fields[0]; + + runningEquipment = new HashSet(); + + if (fields.length >= 2) { + for (String equip : fields[1].split(",")) { + if (equip.length() == 0) + continue; + runningEquipment.add(equip); + } + } + } + + /** + * Return true if no equipment is currently running. + * + * @return true if no equipment is currently running. + */ + public boolean isIdle() { + return runningEquipment.isEmpty(); + } + + /** + * Return true if any heating equipment is currently running. + * + * @return true if any heating equipment is running. + */ + public boolean isHeating() { + return runningEquipment.contains("heatPump") || runningEquipment.contains("heatPump2") + || runningEquipment.contains("heatPump3") || runningEquipment.contains("auxHeat1") + || runningEquipment.contains("auxHeat2") || runningEquipment.contains("auxHeat3"); + } + + /** + * Return true if any cooling equipment is currently running. + * + * @return true if any cooling equipment is currently running. + */ + public boolean isCooling() { + return runningEquipment.contains("compCool1") || runningEquipment.contains("compCool2"); + } + + /** + * Return true if the named equipment is running. + * + * @param equipment + * the name of the equipment to check. Possible names are: heatPump, heatPump2, heatPump3, compCool1, + * compCool2, auxHeat1, auxHeat2, auxHeat3, fan, humidifier, dehumidifier, ventilator, economizer, + * compHotWater, auxHotWater. + * @return true if the named equipment is running + */ + public boolean isRunning(final String equipment) { + return runningEquipment.contains(equipment); + } + + /** + * @return the thermostat identifier + */ + public String getThermostatIdentifier() { + return this.thermostatIdentifier; + } + + /** + * @return A set of the running equipment. Possible contents are: heatPump, heatPump2, heatPump3, compCool1, + * compCool2, auxHeat1, auxHeat2, auxHeat3, fan, humidifier, dehumidifier, ventilator, economizer, + * compHotWater, auxHotWater. + */ + public Set getRunningEquipment() { + return this.runningEquipment; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("thermostatIdentifier", this.thermostatIdentifier); + builder.append("runningEquipment", this.runningEquipment); + + return builder.toString(); + } + } + + /** + * @return the list of CSV revision values + */ + @JsonProperty("revisionList") + public List getRevisionList() { + return this.revisionList; + } + + /** + * @return the list of CSV status values + * + * The statusList is only returned when the request {@link Selection} object has the + * {@link Selection#setIncludeEquipmentStatus(Boolean)} called with true. The default is + * false. + */ + @JsonProperty("statusList") + public List getStatusList() { + return this.statusList; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("revisionList", this.revisionList); + builder.append("statusList", this.statusList); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/TokenRequest.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/TokenRequest.java new file mode 100644 index 00000000000..a3bc03ec096 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/TokenRequest.java @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import static org.openhab.io.net.http.HttpUtil.executeUrl; + +import org.apache.commons.httpclient.util.URIUtil; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.openhab.binding.ecobee.internal.EcobeeException; + +/** + * The application will need to request access and refresh tokens once the user has authorized the application within + * the ecobee Web Portal. + * + * @see TokenResponse + * @see Requesting + * Tokens (Access & Refresh) + * @author John Cocula + * @since 1.7.0 + */ +public class TokenRequest extends AbstractRequest { + + private static final String RESOURCE_URL = API_BASE_URL + "token"; + + private String authToken; + private String appKey; + + /** + * Construct a token request. + * + * @param authToken + * the authorization token you were issued + * @param appKey + * the application key for your application (this binding) + */ + public TokenRequest(final String authToken, final String appKey) { + assert authToken != null : "authToken must not be null!"; + assert appKey != null : "appKey must not be null!"; + + this.authToken = authToken; + this.appKey = appKey; + } + + @Override + public TokenResponse execute() { + final String url = buildQueryString(); + String json = null; + + try { + json = executeQuery(url); + + final TokenResponse response = JSON.readValue(json, TokenResponse.class); + + return response; + } catch (final Exception e) { + throw newException("Could not get auth token.", e, url, json); + } + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("authToken", this.authToken); + builder.append("appKey", this.appKey); + return builder.toString(); + } + + protected String executeQuery(final String url) { + return executeUrl(HTTP_POST, url, HTTP_HEADERS, null, null, HTTP_REQUEST_TIMEOUT); + } + + private String buildQueryString() { + final StringBuilder urlBuilder = new StringBuilder(RESOURCE_URL); + + try { + urlBuilder.append("?grant_type=ecobeePin"); + urlBuilder.append("&code="); + urlBuilder.append(authToken); + urlBuilder.append("&client_id="); + urlBuilder.append(appKey); + return URIUtil.encodeQuery(urlBuilder.toString()); + } catch (final Exception e) { + throw new EcobeeException(e); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/TokenResponse.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/TokenResponse.java new file mode 100644 index 00000000000..1b4749ace35 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/TokenResponse.java @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * @see TokenRequest + * @see RefreshTokenRequest + * @see PIN + * Authorization Strategy + * @see Refreshing Your + * Tokens + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class TokenResponse extends AbstractAuthResponse { + + @JsonProperty("access_token") + private String accessToken; + @JsonProperty("token_type") + private String tokenType; + @JsonProperty("expires_in") + private Integer expiresIn; + @JsonProperty("refresh_token") + private String refreshToken; + @JsonProperty("scope") + private String scope; + + /** + * @return the accessToken + */ + @JsonProperty("access_token") + public String getAccessToken() { + return this.accessToken; + } + + /** + * @return the tokenType + */ + @JsonProperty("token_type") + public String getTokenType() { + return this.tokenType; + } + + /** + * @return the expiresIn + */ + @JsonProperty("expires_in") + public Integer getExpiresIn() { + return this.expiresIn; + } + + /** + * @return the refreshToken + */ + @JsonProperty("refresh_token") + public String getRefreshToken() { + return this.refreshToken; + } + + /** + * @return the scope + */ + @JsonProperty("scope") + public String getScope() { + return this.scope; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("accessToken", this.accessToken); + builder.append("tokenType", this.tokenType); + builder.append("expiresIn", this.expiresIn); + builder.append("refreshToken", this.refreshToken); + builder.append("scope", this.scope); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/UpdateThermostatRequest.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/UpdateThermostatRequest.java new file mode 100644 index 00000000000..6e5e27d8ec3 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/UpdateThermostatRequest.java @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import static org.openhab.io.net.http.HttpUtil.executeUrl; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.List; +import java.util.Properties; + +import org.apache.commons.httpclient.util.URIUtil; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.annotate.JsonIgnore; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.map.JsonMappingException; +import org.openhab.binding.ecobee.internal.EcobeeException; + +/** + * Updates thermostats to the Ecobee API. + * + * @author John Cocula + * @since 1.7.0 + * @see GET + * Thermostats + */ +public class UpdateThermostatRequest extends AbstractRequest { + + private static final String RESOURCE_URL = API_BASE_URL + "1/thermostat"; + + @JsonIgnore + private final String accessToken; + + @JsonProperty("selection") + private final Selection selection; + + @JsonProperty("functions") + private final List functions; + + @JsonProperty("thermostat") + private final Thermostat thermostat; + + /** + * Creates a request for the measurements of a device or module. + * + * If you don't specify a moduleId you will retrieve the device's measurements. If you do specify a moduleId you + * will retrieve the module's measurements. + * + * @param accessToken + * the access token that permits this API call + * @param selection + * which thermostats will be updated + * @param functions + * optional, a list of functions to send + * @param thermostat + * optional, a thermostat that has writeable properties specified + */ + public UpdateThermostatRequest(final String accessToken, final Selection selection, + final List functions, final Thermostat thermostat) { + assert accessToken != null : "accessToken must not be null!"; + assert selection != null : "selection must not be null!"; + + this.accessToken = accessToken; + this.selection = selection; + this.functions = functions; + this.thermostat = thermostat; + } + + @Override + public ApiResponse execute() { + final String url = buildQueryString(); + String json = null; + + try { + json = executeQuery(url); + + final ApiResponse response = JSON.readValue(json, ApiResponse.class); + + return response; + } catch (final Exception e) { + throw newException("Could not get thermostats.", e, url, json); + } + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("accessToken", this.accessToken); + builder.append("selection", this.selection); + if (this.functions != null) { + builder.append("functions", this.functions); + } + if (this.thermostat != null) { + builder.append("thermostat", this.thermostat); + } + + return builder.toString(); + } + + protected String executeQuery(final String url) throws JsonGenerationException, JsonMappingException, IOException { + Properties headers = new Properties(); + headers.putAll(HTTP_HEADERS); + headers.put("Authorization", "Bearer " + this.accessToken); + return executeUrl(HTTP_POST, url, headers, new ByteArrayInputStream(JSON.writeValueAsBytes(this)), + "application/json", HTTP_REQUEST_TIMEOUT); + } + + private String buildQueryString() { + final StringBuilder urlBuilder = new StringBuilder(RESOURCE_URL); + + try { + urlBuilder.append("?json=true&token="); + urlBuilder.append(this.accessToken); + return URIUtil.encodeQuery(urlBuilder.toString()); + } catch (final Exception e) { + throw new EcobeeException(e); + } + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/User.java b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/User.java new file mode 100644 index 00000000000..95ebf2a68ca --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/java/org/openhab/binding/ecobee/internal/messages/User.java @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.ecobee.internal.messages; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * The User object. The User object contains information pertaining to the User associated with a thermostat. + * + * @see Object + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class User extends AbstractMessagePart { + private String userName; + private String displayName; + private String firstName; + private String lastName; + private String honorific; + private String registerDate; + private String registerTime; + private String defaultThermostatIdentifier; + private String managementRef; + private String utilityRef; + private String supportRef; + private String phoneNumber; + + /** + * @return the User login userName. Usually a valid email address. + */ + @JsonProperty("userName") + public String getUserName() { + return this.userName; + } + + /** + * @return the User display name + */ + @JsonProperty("displayName") + public String getDisplayName() { + return this.displayName; + } + + /** + * @param displayName + * the User display name + */ + @JsonProperty("displayName") + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + /** + * @return the User first name + */ + @JsonProperty("firstName") + public String getFirstName() { + return this.firstName; + } + + /** + * @param firstName + * the User first name + */ + @JsonProperty("firstName") + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + /** + * @return the User last name + */ + @JsonProperty("lastName") + public String getLastName() { + return this.lastName; + } + + /** + * @param lastName + * the User last name + */ + @JsonProperty("lastName") + public void setLastName(String lastName) { + this.lastName = lastName; + } + + /** + * @return the User title such as Mr. or Mrs. + */ + @JsonProperty("honorific") + public String getHonorific() { + return this.honorific; + } + + /** + * @return the User date of registration + */ + @JsonProperty("registerDate") + public String getRegisterDate() { + return this.registerDate; + } + + /** + * @return the User time of registration + */ + @JsonProperty("registerTime") + public String getRegisterTime() { + return this.registerTime; + } + + /** + * @return the Thermostat identifier this User is associated with + */ + @JsonProperty("defaultThermostatIdentifier") + public String getDefaultThermostatIdentifier() { + return this.defaultThermostatIdentifier; + } + + /** + * @return the User management reference + */ + @JsonProperty("managementRef") + public String getManagementRef() { + return this.managementRef; + } + + /** + * @return the User utility reference + */ + @JsonProperty("utilityRef") + public String getUtilityRef() { + return this.utilityRef; + } + + /** + * @return the User support reference + */ + @JsonProperty("supportRef") + public String getSupportRef() { + return this.supportRef; + } + + /** + * @return the User phone number + */ + @JsonProperty("phoneNumber") + public String getPhoneNumber() { + return this.phoneNumber; + } + + /** + * @param phoneNumber + * the User phone number + */ + @JsonProperty("phoneNumber") + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("userName", this.userName); + builder.append("displayName", this.displayName); + builder.append("firstName", this.firstName); + builder.append("lastName", this.lastName); + builder.append("honorific", this.honorific); + builder.append("registerDate", this.registerDate); + builder.append("registerTime", this.registerTime); + builder.append("defaultThermostatIdentifier", this.defaultThermostatIdentifier); + builder.append("managementRef", this.managementRef); + builder.append("utilityRef", this.utilityRef); + builder.append("supportRef", this.supportRef); + builder.append("phoneNumber", this.phoneNumber); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/resources/ecobee.items b/bundles/binding/org.openhab.binding.ecobee/src/main/resources/ecobee.items new file mode 100644 index 00000000000..7efcd3782aa --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/resources/ecobee.items @@ -0,0 +1,192 @@ +/* Ecobee binding items */ + +String identifier "identifier [%s]" { ecobee="<[123456789012#identifier]" } +String name "name [%s]" { ecobee="=[123456789012#name]" } +String thermostatRev "thermostatRev [%s]" { ecobee="<[123456789012#thermostatRev]" } +String isRegistered "isRegistered [%s]" { ecobee="<[123456789012#isRegistered]" } +String modelNumber "modelNumber [%s]" { ecobee="<[123456789012#modelNumber]" } +DateTime lastModified "lastModified [%1$tm/%1$td/%1$tY %1$tH:%1$tM:%1$tS]" { ecobee="<[123456789012#lastModified]" } +DateTime thermostatTime "thermostatTime [%1$tm/%1$td/%1$tY %1$tH:%1$tM:%1$tS]" { ecobee="<[123456789012#thermostatTime]" } +DateTime utcTime "utcTime [%1$tm/%1$td/%1$tY %1$tH:%1$tM:%1$tS]" { ecobee="<[123456789012#utcTime]" } +String equipmentStatus "equipmentStatus [%s]" { ecobee="<[123456789012#equipmentStatus]" } +String version_thermostatFirmwareVersion "thermostatFirmwareVersion [%s]" { ecobee="<[123456789012#version.thermostatFirmwareVersion]" } +String program_currentClimateRef "currentClimateRef [%s]" { ecobee="<[123456789012#program.currentClimateRef]" } + +Group All +Group gSettings (All) + +String settings_hvacMode "hvacMode [%s]" (gSettings) { ecobee="=[123456789012#settings.hvacMode]" } +String settings_lastServiceDate "lastServiceDate [%s]" (gSettings) { ecobee="=[123456789012#settings.lastServiceDate]" } +Switch settings_serviceRemindMe "serviceRemindMe [%s]" (gSettings) { ecobee="=[123456789012#settings.serviceRemindMe]" } +Number settings_monthsBetweenService "monthsBetweenService [%d]" (gSettings) { ecobee="=[123456789012#settings.monthsBetweenService]" } +String settings_remindMeDate "remindMeDate [%s]" (gSettings) { ecobee="=[123456789012#settings.remindMeDate]" } +String settings_vent "vent [%s]" (gSettings) { ecobee="=[123456789012#settings.vent]" } +Number settings_ventilatorMinOnTime "ventilatorMinOnTime [%d]" (gSettings) { ecobee="=[123456789012#settings.ventilatorMinOnTime]" } +Switch settings_serviceRemindTechnician "serviceRemindTechnician [%s]" (gSettings) { ecobee="=[123456789012#settings.serviceRemindTechnician]" } +String settings_eiLocation "eiLocation [%s]" (gSettings) { ecobee="=[123456789012#settings.eiLocation]" } +Number settings_coldTempAlert "coldTempAlert [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.coldTempAlert]" } +Switch settings_coldTempAlertEnabled "coldTempAlertEnabled [%s]" (gSettings) { ecobee="=[123456789012#settings.coldTempAlertEnabled]" } +Number settings_hotTempAlert "hotTempAlert [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.hotTempAlert]" } +Switch settings_hotTempAlertEnabled "hotTempAlertEnabled [%s]" (gSettings) { ecobee="=[123456789012#settings.hotTempAlertEnabled]" } +Number settings_coolStages "coolStages [%d]" (gSettings) { ecobee="<[123456789012#settings.coolStages]" } +Number settings_heatStages "heatStages [%d]" (gSettings) { ecobee="<[123456789012#settings.heatStages]" } +Number settings_maxSetBack "maxSetBack [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.maxSetBack]" } +Number settings_maxSetForward "maxSetForward [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.maxSetForward]" } +Number settings_quickSaveSetBack "quickSaveSetBack [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.quickSaveSetBack]" } +Number settings_quickSaveSetForward "quickSaveSetForward [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.quickSaveSetForward]" } +Switch settings_hasHeatPump "hasHeatPump [%s]" (gSettings) { ecobee="<[123456789012#settings.hasHeatPump]" } +Switch settings_hasForcedAir "hasForcedAir [%s]" (gSettings) { ecobee="<[123456789012#settings.hasForcedAir]" } +Switch settings_hasBoiler "hasBoiler [%s]" (gSettings) { ecobee="<[123456789012#settings.hasBoiler]" } +Switch settings_hasHumidifier "hasHumidifier [%s]" (gSettings) { ecobee="<[123456789012#settings.hasHumidifier]" } +Switch settings_hasErv "hasErv [%s]" (gSettings) { ecobee="<[123456789012#settings.hasErv]" } +Switch settings_hasHrv "hasHrv [%s]" (gSettings) { ecobee="<[123456789012#settings.hasHrv]" } +Switch settings_condensationAvoid "condensationAvoid [%s]" (gSettings) { ecobee="=[123456789012#settings.condensationAvoid]" } +Switch settings_useCelsius "useCelsius [%s]" (gSettings) { ecobee="=[123456789012#settings.useCelsius]" } +Switch settings_useTimeFormat12 "useTimeFormat12 [%s]" (gSettings) { ecobee="=[123456789012#settings.useTimeFormat12]" } +String settings_locale "locale [%s]" (gSettings) { ecobee="=[123456789012#settings.locale]" } +String settings_humidity "humidity [%s]" (gSettings) { ecobee="=[123456789012#settings.humidity]" } +String settings_humidifierMode "humidifierMode [%s]" (gSettings) { ecobee="=[123456789012#settings.humidifierMode]" } +Number settings_backlightOnIntensity "backlightOnIntensity [%d]" (gSettings) { ecobee="=[123456789012#settings.backlightOnIntensity]" } +Number settings_backlightSleepIntensity "backlightSleepIntensity [%d]" (gSettings) { ecobee="=[123456789012#settings.backlightSleepIntensity]" } +Number settings_backlightOffTime "backlightOffTime [%d]" (gSettings) { ecobee="=[123456789012#settings.backlightOffTime]" } +Number settings_soundTickVolume "soundTickVolume [%d]" (gSettings) { ecobee="=[123456789012#settings.soundTickVolume]" } +Number settings_soundAlertVolume "soundAlertVolume [%d]" (gSettings) { ecobee="=[123456789012#settings.soundAlertVolume]" } +Number settings_compressorProtectionMinTime "compressorProtectionMinTime [%d]" (gSettings) { ecobee="=[123456789012#settings.compressorProtectionMinTime]" } +Number settings_compressorProtectionMinTemp "compressorProtectionMinTemp [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.compressorProtectionMinTemp]" } +Number settings_stage1HeatingDifferentialTemp "stage1HeatingDifferentialTemp [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.stage1HeatingDifferentialTemp]" } +Number settings_stage1CoolingDifferentialTemp "stage1CoolingDifferentialTemp [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.stage1CoolingDifferentialTemp]" } +Number settings_stage1HeatingDissipationTime "stage1HeatingDissipationTime [%d]" (gSettings) { ecobee="=[123456789012#settings.stage1HeatingDissipationTime]" } +Number settings_stage1CoolingDissipationTime "stage1CoolingDissipationTime [%d]" (gSettings) { ecobee="=[123456789012#settings.stage1CoolingDissipationTime]" } +Switch settings_heatPumpReversalOnCool "heatPumpReversalOnCool [%s]" (gSettings) { ecobee="=[123456789012#settings.heatPumpReversalOnCool]" } +Switch settings_fanControlRequired "fanControlRequired [%s]" (gSettings) { ecobee="=[123456789012#settings.fanControlRequired]" } +Number settings_fanMinOnTime "fanMinOnTime [%d]" (gSettings) { ecobee="=[123456789012#settings.fanMinOnTime]" } +Number settings_heatCoolMinDelta "heatCoolMinDelta [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.heatCoolMinDelta]" } +Number settings_tempCorrection "tempCorrection [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.tempCorrection]" } +String settings_holdAction "holdAction [%s]" (gSettings) { ecobee="=[123456789012#settings.holdAction]" } +Switch settings_heatPumpGroundWater "heatPumpGroundWater [%s]" (gSettings) { ecobee="<[123456789012#settings.heatPumpGroundWater]" } +Switch settings_hasElectric "hasElectric [%s]" (gSettings) { ecobee="<[123456789012#settings.hasElectric]" } +Switch settings_hasDehumidifier "hasDehumidifier [%s]" (gSettings) { ecobee="<[123456789012#settings.hasDehumidifier]" } +String settings_dehumidifierMode "dehumidifierMode [%s]" (gSettings) { ecobee="=[123456789012#settings.dehumidifierMode]" } +Number settings_dehumidifierLevel "dehumidifierLevel [%d]" (gSettings) { ecobee="=[123456789012#settings.dehumidifierLevel]" } +Switch settings_dehumidifyWithAC "dehumidifyWithAC [%s]" (gSettings) { ecobee="=[123456789012#settings.dehumidifyWithAC]" } +Number settings_dehumidifyOvercoolOffset "dehumidifyOvercoolOffset [%d]" (gSettings) { ecobee="=[123456789012#settings.dehumidifyOvercoolOffset]" } +Switch settings_autoHeatCoolFeatureEnabled "autoHeatCoolFeatureEnabled [%s]" (gSettings) { ecobee="=[123456789012#settings.autoHeatCoolFeatureEnabled]" } +Switch settings_wifiOfflineAlert "wifiOfflineAlert [%s]" (gSettings) { ecobee="=[123456789012#settings.wifiOfflineAlert]" } +Number settings_heatMinTemp "heatMinTemp [%.1f °F]" (gSettings) { ecobee="<[123456789012#settings.heatMinTemp]" } +Number settings_heatMaxTemp "heatMaxTemp [%.1f °F]" (gSettings) { ecobee="<[123456789012#settings.heatMaxTemp]" } +Number settings_coolMinTemp "coolMinTemp [%.1f °F]" (gSettings) { ecobee="<[123456789012#settings.coolMinTemp]" } +Number settings_coolMaxTemp "coolMaxTemp [%.1f °F]" (gSettings) { ecobee="<[123456789012#settings.coolMaxTemp]" } +Number settings_heatRangeHigh "heatRangeHigh [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.heatRangeHigh]" } +Number settings_heatRangeLow "heatRangeLow [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.heatRangeLow]" } +Number settings_coolRangeHigh "coolRangeHigh [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.coolRangeHigh]" } +Number settings_coolRangeLow "coolRangeLow [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.coolRangeLow]" } +String settings_userAccessCode "userAccessCode [%s]" (gSettings) { ecobee="=[123456789012#settings.userAccessCode]" } +Number settings_userAccessSetting "userAccessSetting [%d]" (gSettings) { ecobee="=[123456789012#settings.userAccessSetting]" } +Number settings_auxRuntimeAlert "auxRuntimeAlert [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.auxRuntimeAlert]" } +Number settings_auxOutdoorTempAlert "auxOutdoorTempAlert [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.auxOutdoorTempAlert]" } +Number settings_auxMaxOutdoorTemp "auxMaxOutdoorTemp [%.1f °F]" (gSettings) { ecobee="=[123456789012#settings.auxMaxOutdoorTemp]" } +Switch settings_auxRuntimeAlertNotify "auxRuntimeAlertNotify [%s]" (gSettings) { ecobee="=[123456789012#settings.auxRuntimeAlertNotify]" } +Switch settings_auxOutdoorTempAlertNotify "auxOutdoorTempAlertNotify [%s]" (gSettings) { ecobee="=[123456789012#settings.auxOutdoorTempAlertNotify]" } +Switch settings_auxRuntimeAlertNotifyTechnician "auxRuntimeAlertNotifyTechnician [%s]" (gSettings) { ecobee="=[123456789012#settings.auxRuntimeAlertNotifyTechnician]" } +Switch settings_auxOutdoorTempAlertNotifyTechnician "auxOutdoorTempAlertNotifyTechnician [%s]" (gSettings) { ecobee="=[123456789012#settings.auxOutdoorTempAlertNotifyTechnician]" } +Switch settings_disablePreHeating "disablePreHeating [%s]" (gSettings) { ecobee="=[123456789012#settings.disablePreHeating]" } +Switch settings_disablePreCooling "disablePreCooling [%s]" (gSettings) { ecobee="=[123456789012#settings.disablePreCooling]" } +Switch settings_installerCodeRequired "installerCodeRequired [%s]" (gSettings) { ecobee="=[123456789012#settings.installerCodeRequired]" } +String settings_drAccept "drAccept [%s]" (gSettings) { ecobee="=[123456789012#settings.drAccept]" } +Switch settings_isRentalProperty "isRentalProperty [%s]" (gSettings) { ecobee="=[123456789012#settings.isRentalProperty]" } +Switch settings_useZoneController "useZoneController [%s]" (gSettings) { ecobee="=[123456789012#settings.useZoneController]" } +Number settings_randomStartDelayCool "randomStartDelayCool [%d]" (gSettings) { ecobee="=[123456789012#settings.randomStartDelayCool]" } +Number settings_randomStartDelayHeat "randomStartDelayHeat [%d]" (gSettings) { ecobee="=[123456789012#settings.randomStartDelayHeat]" } +Number settings_humidityHighAlert "humidityHighAlert [%d]" (gSettings) { ecobee="=[123456789012#settings.humidityHighAlert]" } +Number settings_humidityLowAlert "humidityLowAlert [%d]" (gSettings) { ecobee="=[123456789012#settings.humidityLowAlert]" } +Switch settings_disableHeatPumpAlerts "disableHeatPumpAlerts [%s]" (gSettings) { ecobee="=[123456789012#settings.disableHeatPumpAlerts]" } +Switch settings_disableAlertsOnIdt "disableAlertsOnIdt [%s]" (gSettings) { ecobee="=[123456789012#settings.disableAlertsOnIdt]" } +Switch settings_humidityAlertNotify "humidityAlertNotify [%s]" (gSettings) { ecobee="=[123456789012#settings.humidityAlertNotify]" } +Switch settings_humidityAlertNotifyTechnician "humidityAlertNotifyTechnician [%s]" (gSettings) { ecobee="=[123456789012#settings.humidityAlertNotifyTechnician]" } +Switch settings_tempAlertNotify "tempAlertNotify [%s]" (gSettings) { ecobee="=[123456789012#settings.tempAlertNotify]" } +Switch settings_tempAlertNotifyTechnician "tempAlertNotifyTechnician [%s]" (gSettings) { ecobee="=[123456789012#settings.tempAlertNotifyTechnician]" } +Number settings_monthlyElectricityBillLimit "monthlyElectricityBillLimit [%d]" (gSettings) { ecobee="=[123456789012#settings.monthlyElectricityBillLimit]" } +Switch settings_enableElectricityBillAlert "enableElectricityBillAlert [%s]" (gSettings) { ecobee="=[123456789012#settings.enableElectricityBillAlert]" } +Switch settings_enableProjectedElectricityBillAlert "enableProjectedElectricityBillAlert [%s]" (gSettings) { ecobee="=[123456789012#settings.enableProjectedElectricityBillAlert]" } +Number settings_electricityBillingDayOfMonth "electricityBillingDayOfMonth [%d]" (gSettings) { ecobee="=[123456789012#settings.electricityBillingDayOfMonth]" } +Number settings_electricityBillCycleMonths "electricityBillCycleMonths [%d]" (gSettings) { ecobee="=[123456789012#settings.electricityBillCycleMonths]" } +Number settings_electricityBillStartMonth "electricityBillStartMonth [%d]" (gSettings) { ecobee="=[123456789012#settings.electricityBillStartMonth]" } +Number settings_ventilatorMinOnTimeHome "ventilatorMinOnTimeHome [%d]" (gSettings) { ecobee="=[123456789012#settings.ventilatorMinOnTimeHome]" } +Number settings_ventilatorMinOnTimeAway "ventilatorMinOnTimeAway [%d]" (gSettings) { ecobee="=[123456789012#settings.ventilatorMinOnTimeAway]" } +Switch settings_backlightOffDuringSleep "backlightOffDuringSleep [%s]" (gSettings) { ecobee="=[123456789012#settings.backlightOffDuringSleep]" } +Switch settings_autoAway "autoAway [%s]" (gSettings) { ecobee="<[123456789012#settings.autoAway]" } +Switch settings_smartCirculation "smartCirculation [%s]" (gSettings) { ecobee="=[123456789012#settings.smartCirculation]" } +Switch settings_followMeComfort "followMeComfort [%s]" (gSettings) { ecobee="=[123456789012#settings.followMeComfort]" } +String settings_ventilatorType "ventilatorType [%s]" (gSettings) { ecobee="<[123456789012#settings.ventilatorType]" } +Switch settings_isVentilatorTimerOn "isVentilatorTimerOn [%s]" (gSettings) { ecobee="=[123456789012#settings.isVentilatorTimerOn]" } +DateTime settings_ventilatorOffDateTime "ventilatorOffDateTime [%1$tm/%1$td/%1$tY %1$tH:%1$tM:%1$tS]" (gSettings) { ecobee="<[123456789012#settings.ventilatorOffDateTime]" } +Switch settings_hasUVFilter "hasUVFilter [%s]" (gSettings) { ecobee="=[123456789012#settings.hasUVFilter]" } +Switch settings_coolingLockout "coolingLockout [%s]" (gSettings) { ecobee="=[123456789012#settings.coolingLockout]" } +Switch settings_ventilatorFreeCooling "ventilatorFreeCooling [%s]" (gSettings) { ecobee="=[123456789012#settings.ventilatorFreeCooling]" } +Switch settings_dehumidifyWhenHeating "dehumidifyWhenHeating [%s]" (gSettings) { ecobee="=[123456789012#settings.dehumidifyWhenHeating]" } +String settings_groupRef "groupRef [%s]" (gSettings) { ecobee="=[123456789012#settings.groupRef]" } +String settings_groupName "groupName [%s]" (gSettings) { ecobee="=[123456789012#settings.groupName]" } +Number settings_groupSetting "groupSetting [%d]" (gSettings) { ecobee="=[123456789012#settings.groupSetting]" } + +Group gRuntime (All) + +String runtime_runtimeRev "runtimeRev [%s]" (gRuntime) { ecobee="<[123456789012#runtime.runtimeRev]" } +Switch runtime_connected "connected [%s]" (gRuntime) { ecobee="<[123456789012#runtime.connected]" } +DateTime runtime_firstConnected "firstConnected [%1$tm/%1$td/%1$tY %1$tH:%1$tM:%1$tS]" (gRuntime) { ecobee="<[123456789012#runtime.firstConnected]" } +DateTime runtime_connectDateTime "connectDateTime [%1$tm/%1$td/%1$tY %1$tH:%1$tM:%1$tS]" (gRuntime) { ecobee="<[123456789012#runtime.connectDateTime]" } +String runtime_disconnectDateTime "disconnectDateTime [%s]" (gRuntime) { ecobee="<[123456789012#runtime.disconnectDateTime]" } +DateTime runtime_lastModified "lastModified [%1$tm/%1$td/%1$tY %1$tH:%1$tM:%1$tS]" (gRuntime) { ecobee="<[123456789012#runtime.lastModified]" } +DateTime runtime_lastStatusModified "lastStatusModified [%1$tm/%1$td/%1$tY %1$tH:%1$tM:%1$tS]" (gRuntime) { ecobee="<[123456789012#runtime.lastStatusModified]" } +String runtime_runtimeDate "runtimeDate [%s]" (gRuntime) { ecobee="<[123456789012#runtime.runtimeDate]" } +Number runtime_runtimeInterval "runtimeInterval [%d]" (gRuntime) { ecobee="<[123456789012#runtime.runtimeInterval]" } +Number runtime_actualTemperature "actualTemperature [%.1f °F]" (gRuntime) { ecobee="<[123456789012#runtime.actualTemperature]" } +Number runtime_actualHumidity "actualHumidity [%d %%]" (gRuntime) { ecobee="<[123456789012#runtime.actualHumidity]" } +Number runtime_desiredHeat "desiredHeat [%.1f °F]" (gRuntime) { ecobee="<[123456789012#runtime.desiredHeat]" } +Number runtime_desiredCool "desiredCool [%.1f °F]" (gRuntime) { ecobee="<[123456789012#runtime.desiredCool]" } +Number runtime_desiredHumidity "desiredHumidity [%d %%]" (gRuntime) { ecobee="<[123456789012#runtime.desiredHumidity]" } +Number runtime_desiredDehumidity "desiredDehumidity [%d %%]" (gRuntime) { ecobee="<[123456789012#runtime.desiredDehumidity]" } +String runtime_desiredFanMode "desiredFanMode [%s]" (gRuntime) { ecobee="<[123456789012#runtime.desiredFanMode]" } + +Group gLocation (All) + +Number location_timeZoneOffsetMinutes "timeZoneOffsetMinutes [%d]" (gLocation) { ecobee="<[123456789012#location.timeZoneOffsetMinutes]" } +String location_timeZone "timeZone [%s]" (gLocation) { ecobee="=[123456789012#location.timeZone]" } +Switch location_isDaylightSaving "isDaylightSaving [%s]" (gLocation) { ecobee="=[123456789012#location.isDaylightSaving]" } +String location_streetAddress "streetAddress [%s]" (gLocation) { ecobee="=[123456789012#location.streetAddress]" } +String location_city "city [%s]" (gLocation) { ecobee="=[123456789012#location.city]" } +String location_provinceState "provinceState [%s]" (gLocation) { ecobee="=[123456789012#location.provinceState]" } +String location_country "country [%s]" (gLocation) { ecobee="=[123456789012#location.country]" } +String location_postalCode "postalCode [%s]" (gLocation) { ecobee="=[123456789012#location.postalCode]" } +String location_phoneNumber "phoneNumber [%s]" (gLocation) { ecobee="=[123456789012#location.phoneNumber]" } +String location_mapCoordinates "mapCoordinates [%s]" (gLocation) { ecobee="=[123456789012#location.mapCoordinates]" } + +Group gWeather (All) + +DateTime weather_timestamp "timestamp [%1$tm/%1$td/%1$tY %1$tH:%1$tM:%1$tS]" (gWeather) { ecobee="<[123456789012#weather.timestamp]" } +String weather_weatherStation "weatherStation [%s]" (gWeather) { ecobee="<[123456789012#weather.weatherStation]" } + +Number weather_forecasts0_weatherSymbol "weatherSymbol [%d]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].weatherSymbol]" } +DateTime weather_forecasts0_dateTime "dateTime [%1$tm/%1$td/%1$tY %1$tH:%1$tM:%1$tS]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].dateTime]" } +String weather_forecasts0_condition "condition [%s]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].condition]" } +Number weather_forecasts0_temperature "temperature [%.1f °F]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].temperature]" } +Number weather_forecasts0_pressure "pressure [%d]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].pressure]" } +Number weather_forecasts0_relativeHumidity "relativeHumidity [%d %%]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].relativeHumidity]" } +Number weather_forecasts0_dewpoint "dewpoint [%d]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].dewpoint]" } +Number weather_forecasts0_visibility "visibility [%d]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].visibility]" } +Number weather_forecasts0_windSpeed "windSpeed [%d]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].windSpeed]" } +Number weather_forecasts0_windGust "windGust [%d]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].windGust]" } +String weather_forecasts0_windDirection "windDirection [%s]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].windDirection]" } +Number weather_forecasts0_windBearing "windBearing [%d]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].windBearing]" } +Number weather_forecasts0_pop "pop [%d %%]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].pop]" } +Number weather_forecasts0_tempHigh "tempHigh [%.1f °F]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].tempHigh]" } +Number weather_forecasts0_tempLow "tempLow [%.1f °F]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].tempLow]" } +Number weather_forecasts0_sky "sky [%d]" (gWeather) { ecobee="<[123456789012#weather.forecasts[0].sky]" } + +Group gHouseDetails (All) + +String houseDetails_style "style [%s]" (gHouseDetails) { ecobee="=[123456789012#houseDetails.style]" } +Number houseDetails_size "size [%d]" (gHouseDetails) { ecobee="=[123456789012#houseDetails.size]" } +Number houseDetails_numberOfFloors "numberOfFloors [%d]" (gHouseDetails) { ecobee="=[123456789012#houseDetails.numberOfFloors]" } +Number houseDetails_numberOfRooms "numberOfRooms [%d]" (gHouseDetails) { ecobee="=[123456789012#houseDetails.numberOfRooms]" } +Number houseDetails_numberOfOccupants "numberOfOccupants [%d]" (gHouseDetails) { ecobee="=[123456789012#houseDetails.numberOfOccupants]" } +Number houseDetails_age "age [%d]" (gHouseDetails) { ecobee="=[123456789012#houseDetails.age]" } diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/resources/ecobee.sitemap b/bundles/binding/org.openhab.binding.ecobee/src/main/resources/ecobee.sitemap new file mode 100644 index 00000000000..0006b31b846 --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/resources/ecobee.sitemap @@ -0,0 +1,22 @@ +sitemap ecobee label="Ecobee Thermostat Test" +{ + Frame label="Thermostat" { + Text item=identifier + Text item=name + Text item=thermostatRev + Switch item=isRegistered + Text item=modelNumber + Text item=lastModified + Text item=thermostatTime + Text item=utcTime + Text item=equipmentStatus + Text item=version_thermostatFirmwareVersion + Text item=program_currentClimateRef + Switch item=settings_hvacMode label="HVAC Mode" mappings=[ auto=auto, auxHeatOnly=auxHeatOnly, cool=cool, heat=heat, off=off ] + Group item=gSettings label="Settings" icon="temperature" + Group item=gRuntime label="Runtime" icon="temperature" + Group item=gLocation label="Location" icon="house" + Group item=gWeather label="Weather" icon="contact-open" + Group item=gHouseDetails label="House Details" icon="house" + } +} diff --git a/bundles/binding/org.openhab.binding.ecobee/src/main/resources/readme.txt b/bundles/binding/org.openhab.binding.ecobee/src/main/resources/readme.txt new file mode 100644 index 00000000000..98698c670dc --- /dev/null +++ b/bundles/binding/org.openhab.binding.ecobee/src/main/resources/readme.txt @@ -0,0 +1 @@ +Bundle resources go in here! \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/EcoTouchBindingProvider.java b/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/EcoTouchBindingProvider.java index c5b63aa73bb..0036267336a 100644 --- a/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/EcoTouchBindingProvider.java +++ b/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/EcoTouchBindingProvider.java @@ -28,6 +28,15 @@ public interface EcoTouchBindingProvider extends BindingProvider { */ public String[] getItemNamesForType(EcoTouchTags bindingType); + /** + * Returns the type for an specific item. + * + * @param itemName + * the name of the item (set inside a *.items config file) + * @return type of this binding + */ + public EcoTouchTags getTypeForItemName(String itemName); + /** * Provides an array of all active tag names of this provider * diff --git a/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/EcoTouchTags.java b/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/EcoTouchTags.java index 6e17d3a97d1..32caf251695 100644 --- a/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/EcoTouchTags.java +++ b/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/EcoTouchTags.java @@ -10,6 +10,7 @@ import org.openhab.core.items.Item; import org.openhab.core.library.items.NumberItem; +import org.openhab.core.library.items.SwitchItem; /** * Represents all valid commands which could be processed by this binding @@ -352,6 +353,132 @@ public enum EcoTouchTags { } }, + // German: nviNormAussen + TYPE_NVINORMAUSSEN { + { + command = "nviNormAussen"; + itemClass = NumberItem.class; + tagName = "A91"; + } + }, + + // German: nviHeizkreisNorm + TYPE_NVIHEIZKREISNORM { + { + command = "nviHeizkreisNorm"; + itemClass = NumberItem.class; + tagName = "A92"; + } + }, + + // German: nviTHeizgrenze + TYPE_NVITHEIZGRENZE { + { + command = "nviTHeizgrenze"; + itemClass = NumberItem.class; + tagName = "A93"; + } + }, + + // German: nviTHeizgrenzeSoll + TYPE_NVITHEIZGRENZESOLL { + { + command = "nviTHeizgrenzeSoll"; + itemClass = NumberItem.class; + tagName = "A94"; + } + }, + + // German: Betriebsstunden Verdichter 1 + TYPE_OPERATING_HOURS_COMPRESSOR1 { + { + command = "operating_hours_compressor1"; + itemClass = NumberItem.class; + tagName = "I10"; + type = Type.Word; + } + }, + + // German: Betriebsstunden Verdichter 2 + TYPE_OPERATING_HOURS_COMPRESSOR2 { + { + command = "operating_hours_compressor2"; + itemClass = NumberItem.class; + tagName = "I14"; + type = Type.Word; + } + }, + + // German: Betriebsstunden Heizungsumwälzpumpe + TYPE_OPERATING_HOURS_CIRCULATION_PUMP { + { + command = "operating_hours_circulation_pump"; + itemClass = NumberItem.class; + tagName = "I18"; + type = Type.Word; + } + }, + + // German: Betriebsstunden Quellenpumpe + TYPE_OPERATING_HOURS_SOURCE_PUMP { + { + command = "operating_hours_source_pump"; + itemClass = NumberItem.class; + tagName = "I20"; + type = Type.Word; + } + }, + + // German: Betriebsstunden Solarkreis + TYPE_OPERATING_HOURS_SOLAR { + { + command = "operating_hours_solar"; + itemClass = NumberItem.class; + tagName = "I22"; + type = Type.Word; + } + }, + + // German: Handabschaltung Heizbetrieb + TYPE_ENABLE_HEATING { + { + command = "enable_heating"; + itemClass = SwitchItem.class; + tagName = "I30"; + type = Type.Word; + } + }, + + // German: Handabschaltung Kühlbetrieb + TYPE_ENABLE_COOLING { + { + command = "enable_cooling"; + itemClass = SwitchItem.class; + tagName = "I31"; + type = Type.Word; + } + }, + + // German: Handabschaltung Warmwasserbetrieb + TYPE_ENABLE_WARMWATER { + { + command = "enable_warmwater"; + itemClass = SwitchItem.class; + tagName = "I32"; + type = Type.Word; + } + }, + + // German: Handabschaltung Pool_Heizbetrieb + TYPE_ENABLE_POOL { + { + command = "enable_pool"; + itemClass = SwitchItem.class; + tagName = "I33"; + type = Type.Word; + } + }, + // German: Status der Wärmepumpenkomponenten TYPE_STATE { { @@ -366,7 +493,7 @@ public enum EcoTouchTags { TYPE_STATE_SOURCEPUMP { { command = "state_sourcepump"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 0; @@ -377,7 +504,7 @@ public enum EcoTouchTags { TYPE_STATE_HEATINGPUMP { { command = "state_heatingpump"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 1; @@ -389,7 +516,7 @@ public enum EcoTouchTags { TYPE_STATE_EVD { { command = "state_evd"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 2; @@ -400,7 +527,7 @@ public enum EcoTouchTags { TYPE_STATE_compressor1 { { command = "state_compressor1"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 3; @@ -411,7 +538,7 @@ public enum EcoTouchTags { TYPE_STATE_compressor2 { { command = "state_compressor2"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 4; @@ -422,7 +549,7 @@ public enum EcoTouchTags { TYPE_STATE_extheater { { command = "state_extheater"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 5; @@ -433,7 +560,7 @@ public enum EcoTouchTags { TYPE_STATE_alarm { { command = "state_alarm"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 6; @@ -444,7 +571,7 @@ public enum EcoTouchTags { TYPE_STATE_cooling { { command = "state_cooling"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 7; @@ -455,7 +582,7 @@ public enum EcoTouchTags { TYPE_STATE_water { { command = "state_water"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 8; @@ -466,7 +593,7 @@ public enum EcoTouchTags { TYPE_STATE_pool { { command = "state_pool"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 9; @@ -477,7 +604,7 @@ public enum EcoTouchTags { TYPE_STATE_solar { { command = "state_solar"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 10; @@ -488,13 +615,44 @@ public enum EcoTouchTags { TYPE_STATE_cooling4way { { command = "state_cooling4way"; - itemClass = NumberItem.class; + itemClass = SwitchItem.class; tagName = "I51"; type = Type.Bitfield; bitnum = 11; } }, + // German: Meldungen von Ausfällen F0xx die zum Wärmepumpenausfall führen + TYPE_ALARM { + { + command = "alarm"; + itemClass = NumberItem.class; + tagName = "I52"; + type = Type.Word; + } + }, + + // German: Unterbrechungen + TYPE_INTERRUPTIONS { + { + command = "interruptions"; + itemClass = NumberItem.class; + tagName = "I53"; + type = Type.Word; + } + }, + + // German: Temperaturanpassung für die Heizung + TYPE_ADAPT_HEATING { + { + command = "adapt_heating"; + itemClass = NumberItem.class; + tagName = "I263"; + type = Type.Word; // value range 0..8 => -2K .. +2K + } + }, + + ; /** diff --git a/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchBinding.java b/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchBinding.java index 05b87099644..5cd3a6ce2c7 100644 --- a/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchBinding.java +++ b/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchBinding.java @@ -19,7 +19,9 @@ import org.openhab.binding.ecotouch.EcoTouchTags; import org.apache.commons.lang.StringUtils; import org.openhab.core.binding.AbstractActiveBinding; +import org.openhab.core.library.items.NumberItem; import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.OnOffType; import org.openhab.core.types.Command; import org.openhab.core.types.State; import org.osgi.service.cm.ConfigurationException; @@ -124,20 +126,48 @@ protected void execute() { continue; } int heatpumpValue = rawvalues.get(item.getTagName()); + State value; if (item.getType() == EcoTouchTags.Type.Analog) { // analog value encoded as a scaled integer BigDecimal decimal = new BigDecimal(heatpumpValue) .divide(new BigDecimal(10)); - handleEventType(new DecimalType(decimal), item); + value = new DecimalType(decimal); } else if (item.getType() == EcoTouchTags.Type.Word) { // integer - handleEventType(new DecimalType(heatpumpValue), item); + if (NumberItem.class.equals(item.getItemClass())) + value = new DecimalType(heatpumpValue); + else { + // assume SwitchItem + if (heatpumpValue == 0) + value = OnOffType.OFF; + else + value = OnOffType.ON; + } } else { // bit field heatpumpValue >>= item.getBitNum(); heatpumpValue &= 1; - handleEventType(new DecimalType(heatpumpValue), item); + if (NumberItem.class.equals(item.getItemClass())) + value = new DecimalType(heatpumpValue); + else { + // assume SwitchItem + if (heatpumpValue == 0) + value = OnOffType.OFF; + else + value = OnOffType.ON; + } } + + // now consider special cases + if (item == EcoTouchTags.TYPE_ADAPT_HEATING) { + double adapt = ((DecimalType) value).intValue(); + adapt = Math.max(0, adapt); + adapt = Math.min(8, adapt); + adapt = (adapt - 4) / 2.0; + value = new DecimalType(adapt); + } + + handleEventType(value, item); } } @@ -150,8 +180,7 @@ protected void execute() { } - private void handleEventType(org.openhab.core.types.State state, - EcoTouchTags heatpumpCommandType) { + private void handleEventType(State state, EcoTouchTags heatpumpCommandType) { for (EcoTouchBindingProvider provider : providers) { for (String itemName : provider .getItemNamesForType(heatpumpCommandType)) { @@ -163,10 +192,8 @@ private void handleEventType(org.openhab.core.types.State state, /** * @{inheritDoc */ - @Override public void updated(Dictionary config) throws ConfigurationException { - // logger.debug("updated() is called!"); setProperlyConfigured(false); @@ -202,4 +229,68 @@ public void updated(Dictionary config) } } + @Override + protected void internalReceiveCommand(String itemName, Command command) { + // find the EcoTouch binding for the itemName + EcoTouchTags tag = null; + for (EcoTouchBindingProvider provider : providers) { + try { + tag = provider.getTypeForItemName(itemName); + break; + } catch (Exception e) { + } + } + + // consider special cases + if (tag == EcoTouchTags.TYPE_ADAPT_HEATING) { + double adapt = Double.parseDouble(command.toString()); + adapt = (adapt + 2) * 2; + adapt = Math.max(0, adapt); + adapt = Math.min(8, adapt); + command = new DecimalType((int) adapt); + } + + EcoTouchConnector connector = new EcoTouchConnector(ip, username, + password, cookies); + int value = 0; + switch (tag.getType()) { + case Analog: + value = (int) (Double.parseDouble(command.toString()) * 10); + break; + case Word: + if (command == OnOffType.ON) + value = 1; + else if (command == OnOffType.OFF) + value = 0; + else + value = Integer.parseInt(command.toString()); + break; + case Bitfield: + try { + // read-modify-write style + value = connector.getValue(tag.getTagName()); + int bitmask = 1 << tag.getBitNum(); + if (command == OnOffType.OFF + || Integer.parseInt(command.toString()) == 0) { + value = value & ~bitmask; + } else + value = value | bitmask; + } catch (Exception e1) { + // connector.getValue() already logged a specific debug message + logger.warn("cannot send command '" + command + "' to item '" + itemName + "'"); + return; + } + } + + try { + connector.setValue(tag.getTagName(), value); + // It does not make sense to check the returned value from + // setValue(). + // Even if the tag is read only, one would get the newly set value + // back. + } catch (Exception e) { + // connector.setValue() already logged a specific debug message + logger.warn("cannot send command '" + command + "' to item '" + itemName + "'"); + } + } } diff --git a/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchConnector.java b/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchConnector.java index 5bc0df62667..8b60c7d216a 100644 --- a/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchConnector.java +++ b/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchConnector.java @@ -9,7 +9,6 @@ package org.openhab.binding.ecotouch.internal; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; @@ -146,6 +145,71 @@ public int getValue(String tag) throws Exception { return Integer.parseInt(m.group(3)); } + + /** + * Set a value + * + * @param tag + * The register to set (e.g. "A1") + * @param value + * The 16-bit integer to set the register to + * @return value This value is a 16-bit integer. + */ + public int setValue(String tag, int value) throws Exception { + // set value + String url = "http://" + ip + "/cgi/writeTags?returnValue=true&n=1&t1=" + tag + "&v1=" + value; + StringBuilder body = null; + int loginAttempt = 0; + while (loginAttempt < 2) { + try { + URLConnection connection = new URL(url).openConnection(); + if (cookies != null) { + for (String cookie : cookies) { + connection.addRequestProperty("Cookie", + cookie.split(";", 2)[0]); + } + } + InputStream response = connection.getInputStream(); + BufferedReader reader = new BufferedReader( + new InputStreamReader(response)); + body = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + body.append(line + "\n"); + } + if (body.toString().contains("#" + tag)) { + // succeeded + break; + } + // s.th. went wrong; try to log in + throw new Exception(); + } catch (Exception e) { + login(); + loginAttempt++; + } + } + + if (body == null || !body.toString().contains("#" + tag)) { + // failed + logger.debug("Cannot get value for tag '" + tag + + "' from Waterkotte EcoTouch."); + throw new Exception("invalid response from EcoTouch"); + } + + // ok, the body now contains s.th. like + // #A30 S_OK + // 192 223 + + Matcher m = response_pattern.matcher(body.toString()); + boolean b = m.find(); + if (!b) { + // ill formatted response + logger.debug("ill formatted response: '" + body + "'"); + throw new Exception("invalid response from EcoTouch"); + } + + return Integer.parseInt(m.group(3)); + } /** * Authentication token. Store this and use it, when creating the next diff --git a/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchGenericBindingProvider.java b/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchGenericBindingProvider.java index fbe638333cf..2b0befb79e8 100644 --- a/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchGenericBindingProvider.java +++ b/bundles/binding/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchGenericBindingProvider.java @@ -43,18 +43,26 @@ public String getBindingType() { } /** - * @{inheritDoc} + * @{inheritDoc */ - @Override public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException { - if (!(item instanceof NumberItem)) { + EcoTouchTags tag; + try { + tag = EcoTouchTags.fromString(bindingConfig); + } catch (Exception e) { throw new BindingConfigParseException( "item '" + item.getName() - + "' is of type '" - + item.getClass().getSimpleName() - + "', only NumberItems are allowed - please check your *.items configuration"); + + "' tries to bind to '" + + bindingConfig + + "', which is unknown - please check your *.items configuration"); + } + if (!tag.getItemClass().isInstance(item)) { + throw new BindingConfigParseException("item '" + item.getName() + + "' is of type '" + item.getClass().getSimpleName() + + "', only " + tag.getItemClass().getSimpleName() + + " are allowed - please check your *.items configuration"); } } @@ -124,6 +132,15 @@ public String[] getItemNamesForType(EcoTouchTags eventType) { return itemNames.toArray(new String[itemNames.size()]); } + /** + * {@inheritDoc} + */ + public EcoTouchTags getTypeForItemName(String itemName) { + EcoTouchBindingConfig heatpumpConfig = (EcoTouchBindingConfig) bindingConfigs + .get(itemName); + return heatpumpConfig.getType(); + } + /** * {@inheritDoc} */ diff --git a/bundles/binding/org.openhab.binding.ehealth/.classpath b/bundles/binding/org.openhab.binding.ehealth/.classpath index 4033112b349..6d224cd3d0d 100644 --- a/bundles/binding/org.openhab.binding.ehealth/.classpath +++ b/bundles/binding/org.openhab.binding.ehealth/.classpath @@ -4,6 +4,5 @@ - diff --git a/bundles/binding/org.openhab.binding.enocean/.classpath b/bundles/binding/org.openhab.binding.enocean/.classpath index 5e1d8af9be7..a1c8868b1b8 100644 --- a/bundles/binding/org.openhab.binding.enocean/.classpath +++ b/bundles/binding/org.openhab.binding.enocean/.classpath @@ -5,6 +5,5 @@ - diff --git a/bundles/binding/org.openhab.binding.epsonprojector/.classpath b/bundles/binding/org.openhab.binding.epsonprojector/.classpath index 4033112b349..6d224cd3d0d 100644 --- a/bundles/binding/org.openhab.binding.epsonprojector/.classpath +++ b/bundles/binding/org.openhab.binding.epsonprojector/.classpath @@ -4,6 +4,5 @@ - diff --git a/bundles/binding/org.openhab.binding.fritzbox/src/main/java/org/openhab/binding/fritzbox/FritzboxBindingProvider.java b/bundles/binding/org.openhab.binding.fritzbox/src/main/java/org/openhab/binding/fritzbox/FritzboxBindingProvider.java index 5e74995b1c3..4b2ad79103e 100644 --- a/bundles/binding/org.openhab.binding.fritzbox/src/main/java/org/openhab/binding/fritzbox/FritzboxBindingProvider.java +++ b/bundles/binding/org.openhab.binding.fritzbox/src/main/java/org/openhab/binding/fritzbox/FritzboxBindingProvider.java @@ -35,6 +35,9 @@ public interface FritzboxBindingProvider extends BindingProvider { /** binds wlan state to an item */ static final public String TYPE_WLAN = "wlan"; + /** binds guest wlan state to an item */ + static final public String TYPE_GUEST_WLAN = "guestwlan"; + /** binds dect state to an item */ static final public String TYPE_DECT = "dect"; @@ -48,7 +51,7 @@ public interface FritzboxBindingProvider extends BindingProvider { static final public String TYPE_COMMAND = "cmd"; static final public String[] TYPES = { TYPE_INBOUND, TYPE_OUTBOUND, - TYPE_ACTIVE, TYPE_WLAN, TYPE_DECT, TYPE_TAM, TYPE_QUERY, + TYPE_ACTIVE, TYPE_WLAN, TYPE_GUEST_WLAN, TYPE_DECT, TYPE_TAM, TYPE_QUERY, TYPE_COMMAND }; /** diff --git a/bundles/binding/org.openhab.binding.fritzbox/src/main/java/org/openhab/binding/fritzbox/internal/FritzboxBinding.java b/bundles/binding/org.openhab.binding.fritzbox/src/main/java/org/openhab/binding/fritzbox/internal/FritzboxBinding.java index 14f79788a7b..3496d538fde 100644 --- a/bundles/binding/org.openhab.binding.fritzbox/src/main/java/org/openhab/binding/fritzbox/internal/FritzboxBinding.java +++ b/bundles/binding/org.openhab.binding.fritzbox/src/main/java/org/openhab/binding/fritzbox/internal/FritzboxBinding.java @@ -78,11 +78,15 @@ public class FritzboxBinding extends "ctlmgr_ctl w dect settings/enabled"); commandMap.put(FritzboxBindingProvider.TYPE_WLAN, "ctlmgr_ctl w wlan settings/ap_enabled"); + commandMap.put(FritzboxBindingProvider.TYPE_GUEST_WLAN, + "ctlmgr_ctl w wlan settings/guest_ap_enabled"); queryMap.put(FritzboxBindingProvider.TYPE_DECT, "ctlmgr_ctl r dect settings/enabled"); queryMap.put(FritzboxBindingProvider.TYPE_WLAN, "ctlmgr_ctl r wlan settings/ap_enabled"); + queryMap.put(FritzboxBindingProvider.TYPE_GUEST_WLAN, + "ctlmgr_ctl r wlan settings/guest_ap_enabled"); } @Override @@ -248,6 +252,8 @@ private static class TelnetCommandThread extends Thread { "ctlmgr_ctl w dect settings/enabled"); commandMap.put(FritzboxBindingProvider.TYPE_WLAN, "ctlmgr_ctl w wlan settings/ap_enabled"); + commandMap.put(FritzboxBindingProvider.TYPE_GUEST_WLAN, + "ctlmgr_ctl w wlan settings/guest_ap_enabled"); } public TelnetCommandThread(String type, Command command) { diff --git a/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/bus/HomematicBinding.java b/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/bus/HomematicBinding.java index ca3ca984f9b..5383da88a04 100644 --- a/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/bus/HomematicBinding.java +++ b/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/bus/HomematicBinding.java @@ -183,15 +183,24 @@ protected void internalReceiveUpdate(String itemName, State newState) { /** * Restarts the Homematic communicator if no messages arrive within a - * configured time. + * configured time or the reconnect interval is reached. */ @Override protected void execute() { - long timeSinceLastEvent = (System.currentTimeMillis() - communicator.getLastEventTime()) / 1000; - if (timeSinceLastEvent > context.getConfig().getAliveInterval()) { - logger.info("No event since {} seconds, refreshing Homematic server connections", timeSinceLastEvent); - communicator.stop(); - communicator.start(); + if (context.getConfig().getReconnectInterval() == null) { + long timeSinceLastEvent = (System.currentTimeMillis() - communicator.getLastEventTime()) / 1000; + if (timeSinceLastEvent >= context.getConfig().getAliveInterval()) { + logger.info("No event since {} seconds, refreshing Homematic server connections", timeSinceLastEvent); + communicator.stop(); + communicator.start(); + } + } else { + long timeSinceLastReconnect = (System.currentTimeMillis() - communicator.getLastReconnectTime()) / 1000; + if (timeSinceLastReconnect >= context.getConfig().getReconnectInterval()) { + logger.info("Reconnect interval reached, refreshing Homematic server connections"); + communicator.stop(); + communicator.start(); + } } } @@ -208,7 +217,7 @@ protected long getRefreshInterval() { */ @Override protected String getName() { - return "Homematic server keep alive thread"; + return "Homematic server connection tracker"; } } diff --git a/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/common/HomematicConfig.java b/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/common/HomematicConfig.java index 96945469d43..0630430aff7 100644 --- a/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/common/HomematicConfig.java +++ b/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/common/HomematicConfig.java @@ -16,14 +16,16 @@ import org.openhab.binding.homematic.internal.model.HmInterface; import org.openhab.binding.homematic.internal.util.LocalNetworkInterface; import org.osgi.service.cm.ConfigurationException; + /** * Parses the config in openhab.cfg. + * *

        * ############################## Homematic Binding ##############################
        * #
        * # Hostname / IP address of the Homematic CCU or Homegear server
        * homematic:host=
      - *
      + * 
        * # Hostname / IP address for the callback server (optional, default is auto-discovery)
        * # This is normally the IP / hostname of the local host (but not "localhost" or "127.0.0.1"). 
        * # homematic:callback.host=
      @@ -33,7 +35,14 @@
        * 
        * # The interval in seconds to check if the communication with the Homematic server is still alive.
        * # If no message receives from the Homematic server, the binding restarts. (optional, default is 300)
      - * # homematic:alive.interval
      + * # homematic:alive.interval=
      + * 
      + * # The interval in seconds to reconnect to the Homematic server (optional, default is disabled)
      + * # If you have no sensors which sends messages in regular intervals and/or you have low communication, 
      + * # the alive.interval may restart the connection to the Homematic server to often.
      + * # The reconnect.interval disables the alive.interval and reconnects after a fixed period in time. 
      + * # Think in hours when configuring (one hour = 3600)
      + * # homematic:reconnect.interval=
        * 
      * * @author Gerhard Riegler @@ -44,6 +53,7 @@ public class HomematicConfig { private static final String CONFIG_KEY_CALLBACK_HOST = "callback.host"; private static final String CONFIG_KEY_CALLBACK_PORT = "callback.port"; private static final String CONFIG_KEY_ALIVE_INTERVAL = "alive.interval"; + private static final String CONFIG_KEY_RECONNECT_INTERVAL = "reconnect.interval"; private static final Integer DEFAULT_CALLBACK_PORT = 9123; private static final int DEFAULT_ALIVE_INTERVAL = 300; @@ -53,6 +63,7 @@ public class HomematicConfig { private String callbackHost; private Integer callbackPort; private Integer aliveInterval; + private Integer reconnectInterval; /** * Parses and validates the properties in the openhab.cfg. @@ -73,7 +84,7 @@ public void parse(Dictionary properties) throws ConfigurationExceptio callbackPort = parseInt(properties, CONFIG_KEY_CALLBACK_PORT, DEFAULT_CALLBACK_PORT); aliveInterval = parseInt(properties, CONFIG_KEY_ALIVE_INTERVAL, DEFAULT_ALIVE_INTERVAL); - + reconnectInterval = parseInt(properties, CONFIG_KEY_RECONNECT_INTERVAL, null); valid = true; } @@ -124,6 +135,13 @@ public Integer getAliveInterval() { return aliveInterval; } + /** + * Returns the reconnect interval. + */ + public Integer getReconnectInterval() { + return reconnectInterval; + } + /** * Returns true if this config is valid. */ @@ -149,6 +167,7 @@ public String getTclRegaUrl() { public String toString() { return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("host", host) .append("callbackHost", callbackHost).append("callbackPort", callbackPort) - .append("aliveInterval", aliveInterval).toString(); + .append("aliveInterval", reconnectInterval == null ? aliveInterval : "disabled") + .append("reconnectInterval", reconnectInterval == null ? "disabled" : reconnectInterval).toString(); } } diff --git a/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/HomematicCommunicator.java b/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/HomematicCommunicator.java index 9b0c6236ae2..9cb7443c96d 100644 --- a/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/HomematicCommunicator.java +++ b/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/HomematicCommunicator.java @@ -57,6 +57,7 @@ public class HomematicCommunicator implements HomematicCallbackReceiver { private ItemDisabler itemDisabler; private long lastEventTime = System.currentTimeMillis(); + private long lastReconnectTime = System.currentTimeMillis(); private HomematicPublisher publisher = new HomematicPublisher(); /** * Starts the communicator and initializes everything. @@ -89,6 +90,8 @@ public void start() { homematicClient.registerCallback(); scheduleFirstRefresh(); + + lastReconnectTime = System.currentTimeMillis(); } catch (Exception e) { logger.error("Could not start Homematic communicator: " + e.getMessage(), e); stop(); @@ -101,7 +104,7 @@ public void start() { * initial load and server startup */ private void scheduleFirstRefresh() { - logger.info("Scheduling one datapoint reload job in 60 seconds"); + logger.info("Scheduling one datapoint reload job in one minute"); delayedExecutor.schedule(new TimerTask() { @Override @@ -109,7 +112,7 @@ public void run() { logger.debug("Initial Homematic datapoints reload"); context.getStateHolder().reloadDatapoints(); } - }, 60000); + }, 61000); // 61 seconds to prevent reload at a reconnect } /** @@ -377,5 +380,12 @@ public void newDevices(String interfaceId, Object[] deviceDescriptions) { public long getLastEventTime() { return lastEventTime; } + + /** + * Returns the timestamp from the last Homematic server reconnect. + */ + public long getLastReconnectTime() { + return lastReconnectTime; + } } diff --git a/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/converter/ConverterFactory.java b/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/converter/ConverterFactory.java index 2902ccbdb51..a395f26ed57 100644 --- a/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/converter/ConverterFactory.java +++ b/bundles/binding/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/converter/ConverterFactory.java @@ -8,6 +8,7 @@ */ package org.openhab.binding.homematic.internal.converter; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -47,7 +48,7 @@ public Converter createConverter(Item item, HomematicBindingCon return ((ValueBindingConfig) bindingConfig).getConverter(); } - List> acceptedTypes = item.getAcceptedDataTypes(); + List> acceptedTypes = new ArrayList>(item.getAcceptedDataTypes()); Collections.sort(acceptedTypes, typeComparator); for (Class clazz : acceptedTypes) { diff --git a/bundles/binding/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueBinding.java b/bundles/binding/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueBinding.java index 5c814c0fb2f..81bff226b1a 100644 --- a/bundles/binding/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueBinding.java +++ b/bundles/binding/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueBinding.java @@ -94,6 +94,10 @@ public void execute() { // Observation : If the power of a hue lamp is removed, the status is not updated in hue hub. // The heartbeat functionality should fix this, but HueSettings settings = activeBridge.getSettings(); + if (settings == null) { + logger.debug("Hue settings were null, maybe misconfigured bridge IP."); + return; + } for (int i = 1; i <= settings.getCount(); i++) { HueBulb bulb = bulbCache.get(i); if (bulb == null) { diff --git a/bundles/binding/org.openhab.binding.iec6205621meter/.classpath b/bundles/binding/org.openhab.binding.iec6205621meter/.classpath index 25137043b62..4d2554f5302 100644 --- a/bundles/binding/org.openhab.binding.iec6205621meter/.classpath +++ b/bundles/binding/org.openhab.binding.iec6205621meter/.classpath @@ -4,6 +4,5 @@ - diff --git a/bundles/binding/org.openhab.binding.insteonplm/.classpath b/bundles/binding/org.openhab.binding.insteonplm/.classpath index ea4fe6a76b3..4a28cf8c51d 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/.classpath +++ b/bundles/binding/org.openhab.binding.insteonplm/.classpath @@ -4,6 +4,5 @@ - diff --git a/bundles/binding/org.openhab.binding.insteonplm/META-INF/MANIFEST.MF b/bundles/binding/org.openhab.binding.insteonplm/META-INF/MANIFEST.MF index 69770e7e227..629f40786b8 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/META-INF/MANIFEST.MF +++ b/bundles/binding/org.openhab.binding.insteonplm/META-INF/MANIFEST.MF @@ -23,7 +23,13 @@ Import-Package: gnu.io, org.osgi.service.cm, org.osgi.service.component, org.osgi.service.event, - org.slf4j + org.slf4j, + org.apache.http, + org.apache.http.auth, + org.apache.http.client, + org.apache.http.client.methods, + org.apache.http.impl.client, + org.apache.http.util Export-Package: org.openhab.binding.insteonplm Bundle-DocURL: http://www.openhab.org Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/InsteonPLMActiveBinding.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/InsteonPLMActiveBinding.java index bc088255174..82fbe349e84 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/InsteonPLMActiveBinding.java +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/InsteonPLMActiveBinding.java @@ -342,8 +342,11 @@ private void initialize() { m_driver.addMsgListener(m_portListener, port); } } + logger.debug("setting driver listener"); m_driver.setDriverListener(m_portListener); + logger.debug("starting {} ports", m_driver.getNumberOfPorts()); m_driver.startAllPorts(); + logger.debug("ports started"); switch (m_driver.getNumberOfPorts()) { case 0: logger.error("initialization complete, but found no ports!"); @@ -351,7 +354,7 @@ private void initialize() { case 1: logger.debug("initialization complete, found 1 port!"); break; - case 2: + default: logger.warn("initialization complete, found {} ports.", m_driver.getNumberOfPorts()); break; diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/InsteonPLMBindingConfig.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/InsteonPLMBindingConfig.java index 352d417c17d..463a002531f 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/InsteonPLMBindingConfig.java +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/InsteonPLMBindingConfig.java @@ -73,6 +73,14 @@ public InsteonPLMBindingConfig(String name, InsteonAddress adr, String feature, public HashMap getParameters() { return params; } + /** + * Returns a parameter that starts with key= + * @param key + * @return parameter value or null if not found + */ + public String getParameter(String key) { + return (params == null ? null : params.get(key)); + } public String toString() { String s = "addr=" + ((address != null) ? address.toString() : "null_address"); diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/CommandHandler.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/CommandHandler.java index 71bac5146a1..304ba4e0eb1 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/CommandHandler.java +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/CommandHandler.java @@ -14,6 +14,7 @@ import java.util.TimerTask; import org.openhab.binding.insteonplm.InsteonPLMBindingConfig; +import org.openhab.binding.insteonplm.internal.device.DeviceFeatureListener.StateChangeType; import org.openhab.binding.insteonplm.internal.driver.Driver; import org.openhab.binding.insteonplm.internal.driver.ModemDBEntry; import org.openhab.binding.insteonplm.internal.message.FieldException; @@ -67,7 +68,14 @@ protected int getIntParameter(String key, int def) { } return def; } - + /** + * Shorthand to return class name for logging purposes + * @return name of the class + */ + protected String nm() { + return (this.getClass().getSimpleName()); + } + protected int getMaxLightLevel(InsteonPLMBindingConfig conf, int defaultLevel) { HashMap params = conf.getParameters(); if (conf.getFeature().contains("dimmer") && params.containsKey("dimmermax")) { @@ -114,7 +122,7 @@ public static class WarnCommandHandler extends CommandHandler { WarnCommandHandler(DeviceFeature f) { super(f); } @Override public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevice dev) { - logger.warn("command {} is not implemented yet!", cmd); + logger.warn("{}: command {} is not implemented yet!", nm(), cmd); } } @@ -136,19 +144,19 @@ public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevi Msg m = dev.makeStandardMessage((byte) 0x0f, (byte) 0x11, (byte) level, s_getGroup(conf)); dev.enqueueMessage(m, m_feature); - logger.info("LightOnOffCommandHandler: sent msg to switch {} to {}", dev.getAddress(), + logger.info("{}: sent msg to switch {} to {}", nm(), dev.getAddress(), level == 0xff ? "on" : level); } else if (cmd == OnOffType.OFF) { Msg m = dev.makeStandardMessage((byte) 0x0f, (byte) 0x13, (byte) 0x00, s_getGroup(conf)); dev.enqueueMessage(m, m_feature); - logger.info("LightOnOffCommandHandler: sent msg to switch {} off", dev.getAddress()); + logger.info("{}: sent msg to switch {} off", nm(), dev.getAddress()); } // expect to get a direct ack after this! } catch (IOException e) { - logger.error("command send i/o error: ", e); + logger.error("{}: command send i/o error: ", nm(), e); } catch (FieldException e) { - logger.error("command send message creation error ", e); + logger.error("{}: command send message creation error ", nm(), e); } } } @@ -184,19 +192,19 @@ public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevi m.setByte("userData2", (byte) 0x09); m.setByte("userData3", (byte) 0x01); dev.enqueueMessage(m, m_feature); - logger.info("LEDOnOffCommandHandler: sent msg to switch {} on", dev.getAddress()); + logger.info("{}: sent msg to switch {} on", nm(), dev.getAddress()); } else if (cmd == OnOffType.OFF) { Msg m = dev.makeExtendedMessage((byte) 0x1f, (byte)0x2e, (byte)0x00); m.setByte("userData1", (byte)button); m.setByte("userData2", (byte) 0x09); m.setByte("userData3", (byte) 0x00); dev.enqueueMessage(m, m_feature); - logger.info("LEDOnOffCommandHandler: sent msg to switch {} off", dev.getAddress()); + logger.info("{}: sent msg to switch {} off", nm(), dev.getAddress()); } } catch (IOException e) { - logger.error("command send i/o error: ", e); + logger.error("{}: command send i/o error: ", nm(), e); } catch (FieldException e) { - logger.error("command send message creation error ", e); + logger.error("{}: command send message creation error ", nm(), e); } } } @@ -216,12 +224,12 @@ public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevi Msg mcmd = dev.makeX10Message(houseCommandCode,(byte)0x80); // send command code dev.enqueueMessage(mcmd, m_feature); String onOff = cmd == OnOffType.ON ? "ON" : "OFF"; - logger.info("X10OnOffCommandHandler: sent msg to switch {} {}", dev.getAddress(), onOff); + logger.info("{}: sent msg to switch {} {}", nm(), dev.getAddress(), onOff); } } catch (IOException e) { - logger.error("command send i/o error: ", e); + logger.error("{}: command send i/o error: ", nm(), e); } catch (FieldException e) { - logger.error("command send message creation error ", e); + logger.error("{}: command send message creation error ", nm(), e); } } } @@ -240,7 +248,7 @@ public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevi Msg munit = dev.makeX10Message(houseUnitCode, (byte)0x00); // send unit code dev.enqueueMessage(munit, m_feature); PercentType pc = (PercentType)cmd; - logger.debug("changing level of {} to {}", dev.getAddress(), pc.intValue()); + logger.debug("{}: changing level of {} to {}", nm(), dev.getAddress(), pc.intValue()); int level = (pc.intValue() * 32) / 100; byte cmdCode = (level >= 16) ? X10.Command.PRESET_DIM_2.code() : X10.Command.PRESET_DIM_1.code(); @@ -251,9 +259,9 @@ public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevi Msg mcmd = dev.makeX10Message(cmdCode,(byte)0x80); // send command code dev.enqueueMessage(mcmd, m_feature); } catch (IOException e) { - logger.error("command send i/o error: ", e); + logger.error("{}: command send i/o error: ", nm(), e); } catch (FieldException e) { - logger.error("command send message creation error ", e); + logger.error("{}: command send message creation error ", nm(), e); } } static private final int [] s_X10CodeForLevel = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}; @@ -275,13 +283,12 @@ public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevi Msg mcmd = dev.makeX10Message(houseCommandCode,(byte)0x80); // send command code dev.enqueueMessage(mcmd, m_feature); String bd = cmd == IncreaseDecreaseType.INCREASE ? "BRIGHTEN" : "DIM"; - logger.info("X10IncreaseDecreaseCommandHandler: sent msg to switch {} {}", - dev.getAddress(), bd); + logger.info("{}: sent msg to switch {} {}", nm(), dev.getAddress(), bd); } } catch (IOException e) { - logger.error("command send i/o error: ", e); + logger.error("{}: command send i/o error: ", nm(), e); } catch (FieldException e) { - logger.error("command send message creation error ", e); + logger.error("{}: command send message creation error ", nm(), e); } } } @@ -294,11 +301,11 @@ public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevi if (cmd == OnOffType.ON) { Msg m = dev.makeStandardMessage((byte) 0x0f, (byte) 0x11, (byte) 0xff); dev.enqueueMessage(m, m_feature); - logger.info("IOLincOnOffCommandHandler: sent msg to switch {} on", dev.getAddress()); + logger.info("{}: sent msg to switch {} on", nm(), dev.getAddress()); } else if (cmd == OnOffType.OFF) { Msg m = dev.makeStandardMessage((byte) 0x0f, (byte) 0x13, (byte) 0x00); dev.enqueueMessage(m, m_feature); - logger.info("IOLincOnOffCommandHandler: sent msg to switch {} off", dev.getAddress()); + logger.info("{}: sent msg to switch {} off", nm(), dev.getAddress()); } // This used to be configurable, but was made static to make // the architecture of the binding cleaner. @@ -315,31 +322,31 @@ public void run() { } }, delay); } catch (IOException e) { - logger.error("command send i/o error: ", e); + logger.error("{}: command send i/o error: ", nm(), e); } catch (FieldException e) { - logger.error("command send message creation error: ", e); + logger.error("{}: command send message creation error: ", nm(), e); } } } - public static class IncreaseDecreaseHandler extends CommandHandler { - IncreaseDecreaseHandler(DeviceFeature f) { super(f); } + public static class IncreaseDecreaseCommandHandler extends CommandHandler { + IncreaseDecreaseCommandHandler(DeviceFeature f) { super(f); } @Override public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevice dev) { try { if (cmd == IncreaseDecreaseType.INCREASE) { Msg m = dev.makeStandardMessage((byte) 0x0f, (byte) 0x15, (byte) 0x00); dev.enqueueMessage(m, m_feature); - logger.info("IncreaseDecreaseHandler: sent msg to brighten {}", dev.getAddress()); + logger.info("{}: sent msg to brighten {}", nm(), dev.getAddress()); } else if (cmd == IncreaseDecreaseType.DECREASE) { Msg m = dev.makeStandardMessage((byte) 0x0f, (byte) 0x16, (byte) 0x00); dev.enqueueMessage(m, m_feature); - logger.info("IncreaseDecreaseHandler: sent msg to dimm {}", dev.getAddress()); + logger.info("{}: sent msg to dimm {}", nm(), dev.getAddress()); } } catch (IOException e) { - logger.error("command send i/o error: ", e); + logger.error("{}: command send i/o error: ", nm(), e); } catch (FieldException e) { - logger.error("command send message creation error ", e); + logger.error("{}: command send message creation error ", nm(), e); } } } @@ -355,19 +362,55 @@ public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevi level = getMaxLightLevel(conf, level); Msg m = dev.makeStandardMessage((byte) 0x0f, (byte) 0x11, (byte) level); dev.enqueueMessage(m, m_feature); - logger.info("PercentHandler: sent msg to set {} to {}", dev.getAddress(), level); + logger.info("{}: sent msg to set {} to {}", nm(), dev.getAddress(), level); } else { // switch off Msg m = dev.makeStandardMessage((byte) 0x0f, (byte) 0x13, (byte) 0x00); dev.enqueueMessage(m, m_feature); - logger.info("PercentHandler: sent msg to set {} to zero by switching off", dev.getAddress()); + logger.info("{}: sent msg to set {} to zero by switching off", nm(), dev.getAddress()); + } + } catch (IOException e) { + logger.error("{}: command send i/o error: ", nm(), e); + } catch (FieldException e) { + logger.error("{}: command send message creation error ", nm(), e); + } + } + } + + public static class PowerMeterCommandHandler extends CommandHandler { + PowerMeterCommandHandler(DeviceFeature f) { super(f); } + @Override + public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevice dev) { + String cmdParam = conf.getParameter("cmd"); + if (cmdParam == null) { + logger.error("{} ignoring cmd {} because no cmd= is configured!", nm(), cmd); + return; + } + try { + if (cmd == OnOffType.ON) { + if (cmdParam.equals("reset")) { + Msg m = dev.makeStandardMessage((byte) 0x0f, (byte) 0x80, (byte) 0x00); + dev.enqueueMessage(m, m_feature); + logger.info("{}: sent reset msg to power meter {}", nm(), dev.getAddress()); + m_feature.publish(OnOffType.OFF, StateChangeType.ALWAYS, "cmd", "reset"); + } else if (cmdParam.equals("update")) { + Msg m = dev.makeStandardMessage((byte) 0x0f, (byte) 0x82, (byte) 0x00); + dev.enqueueMessage(m, m_feature); + logger.info("{}: sent update msg to power meter {}", nm(), dev.getAddress()); + m_feature.publish(OnOffType.OFF, StateChangeType.ALWAYS, "cmd", "update"); + } else { + logger.error("{}: ignoring unknown cmd {} for power meter {}", nm(), cmdParam, dev.getAddress()); + } + } else if (cmd == OnOffType.OFF) { + logger.info("{}: ignoring off request for power meter {}", nm(), dev.getAddress()); } } catch (IOException e) { - logger.error("command send i/o error: ", e); + logger.error("{}: command send i/o error: ", nm(), e); } catch (FieldException e) { - logger.error("command send message creation error ", e); + logger.error("{}: command send message creation error ", nm(), e); } } } + public static class ModemCommandHandler extends CommandHandler { ModemCommandHandler(DeviceFeature f) { super(f); } @Override @@ -375,12 +418,12 @@ public void handleCommand(InsteonPLMBindingConfig conf, Command cmd, InsteonDevi if (!(cmd instanceof OnOffType) || ((OnOffType) cmd) != OnOffType.ON) return; String removeAddr = conf.getParameters().get("remove_address"); if (!InsteonAddress.s_isValid(removeAddr)) { - logger.debug("invalid remove address: {}", removeAddr); + logger.debug("{}: invalid remove address: {}", nm(), removeAddr); return; } InsteonAddress addr = new InsteonAddress(removeAddr); if (removeFromModem(addr)) { - logger.debug("successfully removed device {} from modem db", addr); + logger.debug("{} successfully removed device {} from modem db", nm(), addr); } } @@ -402,15 +445,15 @@ boolean removeFromModem(InsteonAddress aAddr) { m.setByte("linkData3", (byte)0x00); dbe.getPort().writeMessage(m); removed = true; - logger.info("wrote erase message: {}", m); + logger.info("{}: wrote erase message: {}", nm(), m); } } else { - logger.warn("address {} not found in modem database!", aAddr); + logger.warn("{}: address {} not found in modem database!", nm(), aAddr); } } catch (FieldException e) { - logger.error("field exception: ", e); + logger.error("{}: field exception: ", nm(), e); } catch (IOException e) { - logger.error("i/o exception: ", e); + logger.error("{}: i/o exception: ", nm(), e); } finally { driver.unlockModemDBEntries(); } diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/DeviceFeature.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/DeviceFeature.java index fa7e38dcf23..9e30d686dc9 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/DeviceFeature.java +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/DeviceFeature.java @@ -201,6 +201,26 @@ public Msg makePollMsg() { return m; } + /** + * Publish new state to all device feature listeners, but give them + * additional dataKey and dataValue information so they can decide + * whether to publish the data to the bus. + * + * @param newState state to be published + * @param changeType what kind of changes to publish + * @param dataKey the key on which to filter + * @param dataValue the value that must be matched + */ + public void publish(State newState, StateChangeType changeType, String dataKey, + String dataValue) { + logger.debug("{}:{} publishing: {}", this.getDevice().getAddress(), + getName(), newState); + synchronized(m_listeners) { + for (DeviceFeatureListener listener : m_listeners) { + listener.stateChanged(newState, changeType, dataKey, dataValue); + } + } + } /** * Publish new state to all device feature listeners * @param newState state to be published diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/DeviceFeatureListener.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/DeviceFeatureListener.java index 4a8daa08a65..79eee93d79a 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/DeviceFeatureListener.java +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/DeviceFeatureListener.java @@ -11,6 +11,8 @@ import java.util.HashMap; import org.openhab.core.types.State; import org.openhab.core.events.EventPublisher; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.PercentType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,15 +50,19 @@ public DeviceFeatureListener(String item, EventPublisher eventPublisher) { public String getItemName() { return m_itemName; } - /** - * Test is given parameter is configured - * @param key parameter to test for - * @return + * Test if string parameter is present and has a given value + * + * @param key key to match + * @param value value to match + * @return true if key exists and value matches */ - public boolean hasParameter(String key) { - return m_parameters != null && m_parameters.get(key) != null; + private boolean parameterHasValue(String key, String value) { + if (m_parameters == null) return false; + String v = m_parameters.get(key); + return (v != null &&v.equals(value)); } + /** * Set parameters for this feature listener * @param p the parameters to set @@ -64,26 +70,7 @@ public boolean hasParameter(String key) { public void setParameters(HashMap p) { m_parameters = p; } - /** - * Gets integer parameter or -1 if not found - * @param key name of parameter to get - * @return value of parameter or -1 if not found - */ - public int getIntParameter(String key) { - return (getIntParameter(key, -1)); - } - /** - * Gets integer parameter or default value - * @param key the parameter key to look for - * @param def the default if key is not found - * @return the value (or default if key is not found) - */ - public int getIntParameter(String key, int def) { - if (m_parameters == null) return def; - String s = m_parameters.get(key); - if (s == null) return def; - return (Integer.parseInt(s)); - } + /** * Publishes a state change on the openhab bus * @param state the new state to publish on the openhab bus @@ -94,14 +81,51 @@ public void stateChanged(State state, StateChangeType changeType) { if (oldState == null) { logger.trace("new state: {}:{}", state.getClass().getSimpleName(), state); // state has changed, must publish - m_eventPublisher.postUpdate(m_itemName, state); + publishState(state); } else { logger.trace("old state: {}:{}=?{}", state.getClass().getSimpleName(), oldState, state); // only publish if state has changed or it is requested explicitly - if (changeType == StateChangeType.ALWAYS || oldState != state) { - m_eventPublisher.postUpdate(m_itemName, state); + if (changeType == StateChangeType.ALWAYS || !oldState.equals(state)) { + publishState(state); } } m_state.put(state.getClass(), state); } + /** + * Call this function to inform about a state change for a given + * parameter key and value. If dataKey and dataValue don't match, + * the state change will be ignored. + * @param state the new state to which the feature has changed + * @param changeType how to process the state change (always, or only when changed) + * @param dataKey the data key on which to filter + * @param dataValue the value that the data key must match for the state to be published + */ + public void stateChanged(State state, StateChangeType changeType, + String dataKey, String dataValue) { + if (parameterHasValue(dataKey, dataValue)) { + stateChanged(state, changeType); + } + } + /** + * Publish the state. In the case of PercentType, if the value is + * 0, send a OnOffType.OFF and if the value is 100, send a OnOffType.ON. + * That way an OpenHAB Switch will work properly with a Insteon dimmer, + * as long it is used like a switch (On/Off). An openHAB DimmerItem will + * internally convert the ON back to 100% and OFF back to 0, so there is + * no need to send both 0/OFF and 100/ON. + * + * @param state the new state of the feature + */ + private void publishState(State state) { + State publishState = state; + if (state instanceof PercentType) { + if (state.equals(PercentType.ZERO)) { + publishState = OnOffType.OFF; + } else if (state.equals(PercentType.HUNDRED)) { + publishState = OnOffType.ON; + } + } + + m_eventPublisher.postUpdate(m_itemName, publishState); + } } diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/InsteonDevice.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/InsteonDevice.java index d1899df9a59..829dfad158c 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/InsteonDevice.java +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/InsteonDevice.java @@ -52,6 +52,9 @@ public static enum DeviceStatus { private Long m_lastMsgReceived = 0L; private boolean m_isModem = false; private Deque m_requestQueue = new LinkedList(); + private DeviceFeature.QueryStatus m_requestQueueState = DeviceFeature.QueryStatus.QUERY_ANSWERED; + private static final long QUERY_TIMEOUT = 2000; + private long m_lastQueryTime = 0L; private boolean m_hasModemDBEntry = false; private DeviceStatus m_status = DeviceStatus.INITIALIZED; @@ -301,6 +304,17 @@ public long processRequestQueue(long timeNow) { if (m_requestQueue.isEmpty()) { return 0L; } + if (m_requestQueueState == DeviceFeature.QueryStatus.QUERY_PENDING) { + long dt = timeNow - (m_lastQueryTime + QUERY_TIMEOUT); + if (dt < 0) { + logger.debug("still waiting for query reply from {} for another {} usec", + m_address, dt); + return (m_lastQueryTime + QUERY_TIMEOUT); + } else { + logger.warn("gave up waiting for query reply from device {}", m_address); + } + } + m_lastQueryTime = timeNow; QEntry qe = m_requestQueue.poll(); qe.getFeature().setQueryStatus(DeviceFeature.QueryStatus.QUERY_PENDING); long quietTime = qe.getMsg().getQuietTime(); @@ -319,13 +333,24 @@ public long processRequestQueue(long timeNow) { * @param f device feature that sent this message (so we can associate the response message with it) */ public void enqueueMessage(Msg m, DeviceFeature f) { + enqueueDelayedMessage(m, f, 0); + } + + /** + * Enqueues message to be sent after a delay + * @param m message to be sent + * @param f device feature that sent this message (so we can associate the response message with it) + * @param d time (in milliseconds)to delay before enqueuing message + */ + public void enqueueDelayedMessage(Msg m, DeviceFeature f, long delay) { synchronized (m_requestQueue) { m_requestQueue.add(new QEntry(f, m)); } long now = System.currentTimeMillis(); - RequestQueueManager.s_instance().addQueue(this, now); + logger.trace("enqueing direct message with delay {}", delay); + RequestQueueManager.s_instance().addQueue(this, now + delay); } - + private void writeMessage(Msg m) throws IOException { m_driver.writeMessage(getPort(), m); } diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/MessageDispatcher.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/MessageDispatcher.java index 0490e137b0c..be98ef49371 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/MessageDispatcher.java +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/MessageDispatcher.java @@ -73,7 +73,8 @@ protected boolean handleAllLinkMessage(Msg msg, String port) { * Dispatches message * @param msg Message to dispatch * @param port Insteon device ('/dev/usb') from which the message came - * @return true if dispatch was successful, false otherwise + * @return true if this message was found to be a reply to a direct message, + * and was claimed by one of the handlers */ public abstract boolean dispatch(Msg msg, String port); @@ -96,10 +97,10 @@ public boolean dispatch(Msg msg, String port) { cmd1 = msg.getByte("command1"); } catch (FieldException e) { logger.debug("no command found, dropping msg {}", msg); - return isConsumed; + return false; } if (handleAllLinkMessage(msg, port)) { - return isConsumed; + return false; } if (msg.isAckOfDirect()) { // in the case of direct ack, the cmd1 code is useless. @@ -127,26 +128,25 @@ public boolean dispatch(Msg msg, String port) { if (isConsumed) { m_feature.setQueryStatus(DeviceFeature.QueryStatus.QUERY_ANSWERED); } - return isConsumed; } } - - private static class GreedyDispatcher extends MessageDispatcher { - GreedyDispatcher(DeviceFeature f) { super(f); } + + private static class SimpleDispatcher extends MessageDispatcher { + SimpleDispatcher(DeviceFeature f) { super(f); } @Override public boolean dispatch(Msg msg, String port) { byte cmd1 = 0x00; - boolean isConsumed = false; try { if (handleAllLinkMessage(msg, port)) { - return isConsumed; + return false; } cmd1 = msg.getByte("command1"); } catch (FieldException e) { logger.debug("no cmd1 found, dropping msg {}", msg); - return isConsumed; + return false; } + boolean isConsumed = msg.isAckOfDirect() && (m_feature.getQueryStatus() == DeviceFeature.QueryStatus.QUERY_PENDING); int key = (cmd1 & 0xFF); MessageHandler h = m_feature.getMsgHandlers().get(key); if (h == null) h = m_feature.getDefaultMsgHandler(); @@ -198,7 +198,7 @@ public boolean dispatch(Msg msg, String port) { public static MessageDispatcher s_makeMessageDispatcher(String name, DeviceFeature f) { if (name.equals("PassThroughDispatcher")) return new PassThroughDispatcher(f); else if (name.equals("DefaultDispatcher")) return new DefaultDispatcher(f); - else if (name.equals("GreedyDispatcher")) return new GreedyDispatcher(f); + else if (name.equals("SimpleDispatcher")) return new SimpleDispatcher(f); else if (name.equals("X10Dispatcher")) return new X10Dispatcher(f); else { logger.error("unimplemented message dispatcher requested: {}", name); diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/MessageHandler.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/MessageHandler.java index c2f7fc32ddf..6944d21142f 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/MessageHandler.java +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/MessageHandler.java @@ -9,6 +9,8 @@ package org.openhab.binding.insteonplm.internal.device; import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.GregorianCalendar; import java.util.HashMap; @@ -240,13 +242,13 @@ public void handleMessage(int group, byte cmd1, Msg msg, if (msg.isAckOfDirect()) { logger.error("{}: device {}: ignoring ack of direct.", nm(), a); } else { - logger.info("{}: device {} was turned on.", nm(), a); - m_feature.publish(OnOffType.ON, StateChangeType.ALWAYS); + logger.info("{}: device {} was turned on. Sending poll request to get actual level", nm(), a); + m_feature.publish(PercentType.HUNDRED, StateChangeType.ALWAYS); // need to poll to find out what level the dimmer is at now. // it may not be at 100% because dimmers can be configured // to switch to e.g. 75% when turned on. Msg m = f.makePollMsg(); - if (m != null) f.getDevice().enqueueMessage(m, f); + if (m != null) f.getDevice().enqueueDelayedMessage(m, f, 1000); } } } @@ -264,8 +266,21 @@ public void handleMessage(int group, byte cmd1, Msg msg, } } - public static class LightOffHandler extends MessageHandler { - LightOffHandler(DeviceFeature p) { super(p); } + public static class LightOffDimmerHandler extends MessageHandler { + LightOffDimmerHandler(DeviceFeature p) { super(p); } + @Override + public void handleMessage(int group, byte cmd1, Msg msg, + DeviceFeature f, String fromPort) { + if (!isDuplicate(msg) && isMybutton(msg, f)) { + logger.info("{}: device {} was turned off.", nm(), + f.getDevice().getAddress()); + f.publish(PercentType.ZERO, StateChangeType.ALWAYS); + } + } + } + + public static class LightOffSwitchHandler extends MessageHandler { + LightOffSwitchHandler(DeviceFeature p) { super(p); } @Override public void handleMessage(int group, byte cmd1, Msg msg, DeviceFeature f, String fromPort) { @@ -301,7 +316,7 @@ public void handleMessage(int group, byte cmd1, Msg msg, m_feature.publish(isOn ? OnOffType.ON : OnOffType.OFF, StateChangeType.CHANGED); } } catch (FieldException e) { - logger.error("error parsing {}: ", msg, e); + logger.error("{} error parsing {}: ", nm(), msg, e); } } /** @@ -360,17 +375,17 @@ public void handleMessage(int group, byte cmd1, Msg msg, cmd2 = 0xff; } - int level = cmd2*100/255; - if (level == 0 && cmd2 > 0) level = 1; if (cmd2 == 0) { - logger.info("{}: set device {} to OFF", nm(), + logger.info("{}: set device {} to level 0", nm(), dev.getAddress()); - m_feature.publish(OnOffType.OFF, StateChangeType.CHANGED); + m_feature.publish(PercentType.ZERO, StateChangeType.CHANGED); } else if (cmd2 == 0xff) { - logger.info("{}: set device {} to ON", nm(), + logger.info("{}: set device {} to level 100", nm(), dev.getAddress()); - m_feature.publish(OnOffType.ON, StateChangeType.CHANGED); + m_feature.publish(PercentType.HUNDRED, StateChangeType.CHANGED); } else { + int level = cmd2*100/255; + if (level == 0) level = 1; logger.info("{}: set device {} to level {}", nm(), dev.getAddress(), level); m_feature.publish(new PercentType(level), StateChangeType.CHANGED); @@ -398,7 +413,8 @@ public void handleMessage(int group, byte cmd1, Msg msg, DeviceFeature f, String fromPort) { InsteonDevice dev = f.getDevice(); if (!msg.isExtended()) { - logger.warn("device {} expected extended msg as info reply, got {}", dev.getAddress(), msg); + logger.warn("{} device {} expected extended msg as info reply, got {}", + nm(), dev.getAddress(), msg); return; } try { @@ -408,14 +424,14 @@ public void handleMessage(int group, byte cmd1, Msg msg, int prodKey = msg.getInt24("userData2", "userData3", "userData4"); int devCat = msg.getByte("userData5"); int subCat = msg.getByte("userData6"); - logger.info("{} got product data: cat: {} subcat: {} key: {} ", dev.getAddress(), devCat, subCat, - Utils.getHexString(prodKey)); + logger.info("{} {} got product data: cat: {} subcat: {} key: {} ", + nm(), dev.getAddress(), devCat, subCat, Utils.getHexString(prodKey)); break; case 0x02: // this is a device text string response message - logger.info("{} got text str {} ", dev.getAddress(), msg); + logger.info("{} {} got text str {} ", nm(), dev.getAddress(), msg); break; default: - logger.warn("unknown cmd2 = {} in info reply message {}", cmd2, msg); + logger.warn("{} unknown cmd2 = {} in info reply message {}", nm(), cmd2, msg); break; } } catch (FieldException e) { @@ -424,23 +440,26 @@ public void handleMessage(int group, byte cmd1, Msg msg, } } - public static class MotionSensorLightReplyHandler extends MessageHandler { - MotionSensorLightReplyHandler(DeviceFeature p) { super(p); } + public static class MotionSensorDataReplyHandler extends MessageHandler { + MotionSensorDataReplyHandler(DeviceFeature p) { super(p); } @Override public void handleMessage(int group, byte cmd1, Msg msg, DeviceFeature f, String fromPort) { InsteonDevice dev = f.getDevice(); if (!msg.isExtended()) { - logger.trace("device {} ignoring non-extended msg {}", dev.getAddress(), msg); + logger.trace("{} device {} ignoring non-extended msg {}", nm(), dev.getAddress(), msg); return; } try { int cmd2 = (int) (msg.getByte("command2") & 0xff); switch (cmd2) { case 0x00: // this is a product data response message + int batteryLevel = msg.getByte("userData12") & 0xff; int lightLevel = msg.getByte("userData11") & 0xff; - logger.debug("{} got light level {}", dev.getAddress(), lightLevel); - m_feature.publish(new DecimalType(lightLevel), StateChangeType.CHANGED); + logger.debug("{}: {} got light level: {}, battery level: {}", + nm(), dev.getAddress(), lightLevel, batteryLevel); + m_feature.publish(new DecimalType(lightLevel), StateChangeType.CHANGED, "field", "light_level"); + m_feature.publish(new DecimalType(batteryLevel), StateChangeType.CHANGED, "field", "battery_level"); break; default: logger.warn("unknown cmd2 = {} in info reply message {}", cmd2, msg); @@ -451,24 +470,27 @@ public void handleMessage(int group, byte cmd1, Msg msg, } } } - - public static class MotionSensorBatteryReplyHandler extends MessageHandler { - MotionSensorBatteryReplyHandler(DeviceFeature p) { super(p); } + + public static class HiddenDoorSensorDataReplyHandler extends MessageHandler { + HiddenDoorSensorDataReplyHandler(DeviceFeature p) { super(p); } @Override public void handleMessage(int group, byte cmd1, Msg msg, DeviceFeature f, String fromPort) { InsteonDevice dev = f.getDevice(); if (!msg.isExtended()) { - logger.warn("device {} expected extended msg as info reply, got {}", dev.getAddress(), msg); + logger.trace("{} device {} ignoring non-extended msg {}", nm(), dev.getAddress(), msg); return; } try { int cmd2 = (int) (msg.getByte("command2") & 0xff); switch (cmd2) { case 0x00: // this is a product data response message - int batteryLevel = msg.getByte("userData12") & 0xff; - logger.debug("{} got battery level {}", dev.getAddress(), batteryLevel); - m_feature.publish(new DecimalType(batteryLevel), StateChangeType.CHANGED); + int batteryLevel = msg.getByte("userData4") & 0xff; + int batteryWatermark = msg.getByte("userData7") & 0xff; + logger.debug("{}: {} got light level: {}, battery level: {}", + nm(), dev.getAddress(), batteryWatermark, batteryLevel); + m_feature.publish(new DecimalType(batteryWatermark), StateChangeType.CHANGED, "field", "battery_watermark_level"); + m_feature.publish(new DecimalType(batteryLevel), StateChangeType.CHANGED, "field", "battery_level"); break; default: logger.warn("unknown cmd2 = {} in info reply message {}", cmd2, msg); @@ -480,6 +502,51 @@ public void handleMessage(int group, byte cmd1, Msg msg, } } + public static class PowerMeterUpdateHandler extends MessageHandler { + PowerMeterUpdateHandler(DeviceFeature p) { super(p); } + @Override + public void handleMessage(int group, byte cmd1, Msg msg, + DeviceFeature f, String fromPort) { + if (msg.isExtended()) { + try { + int b7 = msg.getByte("userData7") & 0xff; + int b8 = msg.getByte("userData8") & 0xff; + int watts = (b7 << 8) | b8; + + int b9 = msg.getByte("userData9") & 0xff; + int b10 = msg.getByte("userData10") & 0xff; + int b11 = msg.getByte("userData11") & 0xff; + int b12 = msg.getByte("userData12") & 0xff; + BigDecimal kwh = BigDecimal.ZERO; + if (b9 != 0xff) { + int e = (b9 << 24) | (b10 << 16) | (b11 << 8) | b12; + kwh = new BigDecimal(e * 65535.0 / (1000 * 60 * 60 * 60)).setScale(4, RoundingMode.HALF_UP); + } + + logger.debug("{}:{} watts: {} kwh: {} ", nm(), f.getDevice().getAddress(), watts, kwh); + m_feature.publish(new DecimalType(kwh), StateChangeType.CHANGED, "field", "kwh"); + m_feature.publish(new DecimalType(watts), StateChangeType.CHANGED, "field", "watts"); + } catch (FieldException e) { + logger.error("error parsing {}: ", msg, e); + } + } + } + } + + public static class PowerMeterResetHandler extends MessageHandler { + PowerMeterResetHandler(DeviceFeature p) { super(p); } + @Override + public void handleMessage(int group, byte cmd1, Msg msg, + DeviceFeature f, String fromPort) { + InsteonDevice dev = f.getDevice(); + logger.info("{}: power meter {} was reset", nm(), dev.getAddress()); + + // poll device to get updated kilowatt hours and watts + Msg m = f.makePollMsg(); + if (m != null) f.getDevice().enqueueMessage(m, f); + } + } + public static class LastTimeHandler extends MessageHandler { LastTimeHandler(DeviceFeature p) { super(p); } @Override @@ -503,7 +570,7 @@ public void handleMessage(int group, byte cmd1a, Msg msg, cmd = msg.getByte("Cmd"); cmd2 = msg.getByte("command2"); } catch (FieldException e) { - logger.debug("no cmd found, dropping msg {}", msg); + logger.debug("{} no cmd found, dropping msg {}", nm(), msg); return; } if (msg.isAckOfDirect() && (f.getQueryStatus() == DeviceFeature.QueryStatus.QUERY_PENDING) @@ -552,7 +619,7 @@ public void handleMessage(int group, byte cmd1, Msg msg, break; } } catch (FieldException e) { - logger.debug("no cmd2 found, dropping msg {}", msg); + logger.debug("{} no cmd2 found, dropping msg {}", nm(), msg); return; } diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/PollHandler.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/PollHandler.java index 88e41b2453b..4aa52a1300a 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/PollHandler.java +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/PollHandler.java @@ -85,6 +85,23 @@ public Msg makeMsg(InsteonDevice d) { } } + public static class PowerMeterPollHandler extends PollHandler { + PowerMeterPollHandler(DeviceFeature f) { super(f); } + @Override + public Msg makeMsg(InsteonDevice d) { + Msg m = null; + try { + m = d.makeStandardMessage((byte)0x0f, (byte)0x82, (byte)0x00); + m.setQuietTime(500L); + } catch (FieldException e) { + logger.warn("error setting field in msg: ", e); + } catch (IOException e) { + logger.error("poll failed with exception ", e); + } + return m; + } + } + public static class NoPollHandler extends PollHandler { NoPollHandler(DeviceFeature f) { super(f); } @Override diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/RequestQueueManager.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/RequestQueueManager.java index fd4a7df2daa..6862460e2b7 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/RequestQueueManager.java +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/device/RequestQueueManager.java @@ -31,7 +31,11 @@ private RequestQueueManager() { m_queueThread = new Thread(new RequestQueueReader()); m_queueThread.start(); } - + /** + * Add device to global request queue + * @param dev + * @param time + */ public void addQueue(InsteonDevice dev, long time) { synchronized (m_requestQueues) { if (!m_requestQueueHash.containsKey(dev)) { diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/IOStream.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/IOStream.java new file mode 100644 index 00000000000..958a9263753 --- /dev/null +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/IOStream.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2010-2013, openHAB.org and others. + * + * 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.insteonplm.internal.driver; + +import java.io.InputStream; +import java.io.OutputStream; + +import org.openhab.binding.insteonplm.internal.driver.hub.HubIOStream; + +/** + * Abstract class for implementation for I/O stream with anything that looks + * like a PLM (e.g. the insteon hub) + * + * @author Bernd Pfrommer + * @author Daniel Pfrommer + * @since 1.7.0 + */ + +public abstract class IOStream { + protected InputStream m_in = null; + protected OutputStream m_out = null; + /** + * Getter for input stream from modem/hub + * @return input stream for incoming data + */ + public InputStream in() { return m_in; } + /** + * Getter for output stream for outgoing data to the modem/hub + * @return + */ + public OutputStream out() { return m_out; } + + /** + * Opens the IOStream + * @return true if open was successful, false if not + */ + public abstract boolean open(); + /** + * Closes the IOStream + */ + public abstract void close(); + + /** + * Creates an IOStream from an allowed config string: + * + * /dev/ttyXYZ (serial port like e.g. usb: /dev/ttyUSB0 or alias /dev/insteon) + * + * /hub2/user:password@myinsteonhub.mydomain.com:25105,poll_time=1000 (insteon hub2 (2014)) + * + * /hub/user:password@myinsteonhub.mydomain.com:9761 (pre-2014 hub with raw tcp PLM access) + * + * @param config + * @return reference to IOStream + */ + + public static IOStream s_create(String config) { + if (config.startsWith("/hub2/")) { + config = config.substring(6); //Get rid of the /hub2/ part + + String user = null; + String pass = null; + String host = null; + int port = 25105; + int pollTime = 1000; // poll time in milliseconds + + String[] parts = config.split(","); // split off options at the end + + //Parse the first part, the address + String[] adr = parts[0].split("@"); + String[] hostPort; + if (adr.length > 1) { + String[] userPass = adr[0].split(":"); + user = userPass[0]; + pass = userPass[1]; + hostPort = adr[1].split(":"); + } else { + hostPort = parts[0].split(":"); + } + + host = hostPort[0]; + if (hostPort.length > 1) port = Integer.parseInt(hostPort[1]); + + // check if additional options are given + if (parts.length > 1) { + if (parts[1].trim().startsWith("poll_time")) { + pollTime = Integer.parseInt(parts[1].split("=")[1].trim()); + } + } + return new HubIOStream(host, port, pollTime, user, pass); + } else if (config.startsWith("/hub/")) { + throw new IllegalArgumentException("old-style hub not implemented yet!"); + } else return new SerialIOStream(config); + } +} diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/Port.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/Port.java index 4d05d53372b..eab011fff81 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/Port.java +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/Port.java @@ -8,16 +8,7 @@ */ package org.openhab.binding.insteonplm.internal.driver; -import gnu.io.CommPort; -import gnu.io.CommPortIdentifier; -import gnu.io.NoSuchPortException; -import gnu.io.PortInUseException; -import gnu.io.SerialPort; -import gnu.io.UnsupportedCommOperationException; - import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.util.ArrayList; import java.util.concurrent.LinkedBlockingQueue; @@ -33,15 +24,21 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * The Port class represents a serial port and thereby its connected Insteon modem. - * It does the initialization of the serial port, and (via its inner classes SerialReader and SerialWriter) + * The Port class represents a port, that is a connection to either an Insteon modem either through + * a serial or USB port, or via an Insteon Hub. + * It does the initialization of the port, and (via its inner classes IOStreamReader and IOStreamWriter) * manages the reading/writing of messages on the Insteon network. * - * The SerialReader and SerialWriter class combined implement the somewhat tricky flow control protocol. + * The IOStreamReader and IOStreamWriter class combined implement the somewhat tricky flow control protocol. * In combination with the MsgFactory class, the incoming data stream is turned into a Msg structure * for further processing by the upper layers (MsgListeners). * + * A write queue is maintained to pace the flow of outgoing messages. Sending messages back-to-back + * can lead to dropped messages. + * + * * @author Bernd Pfrommer + * @author Daniel Pfrommer * @since 1.5.0 */ @@ -49,24 +46,20 @@ public class Port { private static final Logger logger = LoggerFactory.getLogger(Port.class); /** - * A write queue is maintained to pace the flow of outgoing messages. Sending messages back-to-back - * can lead to dropped messages. + * The ReplyType is used to keep track of the state of the serial port receiver */ enum ReplyType { GOT_ACK, WAITING_FOR_ACK, GOT_NACK } + + private IOStream m_ioStream = null; private String m_devName = "INVALID"; private String m_logName = "INVALID"; private Modem m_modem = null; - private SerialReader m_reader = null; - private SerialWriter m_writer = null; - private SerialPort m_port = null; - private InputStream m_in = null; - private OutputStream m_out = null; - private final String m_appName = "PLM"; - private final int m_speed = 19200; // baud rate + private IOStreamReader m_reader = null; + private IOStreamWriter m_writer = null; private final int m_readSize = 1024; // read buffer size private Thread m_readThread = null; private Thread m_writeThread = null; @@ -88,12 +81,13 @@ public Port(String devName, Driver d) { m_logName = devName; m_modem = new Modem(); addListener(m_modem); - m_reader = new SerialReader(); - m_writer = new SerialWriter(); + m_ioStream = IOStream.s_create(devName); + m_reader = new IOStreamReader(); + m_writer = new IOStreamWriter(); } - public boolean isRunning() { return m_running; } public synchronized boolean isModemDBComplete() { return (m_modemDBComplete); } + public boolean isRunning() { return m_running; } public InsteonAddress getAddress() { return m_modem.getAddress(); } public InsteonDevice getModem() { return m_modem.getDevice(); } public String getDeviceName() { return m_devName; } @@ -113,60 +107,34 @@ public void removeListener(MsgListener l) { } } } - + + /** + * Starts threads necessary for reading and writing + */ public void start() { + logger.debug("starting port {}", m_logName); if (m_running) { logger.debug("port {} already running, not started again", m_logName); } - try { - /* by default, RXTX searches only devices /dev/ttyS* and - * /dev/ttyUSB*, and will so not find symlinks. The - * setProperty() call below helps - */ - System.setProperty("gnu.io.rxtx.SerialPorts", m_devName); - CommPortIdentifier ci = - CommPortIdentifier.getPortIdentifier(m_devName); - CommPort cp = ci.open(m_appName, 1000); - if (cp instanceof SerialPort) { - m_port = (SerialPort)cp; - } else { - throw new IllegalStateException("unknown port type"); - } - m_port.setSerialPortParams(m_speed, SerialPort.DATABITS_8, - SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); - m_port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); - logger.debug("setting port speed to {}", m_speed); - m_port.disableReceiveFraming(); - m_port.disableReceiveThreshold(); - m_in = m_port.getInputStream(); - m_out = m_port.getOutputStream(); - m_readThread = new Thread(m_reader); - m_writeThread = new Thread(m_writer); - m_readThread.start(); - m_writeThread.start(); - m_modem.initialize(); - ModemDBBuilder mdbb = new ModemDBBuilder(this); - mdbb.start(); // start downloading the device list - m_running = true; - } catch (IOException e) { - logger.error("cannot open port: {}, got IOException ", m_logName, e); - } catch (PortInUseException e) { - logger.error("cannot open port: {}, it is in use!", m_logName); - } catch (UnsupportedCommOperationException e) { - logger.error("got unsupported operation {} on port {}", - e.getMessage(), m_logName); - } catch (NoSuchPortException e) { - logger.error("got no such port for {}", m_logName); - } catch (IllegalStateException e) { - logger.error("got unknown port type for {}", m_logName); - } finally { - if (!m_running) { - logger.error("failed to open port {}", m_logName); - } else { - logger.info("successfully opened port {}", m_logName); - } + if (!m_ioStream.open()) { + logger.debug("failed to open port {}", m_logName); + return; } + m_readThread = new Thread(m_reader); + m_writeThread = new Thread(m_writer); + m_readThread.setName(m_logName + " Reader"); + m_writeThread.setName(m_logName + " Writer"); + m_readThread.start(); + m_writeThread.start(); + m_modem.initialize(); + ModemDBBuilder mdbb = new ModemDBBuilder(this); + mdbb.start(); // start downloading the device list + m_running = true; } + + /** + * Stops all threads + */ public void stop() { if (!m_running) { logger.debug("port {} not running, no need to stop it", m_logName); @@ -189,14 +157,17 @@ public void stop() { logger.debug("got interrupted waiting for write thread to exit."); } logger.debug("all threads for port {} stopped.", m_logName); - if (m_port != null) { - m_port.close(); - } + m_ioStream.close(); m_running = false; synchronized (m_listeners) { m_listeners.clear(); } } + /** + * Adds message to the write queue + * @param m message to be added to the write queue + * @throws IOException + */ public void writeMessage(Msg m) throws IOException { if (m == null) { logger.error("trying to write null message!"); @@ -215,6 +186,9 @@ public void writeMessage(Msg m) throws IOException { } + /** + * Gets called by the modem database builder when the modem database is complete + */ public void modemDBComplete() { synchronized (this) { m_modemDBComplete = true; @@ -223,60 +197,79 @@ public void modemDBComplete() { } /** - * The SerialReader uses the MsgFactory to turn the incoming bytes into - * Msgs for the listeners. It also communicates with the SerialWriter - * via a synchronized objects to implement flow control (tell the SerialWriter - * that it needs to retransmit, or the message has been received correctly). + * The IOStreamReader uses the MsgFactory to turn the incoming bytes into + * Msgs for the listeners. It also communicates with the IOStreamWriter + * to implement flow control (tell the IOStreamWriter that it needs to retransmit, + * or the reply message has been received correctly). * - * @author pfrommer + * @author Bernd Pfrommer */ - class SerialReader implements Runnable { - private ReplyType m_reply = ReplyType.GOT_ACK; + class IOStreamReader implements Runnable { + + private ReplyType m_reply = ReplyType.GOT_ACK; + private Object m_replyLock = new Object(); + /** + * Helper function for implementing synchronization between reader and writer + * @return reference to the RequesReplyLock + */ + public Object getRequestReplyLock() { return m_replyLock; } + @Override public void run() { + logger.debug("starting reader..."); byte[] buffer = new byte[2 * m_readSize]; int len = -1; try { - while ((len = m_in.read(buffer, 0, m_readSize)) > -1) { + while ((len = m_ioStream.in().read(buffer, 0, m_readSize)) > -1) { m_msgFactory.addData(buffer, len); - // must call processData() until we get a null pointer back - try { - for (Msg m = m_msgFactory.processData(); m != null; - m = m_msgFactory.processData()) { - toAllListeners(m); - notifyWaiters(m); - } - } catch (IOException e) { - // got bad data from modem, - // unblock those waiting for ack - logger.warn("bad data received: {}", e.toString()); - if (m_reply == ReplyType.WAITING_FOR_ACK) { - logger.warn("got bad data back, must assume message was acked."); - m_reply = ReplyType.GOT_ACK; - notify(); - } - } + processMessages(); } } catch (IOException e) { e.printStackTrace(); - logger.error("got io exception on port {}, port is no longer read!", m_logName); + logger.error("got read IOException on port {}, port is now disabled!", m_logName); } } - private synchronized void notifyWaiters(Msg msg) { - if (m_reply == ReplyType.WAITING_FOR_ACK) { - if (!msg.isUnsolicited()) { - m_reply = (msg.isPureNack() ? ReplyType.GOT_NACK : ReplyType.GOT_ACK); - logger.trace("signaling receipt of ack: {}", (m_reply == ReplyType.GOT_ACK)); - notify(); - } else if (msg.isPureNack()){ - m_reply = ReplyType.GOT_NACK; - logger.trace("signaling receipt of pure nack"); - notify(); - } else { - logger.trace("got unsolicited message"); + + private void processMessages() { + try { + // must call processData() until we get a null pointer back + for (Msg m = m_msgFactory.processData(); m != null; + m = m_msgFactory.processData()) { + toAllListeners(m); + notifyWriter(m); + } + } catch (IOException e) { + // got bad data from modem, + // unblock those waiting for ack + logger.warn("bad data received: {}", e.toString()); + synchronized (getRequestReplyLock()) { + if (m_reply == ReplyType.WAITING_FOR_ACK) { + logger.warn("got bad data back, must assume message was acked."); + m_reply = ReplyType.GOT_ACK; + getRequestReplyLock().notify(); + } + } + } + } + + private void notifyWriter(Msg msg) { + synchronized (getRequestReplyLock()) { + if (m_reply == ReplyType.WAITING_FOR_ACK) { + if (!msg.isUnsolicited()) { + m_reply = (msg.isPureNack() ? ReplyType.GOT_NACK : ReplyType.GOT_ACK); + logger.trace("signaling receipt of ack: {}", (m_reply == ReplyType.GOT_ACK)); + getRequestReplyLock().notify(); + } else if (msg.isPureNack()){ + m_reply = ReplyType.GOT_NACK; + logger.trace("signaling receipt of pure nack"); + getRequestReplyLock().notify(); + } else { + logger.trace("got unsolicited message"); + } } } } + @SuppressWarnings("unchecked") private void toAllListeners(Msg msg) { // When we deliver the message, the recipient @@ -295,15 +288,15 @@ private void toAllListeners(Msg msg) { /** * Blocking wait for ack or nack from modem. - * Called by SerialWriter for flow control. + * Called by IOStreamWriter for flow control. * @return true if retransmission is necessary */ - public synchronized boolean waitForReply() { + public boolean waitForReply() { m_reply = ReplyType.WAITING_FOR_ACK; while (m_reply == ReplyType.WAITING_FOR_ACK) { try { logger.trace("writer waiting for ack."); - wait(); + getRequestReplyLock().wait(); logger.trace("writer got ack: {}", (m_reply == ReplyType.GOT_ACK)); } catch (InterruptedException e) { // do nothing @@ -313,14 +306,16 @@ public synchronized boolean waitForReply() { } } /** - * Writes messages to the serial port. Flow control is implemented following Insteon + * Writes messages to the port. Flow control is implemented following Insteon * documents to avoid over running the modem. + * + * @author Bernd Pfrommer */ - class SerialWriter implements Runnable { + class IOStreamWriter implements Runnable { private static final int WAIT_TIME = 200; // milliseconds @Override public void run() { - logger.debug("Starting writer..."); + logger.debug("starting writer..."); while(true) { try { // this call blocks until the lock on the queue is released @@ -334,11 +329,14 @@ public void run() { // file definitions be available *before* the modem link records, // slow down the modem traffic with the following statement: // Thread.sleep(500); - m_out.write(msg.getData()); - while (m_reader.waitForReply()) { - Thread.sleep(WAIT_TIME); - logger.trace("retransmitting msg: {}", msg); - m_out.write(msg.getData()); + synchronized (m_reader.getRequestReplyLock()) { + m_ioStream.out().write(msg.getData()); + while (m_reader.waitForReply()) { + Thread.sleep(WAIT_TIME); + logger.trace("retransmitting msg: {}", msg); + m_ioStream.out().write(msg.getData()); + } + } // if rate limited, need to sleep now. if (msg.getQuietTime() > 0) { diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/SerialIOStream.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/SerialIOStream.java new file mode 100644 index 00000000000..e518445f5d9 --- /dev/null +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/SerialIOStream.java @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2010-2013, openHAB.org and others. + * + * 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.insteonplm.internal.driver; + +import gnu.io.CommPort; +import gnu.io.CommPortIdentifier; +import gnu.io.NoSuchPortException; +import gnu.io.PortInUseException; +import gnu.io.SerialPort; +import gnu.io.UnsupportedCommOperationException; + +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** +* Implements IOStream for serial devices. +* +* @author Bernd Pfrommer +* @author Daniel Pfrommer +* @since 1.7.0 +*/ +public class SerialIOStream extends IOStream { + private static final Logger logger = LoggerFactory.getLogger(SerialIOStream.class); + private SerialPort m_port = null; + private final String m_appName = "PLM"; + private final int m_speed = 19200; // baud rate + private String m_devName = null; + + public SerialIOStream(String devName) { + m_devName = devName; + } + + @Override + public boolean open() { + try { + /* by default, RXTX searches only devices /dev/ttyS* and + * /dev/ttyUSB*, and will so not find symlinks. The + * setProperty() call below helps + */ + System.setProperty("gnu.io.rxtx.SerialPorts", m_devName); + CommPortIdentifier ci = + CommPortIdentifier.getPortIdentifier(m_devName); + CommPort cp = ci.open(m_appName, 1000); + if (cp instanceof SerialPort) { + m_port = (SerialPort)cp; + } else { + throw new IllegalStateException("unknown port type"); + } + m_port.setSerialPortParams(m_speed, SerialPort.DATABITS_8, + SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); + m_port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); + logger.debug("setting port speed to {}", m_speed); + m_port.disableReceiveFraming(); + m_port.enableReceiveThreshold(1); + m_port.disableReceiveTimeout(); + m_in = m_port.getInputStream(); + m_out = m_port.getOutputStream(); + logger.info("successfully opened port {}", m_devName); + return true; + } catch (IOException e) { + logger.error("cannot open port: {}, got IOException ", m_devName, e); + } catch (PortInUseException e) { + logger.error("cannot open port: {}, it is in use!", m_devName); + } catch (UnsupportedCommOperationException e) { + logger.error("got unsupported operation {} on port {}", + e.getMessage(), m_devName); + } catch (NoSuchPortException e) { + logger.error("got no such port for {}", m_devName); + } catch (IllegalStateException e) { + logger.error("got unknown port type for {}", m_devName); + } + return false; + } + + @Override + public void close() { + if (m_port != null) { + m_port.close(); + } + m_port = null; + } + + +} diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/hub/HubIOStream.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/hub/HubIOStream.java new file mode 100644 index 00000000000..178e71c9843 --- /dev/null +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/hub/HubIOStream.java @@ -0,0 +1,287 @@ +/** + * Copyright (c) 2010-2013, openHAB.org and others. + * + * 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.insteonplm.internal.driver.hub; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigInteger; +import java.nio.ByteBuffer; + +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.util.EntityUtils; +import org.openhab.binding.insteonplm.internal.driver.IOStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implements IOStream for a Hub 2014 device + * @author Daniel Pfrommer + * @since 1.7.0 + * + */ +public class HubIOStream extends IOStream implements Runnable { + private static final Logger logger = LoggerFactory.getLogger(HubIOStream.class); + + /** time between polls (in milliseconds */ + private int m_pollTime = 1000; + + private String m_host = null; + private int m_port = -1; + private String m_user = null; + private String m_pass = null; + + private DefaultHttpClient m_client = null; + private Thread m_pollThread = null; + + // index of the last byte we have read in the buffer + private int m_bufferIdx = -1; + + /** + * Constructor for HubIOStream + * @param host host name of hub device + * @param port port to connect to + * @param pollTime time between polls (in milliseconds) + * @param user hub user name + * @param pass hub password + */ + public HubIOStream(String host, int port, int pollTime, String user, String pass) { + m_host = host; + m_port = port; + m_pollTime = pollTime; + m_user = user; + m_pass = pass; + } + + @Override + public boolean open() { + m_client = new DefaultHttpClient(); + if (m_user != null && m_pass != null) { + m_client.getCredentialsProvider().setCredentials(new AuthScope(m_host, m_port), + new UsernamePasswordCredentials(m_user, m_pass)); + } + m_in = new HubInputStream(); + + m_pollThread = new Thread(this); + m_pollThread.start(); + + m_out = new HubOutputStream(); + return true; + } + + @Override + public void close() { + m_pollThread.interrupt(); + m_client = null; + + try { + m_in.close(); + m_out.close(); + } catch (IOException e) { + logger.error("failed to close streams", e); + } + } + + /** + * Fetches the latest status buffer from the Hub + * @return string with status buffer + * @throws IOException + */ + private synchronized String bufferStatus() throws IOException { + String result = getURL("/buffstatus.xml"); + result = result.split("")[1].split("")[0].trim(); + return result; + } + /** + * Sends command to Hub to clear the status buffer + * @throws IOException + */ + private synchronized void clearBuffer() throws IOException { + getURL("/1?XB=M=1"); + m_bufferIdx = 0; + } + + /** + * Sends Insteon message (byte array) as a readable ascii string to the Hub + * @param msg byte array representing the Insteon message + * @throws IOException in case of I/O error + */ + public synchronized void write(ByteBuffer msg) throws IOException { + poll(); // fetch the status buffer before we send out commands + clearBuffer(); // clear the status buffer explicitly. + + StringBuilder b = new StringBuilder(); + while (msg.remaining() > 0) { + b.append(String.format("%02x", msg.get())); + } + String hexMSG = b.toString(); + getURL("/3?"+ hexMSG + "=I=3"); + } + + /** + * Polls the Hub web interface to fetch the status buffer + * @throws IOException if something goes wrong with I/O + */ + public synchronized void poll() throws IOException { + String buffer = bufferStatus(); // fetch via http call + logger.trace("poll: {}", buffer); + // + // The Hub maintains a ring buffer where the last two digits (in hex!) represent + // the position of the last byte read. + // + String data = buffer.substring(0, buffer.length() - 2); // pure data w/o index pointer + + int nIdx = -1; + try { + nIdx = Integer.parseInt(buffer.substring(buffer.length() - 2, buffer.length()), 16); + } catch (NumberFormatException e) { + m_bufferIdx = -1; + logger.error("invalid buffer size received in line: {}", buffer); + return; + } + + if (m_bufferIdx == -1) { + // this is the first call or first call after error, no need for buffer copying + m_bufferIdx = nIdx; + return; // XXX why return here???? + } + + StringBuilder msg = new StringBuilder(); + if (nIdx < m_bufferIdx) { + msg.append(data.substring(m_bufferIdx + 1, data.length())); + msg.append(data.substring(0, nIdx)); + logger.trace("wrap around: copying new data on: {}", msg.toString()); + } else { + msg.append(data.substring(m_bufferIdx, nIdx)); + logger.trace("no wrap: appending new data: {}", msg.toString()); + } + if (msg.length() != 0) { + ByteBuffer buf = ByteBuffer.wrap(s_hexStringToByteArray(msg.toString())); + ((HubInputStream) m_in).handle(buf); + } + m_bufferIdx = nIdx; + } + + /** + * Helper method to fetch url from http server + * @param resource the url + * @return contents returned by http server + * @throws IOException + */ + private String getURL(String resource) throws IOException { + synchronized(m_client) { + StringBuilder b = new StringBuilder(); + b.append("http://"); + b.append(m_host); + if (m_port != -1) { + b.append(":").append(m_port); + } + b.append(resource); + + HttpGet get = new HttpGet(b.toString()); + HttpResponse res = m_client.execute(get); + String html = EntityUtils.toString(res.getEntity()); + return html; + } + } + + /** + * Entry point for thread + */ + public void run() { + while(!Thread.currentThread().isInterrupted()) { + try { + poll(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + Thread.sleep(m_pollTime); + } catch (InterruptedException e) { + break; + } + } + } + + /** + * Helper function to convert an ascii hex string (received from hub) + * into a byte array + * @param s string received from hub + * @return simple byte array + */ + public static byte[] s_hexStringToByteArray(String s) { + return new BigInteger(s, 16).toByteArray(); + } + + /** + * Implements an InputStream for the Hub 2014 + * @author Daniel Pfrommer + * + */ + public class HubInputStream extends InputStream { + + //A buffer to keep bytes while we are waiting for the inputstream to read + private ReadByteBuffer m_buffer = new ReadByteBuffer(1024); + + public HubInputStream() {} + + public void handle(ByteBuffer buffer) throws IOException { + //Make sure we cleanup as much space as possible + m_buffer.makeCompact(); + m_buffer.add(buffer.array()); + } + + @Override + public int read() throws IOException { + return m_buffer.get(); + } + @Override + public int read(byte[] b, int off, int len) throws IOException { + return m_buffer.get(b, off, len); + } + @Override + public void close() throws IOException {} + } + + /** + * Implements an OutputStream for the Hub 2014 + * + * @author Daniel Pfrommer + * + */ + public class HubOutputStream extends OutputStream { + private ByteArrayOutputStream m_out = new ByteArrayOutputStream(); + + @Override + public void write(int b) throws IOException { + m_out.write(b); + flushBuffer(); + } + @Override + public void write(byte[] b, int off, int len) { + m_out.write(b, off, len); + flushBuffer(); + } + private void flushBuffer() { + ByteBuffer buffer = ByteBuffer.wrap(m_out.toByteArray()); + try { + HubIOStream.this.write(buffer); + } catch (IOException e) { + logger.error("failed to write to hub", e); + } + + m_out.reset(); + } + } +} diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/hub/ReadByteBuffer.java b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/hub/ReadByteBuffer.java new file mode 100644 index 00000000000..35cf67ec1c5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/java/org/openhab/binding/insteonplm/internal/driver/hub/ReadByteBuffer.java @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2010-2013, openHAB.org and others. + * + * 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.insteonplm.internal.driver.hub; + +import java.util.Arrays; +/** + * ReadByteBuffer buffer class + * + * @author Daniel Pfrommer + * @since 1.7.0 + */ + +public class ReadByteBuffer { + private byte m_buf[]; // the actual buffer + private int m_count; // number of valid bytes + private int m_index = 0; // current read index + + /** + * Constructor for ByteArrayIO with dynamic size + * @param size initial size, but will grow dynamically + */ + public ReadByteBuffer(int size) { + m_buf = new byte[size]; + } + /** + * Number of unread bytes + * @return number of bytes not yet read + */ + public synchronized int remaining() { + return m_count - m_index; + } + + /** + * Blocking read of a single byte + * @return byte read + */ + public synchronized byte get() { + while (remaining() < 1) { + try { + wait(); + } catch (InterruptedException e) { + // do nothin' + } + } + return m_buf[m_index++]; + } + /** + * Blocking read of multiple bytes + * @param bytes destination array for bytes read + * @param off offset into dest array + * @param len max number of bytes to read into dest array + * @return number of bytes actually read + */ + public synchronized int get(byte[] bytes, int off, int len) { + while (remaining() < 1) { + try { + wait(); + } catch (InterruptedException e) { + // do nothing + } + } + int b = Math.min(len, remaining()); + System.arraycopy(m_buf, m_index, bytes, off, b); + m_index += b; + return b; + } + /** + * Adds bytes to the byte buffer + * @param b byte array with new bytes + * @param off starting offset into buffer + * @param len number of bytes to add + */ + private synchronized void add(byte b[], int off, int len) { + if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) > b.length) || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + int nCount = m_count + len; + if (nCount > m_buf.length) { + // dynamically grow the array + m_buf = Arrays.copyOf(m_buf, Math.max(m_buf.length << 1, nCount)); + } + // append new data to end of buffer + System.arraycopy(b, off, m_buf, m_count, len); + m_count = nCount; + notifyAll(); + } + /** + * Adds bytes to the byte buffer + * @param b the new bytes to be added + */ + public void add(byte[] b) { + add(b, 0, b.length); + } + + /** + * Shrink the buffer to smallest size possible + */ + public synchronized void makeCompact() { + if (m_index == 0) return; + byte[] newBuf = new byte[remaining()]; + System.arraycopy(m_buf, m_index, newBuf, 0, newBuf.length); + m_index = 0; + m_count = newBuf.length; + m_buf = newBuf; + } +} \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/device_features.xml b/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/device_features.xml index 05878201607..6dd9f1c3515 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/device_features.xml +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/device_features.xml @@ -3,7 +3,7 @@ DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler SwitchRequestReplyHandler LightOnOffCommandHandler DefaultPollHandler @@ -12,35 +12,35 @@ DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler NoPollHandler DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler NoPollHandler DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler NoPollHandler DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler NoPollHandler DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler SwitchRequestReplyHandler LightOnOffCommandHandler LEDBitPollHandler @@ -49,7 +49,7 @@ DefaultDispatcher NoOpMsgHandler LightOnDimmerHandler - LightOffHandler + LightOffDimmerHandler NoOpMsgHandler StopManualChangeHandler DimmerRequestReplyHandler @@ -61,7 +61,7 @@ DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler SwitchRequestReplyHandler LightOnOffCommandHandler LEDBitPollHandler @@ -70,7 +70,7 @@ DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler SwitchRequestReplyHandler LightOnOffCommandHandler LEDBitPollHandler @@ -79,7 +79,7 @@ DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler SwitchRequestReplyHandler LightOnOffCommandHandler LEDBitPollHandler @@ -88,7 +88,7 @@ DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler SwitchRequestReplyHandler LightOnOffCommandHandler LEDBitPollHandler @@ -97,7 +97,7 @@ DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler SwitchRequestReplyHandler LightOnOffCommandHandler LEDBitPollHandler @@ -106,7 +106,7 @@ DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler SwitchRequestReplyHandler LightOnOffCommandHandler LEDBitPollHandler @@ -115,7 +115,7 @@ DefaultDispatcher NoOpMsgHandler LightOnSwitchHandler - LightOffHandler + LightOffSwitchHandler SwitchRequestReplyHandler LightOnOffCommandHandler LEDBitPollHandler @@ -129,11 +129,12 @@ DefaultDispatcher NoOpMsgHandler LightOnDimmerHandler - LightOffHandler + LightOffDimmerHandler NoOpMsgHandler StopManualChangeHandler DimmerRequestReplyHandler PercentHandler + IncreaseDecreaseCommandHandler LightOnOffCommandHandler DefaultPollHandler @@ -165,21 +166,21 @@ NoOpCommandHandler NoPollHandler - - GreedyDispatcher + + SimpleDispatcher NoOpMsgHandler NoOpMsgHandler NoOpMsgHandler - MotionSensorLightReplyHandler + MotionSensorDataReplyHandler NoOpCommandHandler NoPollHandler - - GreedyDispatcher + + SimpleDispatcher NoOpMsgHandler NoOpMsgHandler NoOpMsgHandler - MotionSensorBatteryReplyHandler + HiddenDoorSensorDataReplyHandler NoOpCommandHandler NoPollHandler @@ -203,6 +204,14 @@ NoOpMsgHandler ModemCommandHandler + + SimpleDispatcher + NoOpMsgHandler + PowerMeterResetHandler + PowerMeterUpdateHandler + PowerMeterCommandHandler + PowerMeterPollHandler + X10Dispatcher X10OnHandler @@ -233,4 +242,4 @@ NoOpCommandHandler NoPollHandler - \ No newline at end of file + diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/device_types.xml b/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/device_types.xml index 06e856acc29..eb04646760b 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/device_types.xml +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/device_types.xml @@ -64,11 +64,19 @@ Example entry: 2842-222 Motion Sensor WirelessMotionSensorContact - MotionSensorBatteryLevel - MotionSensorLightLevel + MotionSensorData + GenericLastTime + + + 2486DWH6 + KeypadLinc Dimmer - 6 Button + LoadDimmerButton + KeyPadButton3 + KeyPadButton4 + KeyPadButton5 + KeyPadButton6 GenericLastTime - 2486DWH8 KeypadLinc Dimmer @@ -125,7 +133,8 @@ Example entry: 2845-222 Hidden Door Sensor - GenericContact + WirelessMotionSensorContact + HiddenDoorSensorData GenericLastTime @@ -265,4 +274,11 @@ Example entry: GenericLastTime + + 2423A1 + iMeter Solo Power Meter + PowerMeter + GenericLastTime + + diff --git a/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/msg_definitions.xml b/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/msg_definitions.xml index 21b7bac5b66..d058b2b135e 100644 --- a/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/msg_definitions.xml +++ b/bundles/binding/org.openhab.binding.insteonplm/src/main/resources/msg_definitions.xml @@ -139,6 +139,25 @@ + +
      + 0x02 + 0x61 +
      + 0x00 + 0x00 + 0x00 +
      + +
      + 0x02 + 0x61 +
      + 0x00 + 0x00 + 0x00 + +
      0x02 @@ -226,6 +245,83 @@ 0x00 + +
      + 0x02 + 0x64 +
      + + 0x00 +
      + +
      + 0x02 + 0x64 +
      + + 0x00 + +
      + +
      + 0x02 + 0x65 +
      +
      + +
      + 0x02 + 0x65 +
      + +
      + +
      + 0x02 + 0x66 +
      + + + +
      + +
      + 0x02 + 0x66 +
      + + + + +
      + +
      + 0x02 + 0x67 +
      +
      + +
      + 0x02 + 0x67 +
      + +
      + +
      + 0x02 + 0x68 +
      + +
      + +
      + 0x02 + 0x68 +
      + + +
      0x02 @@ -279,5 +375,26 @@ + +
      + 0x02 + 0x77 +
      +
      + +
      + 0x02 + 0x77 +
      + +
      + +
      + 0x02 + 0x7F +
      + + +
      \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.knx/.classpath b/bundles/binding/org.openhab.binding.knx/.classpath index 848ca603b09..f26ec525795 100644 --- a/bundles/binding/org.openhab.binding.knx/.classpath +++ b/bundles/binding/org.openhab.binding.knx/.classpath @@ -6,6 +6,5 @@ - diff --git a/bundles/binding/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/bus/KNXBinding.java b/bundles/binding/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/bus/KNXBinding.java index 45adac134ce..c84e5b9ee76 100644 --- a/bundles/binding/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/bus/KNXBinding.java +++ b/bundles/binding/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/bus/KNXBinding.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -60,7 +61,7 @@ public class KNXBinding extends AbstractBinding implements /** * used to store events that we have sent ourselves; we need to remember them for not reacting to them */ - private List ignoreEventList = new ArrayList(); + private List ignoreEventList = Collections.synchronizedList(new ArrayList()); private KNXBusReaderScheduler mKNXBusReaderScheduler = new KNXBusReaderScheduler(); @@ -117,8 +118,7 @@ protected void internalReceiveUpdate(String itemName, State newState) { private boolean isEcho(String itemName, Type type) { String ignoreEventListKey = itemName + type.toString(); - if (ignoreEventList.contains(ignoreEventListKey)) { - ignoreEventList.remove(ignoreEventListKey); + if (ignoreEventList.remove(ignoreEventListKey)) { logger.trace("We received this event (item='{}', state='{}') from KNX, so we don't send it back again -> ignore!", itemName, type.toString()); return true; } @@ -246,8 +246,9 @@ public void bindingChanged(BindingProvider provider, String itemName) { if(datapoint.getName().equals(itemName)) { logger.debug("Initializing read of item {}.", itemName); if (!mKNXBusReaderScheduler.scheduleRead(datapoint, knxProvider.getAutoRefreshTime(datapoint))) { - logger.warn("Clouldn't add to KNX bus reader scheduler",datapoint); + logger.warn("Clouldn't add to KNX bus reader scheduler (bindingChanged)",datapoint); } + break; } } } @@ -271,7 +272,7 @@ public void allBindingsChanged(BindingProvider provider) { int autoRefreshTimeInSecs=knxProvider.getAutoRefreshTime(datapoint); if (autoRefreshTimeInSecs>0) { if (!mKNXBusReaderScheduler.scheduleRead(datapoint, knxProvider.getAutoRefreshTime(datapoint))) { - logger.warn("Clouldn't add to KNX bus reader scheduler",datapoint); + logger.warn("Clouldn't add to KNX bus reader scheduler (allBindingsChanged)",datapoint); } } } @@ -294,7 +295,7 @@ public void connectionEstablished() { int autoRefreshTimeInSecs=knxProvider.getAutoRefreshTime(datapoint); if (autoRefreshTimeInSecs>0) { if (!mKNXBusReaderScheduler.scheduleRead(datapoint, autoRefreshTimeInSecs)) { - logger.warn("Clouldn't add to KNX bus reader scheduler",datapoint); + logger.warn("Clouldn't add to KNX bus reader scheduler (connectionEstablished)",datapoint); } } } diff --git a/bundles/binding/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/bus/KNXBusReaderScheduler.java b/bundles/binding/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/bus/KNXBusReaderScheduler.java index 973abc7e9c0..f0ce9c78b94 100644 --- a/bundles/binding/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/bus/KNXBusReaderScheduler.java +++ b/bundles/binding/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/bus/KNXBusReaderScheduler.java @@ -9,6 +9,7 @@ package org.openhab.binding.knx.internal.bus; import java.util.LinkedList; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.BlockingQueue; @@ -77,7 +78,8 @@ public void stop() { sLogger.debug("Auto refresh scheduler couldn't be terminated and termination timed out."); } } catch (InterruptedException e) { - sLogger.debug("Auto refresh scheduler: interrupted while waiting for termination."); + sLogger.warn("Auto refresh scheduler: interrupted while waiting for termination."); + Thread.currentThread().interrupt(); } sLogger.trace("Stopping reader task"); @@ -108,19 +110,21 @@ public synchronized void clear() { } } catch (InterruptedException e) { sLogger.debug("Schedule executor restart failed: interrupted while waiting for termination."); + Thread.currentThread().interrupt(); } mScheduledExecutorService = Executors.newScheduledThreadPool(KNXConnection.getNumberOfThreads()); sLogger.debug("Schedule executor restart: started."); } - for (int autoRefreshTimeInSecs : mScheduleMap.keySet()) { + for (Iterator iterator = mScheduleMap.keySet().iterator(); iterator.hasNext();) { + int autoRefreshTimeInSecs = iterator.next(); List dpList = mScheduleMap.get(autoRefreshTimeInSecs); synchronized(dpList) { sLogger.debug("Clearing list {}", autoRefreshTimeInSecs); dpList.clear(); } sLogger.debug("Removing list {} from scheduler", autoRefreshTimeInSecs); - mScheduleMap.remove(autoRefreshTimeInSecs); + iterator.remove(); } } @@ -147,7 +151,8 @@ public synchronized boolean readOnce(Datapoint datapoint) { /** * Schedules a Datapoint to be cyclicly read. When parameter * autoRefreshTimeInSecs is 0 then calling ths method is equal - * to calling readOnce. + * to calling readOnce. This function will return true if the Datapoint + * was added or if it was already scheduled with an identical autoRefreshTimeInSecs. * * @param datapoint * the Datapoint to be read @@ -182,7 +187,7 @@ public synchronized boolean scheduleRead(Datapoint datapoint, int autoRefreshTim if (oldListNumber > 0) { if (oldListNumber==autoRefreshTimeInSecs) { sLogger.debug("Datapoint '{}' was already in auto refresh list {}", datapoint.getName(), autoRefreshTimeInSecs); - return false; + return true; } List oldList = mScheduleMap.get(oldListNumber); synchronized(oldList) { @@ -196,9 +201,10 @@ public synchronized boolean scheduleRead(Datapoint datapoint, int autoRefreshTim * a configuration file is reread. */ - for (Datapoint dp : oldList) { + for (Iterator iterator = oldList.iterator(); iterator.hasNext();) { + Datapoint dp = iterator.next(); if (dp.toString().equals(datapoint.toString())) { - oldList.remove(dp); + iterator.remove(); } } @@ -285,4 +291,4 @@ public void run() { } } } -} \ No newline at end of file +} diff --git a/bundles/binding/org.openhab.binding.maxcube/src/main/java/org/openhab/binding/maxcube/internal/MaxCubeBinding.java b/bundles/binding/org.openhab.binding.maxcube/src/main/java/org/openhab/binding/maxcube/internal/MaxCubeBinding.java index c0a06618e97..21a36708c5d 100644 --- a/bundles/binding/org.openhab.binding.maxcube/src/main/java/org/openhab/binding/maxcube/internal/MaxCubeBinding.java +++ b/bundles/binding/org.openhab.binding.maxcube/src/main/java/org/openhab/binding/maxcube/internal/MaxCubeBinding.java @@ -146,21 +146,14 @@ public void activate() { @Override public void deactivate() { - if(socket!=null) { - try { - socket.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - } - socket = null; - } + socketClose(); } /** * {@inheritDoc} */ @Override - public void execute() { + public synchronized void execute() { if (ip == null) { logger.debug("Update prior to completion of interface IP configuration"); return; @@ -257,8 +250,7 @@ public void execute() { } } if(!exclusive) { - socket.close(); - socket = null; + socketClose(); } for (MaxCubeBindingProvider provider : providers) { @@ -317,13 +309,15 @@ public void execute() { } } } catch (UnknownHostException e) { - logger.info("Cannot establish connection with MAX!Cube lan gateway while connecting to '{}'", ip); - logger.debug(Utils.getStackTrace(e)); - socket = null; + logger.info("Host error occurred while connecting to MAX! Cube lan gateway '{}': {}", ip, e.getMessage()); + socketClose(); } catch (IOException e) { - logger.info("Cannot read data from MAX!Cube lan gateway while connecting to '{}'", ip); - logger.debug(Utils.getStackTrace(e)); - socket = null; //reconnect on next execution + logger.info("IO error occurred while connecting to MAX! Cube lan gateway '{}': {}", ip, e.getMessage()); + socketClose(); //reconnect on next execution + } catch (Exception e) { + logger.info("Error occurred while connecting to MAX! Cube lan gateway '{}': {}", ip, e.getMessage()); + logger.info(Utils.getStackTrace(e)); + socketClose(); //reconnect on next execution } } @@ -412,11 +406,15 @@ public void internalReceiveCommand(String itemName, Command command) { socket = null; } } catch (UnknownHostException e) { - logger.warn("Cannot establish connection with MAX!cube lan gateway while sending command to '{}'", ip); - logger.debug(Utils.getStackTrace(e)); + logger.info("Host error occurred while connecting to MAX! Cube lan gateway '{}': {}", ip, e.getMessage()); + socketClose(); } catch (IOException e) { - logger.warn("Cannot write data from MAX!Cube lan gateway while connecting to '{}'", ip); - logger.debug(Utils.getStackTrace(e)); + logger.info("IO error occurred while writing to MAX! Cube lan gateway '{}': {}", ip, e.getMessage()); + socketClose(); //reconnect on next execution + } catch (Exception e) { + logger.info("Error occurred while writing to MAX! Cube lan gateway '{}': {}", ip, e.getMessage()); + logger.info(Utils.getStackTrace(e)); + socketClose(); //reconnect on next execution } logger.debug("Command Sent to {}", ip); } else { @@ -440,6 +438,7 @@ private void sMessageProcessing(S_Message message) { private boolean socketConnect() throws UnknownHostException, IOException { socket = new Socket(ip, port); + socket.setSoTimeout(2000); logger.debug("open new connection... to "+ip+" port "+port); reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); writer = new OutputStreamWriter(socket.getOutputStream()); @@ -447,6 +446,17 @@ private boolean socketConnect() throws UnknownHostException, IOException { return true; } + private void socketClose() { + if(socket!=null) { + try { + socket.close(); + } catch (IOException e) { + // Ignore + } + socket = null; + } + } + private Device findDevice(String serialNumber, ArrayList devices) { for (Device device : devices) { if (device.getSerialNumber().toUpperCase().equals(serialNumber)) { diff --git a/bundles/binding/org.openhab.binding.maxcube/src/main/java/org/openhab/binding/maxcube/internal/message/Device.java b/bundles/binding/org.openhab.binding.maxcube/src/main/java/org/openhab/binding/maxcube/internal/message/Device.java index 062b0326cd4..c502dd7979a 100644 --- a/bundles/binding/org.openhab.binding.maxcube/src/main/java/org/openhab/binding/maxcube/internal/message/Device.java +++ b/bundles/binding/org.openhab.binding.maxcube/src/main/java/org/openhab/binding/maxcube/internal/message/Device.java @@ -164,8 +164,11 @@ public static Device update(byte[] raw, List configurations, Devi logger.debug ("No temperature reading in {} mode", heatingThermostat.getMode()) ; } } - logger.debug ("Actual Temperature : {}", (double)actualTemp / 10); - heatingThermostat.setTemperatureActual((double)actualTemp / 10); + + if (actualTemp != 0) { + logger.debug ("Actual Temperature : {}", (double)actualTemp / 10); + heatingThermostat.setTemperatureActual((double)actualTemp / 10); + } break; case EcoSwitch: String eCoSwitchData = Utils.toHex(raw[3] & 0xFF, raw[4] & 0xFF, raw[5] & 0xFF); diff --git a/bundles/binding/org.openhab.binding.maxcul/src/main/java/org/openhab/binding/maxcul/internal/MaxCulBinding.java b/bundles/binding/org.openhab.binding.maxcul/src/main/java/org/openhab/binding/maxcul/internal/MaxCulBinding.java index 32418189b9f..8481a6dc0b2 100644 --- a/bundles/binding/org.openhab.binding.maxcul/src/main/java/org/openhab/binding/maxcul/internal/MaxCulBinding.java +++ b/bundles/binding/org.openhab.binding.maxcul/src/main/java/org/openhab/binding/maxcul/internal/MaxCulBinding.java @@ -10,6 +10,7 @@ import java.util.Collection; import java.util.Dictionary; +import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -242,7 +243,7 @@ public void updated(Dictionary config) String deviceString = (String) config.get("device"); if (StringUtils.isNotBlank(deviceString)) { logger.debug("Setting up device " + deviceString); - setupDevice(deviceString); + setupDevice(deviceString, config); if (cul == null) throw new ConfigurationException("device", "Configuration failed. Unable to access CUL device " @@ -254,14 +255,15 @@ public void updated(Dictionary config) } } - private void setupDevice(String device) { + private void setupDevice(String device, Dictionary config) { if (cul != null) { CULManager.close(cul); } try { accessDevice = device; logger.debug("Opening CUL device on " + accessDevice); - cul = CULManager.getOpenCULHandler(accessDevice, CULMode.MAX); + cul = CULManager.getOpenCULHandler(accessDevice, CULMode.MAX, + convertDictionaryToMap(config)); messageHandler = new MaxCulMsgHandler(this.srcAddr, cul, super.providers); messageHandler.registerMaxCulBindingMessageProcessor(this); @@ -272,6 +274,26 @@ private void setupDevice(String device) { } } + private Map convertDictionaryToMap( + Dictionary config) { + + Map myMap = new HashMap(); + + if (config == null) { + return null; + } + if (config.size() == 0) { + return myMap; + } + + Enumeration allKeys = config.keys(); + while (allKeys.hasMoreElements()) { + String key = allKeys.nextElement(); + myMap.put(key, config.get(key)); + } + return myMap; + } + private Collection getBindingsBySerial(String serial) { Collection bindingConfigs = null; for (MaxCulBindingProvider provider : super.providers) { @@ -287,8 +309,7 @@ private Collection getBindingsBySerial(String serial) { return bindingConfigs; } - private void updateCreditMonitors() - { + private void updateCreditMonitors() { /* find and update credit monitor binding if it exists */ int credit10ms = messageHandler.getCreditStatus(); for (MaxCulBindingProvider provider : super.providers) { @@ -301,7 +322,7 @@ private void updateCreditMonitors() } } } - + @Override public void maxCulMsgReceived(String data, boolean isBroadcast) { logger.debug("Received data from CUL: " + data); diff --git a/bundles/binding/org.openhab.binding.milight/src/main/java/org/openhab/binding/milight/internal/MilightBinding.java b/bundles/binding/org.openhab.binding.milight/src/main/java/org/openhab/binding/milight/internal/MilightBinding.java index c863e37dd82..d49d5a3ef3d 100644 --- a/bundles/binding/org.openhab.binding.milight/src/main/java/org/openhab/binding/milight/internal/MilightBinding.java +++ b/bundles/binding/org.openhab.binding.milight/src/main/java/org/openhab/binding/milight/internal/MilightBinding.java @@ -178,8 +178,7 @@ else if (deviceConfig.getCommandType().equals(BindingType.rgb)) { logger.debug("milight: item is of type rgb"); if (command instanceof HSBType) { sendColor(command, bridgeId, bulb); - } - if (command instanceof PercentType) { + } else if (command instanceof PercentType) { sendPercent(bulb, rgbwSteps, bridgeId, (PercentType) command, BindingType.brightness); } } diff --git a/bundles/binding/org.openhab.binding.mios/OSGI-INF/activebinding.xml b/bundles/binding/org.openhab.binding.mios/OSGI-INF/activebinding.xml index c7069a01347..9df55bc33a7 100644 --- a/bundles/binding/org.openhab.binding.mios/OSGI-INF/activebinding.xml +++ b/bundles/binding/org.openhab.binding.mios/OSGI-INF/activebinding.xml @@ -15,6 +15,7 @@ + diff --git a/bundles/binding/org.openhab.binding.mios/OSGI-INF/genericbindingprovider.xml b/bundles/binding/org.openhab.binding.mios/OSGI-INF/genericbindingprovider.xml index 853941fdacc..f0561814598 100644 --- a/bundles/binding/org.openhab.binding.mios/OSGI-INF/genericbindingprovider.xml +++ b/bundles/binding/org.openhab.binding.mios/OSGI-INF/genericbindingprovider.xml @@ -10,11 +10,12 @@ --> - + - - - - - + + + + + + diff --git a/bundles/binding/org.openhab.binding.mios/README.md b/bundles/binding/org.openhab.binding.mios/README.md index cd3236fc244..6fcc89a0b8a 100644 --- a/bundles/binding/org.openhab.binding.mios/README.md +++ b/bundles/binding/org.openhab.binding.mios/README.md @@ -1,11 +1,50 @@ -# Releases +Documentation for the MiOS Bridge Binding. + +# Introduction +This binding exposes read, and read-command, access to Devices controlled by a MiOS Home Automation controller, such as those seen at http://getvera.com. + +It exposes the ability to do the following things in the MiOS HA Controller + +* `Devices` - Read State Variables & Device Attributes, and invoke (single parameter) UPnP Commands to control the Device. +* `Scenes` - Read the current execution state of a Scene, and invoke those Scenes within the remote HA Controller +* `System` - Read System-level Attributes. +It uses the remote control interfaces (aka "UI Simple" JSON Calls, and HTTP Long-polling) of the MiOS HA Controller to keep the _bound_ openHAB Items in sync with their counterparts in the MiOS HA Controller. -This code is not currently in release-ready form. Changes are expected, especially as feedback is received. +The binding uses the openHAB _Transformation Service_ extensively to "map" the Data & Commands between the two systems. A set of example MAP transform files is provided in the `examples/transform` directory of the Binding, but these can readily be augmented without needing to tweak the code. + +Original code was used from the XBMC Binding, and then heavily modified. Snippets included from the HTTP Binding for the various datatype mapping functions. + +# Releases -## 1.6.0 - * TBD +* 1.6 - First release +* 1.6.2 - #1889 Only change Item state during incremental updates from MiOS Unit, use UTF-8 for JSON responses for i18n. +* 1.6.2 - #1824 datetime handling made more automatic for MiOS style "epoch" dates. +* 1.6.2 - #1909 Add missing aliases for common UPnP ServiceId's. +* 1.7.0 - #???? Add MiOS Action Binding support for calling Device Actions and invoking Scenes. # Configuration + * [MiOS Unit configuration](MiOS-Binding#mios-unit-configuration) + * [Transformations](MiOS-Binding#mios-transformations) + * [Actions](MiOS-Binding#mios-action-addon) + * [Logger](MiOS-Binding#mios-logger) + * [Item configuration (Reading)](MiOS-Binding#mios-item-configuration) + * [MiOS - Device Binding](MiOS-Binding#item--mios-device-binding---values-reading) + * [MiOS - Scene Binding](MiOS-Binding#item--mios-scene-binding---values-reading) + * [MiOS - System Binding](MiOS-Binding#item--mios-system-binding) + * [Transformations (Use)](MiOS-Binding#transformations) + * [Item Commands (Reacting)](MiOS-Binding#item-commands-reacting) + * [MiOS - Device Binding - Commands (Reacting)] (MiOS-Binding#item--mios-device-binding---commands-reacting) + * [Device Command Binding Examples (Parameterless)] (MiOS-Binding#device-command-binding-examples-parameterless) + * [A Switch ...](MiOS-Binding#a-switch) + * [An Armed Sensor ...](MiOS-Binding#an-armed-sensor) + * [A Lock ...] (MiOS-Binding#a-lock) + * [Device Command Binding Examples (Parameterized)](MiOS-Binding#device-command-binding-examples-parameterized) + * [A Dimmer, Volume Control, Speed controlled Fan ...](MiOS-Binding#a-dimmer-volume-control-speed-controlled-fan) + * [A Thermostat ...] (MiOS-Binding#a-thermostat) + * [MiOS Scene Binding - Commands (Reacting)] (MiOS-Binding#item--mios-scene-binding---commands-reacting) + * [Scene Command Binding Examples] (MiOS-Binding#scene-command-binding-examples) + +*** ## MiOS Unit configuration @@ -39,6 +78,8 @@ You can also declare multiple MiOS Units, as illustrated in this example. **NOTE**: The MiOS Unit name is case-sensitive, and may only contain AlphaNumeric characters. The leading character must be an [ASCII] alpha. +[Back to Table of Contents](MiOS-Binding#configuration) + ## MiOS Transformations Internally, the MiOS Binding uses the openHAB _Transformation Service_. The MiOS Binding supplies a number of pre-configured MAP Transformation for the common use-cases. @@ -53,6 +94,67 @@ and placed into your openHAB installation under the directory: **NOTE**: These transformations can be readily extended by the user, for any use-cases that aren't covered by those pre-configured & shipped with the Binding. +[Back to Table of Contents](MiOS-Binding#configuration) + +## MiOS Action Addon + +The MiOS Binding automatically synchronizes data between openHAB Items, and their bound Device Variables on the MiOS Unit. +For more advanced integration, the MiOS Action bundle can be installed. This bundle extends openHAB's Rule language to include support for calling MiOS Device Actions, as well as invoking MiOS Scenes. +Installation of the MiOS Action bundle is optional and only required if your deployment needs the MiOS Rule language extensions. + +[Back to Table of Contents](MiOS-Binding#configuration) + +## MiOS Logger +Especially during setup of the binding the log information can provide you valuable information. Therefore it is recommended to configure logging to use a dedicated file for MiOS logging. + +There are two configuration files to configure the log subsystem of openHAB: + * {openHAB Home}/configurations/logback.xml + * {openHAB Home}/configurations/logback_debug.xml (if you start in debug mode) + +To simplify analysis and to keep things structured we'll use a dedicated logfile for this demo configuration. + +```xml + + + + logs/mios.log + + + logs/mios-%d{yyyy-ww}.log.zip + 7 + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%-30.30logger{36}] - %msg%n + + +``` +Next we configure the actual logger: +```xml + + + + +``` + +Below how it should look if the configuration is correct (TRACE): +``` +... +2015-01-18 16:37:18.971 [DEBUG] [.o.b.mios.internal.MiosBinding] - internalPropertyUpdate: BOUND {mios="unit:vera,device:1/service/urn:micasaverde-com:serviceId:ZWaveNetwork1/Role"}, value=Master SIS:NO PRI:YES, bound 1 time(s) +2015-01-18 16:37:18.971 [TRACE] [.o.b.mios.internal.MiosBinding] - internalPropertyUpdate: NOT BOUND {mios="unit:vera,device:1/service/urn:micasaverde-com:serviceId:ZWaveNetwork1/LastDongleBackup"}, value=2015-01-14T23:30:57 +2015-01-18 16:37:18.971 [TRACE] [.o.b.mios.internal.MiosBinding] - internalPropertyUpdate: NOT BOUND {mios="unit:vera,device:1/service/urn:micasaverde-com:serviceId:ZWaveNetwork1/LastError"}, value=Poll failed +2015-01-18 16:37:18.971 [TRACE] [.o.b.mios.internal.MiosBinding] - internalPropertyUpdate: NOT BOUND {mios="unit:vera,device:1/service/urn:micasaverde-com:serviceId:ZWaveNetwork1/LastHeal"}, value=2015-01-14T05:16:26 +2015-01-18 16:37:18.971 [TRACE] [.o.b.mios.internal.MiosBinding] - internalPropertyUpdate: NOT BOUND {mios="unit:vera,device:1/service/urn:micasaverde-com:serviceId:ZWaveNetwork1/LastRouteFailure"}, value=2015-01-14T04:11:33 +... +``` + +[Back to Table of Contents](MiOS-Binding#configuration) + ## MiOS Item configuration The MiOS Binding provides a few sources of data from the target MiOS Unit. These can be categorized into the following data values: @@ -73,6 +175,7 @@ In many cases, only a subset of these parameters need to be specified/used, with The sections below describe the types of things that can be bound, in addition to the transformations that are permitted, and any default transformations that may be applied for you. +[Back to Table of Contents](MiOS-Binding#configuration) ### Item : MiOS Device Binding - Values (Reading) @@ -174,6 +277,7 @@ The _serviceAliases_ are built into the MiOS Binding and may be expanded over ti |`urn:macrho-com:serviceId:LiftMasterOpener1`|`LiftMasterOpener1`,`LiftMaster`| |`urn:directv-com:serviceId:DVR1`|`DirecTVDVR1`,`DirecTV`| +[Back to Table of Contents](MiOS-Binding#configuration) ### Item : MiOS Scene Binding - Values (Reading) @@ -186,7 +290,9 @@ With examples like: Number SceneGarageOpenId (GScene) {mios="unit:house,scene:109/id"} Number SceneGarageOpenStatus (GScene) {mios="unit:house,scene:109/status"} String SceneGarageOpenActive (GScene) {mios="unit:house,scene:109/active"} - + +[Back to Table of Contents](MiOS-Binding#configuration) + ### Item : MiOS System Binding System Bindings are read-only, with data flowing from the MiOS Unit _into_ openHAB. System Bindings have the form: @@ -202,6 +308,8 @@ With examples like: Number SystemDataVersion "[%d]" (GSystem) {mios="unit:house,system:/DataVersion"} String SystemLoadTime "[%s]" (GSystem) {mios="unit:house,system:/LoadTime"} +[Back to Table of Contents](MiOS-Binding#configuration) + ### Transformations Sometimes the value presented by the binding isn't in the format that you require for your Item. For these cases, the binding provides access to the standard openHAB _Transformation Service_. @@ -273,6 +381,7 @@ For users wanting more advanced configurations, the openHAB _Transformation Serv More reading on these is available in the openHAB Wiki. +[Back to Table of Contents](MiOS-Binding#configuration) ## Item Commands (Reacting) @@ -289,6 +398,7 @@ MiOS Units don't natively handle these Commands so a mapping step must occur bef The `command:` Binding parameter is used to specify that we want data to flow back to the MiOS unit as well as how to perform the required mapping. For most Items bound using the MiOS Binding, internal defaults will take care of the correct `command:`, `in:` and `out:` parameters. These need only be specified if you have something not handled by the internal defaults, or wish to override them with custom behavior. +[Back to Table of Contents](MiOS-Binding#configuration) ### Item : MiOS Device Binding - Commands (Reacting) @@ -316,10 +426,14 @@ _<openHABTransform>_ is `MAP`, `XSLT`, `EXEC`, `XPATH`, etc
      _<BoundValue>_ is `?`, `??`, `?++`, `?--` +[Back to Table of Contents](MiOS-Binding#configuration) + #### Device Command Binding Examples (Parameterless) In practice, when discrete commands are being sent by openHAB, the map is fairly simple. In the examples listed below, the `*.map` files are provided in the `examples/transform` directory of the MiOS binding. +[Back to Table of Contents](MiOS-Binding#configuration) + ##### A Switch... You might start off with an inline definition of the mapping: @@ -334,6 +448,7 @@ or, *more simply*, use the internal defaults altogether: Switch FamilyTheatreLightsStatus "Family Theatre Lights" (GSwitch) {mios="unit:house,device:13/service/SwitchPower1/Status"} +[Back to Table of Contents](MiOS-Binding#configuration) ##### An Armed Sensor... @@ -345,6 +460,7 @@ or the fully spelled out version: Switch LivingRoomZoneArmed "Zone Armed [%s]" {mios="unit:house,device:117/service/SecuritySensor1/Armed,command:MAP(miosArmedCommand.map),in:MAP(miosSwitchIn.map)"} +[Back to Table of Contents](MiOS-Binding#configuration) ##### A Lock... @@ -356,6 +472,7 @@ or the full version: Switch GarageDeadboltDStatus "Garage Deadbolt" (GLock,GSwitch) {mios="unit:house,device:189/service/DoorLock1/Status,command:MAP(miosLockCommand.map),in:MAP(miosSwitchIn.map)"} +[Back to Table of Contents](MiOS-Binding#configuration) #### Device Command Binding Examples (Parameterized) @@ -370,6 +487,7 @@ To do this, we introduce the _<BoundValue>_ parameter that, when present in t Additionally, since _<PCTNumber>_ is just a value, it won't match any of the entries in our Mapping file, so we introduce a magic key `_defaultCommand`. We first attempt to do a literal mapping and, if that doesn't find a match, we go look for this magic key and use it's entry. +[Back to Table of Contents](MiOS-Binding#configuration) ##### A Dimmer, Volume Control, Speed controlled Fan... @@ -390,6 +508,28 @@ The `examples/transform/miosDimmerCommand.map` file has a definition that handle DECREASE=urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget(newLoadlevelTarget=?--) _defaultCommand=urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget(newLoadlevelTarget=??) +[Back to Table of Contents](MiOS-Binding#configuration) + + +##### A Roller shutter... + +The simple version, using internal defaults for the `WindowCovering1` service of the Device: + + Rollershutter Kitchen "Kitchen" (GKitchen) {mios="unit:micasa,device:13/service/WindowCovering1"} + +or the full version: + + Rollershutter Kitchen "Kitchen" (GKitchen) {mios="unit:micasa,device:13/service/WindowCovering1,command:MAP(miosShutterCommand.map)"} + +Since Rollershutter Items in openHAB can be sent `UP`, `DOWN`, `STOP` or _<PCTNumber>_ as the command, the mapping file must account for both the static commands (`UP`, `DOWN`, `STOP`) as well as the possibility of a _Command Value_ being sent. + +The `examples/transform/miosShutterCommand.map` file has a definition that handles this situation: + + DOWN=urn:upnp-org:serviceId:WindowCovering1/Down() + UP=urn:upnp-org:serviceId:WindowCovering1/Up() + STOP=urn:upnp-org:serviceId:WindowCovering1/Stop() + _defaultCommand=urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget(newLoadlevelTarget=??) + ##### A Thermostat... @@ -425,6 +565,7 @@ and these need to be paired with similar items in the `*.sitemap` file: Text item=ThermostatUpstairsBatteryDate } +[Back to Table of Contents](MiOS-Binding#configuration) ### Item : MiOS Scene Binding - Commands (Reacting) @@ -443,6 +584,8 @@ _<openHABCommand>_ is `ON`, `OFF`, `INCREASE`, `DECREASE`, `TOGGLE` etc _<SceneAttribute>_ is `status` | `active` +[Back to Table of Contents](MiOS-Binding#configuration) + #### Scene Command Binding Examples In general Scenes tend to look like: @@ -455,3 +598,5 @@ Or if you want the Scene executed upon receipt of `ON` or `TOGGLE` Commands: **NOTE**: Here we've added an additional configuration to the binding declaration, `autoupdate="false"`, to ensure the Switch no longer has the `ON` and `OFF` States automatically managed. In openHAB, this declaration ensures that the UI rendition appears like a Button. + +[Back to Table of Contents](MiOS-Binding#configuration) \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.mios/examples/scripts/README.md b/bundles/binding/org.openhab.binding.mios/examples/scripts/README.md new file mode 100644 index 00000000000..e522477ab4d --- /dev/null +++ b/bundles/binding/org.openhab.binding.mios/examples/scripts/README.md @@ -0,0 +1,75 @@ +# MiOS Binding Tools and Utilities + +## MiOS openHAB Item file Generator + +The MiOS openHAB Item file Generator tools extract information from a live/running MiOS Unit, and convert them into an Items file suitable for use in openHAB. These tools are intended to build a starting point Items file for the end-user, using the current-generation of the MiOS Binding. + +NOTE: The rules for generating the Items file may change over time. The output of the script may change without notice, and should be reviewed prior to use. + +### OS Requirements + +These scripts are intended to be run on a Linux, Unix or MacOS X system. + +The MiOS openHAB Item file Generator scripts consist of: + +* `miosLoad.sh` - A loader script that calls a MiOS Unit, over HTTP, and extracts it's metadata in the form of a `user_data.xml` file. +* `miosTransform.sh` - A wrapper script to transform a MiOS Unit `user_data.xml` file into the associated Items file. +* `miosTransform.xslt` - An XSLT file containing the rules for conversion from a MiOS Unit `user_data.xml` file into an Items file. + +The following components are assumed installed on the system: + +* `bash` +* `xsltproc` - http://xmlsoft.org/XSLT/xsltproc.html +* `curl` - http://curl.haxx.se/ + +### How to use + +To run the conversion process, the following steps should be executed: + +* Load (`miosLoad.sh`) - retrieves an XML version of the MiOS Device MetaData from your MiOS Unit. +In some cases, MiOS emits _invalid_ XML, so this content may have to be hand-edited prior to feeding it into the next step. This script takes a single parameter, which is the IP Address, or DNS name, of the MiOS Unit to call. The output of this phase is a file called `user_data.xml` + +* Transform (`miosTransform.sh`) - converts the XML into a Textual openHAB Items file. +This script takes a single parameter, which is used for both the name of the generated Items file, as well as the MiOS Unit name used in openhab.cfg (eg. "house"). +If this completes successfully, it will have generated an output file like `house.items` which, after suitable manual review, can be used as an openHAB Items file. + +This is an example of what it's like to run these command line scripts in sequence: + +```ShellSession +Code: [Select] +me$ ./miosLoad.sh 192.168.1.100 +Loading MiOS Unit Metadata from 192.168.1.100... +Metadata Loaded into user_data.xml! +me$ ./miosTransform.sh house +Transforming MiOS Unit Metadata from user_data.xml... +Metadata Transformed into house.items! +Duplicate Item names requiring manual fixes: + String DownstairsDeviceStatus "Downstairs Device Status [%s]" (GDevices) {mios="unit:house,device:385/status"} + Number DownstairsId "ID [%d]" (GDevices) {mios="unit:house,device:385/id"} + String LivingRoomSonosPIcon "Living Room Sonos (P) Icon [%s]" (GDevices,GRoom2) {mios="unit:house,device:295/service/DeviceProperties/Icon"} + String MasterBedroomSonosIcon "Master Bedroom Sonos Icon [%s]" (GDevices,GRoom7) {mios="unit:house,device:331/service/DeviceProperties/Icon"} + String SceneControllerConfigured "_Scene Controller Configured [%s]" (GDevices) {mios="unit:house,device:394/service/HaDevice1/Configured"} + String SceneControllerDeviceStatus "_Scene Controller Device Status [%s]" (GDevices) {mios="unit:house,device:393/status"} + String SceneControllerDeviceStatus "_Scene Controller Device Status [%s]" (GDevices) {mios="unit:house,device:394/status"} + Number SceneControllerId "ID [%d]" (GDevices) {mios="unit:house,device:394/id"} + Number SceneControllerId "ID [%d]" (GDevices) {mios="unit:house,device:4/id"} + String SceneControllerScenes "_Scene Controller Scenes [%s]" (GDevices) {mios="unit:house,device:393/service/SceneController1/Scenes"} + String SceneControllerScenes "_Scene Controller Scenes [%s]" (GDevices) {mios="unit:house,device:394/service/SceneController1/Scenes"} + String SceneMasterBathroom "Master Bathroom Scene" (GScenes) {mios="unit:house,scene:34/status", autoupdate="false"} + String SceneMasterBathroom "Master Bathroom Scene" (GScenes) {mios="unit:house,scene:35/status", autoupdate="false"} + String SceneTestArmed "TestArmed Scene" (GScenes) {mios="unit:house,scene:73/status", autoupdate="false"} + String SceneTestDisarmed "TestDisarmed Scene" (GScenes) {mios="unit:house,scene:76/status", autoupdate="false"} + String UpstairsDeviceStatus "Upstairs Device Status [%s]" (GDevices) {mios="unit:house,device:337/status"} + Number UpstairsId "ID [%d]" (GDevices) {mios="unit:house,device:337/id"} + Contact SceneMasterBathroomActive "Active [%s]" (GScenes) {mios="unit:house,scene:34/active"} + Contact SceneMasterBathroomActive "Active [%s]" (GScenes) {mios="unit:house,scene:35/active"} + Contact SceneTestArmedActive "Active [%s]" (GScenes) {mios="unit:house,scene:79/active"} + Contact SceneTestDisarmedActive "Active [%s]" (GScenes) {mios="unit:house,scene:80/active"} +``` + +At this point, you'll have a _fairly_ complete `house.items` file for use in openHAB. The conversion process takes a number of steps to aid in generating unique Item names in the generated content, but any output in the _Duplicate Item names_ section should be addressed prior to use as an openHAB Items file. + +The tool includes almost all of the _by-hand_ conversion rules used in other MiOS user's openHAB Configurations. MiOS UPnP State variables like `SwitchPower1/Status` become an openHAB `Switch` Item for example. + +The generator tools will get you close to a working openHAB Items file, especially for commonly used MiOS Device types. For exotic MiOS Device Types, not handled by the MiOS internal defaults, the Items file will need to be augmented with the appropriate MAP Transformations. This involves editing the file, and adding the appropriate `in:`, `out:`, and `command:` parameters per the documentation for the MiOS Binding. + diff --git a/bundles/binding/org.openhab.binding.mios/examples/scripts/miosLoad.sh b/bundles/binding/org.openhab.binding.mios/examples/scripts/miosLoad.sh new file mode 100755 index 00000000000..9f41b96a5b8 --- /dev/null +++ b/bundles/binding/org.openhab.binding.mios/examples/scripts/miosLoad.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +if [ "$#" != "1" ] +then + echo "Usage: $0 " + exit 1 +else + MIOS_IP=$1; export MIOS_IP + MIOS_OUT=user_data.xml; export MIOS_OUT +fi + +echo "Loading MiOS Unit Metadata from ${MIOS_IP}..." +curl --max-time 15 \ + --output ${MIOS_OUT} \ + --silent "http://${MIOS_IP}:49451/data_request?id=user_data&output_format=xml" + +if [ "$?" == "0" ] +then + echo "Metadata Loaded into ${MIOS_OUT}!" +else + echo "Failed to load, Check IP Address supplied." +fi + diff --git a/bundles/binding/org.openhab.binding.mios/examples/scripts/miosTransform.sh b/bundles/binding/org.openhab.binding.mios/examples/scripts/miosTransform.sh new file mode 100755 index 00000000000..67e2e903caa --- /dev/null +++ b/bundles/binding/org.openhab.binding.mios/examples/scripts/miosTransform.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +if [ "$#" != "1" ] +then + echo "Usage: $0 " + exit 1 +else + MIOS_UNIT="${1}"; export MIOS_UNIT + MIOS_IN=user_data.xml; export MIOS_OUT + MIOS_ITEM_FILE="${MIOS_UNIT}.items"; export MIOS_ITEM_FILE +fi + +echo "Transforming MiOS Unit Metadata from ${MIOS_IN}..." +xsltproc --stringparam MIOS_UNIT "${MIOS_UNIT}" --output "${MIOS_ITEM_FILE}" miosTransform.xslt "${MIOS_IN}" + +if [ "$?" == "0" ] +then + echo "Metadata Transformed into ${MIOS_ITEM_FILE}!" +else + echo "Failed to Transform, Check for bogus XML in ${MIOS_IN}." + exit 1 +fi + +echo "Duplicate Item names requiring manual fixes:" +lastItemName="" +grep -v ^$ "${MIOS_ITEM_FILE}" | grep -v "^/" | sort -k 2 | while read -r line; do + read -r itemType itemName _ <<< "$line" + + if [ "$itemName" = "$lastItemName" ]; then + echo " $line" + else + lastItemName="$itemName" + fi +done + diff --git a/bundles/binding/org.openhab.binding.mios/examples/scripts/miosTransform.xslt b/bundles/binding/org.openhab.binding.mios/examples/scripts/miosTransform.xslt new file mode 100644 index 00000000000..a95165679a5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.mios/examples/scripts/miosTransform.xslt @@ -0,0 +1,567 @@ + + + + + + + +_#-!@$%^&*=+~`[]{}\\|:;"<\>?/.() + +Group GAll +Group GPersist (GAll) + +Group GSystem "System Information [%d]" <office> + +Group GRooms (GAll) +Group GScenes (GAll) +Group GDevices (GAll) + + + + + +/* If you want more MiOS Internals, uncomment the following. */ +/* Number SystemDataVersion "System Data Version [%d]" (GSystem) {mios="unit:,system:/DataVersion"} */ +/* DateTime SystemLoadTime "System Load Time [%1$ta, %1$tm/%1$te %1$tR]" <calendar> (GSystem) {mios="unit:,system:/LoadTime"} */ +/* String SystemLocalTime "System Local Time [%s]" (GSystem) {mios="unit:,system:/LocalTime"} */ +/* DateTime SystemTimeStamp "System Time Stamp [%1$ta, %1$tm/%1$te %1$tR]" <calendar> (GSystem) {mios="unit:,system:/TimeStamp"} */ +/* Number SystemUserDataDataVersion "System User Data Version [%d]" (GSystem) {mios="unit:,system:/UserData_DataVersion"} */ + +/* If you want Z-Wave Status, uncomment the following. */ +/* Number SystemZWaveStatus "System ZWave Status [%d]" (GSystem) {mios="unit:,system:/ZWaveStatus"} */ +/* String SystemZWaveStatusString "System ZWave Status String [%d]" (GSystem) {mios="unit:,system:/ZWaveStatus,in:MAP(miosZWaveStatusIn.map)"} */ + + + +Group GRoom " [%d]" <office> (GRooms) + + + + + + + + + + + + + + +/* Device - */ +Number Id "ID [%d]" (GDevices) {mios="unit:,device:/id"} +String DeviceStatus " Device Status [MAP(miosDeviceStatusUI.map):%s]" (GDevices) {mios="unit:,device:/status"} + + + + + + + + +SwitchPower1 +Dimming1 +TemperatureSensor1 +HVAC_FanOperatingMode1 +HVAC_UserOperatingMode1 +TemperatureSetpoint1_Cool +TemperatureSetpoint1_Heat +AVTransport +RenderingControl +DeviceProperties +HouseStatus1 +ContentDirectory +AudioIn +ZWaveDevice1 +ZWaveNetwork1 +HaDevice1 +SceneControllerLED1 +SecuritySensor1 +HumiditySensor1 +EnergyMetering1 +SceneController1 +HVAC_OperatingState1 +SerialPort1 +DoorLock1 +AlarmPartition2 +Camera1 +SystemMonitor +WPSwitch1 +Nest1 +NestStructure1 +Weather1 +PingSensor1 +Sonos1 +Paradox +LiftMasterOpener1 +DirecTVDVR1 + + + + + + +Switch +Dimmer +Dimmer +Number +Number +Number +Dimmer +Switch +Integer +Integer +Integer +Integer +DateTime +DateTime +Number +DateTime +DateTime +Integer +Integer +Integer +Integer +DateTime +Contact +Switch +DateTime +Number +Number +Number +DateTime +DateTime +DateTime +DateTime +DateTime +DateTime +Switch +Integer +Integer +Integer +Integer +Integer +Integer +Integer +Integer +Integer +Number +Number +Number +DateTime +Integer +Integer +Integer +Integer +Contact +DateTime +DateTime +DateTime +DateTime +DateTime +DateTime +DateTime +DateTime +DateTime +DateTime +Number +Number +Number +Number +Number +Number +Number +Number +Number +Integer +Integer +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +DateTime +DateTime +DateTime +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Number +Integer +Integer +Number +Number +Number +Integer +DateTime +DateTime +Number +Number +Number +Integer +Switch +Switch +Switch +Switch +Switch +Switch +Switch +Switch +String + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Heat +Cool +Fan +User + + + + + + + + + Battery Level + Battery Date + Timestamp + First Configured + Last Scene Time + Last Heal + Tripped + Armed + Alarm Memory + Vendor Status Code + Vendor Status Data + Vendor Status + Last Alarm Active + Last User + Arm Mode + Detailed Arm Mode + Alarm + Period + Address + Postal Code + Country Code + Location + Streaming URL + Timeout + Address + Invert + Chime + Cycle + Mute + Mode + Commands + Status + Last Trip + Last Error + Last Time Check + Last Time Offset + Last Route Failure + Occupancy State + Street Address + Ignore Room + Current Setpoint + Current Temperature + Current Level + Scene Shortcuts + Proprietary Scenes + Scene Activated + Scene Deactivated + Lock Failure + Lock Button + PIN Failed + Low Battery + Code Changed + Lock Changed + Battery Alarm + User Code + Volume + Input + Channel + Title + URL + Mode Status + Fan Status + Mode State + Mode State (Energy) + Manage LEDs + Fires Off Events + Min Pin Size + Max Pin Size + User Supplied Wattage + kWh + Watts + Mode Target + Comms Failure + Target + Last Update + Load Level Target + Load Level Status + Light Settings + Scenes + Log + Logging + Polling Enabled + Polling Frequency + #Buttons + Configured + Current Status + Transport State + Transport Status + Transport Play Speed + Current Play Mode + Current Track Title + Current Stream Title + Current Album Art + Current Title + Current Details + Current Artist + Current Album + Current Track + Current Track Duration + Current Service + Current Radio + Zone Name + Icon + Preset 1 + Preset 2 + Preset 3 + Preset 4 + Preset 5 + Preset 6 + Color Temperature + Status 1 + Status 2 + Status 3 + Status 4 + Status 5 + Status 6 + Status 7 + Status 8 + Text 1 + Text 2 + Codesets + Codeset + Hue + Saturation + Link Status + UUID + LowLevel + MidLevel + HighLevel + Last Recipient + Last Message Sent + Message + Debug + State + Options + Devices + Maximum Level + Minimum Interval + Remote + Manufacturer Id + Last Check + + FIXME + + + + + + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f F] + [%.1f W] + [%.1f kWh] + [%.1f W] + [%d] + [%.4f] + [%1$ta, %1$tm/%1$te %1$tR] + [MAP(en.map):%s] + + [%d %%] + [%s] + + + + + +<calendar> +<contact> + + + + + + +(GDevices) + + + + + +Number + + + " +" {mios="unit:,device:/service//"} + + + + + + + + + + + + + + + + + + + + + + + +(GScenes,GRoom) +(GScenes) + + +/* Scene - */ +String Scene " Scene" <sofa> {mios="unit:,scene:/status", autoupdate="false"} +Contact SceneActive "Active [MAP(en.map):%s]" <sofa> {mios="unit:,scene:/active"} + + diff --git a/bundles/binding/org.openhab.binding.mios/examples/transform/miosDeviceStatusUI.map b/bundles/binding/org.openhab.binding.mios/examples/transform/miosDeviceStatusUI.map new file mode 100644 index 00000000000..89a5d8c7725 --- /dev/null +++ b/bundles/binding/org.openhab.binding.mios/examples/transform/miosDeviceStatusUI.map @@ -0,0 +1,5 @@ +NONE=None +PENDING=Pending +SUCCESS=Success +ERROR=Error +UNDEFINED=Unknown diff --git a/bundles/binding/org.openhab.binding.mios/examples/transform/miosShutterCommand.map b/bundles/binding/org.openhab.binding.mios/examples/transform/miosShutterCommand.map new file mode 100644 index 00000000000..1c500f0f8f4 --- /dev/null +++ b/bundles/binding/org.openhab.binding.mios/examples/transform/miosShutterCommand.map @@ -0,0 +1,4 @@ +DOWN=urn:upnp-org:serviceId:WindowCovering1/Down() +UP=urn:upnp-org:serviceId:WindowCovering1/Up() +STOP=urn:upnp-org:serviceId:WindowCovering1/Stop() +_defaultCommand=urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget(newLoadlevelTarget=??) diff --git a/bundles/binding/org.openhab.binding.mios/examples/transform/miosZWaveStatusIn.map b/bundles/binding/org.openhab.binding.mios/examples/transform/miosZWaveStatusIn.map index f5bf606d852..9c0a8ac2dac 100644 --- a/bundles/binding/org.openhab.binding.mios/examples/transform/miosZWaveStatusIn.map +++ b/bundles/binding/org.openhab.binding.mios/examples/transform/miosZWaveStatusIn.map @@ -1,3 +1,8 @@ -1=ZWave is in the house -0=ZWave is in the dog house +0=Not Set +1=OK +2=Quitting +3=Waiting to Quit +4=No Dongle +5=Running Init/Configure Scripts +6=Failure -=Your guess is as good as mine! diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/MiosActionProvider.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/MiosActionProvider.java new file mode 100644 index 00000000000..e5e446141d9 --- /dev/null +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/MiosActionProvider.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.mios; + +import java.util.List; +import java.util.Map.Entry; + +/** + * openHAB Action Provider interface for MiOS Devices. + * + * Defines how to get properties from a MiOS-specific binding configuration. + * + * @author Mark Clark + * @since 1.7.0 + */ +public interface MiosActionProvider { + /** + * Invoke the named MiOS Scene. + * + * Requests the named MiOS Scene, associated with the [Scene] Item be invoked. The invocation itself is + * asynchronous, and may fail. The return status of this call is whether we were successful in queuing the Scene + * request. + * + * @param itemName + * the name of of the openHAB Item to which the Scene invocation should be delivered. + * @return true if the Scene request was sent. + */ + public boolean invokeMiosScene(String itemName); + + /** + * Invoke the named MiOS Action. + * + * Requests the named MiOS Action, associated with the [Device] Item be invoked. Callers can pass an Action to be + * invoked, in the form: / OR; / + * + * The invocation itself is asynchronous, and may fail. The return status of this call is whether we were successful + * in queuing the Action request. + * + * @param itemName + * the name of of the openHAB Item to which the Action invocation should be delivered. + * @param actionName + * the name of the Action to request upon the specified ItemName. + * @param params + * a list of String name/value pairs to be used as the Parameter list for the Action call + * @return true if the Action request was sent. + */ + public boolean invokeMiosAction(String itemName, String actionName, List> params); +} diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/MiosBindingProvider.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/MiosBindingProvider.java index a7d230cb586..fcc8e5c827c 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/MiosBindingProvider.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/MiosBindingProvider.java @@ -11,7 +11,6 @@ import java.util.List; import org.openhab.core.binding.BindingProvider; -import org.openhab.core.items.Item; import org.openhab.core.items.ItemRegistry; /** @@ -29,8 +28,7 @@ public interface MiosBindingProvider extends BindingProvider { * @param itemName * the name of the Item. * - * @return the name of the MiOS Unit associated with the the Item - * {@code itemName} + * @return the name of the MiOS Unit associated with the the Item {@code itemName} */ String getMiosUnitName(String itemName); @@ -40,8 +38,7 @@ public interface MiosBindingProvider extends BindingProvider { * @param itemName * the name of the Item. * - * @return the property string component for the Binding on the Item - * {@code itemName} + * @return the property string component for the Binding on the Item {@code itemName} */ String getProperty(String itemName); @@ -50,10 +47,8 @@ public interface MiosBindingProvider extends BindingProvider { /** * Gets the ItemRegistry (catalog) used by this BindingProvider. * - * The {@code ItemRegistry} is injected into the {@code MiosBindingProvider} - * through OSGi configuration. This method provider read-only access to the - * {@code ItemRegistry}, which is the catalog of Items in use by this - * system. + * The {@code ItemRegistry} is injected into the {@code MiosBindingProvider} through OSGi configuration. This method + * provider read-only access to the {@code ItemRegistry}, which is the catalog of Items in use by this system. * * @return the ItemRegistry associated with this BindingProvider. */ diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosActivator.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosActivator.java index 3bbff3c175b..1aeb974fd52 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosActivator.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosActivator.java @@ -50,8 +50,7 @@ public void stop(BundleContext bc) throws Exception { /** * Returns the OSGi BundleContext of this bundle. * - * The OSGi BundleContext is needed to talk with other services running - * under OSGi. + * The OSGi BundleContext is needed to talk with other services running under OSGi. *

      * eg. openHAB's {@code TransformationService}. * diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosBinding.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosBinding.java index 58a5a9bd2e2..a19a05129fb 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosBinding.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosBinding.java @@ -12,10 +12,15 @@ import java.util.Dictionary; import java.util.Enumeration; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import org.openhab.binding.mios.MiosActionProvider; import org.openhab.binding.mios.MiosBindingProvider; +import org.openhab.binding.mios.internal.config.DeviceBindingConfig; import org.openhab.binding.mios.internal.config.MiosBindingConfig; +import org.openhab.binding.mios.internal.config.SceneBindingConfig; import org.openhab.core.binding.AbstractBinding; import org.openhab.core.binding.BindingProvider; import org.openhab.core.items.Item; @@ -33,15 +38,13 @@ import org.slf4j.LoggerFactory; /** - * The MiOS Binding is responsible for coordinating changes to openHAB Items - * from the corresponding/bound information from each configured MiOS Unit. + * The MiOS Binding is responsible for coordinating changes to openHAB Items from the corresponding/bound information + * from each configured MiOS Unit. * - * The Binding allows information from a MiOS Unit to be bound to openHAB Items, - * as well a allowing openHAB Commands to be propagated back to the MiOS Unit - * under control. + * The Binding allows information from a MiOS Unit to be bound to openHAB Items, as well a allowing openHAB Commands to + * be propagated back to the MiOS Unit under control. * - * The following types of information from a MiOS Unit can be bound to openHAB - * Items: + * The following types of information from a MiOS Unit can be bound to openHAB Items: *

      * *

        @@ -51,48 +54,40 @@ *
      *

      * - * Similarly, through a configurable set of openHAB Transformations, any - * Commands sent to these Items can be proxied back to the corresponding MiOS - * Unit. + * Similarly, through a configurable set of openHAB Transformations, any Commands sent to these Items can be proxied + * back to the corresponding MiOS Unit. *

      * - * Data flowing between the MiOS Unit and openHAB can be transformed as it flows - * between the two systems. This transformation is configurable, and is - * expressed in the Item Binding using standard openHAB + * Data flowing between the MiOS Unit and openHAB can be transformed as it flows between the two systems. This + * transformation is configurable, and is expressed in the Item Binding using standard openHAB * {@code TransformationService} expressions. *

      * - * Example MAP-based Transformation files are provided for commonly required - * transformations.
      - * eg. For Switch Data flowing into openHAB {@code MAP(miosSwitchIn.map)}, and - * for Switch Commands flowing in to MiOS {@code MAP(miosSwitchOut.map)} + * Example MAP-based Transformation files are provided for commonly required transformations.
      + * eg. For Switch Data flowing into openHAB {@code MAP(miosSwitchIn.map)}, and for Switch Commands flowing in to MiOS + * {@code MAP(miosSwitchOut.map)} *

      * * The Binding follows the general interaction principals outlined in the MiOS - * {@link UI Simple} - * documentation. + * {@link UI Simple} documentation. *

      * - * In effect, the binding behaves like a "remote control" to one or more - * configured MiOS Units, utilizing a HTTP-based Long-poll to receive updates - * occurring within each Unit, and transforming them into corresponding updates - * to the openHAB Items that have been bound. + * In effect, the binding behaves like a "remote control" to one or more configured MiOS Units, utilizing a HTTP-based + * Long-poll to receive updates occurring within each Unit, and transforming them into corresponding updates to the + * openHAB Items that have been bound. *

      * - * All updates are received asynchronously from the MiOS Units. This interaction - * is managed by a per MiOS Unit {@link MiosUnitConnector} Polling Thread object - * that utilizes a {@link MiosUnit MiOS Unit} configuration object to determine - * the location of the MiOS Unit. + * All updates are received asynchronously from the MiOS Units. This interaction is managed by a per MiOS Unit + * {@link MiosUnitConnector} Polling Thread object that utilizes a {@link MiosUnit MiOS Unit} configuration object to + * determine the location of the MiOS Unit. *

      * * @author Mark Clark * @since 1.6.0 */ -public class MiosBinding extends AbstractBinding implements - ManagedService { +public class MiosBinding extends AbstractBinding implements ManagedService, MiosActionProvider { - private static final Logger logger = LoggerFactory - .getLogger(MiosBinding.class); + private static final Logger logger = LoggerFactory.getLogger(MiosBinding.class); private Map connectors = new HashMap(); private Map nameUnitMapper = null; @@ -102,8 +97,7 @@ private String getName() { } /** - * Invoked by OSGi Framework, once per instance, during the Binding - * activation process. + * Invoked by OSGi Framework, once per instance, during the Binding activation process. * * OSGi is configured to do this in OSGI-INF/activebinding.xml */ @@ -113,11 +107,9 @@ public void activate() { } /** - * Invoked by the OSGi Framework, once per instance, during the Binding - * deactivation process. + * Invoked by the OSGi Framework, once per instance, during the Binding deactivation process. * - * Internally this is used to close out any resources used by the MiOS - * Binding. + * Internally this is used to close out any resources used by the MiOS Binding. * * OSGi is configured to do this in OSGI-INF/activebinding.xml */ @@ -137,8 +129,7 @@ public void deactivate() { */ @Override public void bindingChanged(BindingProvider provider, String itemName) { - logger.debug("bindingChanged: start provider '{}', itemName '{}'", - provider, itemName); + logger.debug("bindingChanged: start provider '{}', itemName '{}'", provider, itemName); if (provider instanceof MiosBindingProvider) { registerWatch((MiosBindingProvider) provider, itemName); @@ -165,8 +156,7 @@ private void registerAllWatches() { logger.debug("registerAllWatches: start"); for (BindingProvider provider : providers) { - logger.debug("registerAllWatches: provider '{}'", - provider.getClass()); + logger.debug("registerAllWatches: provider '{}'", provider.getClass()); if (provider instanceof MiosBindingProvider) { MiosBindingProvider miosProvider = (MiosBindingProvider) provider; @@ -179,8 +169,7 @@ private void registerAllWatches() { } private void registerWatch(MiosBindingProvider miosProvider, String itemName) { - logger.debug("registerWatch: start miosProvider '{}', itemName '{}'", - miosProvider, itemName); + logger.debug("registerWatch: start miosProvider '{}', itemName '{}'", miosProvider, itemName); String unitName = miosProvider.getMiosUnitName(itemName); @@ -199,8 +188,7 @@ private String getMiosUnitName(String itemName) { for (BindingProvider provider : providers) { if (provider instanceof MiosBindingProvider) { if (provider.getItemNames().contains(itemName)) { - return ((MiosBindingProvider) provider) - .getMiosUnitName(itemName); + return ((MiosBindingProvider) provider).getMiosUnitName(itemName); } } } @@ -227,8 +215,7 @@ private MiosUnitConnector getMiosConnector(String unitName) { // check if we have been initialized yet - can't process // named units until we have read the binding config. if (nameUnitMapper == null) { - logger.trace( - "Attempting to access the named MiOS Unit '{}' before the binding config has been loaded", + logger.trace("Attempting to access the named MiOS Unit '{}' before the binding config has been loaded", unitName); return null; } @@ -237,15 +224,12 @@ private MiosUnitConnector getMiosConnector(String unitName) { // Check this Unit name exists in our config if (miosUnit == null) { - logger.error( - "Named MiOS Unit '{}' does not exist in the binding config", - unitName); + logger.error("Named MiOS Unit '{}' does not exist in the binding config", unitName); return null; } // create a new connection handler - logger.debug("Creating new MiosConnector for '{}' on {}", unitName, - miosUnit.getHostname()); + logger.debug("Creating new MiosConnector for '{}' on {}", unitName, miosUnit.getHostname()); connector = new MiosUnitConnector(miosUnit, this); connectors.put(unitName, connector); @@ -253,8 +237,7 @@ private MiosUnitConnector getMiosConnector(String unitName) { try { connector.open(); } catch (Exception e) { - logger.error("Connection failed for '{}' on {}", unitName, - miosUnit.getHostname()); + logger.error("Connection failed for '{}' on {}", unitName, miosUnit.getHostname()); } return connector; @@ -266,16 +249,14 @@ private MiosUnitConnector getMiosConnector(String unitName) { @Override protected void internalReceiveCommand(String itemName, Command command) { try { - logger.debug("internalReceiveCommand: itemName '{}', command '{}'", - itemName, command); + logger.debug("internalReceiveCommand: itemName '{}', command '{}'", itemName, command); // Lookup the MiOS Unit name and property for this item String unitName = getMiosUnitName(itemName); MiosUnitConnector connector = getMiosConnector(unitName); if (connector == null) { - logger.warn( - "Received command ({}) for item '{}' but no connector found for MiOS Unit '{}', ignoring", + logger.warn("Received command ({}) for item '{}' but no connector found for MiOS Unit '{}', ignoring", new Object[] { command.toString(), itemName, unitName }); return; } @@ -290,8 +271,7 @@ protected void internalReceiveCommand(String itemName, Command command) { for (BindingProvider provider : providers) { if (provider instanceof MiosBindingProvider) { MiosBindingProviderImpl miosProvider = (MiosBindingProviderImpl) provider; - MiosBindingConfig config = miosProvider - .getMiosBindingConfig(itemName); + MiosBindingConfig config = miosProvider.getMiosBindingConfig(itemName); if (config != null) { ItemRegistry reg = miosProvider.getItemRegistry(); @@ -301,13 +281,11 @@ protected void internalReceiveCommand(String itemName, Command command) { State state = item.getState(); connector.invokeCommand(config, command, state); } else { - logger.warn( - "internalReceiveCommand: Missing ItemRegistry for item '{}' command '{}'", + logger.warn("internalReceiveCommand: Missing ItemRegistry for item '{}' command '{}'", itemName, command); } } else { - logger.trace( - "internalReceiveCommand: Missing BindingConfig for item '{}' command '{}'", + logger.trace("internalReceiveCommand: Missing BindingConfig for item '{}' command '{}'", itemName, command); } } @@ -323,9 +301,8 @@ protected void internalReceiveCommand(String itemName, Command command) { */ @Override protected void internalReceiveUpdate(String itemName, State newState) { - logger.trace( - "internalReceiveUpdate: itemName '{}', newState '{}', class '{}'", - new Object[] { itemName, newState, newState.getClass() }); + logger.trace("internalReceiveUpdate: itemName '{}', newState '{}', class '{}'", new Object[] { itemName, + newState, newState.getClass() }); // No need to implement this for MiOS Bridge Binding since anything // that needs to be sent back to the MiOS System will be done via a @@ -339,8 +316,7 @@ protected void internalReceiveUpdate(String itemName, State newState) { * {@inheritDoc} */ @Override - public void updated(Dictionary properties) - throws ConfigurationException { + public void updated(Dictionary properties) throws ConfigurationException { logger.trace(getName() + " updated()"); Map units = new HashMap(); @@ -373,8 +349,7 @@ public void updated(Dictionary properties) } boolean created = false; - String hackUnitName = (unitName == null) ? MiosUnit.CONFIG_DEFAULT_UNIT - : unitName; + String hackUnitName = (unitName == null) ? MiosUnit.CONFIG_DEFAULT_UNIT : unitName; MiosUnit unit = units.get(hackUnitName); if (unit == null) { @@ -412,11 +387,10 @@ public void updated(Dictionary properties) } /** - * Push a value into all openHAB Items that match a given MiOS Property name - * (from the Item Binding declaration). + * Push a value into all openHAB Items that match a given MiOS Property name (from the Item Binding declaration). *

      - * In the process, this routine will perform Datatype conversions from Java - * types to openHAB's type system. These conversions are as follows: + * In the process, this routine will perform Datatype conversions from Java types to openHAB's type system. These + * conversions are as follows: *

      *

        *
      • {@code String} -> {@code StringType} @@ -433,39 +407,29 @@ public void updated(Dictionary properties) * @exception IllegalArgumentException * thrown if the value isn't one of the supported types. */ - public void postPropertyUpdate(String property, Object value, - boolean incremental) throws Exception { + public void postPropertyUpdate(String property, Object value, boolean incremental) throws Exception { if (value instanceof String) { - internalPropertyUpdate(property, new StringType(value == null ? "" - : (String) value), incremental); + internalPropertyUpdate(property, new StringType(value == null ? "" : (String) value), incremental); } else if (value instanceof Integer) { - internalPropertyUpdate(property, new DecimalType((Integer) value), - incremental); + internalPropertyUpdate(property, new DecimalType((Integer) value), incremental); } else if (value instanceof Calendar) { - internalPropertyUpdate(property, - new DateTimeType((Calendar) value), incremental); + internalPropertyUpdate(property, new DateTimeType((Calendar) value), incremental); } else if (value instanceof Double) { - internalPropertyUpdate(property, new DecimalType((Double) value), - incremental); + internalPropertyUpdate(property, new DecimalType((Double) value), incremental); } else if (value instanceof Boolean) { postPropertyUpdate(property, - ((Boolean) value).booleanValue() ? OnOffType.ON.toString() - : OnOffType.OFF.toString(), incremental); + ((Boolean) value).booleanValue() ? OnOffType.ON.toString() : OnOffType.OFF.toString(), incremental); } else { - throw new IllegalArgumentException(String.format( - "Unexpected Datatype, property=%s datatype=%s", property, + throw new IllegalArgumentException(String.format("Unexpected Datatype, property=%s datatype=%s", property, value.getClass().toString())); } } - private void internalPropertyUpdate(String property, State value, - boolean incremental) throws Exception { + private void internalPropertyUpdate(String property, State value, boolean incremental) throws Exception { int bound = 0; if (value == null) { - logger.trace( - "internalPropertyUpdate: Value is null for Property '{}', ignored.", - property); + logger.trace("internalPropertyUpdate: Value is null for Property '{}', ignored.", property); return; } @@ -473,11 +437,9 @@ private void internalPropertyUpdate(String property, State value, if (provider instanceof MiosBindingProvider) { MiosBindingProviderImpl miosProvider = (MiosBindingProviderImpl) provider; - for (String itemName : miosProvider - .getItemNamesForProperty(property)) { + for (String itemName : miosProvider.getItemNamesForProperty(property)) { - MiosBindingConfig config = miosProvider - .getMiosBindingConfig(itemName); + MiosBindingConfig config = miosProvider.getMiosBindingConfig(itemName); if (config != null) { // Transform whatever value we have, based upon the @@ -487,9 +449,8 @@ private void internalPropertyUpdate(String property, State value, State newValue = config.transformIn(value); if (newValue != value) { - logger.trace( - "internalPropertyUpdate: transformation performed, from '{}' to '{}'", - value, newValue); + logger.trace("internalPropertyUpdate: transformation performed, from '{}' to '{}'", value, + newValue); value = newValue; } @@ -507,9 +468,8 @@ private void internalPropertyUpdate(String property, State value, // unnecessary manner. // if (incremental) { - logger.debug( - "internalPropertyUpdate: Updating (Incremental) itemName '{}' with value '{}'", - itemName, value); + logger.debug("internalPropertyUpdate: BOUND (Incr) Updating '{} {mios=\"{}\"}' to '{}'", + itemName, property, value); eventPublisher.postUpdate(itemName, value); } else { @@ -517,26 +477,22 @@ private void internalPropertyUpdate(String property, State value, State oldValue = reg.getItem(itemName).getState(); if ((oldValue == null && value != null) - || (UnDefType.UNDEF.equals(oldValue) && !UnDefType.UNDEF - .equals(value)) + || (UnDefType.UNDEF.equals(oldValue) && !UnDefType.UNDEF.equals(value)) || !oldValue.equals(value)) { logger.debug( - "internalPropertyUpdate: Updating (Full) itemName '{}' with value '{}', oldValue '{}'", - new Object[] { itemName, value, - oldValue }); + "internalPropertyUpdate: BOUND (Full) Updating '{} {mios=\"{}\"}' to '{}', was '{}'", + new Object[] { itemName, property, value, oldValue }); eventPublisher.postUpdate(itemName, value); } else { logger.trace( - "internalPropertyUpdate: Ignoring (Full) itemName '{}' with value '{}', oldValue '{}'", - new Object[] { itemName, value, - oldValue }); + "internalPropertyUpdate: BOUND (Full) Ignoring '{} {mios=\"{}\"}' to '{}', was '{}'", + new Object[] { itemName, property, value, oldValue }); } } bound++; } else { - logger.trace( - "internalPropertyUpdate: Found null BindingConfig for item '{}' property '{}'", + logger.trace("internalPropertyUpdate: Found null BindingConfig for item '{}' property '{}'", itemName, property); } } @@ -544,13 +500,112 @@ private void internalPropertyUpdate(String property, State value, } if (bound == 0) { - logger.trace( - "internalPropertyUpdate: NOT BOUND {mios=\"{}\"}, value={}", - property, value); + logger.trace("internalPropertyUpdate: NOT BOUND {mios=\"{}\"}, value={}", property, value); } else { - logger.debug( - "internalPropertyUpdate: BOUND {mios=\"{}\"}, value={}, bound {} time(s)", - new Object[] { property, value, bound }); + logger.trace("internalPropertyUpdate: BOUND {mios=\"{}\"}, value={}, bound {} time(s)", new Object[] { + property, value, bound }); + } + } + + /** + * {@inheritDoc} + */ + public boolean invokeMiosScene(String itemName) { + try { + logger.debug("invokeMiosScene item {}", itemName); + + boolean sent = false; + + // Lookup the MiOS Unit name and property for this item + String unitName = getMiosUnitName(itemName); + + MiosUnitConnector connector = getMiosConnector(unitName); + if (connector == null) { + logger.warn( + "invokeMiosScene: Scene call for item '{}' but no connector found for MiOS Unit '{}', ignoring", + itemName, unitName); + return false; + } + + if (!connector.isConnected()) { + logger.warn( + "invokeMiosScene: Scene call for item '{}' but the connection to the MiOS Unit '{}' is down, ignoring", + itemName, unitName); + return false; + } + + for (BindingProvider provider : providers) { + if (provider instanceof MiosBindingProvider) { + MiosBindingProviderImpl miosProvider = (MiosBindingProviderImpl) provider; + MiosBindingConfig config = miosProvider.getMiosBindingConfig(itemName); + + if ((config != null) && (config instanceof SceneBindingConfig)) { + connector.invokeScene((SceneBindingConfig) config); + sent = true; + } else { + logger.error( + "invokeMiosScene: Missing BindingConfig for item '{}', or not bound to a MiOS Scene.", + itemName); + } + } + } + + return sent; + } catch (Exception e) { + logger.error("invokeMiosScene: Error handling command", e); + return false; } } + + /** + * {@inheritDoc} + */ + public boolean invokeMiosAction(String itemName, String actionName, List> params) { + try { + logger.debug("invokeMiosAction item {}, action {}, params {}", + new Object[] { itemName, actionName, Integer.valueOf((params == null) ? 0 : params.size()) }); + + boolean sent = false; + + // Lookup the MiOS Unit name and property for this item + String unitName = getMiosUnitName(itemName); + + MiosUnitConnector connector = getMiosConnector(unitName); + if (connector == null) { + logger.warn( + "invokeMiosAction: Action call for item '{}' but no connector found for MiOS Unit '{}', ignoring", + itemName, unitName); + return false; + } + + if (!connector.isConnected()) { + logger.warn( + "invokeMiosAction: Action call for item '{}' but the connection to the MiOS Unit '{}' is down, ignoring", + itemName, unitName); + return false; + } + + for (BindingProvider provider : providers) { + if (provider instanceof MiosBindingProvider) { + MiosBindingProviderImpl miosProvider = (MiosBindingProviderImpl) provider; + MiosBindingConfig config = miosProvider.getMiosBindingConfig(itemName); + + if ((config != null) && (config instanceof DeviceBindingConfig)) { + connector.invokeAction((DeviceBindingConfig) config, actionName, params); + sent = true; + } else { + logger.error( + "invokeMiosAction: Missing BindingConfig for item '{}', or not bound to a MiOS Device.", + itemName); + } + } + } + + return sent; + } catch (Exception e) { + logger.error("invokeMiosScene: Error handling command", e); + return false; + } + } + } diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosBindingProviderImpl.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosBindingProviderImpl.java index dfc7fbdc8ae..0562aa81584 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosBindingProviderImpl.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosBindingProviderImpl.java @@ -31,29 +31,24 @@ /** * This class is responsible for parsing the binding configuration. * - * Each MiOS Binding declaration consists of a comma-separated list of elements, - * of the form :, that are expressed in a specific order. + * Each MiOS Binding declaration consists of a comma-separated list of elements, of the form :, that are + * expressed in a specific order. *

        * * The order is: *

          - *
        • {@code unit:} - the name of the MiOS Unit, declared in the openHAB - * configuration. The value is a case-sensitive MiOS Unit name [alphaNumeric] - * String. + *
        • {@code unit:} - the name of the MiOS Unit, declared in the openHAB configuration. The value is a + * case-sensitive MiOS Unit name [alphaNumeric] String. * - *
        • {@code :} - the type of entity bound at the MiOS Unit. The - * value is a MiOS-specific identifier Integer. Type names include " - * {@code device}", " {@code scene}", and "{@code system}" and the corresponding - * {@code id} used within the MiOS Unit. + *
        • {@code :} - the type of entity bound at the MiOS Unit. The value is a MiOS-specific identifier Integer. + * Type names include " {@code device}", " {@code scene}", and "{@code system}" and the corresponding {@code id} used + * within the MiOS Unit. * - *
        • {@code command:} - a Transformation expression to map openHAB - * Command data to MiOS UPnP calls. + *
        • {@code command:} - a Transformation expression to map openHAB Command data to MiOS UPnP calls. * - *
        • {@code in:} - a Transformation expression for inbound data - * from the MiOS Unit for openHAB. + *
        • {@code in:} - a Transformation expression for inbound data from the MiOS Unit for openHAB. * - *
        • {@code out:} - a Transformation expression for outbound data - * from openHAB for the MiOS Unit. + *
        • {@code out:} - a Transformation expression for outbound data from openHAB for the MiOS Unit. *
        *

        * Example MiOS binding expressions look like the following: @@ -62,32 +57,26 @@ * A read-only, binding expression with no mappings applied
        * {@code mios="unit:house,device:228/service/AlarmPartition2/DetailedArmMode"} *

      • - * A read-write, binding expression with input & output value and command - * transformations
        + * A read-write, binding expression with input & output value and command transformations
        * {@code mios="unit:house,device:6/service/SwitchPower1/Status,command:ON|OFF,in:MAP(miosSwitchIn.map),out:MAP(miosSwitchOut.map)"} *
      * * @author Mark Clark * @since 1.6.0 */ -public class MiosBindingProviderImpl extends AbstractGenericBindingProvider - implements MiosBindingProvider { +public class MiosBindingProviderImpl extends AbstractGenericBindingProvider implements MiosBindingProvider { // TODO: Fix parsing for system to be tighter. We "opened" the parsing for - // the others to permit no "id" field, but that's not value - private static final Pattern BINDING_PATTERN = Pattern - .compile("(unit:(?[a-zA-Z]+[a-zA-Z0-9]*),)" - + "(?[^,]+)" - + "(,command:(?[^,]*))?" - + "(,in:(?[a-zA-Z]+[a-zA-Z0-9]*\\([^,]*\\)))?" - + "(,out:(?[a-zA-Z]+[a-zA-Z0-9]*\\([^,]*\\)))?"); + // the others to permit no "id" field, but that's not valid + private static final Pattern BINDING_PATTERN = Pattern.compile("(unit:(?[a-zA-Z]+[a-zA-Z0-9]*),)" + + "(?[^,]+)" + "(,command:(?[^,]*))?" + + "(,in:(?[a-zA-Z]+[a-zA-Z0-9]*\\([^,]*\\)))?" + + "(,out:(?[a-zA-Z]+[a-zA-Z0-9]*\\([^,]*\\)))?"); - private static final Pattern IN_CONFIG_PATTERN = Pattern - .compile("((?device|scene|system|room):" + "(?[0-9]*))" - + "(/(?.+))?"); + private static final Pattern IN_CONFIG_PATTERN = Pattern.compile("((?device|scene|system|room):" + + "(?[0-9]*))" + "(/(?.+))?"); - private static final Logger logger = LoggerFactory - .getLogger(MiosBindingProviderImpl.class); + private static final Logger logger = LoggerFactory.getLogger(MiosBindingProviderImpl.class); // Injected by the OSGi Container through the setItemRegistry and // unsetItemRegistry methods. @@ -96,9 +85,8 @@ public class MiosBindingProviderImpl extends AbstractGenericBindingProvider /** * Invoked by the OSGi Framework. * - * This method is invoked by OSGi during the initialization of the - * MiOSBinding, so we have subsequent access to the ItemRegistry (needed to - * get values from Items in openHAB) + * This method is invoked by OSGi during the initialization of the MiOSBinding, so we have subsequent access to the + * ItemRegistry (needed to get values from Items in openHAB) */ public void setItemRegistry(ItemRegistry itemRegistry) { logger.debug("setItemRegistry: called"); @@ -108,9 +96,8 @@ public void setItemRegistry(ItemRegistry itemRegistry) { /** * Invoked by the OSGi Framework. * - * This method is invoked by OSGi during the initialization of the - * MiOSBinding, so we have subsequent access to the ItemRegistry (needed to - * get values from Items in openHAB) + * This method is invoked by OSGi during the initialization of the MiOSBinding, so we have subsequent access to the + * ItemRegistry (needed to get values from Items in openHAB) */ public void unsetItemRegistry(ItemRegistry itemRegistry) { logger.debug("unsetItemRegistry: called"); @@ -132,8 +119,7 @@ public String getBindingType() { * {@inheritDoc} */ @Override - public void validateItemType(Item item, String bindingConfig) - throws BindingConfigParseException { + public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException { // Validation is done at the BindingConfig level, just after parsing the // bindingConfig String inside processBindingConfiguration. } @@ -142,17 +128,15 @@ public void validateItemType(Item item, String bindingConfig) * {@inheritDoc} */ @Override - public void processBindingConfiguration(String context, Item item, - String bindingConfig) throws BindingConfigParseException { + public void processBindingConfiguration(String context, Item item, String bindingConfig) + throws BindingConfigParseException { super.processBindingConfiguration(context, item, bindingConfig); try { - MiosBindingConfig config = parseBindingConfig(context, item, - bindingConfig); + MiosBindingConfig config = parseBindingConfig(context, item, bindingConfig); config.validateItemType(item); - logger.debug( - "processBindingConfiguration: Adding Item '{}' Binding '{}', from '{}'", + logger.debug("processBindingConfiguration: Adding Item '{}' Binding '{}', from '{}'", new Object[] { item.getName(), config, context }); addBindingConfig(item, config); } catch (BindingConfigParseException bcpe) { @@ -164,16 +148,15 @@ public void processBindingConfiguration(String context, Item item, } } - private MiosBindingConfig parseBindingConfig(String context, Item item, - String bindingConfig) throws BindingConfigParseException { + private MiosBindingConfig parseBindingConfig(String context, Item item, String bindingConfig) + throws BindingConfigParseException { Matcher matcher; matcher = BINDING_PATTERN.matcher(bindingConfig); if (!matcher.matches()) { - throw new BindingConfigParseException( - String.format( - "Config for item '%s' could not be parsed. Bad general format '%s'", - item.getName(), bindingConfig.toString())); + throw new BindingConfigParseException(String.format( + "Config for item '%s' could not be parsed. Bad general format '%s'", item.getName(), + bindingConfig.toString())); } String unitName = matcher.group("unit"); @@ -184,47 +167,39 @@ private MiosBindingConfig parseBindingConfig(String context, Item item, String inTrans = matcher.group("inTransform"); String outTrans = matcher.group("outTransform"); - logger.trace( - "parseBindingConfig: unit '{}' thing '{}' inTrans '{}' outTrans '{}'", - new Object[] { unitName, inThing, inTrans, outTrans }); + logger.trace("parseBindingConfig: unit '{}' thing '{}' inTrans '{}' outTrans '{}'", new Object[] { unitName, + inThing, inTrans, outTrans }); // The inbound pattern is mandatory, and enforced by the // pattern-matcher. matcher = IN_CONFIG_PATTERN.matcher(inThing); if (!matcher.matches()) - throw new BindingConfigParseException( - String.format( - "Config for item '%s' could not be parsed. Bad thing format '%s'", - item.getName(), bindingConfig)); + throw new BindingConfigParseException(String.format( + "Config for item '%s' could not be parsed. Bad thing format '%s'", item.getName(), bindingConfig)); String inType = matcher.group("inType"); String inId = matcher.group("id"); String inStuff = matcher.group("inStuff"); - logger.trace( - "parseBindingConfig: in: (Type '{}' id '{}' Stuff '{}'), command: ('{}')", - new Object[] { inType, inId, inStuff, commandThing }); + logger.trace("parseBindingConfig: in: (Type '{}' id '{}' Stuff '{}'), command: ('{}')", new Object[] { inType, + inId, inStuff, commandThing }); // FIXME: Inline a factory for now... if (inType.equals("device")) { - return DeviceBindingConfig.create(context, item.getName(), - unitName, Integer.parseInt(inId), inStuff, item.getClass(), - commandThing, inTrans, outTrans); + return DeviceBindingConfig.create(context, item.getName(), unitName, Integer.parseInt(inId), inStuff, + item.getClass(), commandThing, inTrans, outTrans); } else if (inType.equals("scene")) { - return SceneBindingConfig.create(context, item.getName(), unitName, - Integer.parseInt(inId), inStuff, item.getClass(), - commandThing, inTrans, outTrans); + return SceneBindingConfig.create(context, item.getName(), unitName, Integer.parseInt(inId), inStuff, + item.getClass(), commandThing, inTrans, outTrans); } else if (inType.equals("system")) { - return SystemBindingConfig.create(context, item.getName(), - unitName, inStuff, item.getClass(), inTrans, outTrans); - } else if (inType.equals("room")) { - return RoomBindingConfig.create(context, item.getName(), unitName, - Integer.parseInt(inId), inStuff, item.getClass(), inTrans, + return SystemBindingConfig.create(context, item.getName(), unitName, inStuff, item.getClass(), inTrans, outTrans); + } else if (inType.equals("room")) { + return RoomBindingConfig.create(context, item.getName(), unitName, Integer.parseInt(inId), inStuff, + item.getClass(), inTrans, outTrans); } else throw new BindingConfigParseException(String.format( - "Invalid binding type received for Item %s, bad type (%s)", - item.getName(), inType)); + "Invalid binding type received for Item %s, bad type (%s)", item.getName(), inType)); } public MiosBindingConfig getMiosBindingConfig(String itemName) { @@ -258,15 +233,12 @@ public List getItemNamesForProperty(String property) { // TODO: Make a reverse map somewhere, and keep it around as this is // going to get a lot of calls, and a lot of garbage along the way!! - for (Entry bindingConfigEntry : bindingConfigs - .entrySet()) { + for (Entry bindingConfigEntry : bindingConfigs.entrySet()) { if (bindingConfigEntry.getValue() instanceof MiosBindingConfig) { - String p = ((MiosBindingConfig) bindingConfigEntry.getValue()) - .toProperty(); + String p = ((MiosBindingConfig) bindingConfigEntry.getValue()).toProperty(); if (p.equals(property)) { - logger.trace( - "getItemNamesForProperty: MATCH property '{}' against BindingConfig.toProperty '{}'", + logger.trace("getItemNamesForProperty: MATCH property '{}' against BindingConfig.toProperty '{}'", property, p); String itemName = bindingConfigEntry.getKey(); diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosUnit.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosUnit.java index 9a651edaebb..de70765d880 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosUnit.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosUnit.java @@ -14,19 +14,16 @@ /** * Connection properties for an MiOS Unit. * - * Class used internally to contain the configuration of a named MiOS - * Unit, after it's been materialized from openHAB's configuration components. + * Class used internally to contain the configuration of a named MiOS Unit, after it's been materialized from + * openHAB's configuration components. * - * The MiOS Unit is a named set of attributes that the MiOS Binding uses - * to determine where communications need to be established: + * The MiOS Unit is a named set of attributes that the MiOS Binding uses to determine where communications need + * to be established: *

      *

        - *
      • Hostname - the name, or IP Address of the host that's - * running the MiOS Unit. - *
      • Port - the (numeric) TCP port of the host that's running the - * MiOS Unit (default: 3480) - *
      • Timeout - the Timeout to use for HTTP connections to the - * MiOS Unit (default: 60000 ms) + *
      • Hostname - the name, or IP Address of the host that's running the MiOS Unit. + *
      • Port - the (numeric) TCP port of the host that's running the MiOS Unit (default: 3480) + *
      • Timeout - the Timeout to use for HTTP connections to the MiOS Unit (default: 60000 ms) *
      *

      * @@ -38,9 +35,8 @@ public class MiosUnit { public static final String CONFIG_DEFAULT_UNIT = "default"; /** - * The minimal permissible timeout to be specified in the Unit - * configuration. This allows us some headroom to tell the MiOS unit that we - * want to long-poll for less than this amount of time. + * The minimal permissible timeout to be specified in the Unit configuration. This allows us some headroom to tell + * the MiOS unit that we want to long-poll for less than this amount of time. */ private static final int CONFIG_MIN_TIMEOUT = 5000; private static final int CONFIG_DEFAULT_TIMEOUT = 60000; @@ -66,12 +62,10 @@ public class MiosUnit { private int refreshCount = CONFIG_DEFAULT_REFRESH_COUNT; private int errorCount = CONFIG_DEFAULT_ERROR_COUNT; - private static final Logger logger = LoggerFactory - .getLogger(MiosUnit.class); + private static final Logger logger = LoggerFactory.getLogger(MiosUnit.class); /** - * All MiOS unit's have a name, that must be specified as the configuration - * is being loaded. + * All MiOS unit's have a name, that must be specified as the configuration is being loaded. */ public MiosUnit(String name) { this.name = name; @@ -89,8 +83,7 @@ public String getHostname() { /** * Get the Port setting for the MiOS unit configuration. * - * The default Port for a MiOS Unit is 3480, but this can be overridden in - * config as needed. + * The default Port for a MiOS Unit is 3480, but this can be overridden in config as needed. * * @return the Port associated with the MiOS Unit. */ @@ -110,14 +103,11 @@ public int getTimeout() { } /** - * Get the Minimum time, in ms, that the MiOS Unit should wait/delay in - * order to "bundle" changes in their response. + * Get the Minimum time, in ms, that the MiOS Unit should wait/delay in order to "bundle" changes in their response. * - * If this configuration is not specified, then it will default to 0ms, or - * no-delay. + * If this configuration is not specified, then it will default to 0ms, or no-delay. * - * @return the Minimum Delay for dealing with the MiOS Unit, in - * milliseconds. + * @return the Minimum Delay for dealing with the MiOS Unit, in milliseconds. */ public int getMinimumDelay() { return minimumDelay; @@ -126,15 +116,13 @@ public int getMinimumDelay() { /** * Get the Refresh Count setting for the MiOS Unit configuration. * - * This setting is used to control how often (loop cycles) should be - * performed loading incremental data, before a full-refresh of data should - * be performed from the MiOS Unit under control. + * This setting is used to control how often (loop cycles) should be performed loading incremental data, before a + * full-refresh of data should be performed from the MiOS Unit under control. * - * If this setting is not specified, it will default to never performing the - * full-refresh on the MiOS Unit (internally, a 0 value). + * If this setting is not specified, it will default to never performing the full-refresh on the MiOS Unit + * (internally, a 0 value). * - * @return the Full Refresh cycle count. A value of 0 will disable the Full - * Refresh from occurring. + * @return the Full Refresh cycle count. A value of 0 will disable the Full Refresh from occurring. */ public int getRefreshCount() { return refreshCount; @@ -143,17 +131,14 @@ public int getRefreshCount() { /** * Get the Error Count setting for the MiOS Unit configuration. * - * This setting is used to control how many errors are permitted, in - * attempting to retrieve data from the MiOS Unit, prior to forcing a - * full-refresh. By default, this logic is disabled (a 0 value), but it can - * be reset so that errors in the retrieval will trigger a full data-set to - * be fetched. + * This setting is used to control how many errors are permitted, in attempting to retrieve data from the MiOS Unit, + * prior to forcing a full-refresh. By default, this logic is disabled (a 0 value), but it can be reset so that + * errors in the retrieval will trigger a full data-set to be fetched. * - * If this setting is not specified, it will default to never performing the - * full-refresh on the MiOS Unit (internally, a 0 value). + * If this setting is not specified, it will default to never performing the full-refresh on the MiOS Unit + * (internally, a 0 value). * - * @return the Error count. A value of 0 will disable the Full Refresh from - * occurring upon errors. + * @return the Error count. A value of 0 will disable the Full Refresh from occurring upon errors. */ public int getErrorCount() { return errorCount; @@ -183,13 +168,11 @@ public void setPort(int port) { * Set the Timeout of the MiOS Unit configuration. * * @param timeout - * the timeout to set for any connections associated with this - * MiOS Unit. + * the timeout to set for any connections associated with this MiOS Unit. */ public void setTimeout(int timeout) { if (timeout < CONFIG_MIN_TIMEOUT) { - logger.warn("Timeout of {} below minimum permitted, {} used.", - timeout, CONFIG_MIN_TIMEOUT); + logger.warn("Timeout of {} below minimum permitted, {} used.", timeout, CONFIG_MIN_TIMEOUT); timeout = CONFIG_MIN_TIMEOUT; } this.timeout = timeout; @@ -199,14 +182,11 @@ public void setTimeout(int timeout) { * Set the Minimum Delay of the MiOS Unit configuration. * * @param delay - * the minimum delay, in ms, to use for any connections - * associated with this MiOS Unit. + * the minimum delay, in ms, to use for any connections associated with this MiOS Unit. */ public void setMinimumDelay(int delay) { if (delay < CONFIG_MIN_MINIMUM_DELAY) { - logger.warn( - "Minimum Delay of {} below minimum permitted, {] used.", - minimumDelay, CONFIG_MIN_MINIMUM_DELAY); + logger.warn("Minimum Delay of {} below minimum permitted, {] used.", minimumDelay, CONFIG_MIN_MINIMUM_DELAY); delay = CONFIG_MIN_MINIMUM_DELAY; } this.minimumDelay = delay; @@ -216,14 +196,12 @@ public void setMinimumDelay(int delay) { * Set the Refresh Count of the MiOS Unit configuration. * * @param count - * the number of loop/cycles before a Full-data refresh is - * performed from the MiOS Unit. A value of 0 disables the - * refresh processing. + * the number of loop/cycles before a Full-data refresh is performed from the MiOS Unit. A value of 0 + * disables the refresh processing. */ public void setRefreshCount(int count) { if (count < 0) { - logger.warn("RefreshCount {} below minimum permitted, {} used.", - count, CONFIG_DISABLE_REFRESH_COUNT); + logger.warn("RefreshCount {} below minimum permitted, {} used.", count, CONFIG_DISABLE_REFRESH_COUNT); count = CONFIG_DISABLE_REFRESH_COUNT; } this.refreshCount = count; @@ -233,14 +211,12 @@ public void setRefreshCount(int count) { * Set the Error Count of the MiOS Unit configuration. * * @param errors - * the number of error loop/cycles before a Full-data refresh is - * performed from the MiOS Unit. A value of 0 disables the - * processing. + * the number of error loop/cycles before a Full-data refresh is performed from the MiOS Unit. A value of + * 0 disables the processing. */ public void setErrorCount(int errors) { if (errors < 0) { - logger.warn("RefreshCount {} below minimum permitted, {} used.", - errors, CONFIG_DISABLE_ERROR_COUNT); + logger.warn("RefreshCount {} below minimum permitted, {} used.", errors, CONFIG_DISABLE_ERROR_COUNT); errors = CONFIG_DISABLE_ERROR_COUNT; } this.errorCount = errors; @@ -249,8 +225,8 @@ public void setErrorCount(int errors) { /** * Get the name of the MiOS Unit configuration. * - * Each MiOS Unit has a name within the configuration properties. If it's - * not named, then the "default" name is "default". + * Each MiOS Unit has a name within the configuration properties. If it's not named, then the "default" name is + * "default". *

      * * Otherwise, the name is that specified in the openHAB configuration. @@ -270,13 +246,12 @@ public String getName() { /** * Provide any unit-specific prefix to a given property name. * - * Internally this method is used to augment a "MiOS Unit neutral" property - * string with the name of this MiOS Unit. + * Internally this method is used to augment a "MiOS Unit neutral" property string with the name of this MiOS + * Unit. *

      * - * In many cases, the code that builds the property string isn't aware of - * the MiOS Unit that it's part of, and the MiOS Unit needs to be added on - * later. + * In many cases, the code that builds the property string isn't aware of the MiOS Unit that it's part of, and the + * MiOS Unit needs to be added on later. * * @param property * an unformatted property name. diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosUnitConnector.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosUnitConnector.java index b9691017c7f..49d55d28db3 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosUnitConnector.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/MiosUnitConnector.java @@ -9,7 +9,6 @@ package org.openhab.binding.mios.internal; import java.io.IOException; -import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; @@ -18,7 +17,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Properties; +import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.regex.Matcher; @@ -36,6 +35,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.ning.http.client.AsyncCompletionHandler; import com.ning.http.client.AsyncHttpClient; import com.ning.http.client.AsyncHttpClientConfig; import com.ning.http.client.AsyncHttpClientConfig.Builder; @@ -48,15 +48,11 @@ * This code has two functions to perform: *

        *
      • Inbound changes from the MiOS Unit.
        - * Manages an internal thread to periodically poll the configured MiOS Unit and - * timeout at the specified interval. All changes are internally transformed - * from their original (JSON) form, and dispatched to the relevant parts of - * openHAB. + * Manages an internal thread to periodically poll the configured MiOS Unit and timeout at the specified interval. All + * changes are internally transformed from their original (JSON) form, and dispatched to the relevant parts of openHAB. *
      • Outbound commands to the MiOS Unit.
        - * Exposes a method to transform & transmit openHAB Commands to the configured - * MiOS Unit, in a non-blocking manner.
        - * Callers wishing to utilize this functionality use the - * invokeCommand method. + * Exposes a method to transform & transmit openHAB Commands to the configured MiOS Unit, in a non-blocking manner.
        + * Callers wishing to utilize this functionality use the invokeCommand method. *
      * * @author Mark Clark @@ -64,8 +60,7 @@ */ public class MiosUnitConnector { - private static final Logger logger = LoggerFactory - .getLogger(MiosUnitConnector.class); + private static final Logger logger = LoggerFactory.getLogger(MiosUnitConnector.class); private static final String ENCODING_CHARSET = "utf-8"; @@ -79,10 +74,10 @@ public class MiosUnitConnector { private static final String DEVICE_URL = "http://%s:%d/data_request?id=action&DeviceNum=%d&serviceId=%s&action=%s"; private static final String DEVICE_URL_PARAMS = DEVICE_URL + "&%s"; - private static final Pattern DEVICE_PATTERN = Pattern - .compile("(?.+)/" - + "(?.+)" - + "\\(((?[a-zA-Z]+[a-zA-Z0-9]*)(=(?.+))?)?\\)"); + private static final Pattern DEVICE_PATTERN = Pattern.compile("(?.+)/" + "(?.+)" + + "\\(((?[a-zA-Z]+[a-zA-Z0-9]*)(=(?.+))?)?\\)"); + + private static final Pattern ACTION_PATTERN = Pattern.compile("(?.+)/" + "(?.+)"); // the MiOS instance and openHAB event publisher handles private final MiosUnit unit; @@ -93,10 +88,18 @@ public class MiosUnitConnector { private Thread pollThread; boolean running; + // Create a place to keep the last "status" attribute, for each Device, so we can compare incoming values for + // Duplicates (Devices & Scenes) + // + // The MiOS system will send duplicate values, so we need this data to avoid pumelling openHAB with unnecessary + // changes (and it can only be done here due to the async nature of openHAB store writes). This map is keyed by the + // DeviceId/SceneId form the MiOS system, which can be either a String, or an Integer. + private HashMap deviceStatusCache = new HashMap(100); + private HashMap sceneStatusCache = new HashMap(100); + /** * @param unit - * The host to connect to. Give a reachable hostname or IP - * address, without protocol or port + * The host to connect to. Give a reachable hostname or IP address, without protocol or port */ public MiosUnitConnector(MiosUnit unit, MiosBinding binding) { logger.debug("Constructor: unit '{}', binding '{}'", unit, binding); @@ -110,8 +113,7 @@ public MiosUnitConnector(MiosUnit unit, MiosBinding binding) { // Use the JDK Provider for now, we're not looking for server-level // scalability, and we'd like to lighten the load for folks wanting to // run atop RPi units. - this.client = new AsyncHttpClient(new JDKAsyncHttpProvider( - builder.build())); + this.client = new AsyncHttpClient(new JDKAsyncHttpProvider(builder.build())); pollCall = new LongPoll(); pollThread = new Thread(pollCall); @@ -120,23 +122,20 @@ public MiosUnitConnector(MiosUnit unit, MiosBinding binding) { /*** * Check if the connection to the MiOS instance is active * - * @return true if an active connection to the MiOS instance exists, false - * otherwise + * @return true if an active connection to the MiOS instance exists, false otherwise */ public boolean isConnected() { return isRunning() && pollCall.isConnected(); } /** - * Attempts to create a connection to the MiOS host and begin listening for - * updates over the async HTTP connection. + * Attempts to create a connection to the MiOS host and begin listening for updates over the async HTTP connection. * * @throws ExecutionException * @throws InterruptedException * @throws IOException */ - public void open() throws IOException, InterruptedException, - ExecutionException { + public void open() throws IOException, InterruptedException, ExecutionException { running = true; pollThread.start(); } @@ -181,24 +180,19 @@ private static String toBindValue(String value, Command command, State state) { } } - private void callDevice(DeviceBindingConfig config, Command command, - State state) throws TransformationException { + private void callDevice(DeviceBindingConfig config, Command command, State state) throws TransformationException { - logger.debug( - "callDevice: Need to remote-invoke Device '{}' action '{}' and current state '{}')", - new Object[] { config.toProperty(), command, state }); + logger.debug("callDevice: Need to remote-invoke Device '{}' action '{}' and current state '{}')", new Object[] { + config.toProperty(), command, state }); String newCommand = config.transformCommand(command); if (newCommand == null) { - logger.warn( - "callDevice: Command '{}' not supported, or missing command: mapping, for Item '{}'", + logger.warn("callDevice: Command '{}' not supported, or missing command: mapping, for Item '{}'", command.toString(), config.getItemName()); return; } else if (newCommand.equals("")) { - logger.trace( - "callDevice: Item '{}' has disabled the use of Command '{}' via it's configuration '{}'", - new Object[] { config.getItemName(), command.toString(), - config.toProperty() }); + logger.trace("callDevice: Item '{}' has disabled the use of Command '{}' via it's configuration '{}'", + new Object[] { config.getItemName(), command.toString(), config.toProperty() }); return; } @@ -208,15 +202,14 @@ private void callDevice(DeviceBindingConfig config, Command command, try { MiosUnit u = getMiosUnit(); - String serviceName = matcher.group("serviceName"); + String serviceName = DeviceBindingConfig.mapServiceAlias(matcher.group("serviceName")); String serviceAction = matcher.group("serviceAction"); String serviceParam = matcher.group("serviceParam"); String serviceValue = matcher.group("serviceValue"); logger.debug( "callDevice: decoded as serviceName '{}' serviceAction '{}' serviceParam '{}' serviceValue '{}'", - new Object[] { serviceName, serviceAction, - serviceParam, serviceValue }); + new Object[] { serviceName, serviceAction, serviceParam, serviceValue }); // Perform any necessary bind-variable style transformations on // the value, before we put it into the URL. @@ -226,59 +219,68 @@ private void callDevice(DeviceBindingConfig config, Command command, // build the parameter section of the URL, encoding parameter // names and values... trust no-one 8) if (serviceParam != null) { - String p = URLEncoder - .encode(serviceParam, ENCODING_CHARSET) - + '=' + String p = URLEncoder.encode(serviceParam, ENCODING_CHARSET) + '=' + URLEncoder.encode(serviceValue, ENCODING_CHARSET); - callMios(String.format(DEVICE_URL_PARAMS, u.getHostname(), - u.getPort(), config.getMiosId(), + callMios(String.format(DEVICE_URL_PARAMS, u.getHostname(), u.getPort(), config.getMiosId(), URLEncoder.encode(serviceName, ENCODING_CHARSET), - URLEncoder.encode(serviceAction, ENCODING_CHARSET), - p)); + URLEncoder.encode(serviceAction, ENCODING_CHARSET), p)); } else { - callMios(String.format(DEVICE_URL, u.getHostname(), - u.getPort(), config.getMiosId(), + callMios(String.format(DEVICE_URL, u.getHostname(), u.getPort(), config.getMiosId(), URLEncoder.encode(serviceName, ENCODING_CHARSET), URLEncoder.encode(serviceAction, ENCODING_CHARSET))); } } catch (UnsupportedEncodingException uee) { - logger.debug( - "Really, trust me, this won't happen ;) exception='{}'", - uee); + logger.debug("Really, trust me, this won't happen ;) exception='{}'", uee); } } else { - logger.error( - "callDevice: The parameter is in the wrong format. BindingConfig '{}', UPnP Action '{}'", + logger.error("callDevice: The parameter is in the wrong format. BindingConfig '{}', UPnP Action '{}'", config, newCommand); } } - private void callScene(SceneBindingConfig config, Command command, - State state) throws TransformationException { - logger.debug("callScene: Need to remote-invoke Scene '{}'", - config.toProperty()); + private void callScene(SceneBindingConfig config, Command command, State state) throws TransformationException { + logger.debug("callScene: Need to remote-invoke Scene '{}'", config.toProperty()); String newCommand = config.transformCommand(command); if (newCommand != null) { MiosUnit u = getMiosUnit(); - callMios(String.format(SCENE_URL, u.getHostname(), u.getPort(), - config.getMiosId())); + callMios(String.format(SCENE_URL, u.getHostname(), u.getPort(), config.getMiosId())); } else { - logger.warn( - "callScene: Command '{}' not supported, or missing command: declaration, for Item '{}'", + logger.warn("callScene: Command '{}' not supported, or missing command: declaration, for Item '{}'", command.toString(), config.getItemName()); } - } private void callMios(String url) { logger.debug("callMios: Would like to fire off the URL '{}'", url); try { - getAsyncHttpClient().prepareGet(url).execute(); + @SuppressWarnings("unused") + Future f = getAsyncHttpClient().prepareGet(url).execute(new AsyncCompletionHandler() { + @Override + public Integer onCompleted(Response response) throws Exception { + + // Yes, their content-type really does come back with just "xml", but we'll add "text/xml" for + // when/if they ever fix that bug... + if (!(response.getStatusCode() == 200 && ("text/xml".equals(response.getContentType()) + || "xml".equals(response.getContentType())))) { + logger.debug("callMios: Error in HTTP Response code {}, content-type {}:\n{}", new Object[] { + response.getStatusCode(), response.getContentType(), + response.hasResponseBody() ? response.getResponseBody() : "No Body" }); + } + return response.getStatusCode(); + } + + @Override + public void onThrowable(Throwable t) { + logger.warn("callMios: Exception Throwable occurred fetching content: {}", t.getMessage(), t); + } + } + + ); // TODO: Run it and walk away? // @@ -286,35 +288,92 @@ private void callMios(String url) { // success/fail of the call, log details (etc) so things can be // diagnosed. } catch (Exception e) { - logger.debug( - "callMios: Exception Error occurred fetching content: {}", - e.getMessage(), e); + logger.warn("callMios: Exception Error occurred fetching content: {}", e.getMessage(), e); + } + } + + /** + * Request that a MiOS Scene be triggered. + * + * Used by openHAB Action code, this method fires off the MiOS Scene associated with the Scene Item. + * + * @param config + * A Scene [Item] Binding Configuration. + */ + public void invokeScene(SceneBindingConfig config) { + + logger.debug("invokeScene: Invoking remote Scene '{}'", config.toProperty()); + + MiosUnit u = getMiosUnit(); + callMios(String.format(SCENE_URL, u.getHostname(), u.getPort(), config.getMiosId())); + } + + /** + * Request that a MiOS Device Action be triggered. + * + * Used by openHAB Action code, this method fires off the MiOS Action associated with the Device Item. + * + * @param config + * A Device [Item] Binding Configuration. + * @param actionName + * a UPnP-style Action to fire off on the remote MiOS Unit. + * @param params + * a NV-Pair style list of parameters to be used by the Action call. + */ + public void invokeAction(DeviceBindingConfig config, String actionName, List> params) { + Matcher matcher = ACTION_PATTERN.matcher(actionName); + if (matcher.matches()) { + try { + MiosUnit u = getMiosUnit(); + + String serviceName = DeviceBindingConfig.mapServiceAlias(matcher.group("serviceName")); + String serviceAction = matcher.group("serviceAction"); + + if (params != null) { + String p = ""; + + for (Entry entry : params) { + if (p.length() != 0) { + p += '&'; + } + + p += URLEncoder.encode(entry.getKey(), ENCODING_CHARSET) + '=' + + URLEncoder.encode(entry.getValue().toString(), ENCODING_CHARSET); + } + + callMios(String.format(DEVICE_URL_PARAMS, u.getHostname(), u.getPort(), config.getMiosId(), + URLEncoder.encode(serviceName, ENCODING_CHARSET), + URLEncoder.encode(serviceAction, ENCODING_CHARSET), p)); + } else { + callMios(String.format(DEVICE_URL, u.getHostname(), u.getPort(), config.getMiosId(), + URLEncoder.encode(serviceName, ENCODING_CHARSET), + URLEncoder.encode(serviceAction, ENCODING_CHARSET))); + } + + } catch (UnsupportedEncodingException uee) { + logger.debug("Really, trust me, this won't happen ;) exception='{}'", uee); + } } } /** * Request a Command be delivered to the MiOS Unit under control. *

      - * The MiOS Binding uses this call to deliver "single valued" openHAB - * Commands to the target MiOS Unit. + * The MiOS Binding uses this call to deliver "single valued" openHAB Commands to the target MiOS Unit. *

      - * Configurable transformations, defined at the BindingConfig level, are - * used to transform this openHAB Command into the specific form required by - * the MiOS Unit. + * Configurable transformations, defined at the BindingConfig level, are used to transform this openHAB Command into + * the specific form required by the MiOS Unit. *

      - * openHAB Commands can only be targeted to Device and Scene Bindings, all - * other requests will cause a warning to be logged. + * openHAB Commands can only be targeted to Device and Scene Bindings, all other requests will cause a warning to be + * logged. */ - public void invokeCommand(MiosBindingConfig config, Command command, - State state) throws Exception { + public void invokeCommand(MiosBindingConfig config, Command command, State state) throws Exception { if (config instanceof SceneBindingConfig) { callScene((SceneBindingConfig) config, command, state); } else if (config instanceof DeviceBindingConfig) { callDevice((DeviceBindingConfig) config, command, state); } else { - logger.warn( - "Unhandled command execution for Command ('{}') on binding '{}'", - command, config); + logger.warn("Unhandled command execution for Command ('{}') on binding '{}'", command, config); } } @@ -333,17 +392,14 @@ private AsyncHttpClient getAsyncHttpClient() { /** * MiOS Poll code. * - * This code will stand up a thread to serially poll the target MiOS Unit. - * The initial poll request will return the full content from the MiOS unit. - * Subsequent calls are requested to only return the incremental/changed - * contents. + * This code will stand up a thread to serially poll the target MiOS Unit. The initial poll request will return the + * full content from the MiOS unit. Subsequent calls are requested to only return the incremental/changed contents. * - * If a processing error (Timeout, etc) is detected, then a full content - * poll is again initiated (since things can change during the interval) + * If a processing error (Timeout, etc) is detected, then a full content poll is again initiated (since things can + * change during the interval) * - * Upon successful polling, a series of calls are made to openHAB to push - * the data to the respective bindings, so that data values will change - * within the user's Rules (etc). + * Upon successful polling, a series of calls are made to openHAB to push the data to the respective bindings, so + * that data values will change within the user's Rules (etc). * * @author Mark Clark * @since 1.6.0 @@ -381,16 +437,13 @@ private String getUri(boolean incremental) { // Use a timeout on the MiOS URL call that's about 2/3 of what // the connection timeout is. - int t = Math.min(c.getIdleConnectionTimeoutInMs(), - unit.getTimeout()) / 500 / 3; + int t = Math.min(c.getIdleConnectionTimeoutInMs(), unit.getTimeout()) / 500 / 3; int d = unit.getMinimumDelay(); - return String.format(Locale.US, STATUS2_INCREMENTAL_URL, - unit.getHostname(), unit.getPort(), loadTime, + return String.format(Locale.US, STATUS2_INCREMENTAL_URL, unit.getHostname(), unit.getPort(), loadTime, dataVersion, new Integer(t), new Integer(d)); } else { - return String.format(Locale.US, STATUS2_URL, - unit.getHostname(), unit.getPort()); + return String.format(Locale.US, STATUS2_URL, unit.getHostname(), unit.getPort()); } } @@ -416,28 +469,23 @@ private void publish(String property, Object value, boolean incremental) { try { getMiosBinding().postPropertyUpdate(p, value, incremental); } catch (Exception e) { - logger.error( - "Exception '{}' raised pushing property '{}' value '{}' into openHAB", + logger.error("Exception '{}' raised pushing property '{}' value '{}' into openHAB", new Object[] { e.getMessage(), p, value, e }); } } - private void processSystem(Map system, - boolean incremental) { + private void processSystem(Map system, boolean incremental) { for (Map.Entry entry : system.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); - if (!key.equals("devices") && !key.equals("scenes") - && !key.equals("rooms") && !key.equals("sections")) { - if (value instanceof String || value instanceof Integer - || value instanceof Double + if (!key.equals("devices") && !key.equals("scenes") && !key.equals("rooms") && !key.equals("sections")) { + if (value instanceof String || value instanceof Integer || value instanceof Double || value instanceof Boolean) { // Skip over Lua code blocks and // fix [known] date-time values on the way through, so // they use the native type. - if (key.equals("DeviceSync") || key.equals("LoadTime") - || key.equals("zwave_heal") + if (key.equals("DeviceSync") || key.equals("LoadTime") || key.equals("zwave_heal") || key.equals("TimeStamp")) { value = fixTimestamp(value); } @@ -452,9 +500,7 @@ private void processSystem(Map system, continue; } - logger.debug( - "processSystem: skipping key={}, class={}", - key, value.getClass()); + logger.debug("processSystem: skipping key={}, class={}", key, value.getClass()); } } } @@ -486,63 +532,81 @@ private void processDevices(List devices, boolean incremental) { } // Enumerate Device Attributes - for (Map.Entry da : device.entrySet()) { + for (Entry da : device.entrySet()) { String key = da.getKey(); Object value = da.getValue(); - if (value instanceof String || value instanceof Integer - || value instanceof Double + if (value instanceof String || value instanceof Integer || value instanceof Double || value instanceof Boolean) { if (key.equals("time_created")) { // fix [known] date-time values on the way through, - // so - // they use the native type. + // so they use the native type. value = fixTimestamp(value); + } else if (key.equals("id")) { + // Skip "id", since it's done at the end. + continue; } - // TODO: Consider putting the Device's ID attribute last - // in the list. When multiple value changes are being - // made, people may want something to indicate - // "these are the last" [bundle] of changes for this - // device. - // - // Otherwise they'll come out in JSON order - // (unpredictable) which may not be the order they're - // normally changed at the MiOS end. Making this last - // would be like having an "end of [device] transaction" - // marker. - - String property = "device:" + deviceId + '/' - + da.getKey(); - publish(property, value, incremental); + boolean force = false; + boolean statusAttr = key.equals("status"); + + // Handle a bug in MiOS's JSON, where they send the STATUS Attribute even if it hasn't + // changed. This resulted in a lot of unnecessary writes to openHAB. We can do this + // because this thread is the single-source of values for the STATUS attribute. + if (statusAttr) { + Integer lastValue = deviceStatusCache.get(deviceId); + if (!value.equals(lastValue)) { + deviceStatusCache.put(deviceId, (Integer) value); + force = true; + } + } + + if (!statusAttr || force) { + String property = "device:" + deviceId + '/' + key; + publish(property, value, incremental); + } } else { // No need to bring these into openHAB, they'll only // bulk up // the system. - if (key.equals("states") || key.equals("ControlURLs") - || key.equals("Jobs") || key.equals("tooltip")) { + if (key.equals("states") || key.equals("ControlURLs") || key.equals("Jobs") + || key.equals("tooltip")) { continue; } - logger.debug( - "processDevices: skipping key={}, class={}", - key, value.getClass()); + logger.debug("processDevices: skipping key={}, class={}", key, value.getClass()); } } // Enumerate Device State Variables List deviceStates = getList(device, "states"); + boolean variablesProcessed = false; for (Object ds : deviceStates) { @SuppressWarnings("unchecked") Map state = (Map) ds; - String var = (String) state.get("service") + "/" - + (String) state.get("variable"); + String var = (String) state.get("service") + "/" + (String) state.get("variable"); String property = "device:" + deviceId + "/service/" + var; // Can be String or Integer Object value = (Object) state.get("value"); publish(property, value, incremental); + variablesProcessed = true; + } + + // The Device's ID attribute is last in the list and only + // sent when at-least-one UPnP State Variable has been changed. + // + // This is done to allow folks something to "trigger" off in a + // rule if they have cross-Item validation dependencies. + // + // Otherwise they'll come out in JSON order + // (unpredictable) which may not be the order they're + // normally changed at the MiOS end. Making this last + // would be like having an "end of [device] transaction" + // marker. + if (variablesProcessed) { + publish("device:" + deviceId + "/id", deviceId, incremental); } } } @@ -562,43 +626,51 @@ private void processScenes(List scenes, boolean incremental) { Integer sceneId = (Integer) scene.get("id"); // Enumerate Scene Attributes - for (Map.Entry da : scene.entrySet()) { + for (Entry da : scene.entrySet()) { String key = da.getKey(); - Object value = da.getValue(); - if (value instanceof String || value instanceof Integer - || value instanceof Double + if (value instanceof String || value instanceof Integer || value instanceof Double || value instanceof Boolean) { if (key.equals("Timestamp")) { // fix [known] date-time values on the way through, - // so - // they use the native type. + // so they use the native type. value = fixTimestamp(value); // Fix the key so it's consistent with the one used - // at - // the System level. + // at the System level. // TODO: Document this. key = "TimeStamp"; } - String property = "scene:" + sceneId + "/" + key; - publish(property, value, incremental); + boolean force = false; + boolean statusAttr = key.equals("status"); + + // Handle a bug in MiOS's JSON, where they send the STATUS Attribute even if it hasn't + // changed. This resulted in a lot of unnecessary writes to openHAB. We can do this + // because this thread is the single-source of values for the STATUS attribute. + if (statusAttr) { + Integer lastValue = sceneStatusCache.get(sceneId); + if (!value.equals(lastValue)) { + sceneStatusCache.put(sceneId, (Integer) value); + force = true; + } + } + + if (!statusAttr || force) { + String property = "scene:" + sceneId + "/" + key; + publish(property, value, incremental); + } } else { // No need to bring these into openHAB, they'll only // bulk up // the system. - if (key.equals("timers") || key.equals("triggers") - || key.equals("groups") - || key.equals("tooltip") || key.equals("Jobs") - || key.equals("lua")) { + if (key.equals("timers") || key.equals("triggers") || key.equals("groups") + || key.equals("tooltip") || key.equals("Jobs") || key.equals("lua")) { continue; } - logger.debug( - "processScenes: skipping key={}, class={}", - key, value.getClass()); + logger.debug("processScenes: skipping key={}, class={}", key, value.getClass()); } } } @@ -612,8 +684,7 @@ private void processSections(List sections, boolean incremental) { // TODO: Implement } - private void processResponse(Map response, - boolean incremental) { + private void processResponse(Map response, boolean incremental) { Integer lt = (Integer) response.get("LoadTime"); Integer dv = (Integer) response.get("DataVersion"); @@ -627,11 +698,8 @@ private void processResponse(Map response, logger.debug( "processResponse: success! loadTime={}, dataVersion={} devices({}) scenes({}) rooms({}) sections({})", - new Object[] { lt, dv, - Integer.toString(devices.size()), - Integer.toString(scenes.size()), - Integer.toString(rooms.size()), - Integer.toString(sections.size()) }); + new Object[] { lt, dv, Integer.toString(devices.size()), Integer.toString(scenes.size()), + Integer.toString(rooms.size()), Integer.toString(sections.size()) }); processDevices(devices, incremental); processScenes(scenes, incremental); @@ -645,8 +713,7 @@ private void processResponse(Map response, this.dataVersion = dv; this.failures = 0; } else { - throw new RuntimeException( - "Processing error on MiOS JSON Response - malformed"); + throw new RuntimeException("Processing error on MiOS JSON Response - malformed"); } } @@ -656,8 +723,7 @@ public boolean isConnected() { // TODO: Need to make this stream-oriented, so we don't have to keep the // entire (large) MiOS JSON string in memory at the same time as the - // parsed - // JSON result. + // parsed JSON result. @SuppressWarnings("unchecked") private Map readJson(String json) { if (json == null) @@ -690,18 +756,15 @@ public void run() { // configuration indicates to do so, or if we get an error. MiosUnit unit = getMiosUnit(); int errorCount = unit.getErrorCount(); - boolean force = (loopCount == 0l) || (errorCount != 0) - && (failures != 0) + boolean force = (loopCount == 0l) || (errorCount != 0) && (failures != 0) && ((failures % errorCount) == 0); boolean incremental = (!force && loadTime != null && dataVersion != null); String uri = getUri(incremental); - logger.debug("run: URI Built was '{}' loop '{}'", uri, - loopCount); + logger.debug("run: URI Built was '{}' loop '{}'", uri, loopCount); - Future f = getAsyncHttpClient().prepareGet(uri) - .execute(); + Future f = getAsyncHttpClient().prepareGet(uri).execute(); Response r = (Response) f.get(); // Force the Response Charset to be UTF-8, since MiOS isn't setting @@ -727,8 +790,7 @@ public void run() { this.failures++; logger.debug( "run: Exception Error occurred fetching/processing content: {},{}. Total failures ({})", - new Object[] { e.getMessage(), e, - Integer.toString(failures) }); + new Object[] { e.getMessage(), e, Integer.toString(failures) }); // TODO: Make the pause configurable and/or add a backoff // mechanism. @@ -742,8 +804,7 @@ public void run() { } } while (isRunning()); - logger.info("run: Shutting down MiOS Polling thread. Unit={}", - getMiosUnit().getName()); + logger.info("run: Shutting down MiOS Polling thread. Unit={}", getMiosUnit().getName()); connected = false; } } diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/DeviceBindingConfig.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/DeviceBindingConfig.java index f8fb1c7e4db..b5c40ef9104 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/DeviceBindingConfig.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/DeviceBindingConfig.java @@ -11,12 +11,14 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.openhab.binding.mios.internal.MiosActivator; import org.openhab.core.items.Item; +import org.openhab.core.library.items.ColorItem; import org.openhab.core.transform.TransformationException; import org.openhab.core.transform.TransformationHelper; import org.openhab.core.transform.TransformationService; @@ -36,8 +38,7 @@ *
    • * mios="unit:unitName,device:deviceId/service/serviceAlias/serviceVariable,optionalTransformations * - *
    • - * mios="unit:unitName,device:deviceId/attrName,optionalTransformations + *
    • mios="unit:unitName,device:deviceId/attrName,optionalTransformations * * *

      @@ -56,8 +57,8 @@ * *

      * - * There are also a set of pre-defined UPnP Service aliases, so a short-hand - * notation can be used for common UPnP ServiceId's:
      + * There are also a set of pre-defined UPnP Service aliases, so a short-hand notation can be used for common UPnP + * ServiceId's:
      *

        *
      • * Number MiOSMemoryAvailable "Available [%.0f KB]" (BindingDemo) {mios="unit:house,device:382/service/SystemMonitor/memoryAvailable"} @@ -70,13 +71,12 @@ *
      *

      * - * The complete list of UPnP Service aliases is listed in the documentation - * file, or can be seen in the file ServiceAliases.properties. + * The complete list of UPnP Service aliases is listed in the documentation file, or can be seen in the file + * ServiceAliases.properties. *

      * - * In addition to binding against a Device's Variables, you can bind to the set - * of Device Attributes it exposes. Specifically it's id and - * status: + * In addition to binding against a Device's Variables, you can bind to the set of Device Attributes it exposes. + * Specifically it's id and status: *

      *

        *
      • @@ -88,38 +88,32 @@ * * Optional Transformations *

        - * In many cases, the values exposed by a MiOS Unit aren't suitable for use - * within openHAB, and a value mapping/transformation may be needed. + * In many cases, the values exposed by a MiOS Unit aren't suitable for use within openHAB, and a value + * mapping/transformation may be needed. *

        * - * Values may be transformed using an input transformation (in:) or - * a command transformation (command:). In future, values will also - * be transformed prior to being sent to a MiOS Unit via the output + * Values may be transformed using an input transformation (in:) or a command transformation ( + * command:). In future, values will also be transformed prior to being sent to a MiOS Unit via the output * transformation (out:) *

        * - * Transformation files are provided, for the common input and command - * transformations, in the examples/transform directory of the MiOS - * Binding. + * Transformation files are provided, for the common input and command transformations, in the + * examples/transform directory of the MiOS Binding. *

        - * The examples presented here assume that these MAP transformation files have - * been copied to the appropriate openHAB configuration location (typically - * configuration/transform). + * The examples presented here assume that these MAP transformation files have been copied to the appropriate openHAB + * configuration location (typically configuration/transform). *

        * * There are example Input transformation maps: *

          - *
        • miosSwitchIn.map - MiOS Switch device ( - * service/SwitchPower1/Status) properties when mapped to a - * Switch Item. - *
        • miosStatusIn.map - MiOS Status attributes ( - * /status) to make them readable states when mapped to a + *
        • miosSwitchIn.map - MiOS Switch device ( service/SwitchPower1/Status) properties when + * mapped to a Switch Item. + *
        • miosStatusIn.map - MiOS Status attributes ( /status) to make them readable states when + * mapped to a String Item. + *
        • miosContactIn.map - MiOS Security Sensor device ( /service/SecuritySensor1/Tripped) + * when mapped to a Contact Item. + *
        • miosZWaveStatusIn.map - MiOS System attribute ( system:/ZWaveStatus) when mapped to a * String Item. - *
        • miosContactIn.map - MiOS Security Sensor device ( - * /service/SecuritySensor1/Tripped) when mapped to a - * Contact Item. - *
        • miosZWaveStatusIn.map - MiOS System attribute ( - * system:/ZWaveStatus) when mapped to a String Item. *
        • miosWeatherConditionGroupIn.map - MiOS *
        * @@ -133,41 +127,30 @@ *

        * And example Command transformation maps: *

          - *
        • miosArmedCommand.map - MiOS Security Sensor device ( - * /service/SecuritySensor1/Armed) when mapped to a - * Switch Item. - *
        • miosDimmerCommand.map - MiOS Dimmer device ( - * /service/Dimming1/LoadLevelStatus) when mapped to a - * Dimmer Item. - *
        • miosLockCommand.map - MiOS Lock device ( - * /service/DoorLock1/Status) properties when mapped to a - * Switch Item. + *
        • miosArmedCommand.map - MiOS Security Sensor device ( /service/SecuritySensor1/Armed) + * when mapped to a Switch Item. + *
        • miosDimmerCommand.map - MiOS Dimmer device ( /service/Dimming1/LoadLevelStatus) when + * mapped to a Dimmer Item. + *
        • miosLockCommand.map - MiOS Lock device ( /service/DoorLock1/Status) properties when + * mapped to a Switch Item. *
        • miosTStatModeStatusCommand.map - MiOS Thermostat device ( - * /service/HVAC_UserOperatingMode1/ModeStatus) when mapped to a - * String Item. + * /service/HVAC_UserOperatingMode1/ModeStatus) when mapped to a String Item. *
        • miosTStatSetpointCoolCommand.map - MiOS Thermostat device ( - * /service/TemperatureSetpoint1_Cool/CurrentSetpoint) when mapped - * to a Number Item. + * /service/TemperatureSetpoint1_Cool/CurrentSetpoint) when mapped to a Number Item. *
        • miosTStatSetpointHeatCommand.map - MiOS Thermostat device ( - * /service/TemperatureSetpoint1_Heat/CurrentSetpoint) when mapped - * to a Number Item. - *
        • miosTStatFanOperatingModeCommand.map - MiOS Thermostat - * device (/service/HVAC_FanOperatingMode1/Mode) when mapped to a - * String Item. - *
        • miosUPnPRenderingControlVolumeCommand.map - MiOS UPnP Volume - * (service/RenderingControl/Volume) property when mapped to a - * Dimmer Item. + * /service/TemperatureSetpoint1_Heat/CurrentSetpoint) when mapped to a Number Item. + *
        • miosTStatFanOperatingModeCommand.map - MiOS Thermostat device ( + * /service/HVAC_FanOperatingMode1/Mode) when mapped to a String Item. + *
        • miosUPnPRenderingControlVolumeCommand.map - MiOS UPnP Volume ( + * service/RenderingControl/Volume) property when mapped to a Dimmer Item. *
        • miosUPnPRenderingControlMuteCommand.map - MiOS UPnP Mute ( - * service/RenderingControl/Mute) property when mapped to a - * Switch Item. - *
        • miosUPnPTransportStatePlayModeCommand.map - MiOS UPnP - * PlayMode (service/AVTransport/TransportState) when mapped to a - * String Item. + * service/RenderingControl/Mute) property when mapped to a Switch Item. + *
        • miosUPnPTransportStatePlayModeCommand.map - MiOS UPnP PlayMode ( + * service/AVTransport/TransportState) when mapped to a String Item. *
        *

        * - * More details on these mappings can be found in the - * README.md file associated + * More details on these mappings can be found in the README.md file associated * with this Binding. *

        * @@ -181,18 +164,14 @@ public class DeviceBindingConfig extends MiosBindingConfig { private static Map COMMAND_DEFAULTS = new HashMap(); static { - COMMAND_DEFAULTS - .put("ON", - "urn:upnp-org:serviceId:SwitchPower1/SetTarget(newTargetValue=1)"); - COMMAND_DEFAULTS - .put("OFF", - "urn:upnp-org:serviceId:SwitchPower1/SetTarget(newTargetValue=0)"); - COMMAND_DEFAULTS.put("TOGGLE", - "urn:micasaverde-com:serviceId:HaDevice1/ToggleState()"); - COMMAND_DEFAULTS.put("INCREASE", - "urn:upnp-org:serviceId:Dimming1/StepUp()"); - COMMAND_DEFAULTS.put("DECREASE", - "urn:upnp-org:serviceId:Dimming1/StepDown()"); + COMMAND_DEFAULTS.put("ON", "urn:upnp-org:serviceId:SwitchPower1/SetTarget(newTargetValue=1)"); + COMMAND_DEFAULTS.put("OFF", "urn:upnp-org:serviceId:SwitchPower1/SetTarget(newTargetValue=0)"); + COMMAND_DEFAULTS.put("TOGGLE", "urn:micasaverde-com:serviceId:HaDevice1/ToggleState()"); + COMMAND_DEFAULTS.put("INCREASE", "urn:upnp-org:serviceId:Dimming1/StepUp()"); + COMMAND_DEFAULTS.put("DECREASE", "urn:upnp-org:serviceId:Dimming1/StepDown()"); + COMMAND_DEFAULTS.put("UP", "urn:upnp-org:serviceId:WindowCovering1/Up()"); + COMMAND_DEFAULTS.put("DOWN", "urn:upnp-org:serviceId:WindowCovering1/Down()"); + COMMAND_DEFAULTS.put("STOP", "urn:upnp-org:serviceId:WindowCovering1/Stop()"); } private static Properties aliasMap = new Properties(); @@ -209,13 +188,11 @@ public class DeviceBindingConfig extends MiosBindingConfig { try { aliasMap.load(input); - logger.debug( - "Successfully loaded UPnP Service Aliases from '{}', entries '{}'", - SERVICE_ALIASES, aliasMap.size()); + logger.debug("Successfully loaded UPnP Service Aliases from '{}', entries '{}'", SERVICE_ALIASES, + aliasMap.size()); } catch (Exception e) { // Pre-shipped with the Binding, so it should never error out. - logger.error("Failed to load Service Alias file '{}', Exception", - SERVICE_ALIASES, e); + logger.error("Failed to load Service Alias file '{}', Exception", SERVICE_ALIASES, e); } input = cl.getResourceAsStream(PARAM_DEFAULTS); @@ -224,24 +201,19 @@ public class DeviceBindingConfig extends MiosBindingConfig { Properties tmp = new Properties(); tmp.load(input); - for (Map.Entry e : tmp.entrySet()) { - paramDefaults.put((String) e.getKey(), - ParameterDefaults.parse((String) e.getValue())); + for (Entry e : tmp.entrySet()) { + paramDefaults.put((String) e.getKey(), ParameterDefaults.parse((String) e.getValue())); } - logger.debug( - "Successfully loaded Device Parameter defaults from '{}', entries '{}'", - PARAM_DEFAULTS, paramDefaults.size()); + logger.debug("Successfully loaded Device Parameter defaults from '{}', entries '{}'", PARAM_DEFAULTS, + paramDefaults.size()); } catch (Exception e) { // Pre-shipped with the Binding, so it should never error out. - logger.error( - "Failed to load Device Parameter defaults file '{}', Exception", - PARAM_DEFAULTS, e); + logger.error("Failed to load Device Parameter defaults file '{}', Exception", PARAM_DEFAULTS, e); } } - private static final Pattern SERVICE_IN_PATTERN = Pattern - .compile("service/(?.+)/(?.+)"); + private static final Pattern SERVICE_IN_PATTERN = Pattern.compile("service/(?[^/]+)(/(?[^/]+))?"); private static final Pattern SERVICE_COMMAND_TRANSFORM_PATTERN = Pattern .compile("(?(?[a-zA-Z]+)\\((?.*)\\))"); @@ -255,13 +227,23 @@ public class DeviceBindingConfig extends MiosBindingConfig { private TransformationService commandTransformationService; - private DeviceBindingConfig(String context, String itemName, - String unitName, int id, String stuff, - Class itemType, String commandTransform, - String inTransform, String outTransform) + private DeviceBindingConfig(String context, String itemName, String unitName, int id, String stuff, + Class itemType, String commandTransform, String inTransform, String outTransform) throws BindingConfigParseException { - super(context, itemName, unitName, id, stuff, itemType, - commandTransform, inTransform, outTransform); + super(context, itemName, unitName, id, stuff, itemType, commandTransform, inTransform, outTransform); + } + + /** + * Map Aliased Service names into their "formal" UPnP-style format. + * + * @param source + * the original Service name to be mapped + * @return the mapped UPnP-style Service name, if an alias mapping exists, or the original source value. + */ + public static final String mapServiceAlias(String source) { + String mapped = (String) aliasMap.get(source); + + return (mapped == null) ? source : mapped; } /** @@ -269,11 +251,9 @@ private DeviceBindingConfig(String context, String itemName, * * @return an initialized MiOS Device Binding Configuration object. */ - public static final MiosBindingConfig create(String context, - String itemName, String unitName, int id, String inStuff, - Class itemType, String commandTransform, - String inTransform, String outTransform) - throws BindingConfigParseException { + public static final MiosBindingConfig create(String context, String itemName, String unitName, int id, + String inStuff, Class itemType, String commandTransform, String inTransform, + String outTransform) throws BindingConfigParseException { try { // Before we initialize, normalize the serviceId string used in any // outgoing stuff. @@ -294,13 +274,10 @@ public static final MiosBindingConfig create(String context, iVar = matcher.group("serviceVar"); // Handle service name aliases. - tmp = (String) aliasMap.get(iName); - if (tmp != null) { - iName = tmp; - } + iName = mapServiceAlias(iName); // Rebuild, since we've normalized the name. - newInStuff = "service/" + iName + '/' + iVar; + newInStuff = "service/" + iName + (iVar == null ? "" : '/' + iVar); } // @@ -310,31 +287,21 @@ public static final MiosBindingConfig create(String context, // ParameterDefaults pd = paramDefaults.get(newInStuff); if (pd != null) { - logger.trace( - "Device ParameterDefaults FOUND '{}' for '{}', '{}'", - itemName, newInStuff, pd); + logger.trace("Device ParameterDefaults FOUND '{}' for '{}', '{}'", itemName, newInStuff, pd); if (commandTransform == null) { commandTransform = pd.getCommandTransform(); - logger.trace( - "Device ParameterDefaults '{}' defaulted command: to '{}'", - itemName, commandTransform); + logger.trace("Device ParameterDefaults '{}' defaulted command: to '{}'", itemName, commandTransform); } if (inTransform == null) { inTransform = pd.getInTransform(); - logger.trace( - "Device ParameterDefaults '{}' defaulted in: to '{}'", - itemName, inTransform); + logger.trace("Device ParameterDefaults '{}' defaulted in: to '{}'", itemName, inTransform); } if (outTransform == null) { outTransform = pd.getOutTransform(); - logger.trace( - "Device ParameterDefaults '{}' defaulted out: to '{}'", - itemName, outTransform); + logger.trace("Device ParameterDefaults '{}' defaulted out: to '{}'", itemName, outTransform); } } else { - logger.trace( - "Device ParameterDefaults NOT FOUND '{}' for '{}'", - itemName, newInStuff); + logger.trace("Device ParameterDefaults NOT FOUND '{}' for '{}'", itemName, newInStuff); } String cTransform = null; @@ -347,8 +314,7 @@ public static final MiosBindingConfig create(String context, cMap = COMMAND_DEFAULTS; } else if (newCommandTransform != null) { // Try for a match as a TransformationService. - matcher = SERVICE_COMMAND_TRANSFORM_PATTERN - .matcher(newCommandTransform); + matcher = SERVICE_COMMAND_TRANSFORM_PATTERN.matcher(newCommandTransform); if (matcher.matches()) { cTransform = matcher.group("transformCommand"); cParam = matcher.group("transformParam"); @@ -357,8 +323,7 @@ public static final MiosBindingConfig create(String context, String[] commandList = newCommandTransform.split("\\|"); String command; - Map l = new HashMap( - commandList.length); + Map l = new HashMap(commandList.length); String mapName; String serviceStr; @@ -367,8 +332,7 @@ public static final MiosBindingConfig create(String context, for (int i = 0; i < commandList.length; i++) { command = commandList[i]; - matcher = SERVICE_COMMAND_INMAP_PATTERN - .matcher(command); + matcher = SERVICE_COMMAND_INMAP_PATTERN.matcher(command); if (matcher.matches()) { mapName = matcher.group("mapName"); serviceName = matcher.group("serviceName"); @@ -376,10 +340,7 @@ public static final MiosBindingConfig create(String context, if (serviceName != null) { // Handle any Service Aliases that might have been used in the inline Map. - tmp = (String) aliasMap.get(serviceName); - if (tmp != null) { - serviceName = tmp; - } + serviceName = mapServiceAlias(serviceName); serviceStr = serviceName + '/' + serviceAction; } else { @@ -389,28 +350,24 @@ public static final MiosBindingConfig create(String context, String oldMapName = l.put(mapName, serviceStr); if (oldMapName != null) { - throw new BindingConfigParseException( - String.format( - "Duplicate inline Map entry '%s' in command: '%s'", - oldMapName, newCommandTransform)); + throw new BindingConfigParseException(String.format( + "Duplicate inline Map entry '%s' in command: '%s'", oldMapName, + newCommandTransform)); } } else { - throw new BindingConfigParseException( - String.format( - "Invalid command, parameter format '%s' in command: '%s'", - command, newCommandTransform)); + throw new BindingConfigParseException(String.format( + "Invalid command, parameter format '%s' in command: '%s'", command, + newCommandTransform)); } } cMap = l; } } - logger.trace("newInStuff '{}', iName '{}', iVar '{}'", - new Object[] { newInStuff, iName, iVar }); + logger.trace("newInStuff '{}', iName '{}', iVar '{}'", new Object[] { newInStuff, iName, iVar }); - DeviceBindingConfig c = new DeviceBindingConfig(context, itemName, - unitName, id, newInStuff, itemType, newCommandTransform, - inTransform, outTransform); + DeviceBindingConfig c = new DeviceBindingConfig(context, itemName, unitName, id, newInStuff, itemType, + newCommandTransform, inTransform, outTransform); c.initialize(); c.commandTransformName = cTransform; @@ -458,22 +415,19 @@ private TransformationService getCommandTransformationService() { BundleContext context = MiosActivator.getContext(); - commandTransformationService = TransformationHelper - .getTransformationService(context, name); + commandTransformationService = TransformationHelper.getTransformationService(context, name); if (commandTransformationService == null) { - logger.warn( - "Transformation Service (command) '{}' not found for declaration '{}'.", - name, getCommandTransform()); + logger.warn("Transformation Service (command) '{}' not found for declaration '{}'.", name, + getCommandTransform()); } return commandTransformationService; } @Override - public String transformCommand(Command command) - throws TransformationException { + public String transformCommand(Command command) throws TransformationException { // Quickly return null if we don't support commands. if (getCommandTransform() == null) { return null; @@ -489,8 +443,7 @@ public String transformCommand(Command command) // If we don't have a transform, look for a special one called // "_default". if (result == null || "".equals(result)) { - result = ts.transform(getCommandTransformParam(), - DEFAULT_COMMAND_TRANSFORM); + result = ts.transform(getCommandTransformParam(), DEFAULT_COMMAND_TRANSFORM); } } else { Map map = getCommandMap(); @@ -512,4 +465,14 @@ public String transformCommand(Command command) return result; } + + @Override + public void validateItemType(Item item) throws BindingConfigParseException { + Class t = getItemType(); + + // Add support for Color Device Items. + if (!(t == ColorItem.class)) { + super.validateItemType(item); + } + } } diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/DeviceDefaults.properties b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/DeviceDefaults.properties index 3e78b390cfb..a725fc44da9 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/DeviceDefaults.properties +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/DeviceDefaults.properties @@ -11,4 +11,5 @@ service/urn\:upnp-org\:serviceId\:HVAC_UserOperatingMode1/ModeStatus=command:MAP service/urn\:upnp-org\:serviceId\:HVAC_FanOperatingMode1/Mode=command:MAP(miosTStatFanOperatingModeCommand.map) service/urn\:upnp-org\:serviceId\:RenderingControl/Volume=command:MAP(miosUPnPRenderingControlVolumeCommand.map) service/urn\:upnp-org\:serviceId\:AVTransport/TransportState=command:MAP(miosUPnPTransportStatePlayModeCommand.map) +service/urn\:upnp-org\:serviceId\:WindowCovering1=command:MAP(miosShutterCommand.map) status=in:MAP(miosStatusIn.map) diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/MiosBindingConfig.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/MiosBindingConfig.java index 8799561d1e1..df41ed744bf 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/MiosBindingConfig.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/MiosBindingConfig.java @@ -15,6 +15,7 @@ import org.openhab.binding.mios.internal.MiosActivator; import org.openhab.core.binding.BindingConfig; import org.openhab.core.items.Item; +import org.openhab.core.library.items.ColorItem; import org.openhab.core.library.items.ContactItem; import org.openhab.core.library.items.DateTimeItem; import org.openhab.core.library.items.DimmerItem; @@ -24,6 +25,7 @@ import org.openhab.core.library.items.SwitchItem; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.HSBType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OpenClosedType; import org.openhab.core.library.types.PercentType; @@ -44,8 +46,7 @@ * MiOS specific abstract class for the openHAB {@link BindingConfig}. *

        * - * Sub-classes of this class represent the various "types" of data that can be - * bound within a MiOS System. + * Sub-classes of this class represent the various "types" of data that can be bound within a MiOS System. *

        * These include the following objects:
        *

          @@ -63,20 +64,17 @@ *
        *

        * - * Each sub-class has a specific format for the miosThing, and examples - * are outlined in those sub-classes, in addition to the README.md - * file shipped with the binding. + * Each sub-class has a specific format for the miosThing, and examples are outlined in those sub-classes, in + * addition to the README.md file shipped with the binding. * * * @author Mark Clark * @since 1.6.0 */ public abstract class MiosBindingConfig implements BindingConfig { - private static Pattern TRANSFORM_PATTERN = Pattern - .compile("(?.+)[(]{1}?(?.*)[)]{1}"); + private static Pattern TRANSFORM_PATTERN = Pattern.compile("(?.+)[(]{1}?(?.*)[)]{1}"); - protected static final Logger logger = LoggerFactory - .getLogger(MiosBindingConfig.class); + protected static final Logger logger = LoggerFactory.getLogger(MiosBindingConfig.class); private int miosId; private String context; @@ -99,10 +97,8 @@ public abstract class MiosBindingConfig implements BindingConfig { private TransformationService inTransformationService; private TransformationService outTransformationService; - protected MiosBindingConfig(String context, String itemName, - String unitName, int miosId, String miosStuff, - Class itemType, String commandTransform, - String inTransform, String outTransform) + protected MiosBindingConfig(String context, String itemName, String unitName, int miosId, String miosStuff, + Class itemType, String commandTransform, String inTransform, String outTransform) throws BindingConfigParseException { // Crude parameter validations assert (miosId >= 0); @@ -125,12 +121,9 @@ protected MiosBindingConfig(String context, String itemName, this.inTransformName = m.group("transform"); this.inTransformParam = m.group("param"); - logger.trace("start: IN '{}', '{}'", this.inTransformName, - this.inTransformParam); + logger.trace("start: IN '{}', '{}'", this.inTransformName, this.inTransformParam); } else { - logger.warn( - "Unable to parse (in) Transformation string '{}', ignored.", - inTransform); + logger.warn("Unable to parse (in) Transformation string '{}', ignored.", inTransform); } } @@ -141,12 +134,9 @@ protected MiosBindingConfig(String context, String itemName, this.outTransformName = m.group("transform"); this.outTransformParam = m.group("param"); - logger.trace("start: OUT '{}', '{}'", this.outTransformName, - this.outTransformParam); + logger.trace("start: OUT '{}', '{}'", this.outTransformName, this.outTransformParam); } else { - logger.warn( - "Unable to parse (out) Transformation string '{}', ignored.", - outTransform); + logger.warn("Unable to parse (out) Transformation string '{}', ignored.", outTransform); } } } @@ -154,8 +144,7 @@ protected MiosBindingConfig(String context, String itemName, /** * The name of the openHAB context. * - * @return the name of the openHAB context this Binding Configuration is - * associated with. + * @return the name of the openHAB context this Binding Configuration is associated with. */ public String getContext() { return this.context; @@ -164,8 +153,7 @@ public String getContext() { /** * The name of the openHAB Item. * - * @return the name of the Item this Binding Configuration is associated - * with. + * @return the name of the Item this Binding Configuration is associated with. */ public String getItemName() { return this.itemName; @@ -175,8 +163,7 @@ public String getItemName() { * The name of the MiOS Unit. *

        * - * @return the name of the MiOS Unit this Binding Configuration is - * associated with. + * @return the name of the MiOS Unit this Binding Configuration is associated with. */ public String getUnitName() { return unitName; @@ -186,13 +173,12 @@ public String getUnitName() { * The type of MiOS object. *

        * - * The MiOS Binding supports binding to Device, Scene, and System objects - * within a MiOS System. This method returns which type of MiOS object the - * Binding Configuration represents, using the same format/value used in the - * Binding Configuration entry. + * The MiOS Binding supports binding to Device, Scene, and System objects within a MiOS System. This method returns + * which type of MiOS object the Binding Configuration represents, using the same format/value used in the Binding + * Configuration entry. *

        - * The value returned is dependent upon the specific sub-class of - * MiOSBindingConfig materialized from the Item configuration information. + * The value returned is dependent upon the specific sub-class of MiOSBindingConfig materialized from the Item + * configuration information. * * @return the type of MiOS object. */ @@ -202,29 +188,24 @@ public String getUnitName() { * The id of the MiOS object. *

        * - * Each object within a MiOS Unit has a type-specific Id. If the type of - * object doesn't have an Id, then the value will be 0. + * Each object within a MiOS Unit has a type-specific Id. If the type of object doesn't have an Id, then the value + * will be 0. * - * @return the Id of the MiOS object, or 0 if the type doesn't allocate - * Id's. + * @return the Id of the MiOS object, or 0 if the type doesn't allocate Id's. */ public int getMiosId() { return miosId; }; /** - * A type-specific Name/Reference representing a named subcomponent of the - * MiOS object. + * A type-specific Name/Reference representing a named subcomponent of the MiOS object. *

        * - * Each object within a MiOS Unit has a type-specific Name/Reference string. - * This value works in conjunction with the MiOS Id, to further define the - * data to be returned. One "id" in a MiOS system may have multiple - * attributes associated with it, and this string is used to disambiguate - * those attributes. + * Each object within a MiOS Unit has a type-specific Name/Reference string. This value works in conjunction with + * the MiOS Id, to further define the data to be returned. One "id" in a MiOS system may have multiple attributes + * associated with it, and this string is used to disambiguate those attributes. * - * @return the Name/Reference of the MiOS object represented by this Binding - * Configuration. + * @return the Name/Reference of the MiOS object represented by this Binding Configuration. */ public String getMiosStuff() { return miosStuff; @@ -234,14 +215,11 @@ public String getMiosStuff() { * Convert to a Property string. *

        * - * This form includes the MiOS Device locator information (Id, Type, and - * Stuff) only. + * This form includes the MiOS Device locator information (Id, Type, and Stuff) only. *

        - * It contains only enough information to identify the target component - * within the MiOS Unit. + * It contains only enough information to identify the target component within the MiOS Unit. * - * @return the Binding Configuration as a string, suitable for use within - * openHAB Configuration files. + * @return the Binding Configuration as a string, suitable for use within openHAB Configuration files. */ public String toProperty() { return cachedProperty; @@ -251,10 +229,8 @@ public String toProperty() { * Convert to a full Binding string. *

        * - * This form includes the MiOS Device locator information, from - * toProperty(), in addition to any transformations ( - * in:, out:, command:) specified in - * the original Binding. + * This form includes the MiOS Device locator information, from toProperty(), in addition to any + * transformations ( in:, out:, command:) specified in the original Binding. */ public String toBinding() { return cachedBinding; @@ -301,23 +277,19 @@ private TransformationService getInTransformationService() { BundleContext context = MiosActivator.getContext(); - inTransformationService = TransformationHelper - .getTransformationService(context, name); + inTransformationService = TransformationHelper.getTransformationService(context, name); if (inTransformationService == null) { - logger.warn( - "Transformation Service (in) '{}' not found for declaration '{}'.", - name, getInTransform()); + logger.warn("Transformation Service (in) '{}' not found for declaration '{}'.", name, getInTransform()); } return inTransformationService; } /** - * Returns a {@link State} which is inherited from the {@link Item}s - * accepted DataTypes. The call is delegated to the {@link TypeParser}. If - * item is null the {@link StringType} is used. + * Returns a {@link State} which is inherited from the {@link Item}s accepted DataTypes. The call is delegated to + * the {@link TypeParser}. If item is null the {@link StringType} is used. *

        * * Code borrowed from {@link HttpBinding}. @@ -325,8 +297,8 @@ private TransformationService getInTransformationService() { * @param itemType * @param value * - * @return a {@link State} which type is inherited by the {@link TypeParser} - * or a {@link StringType} if item is null + * @return a {@link State} which type is inherited by the {@link TypeParser} or a {@link StringType} if + * item is null */ private State createState(String value) { Class itemType = getItemType(); @@ -382,52 +354,45 @@ private State createState(String value) { } catch (NumberFormatException nfe) { result = DateTimeType.valueOf(value); } + } else if (itemType.isAssignableFrom(ColorItem.class)) { + result = HSBType.valueOf(value); } else { result = StringType.valueOf(value); } - logger.trace( - "createState: Converted '{}' to '{}', bound to '{}'", - new Object[] { value, result.getClass().getName(), itemType }); + logger.trace("createState: Converted '{}' to '{}', bound to '{}'", new Object[] { value, + result.getClass().getName(), itemType }); return result; } catch (Exception e) { - logger.debug("Couldn't create state of type '{}' for value '{}'", - itemType, value); + logger.debug("Couldn't create state of type '{}' for value '{}'", itemType, value); return StringType.valueOf(value); } } /** - * Transform data from a MiOS Unit into a form suitable for use in an - * openHAB Item. + * Transform data from a MiOS Unit into a form suitable for use in an openHAB Item. *

        * - * Data received from a MiOS unit is in a number of different formats - * (String, Boolean, DataTime, etc). These values may need to be transformed - * from their original format prior to being pushed into the corresponding - * openHAB Item. + * Data received from a MiOS unit is in a number of different formats (String, Boolean, DataTime, etc). These values + * may need to be transformed from their original format prior to being pushed into the corresponding openHAB Item. *

        - * This method is used internally within the MiOS Binding to perform that - * transformation. + * This method is used internally within the MiOS Binding to perform that transformation. *

        - * This method is responsible for transforming the inbound value from the - * MiOS Unit, into the form required by the openHAB Item. + * This method is responsible for transforming the inbound value from the MiOS Unit, into the form required by the + * openHAB Item. *

        - * metadata supplied by the user, via the in: parameter, in the - * Binding Configuration is used to define the transformation that must be - * performed. + * metadata supplied by the user, via the in: parameter, in the Binding Configuration is used to define + * the transformation that must be performed. *

        - * If the in: parameter is missing, then no transformation will - * occur, and the source-value will be returned (as a - * StringType). + * If the in: parameter is missing, then no transformation will occur, and the source-value will be + * returned (as a StringType). *

        - * If the in: parameter is present, then it's value is used to - * determine which openHAB TransformationService should be used to transform - * the value. + * If the in: parameter is present, then it's value is used to determine which openHAB + * TransformationService should be used to transform the value. * - * @return the transformed value, or the input (value) if no - * transformation has been specified in the Binding Configuration. + * @return the transformed value, or the input (value) if no transformation has been specified in the + * Binding Configuration. * * @throws TransformationException * if the underlying Transformation fails in any manner. @@ -436,15 +401,13 @@ public State transformIn(State value) throws TransformationException { TransformationService ts = getInTransformationService(); if (ts != null) { - return createState(ts.transform(getInTransformParam(), - value.toString())); + return createState(ts.transform(getInTransformParam(), value.toString())); } else { if (value instanceof StringType) { value = createState(value.toString()); - logger.trace( - "transformIn: Converted value '{}' from StringType to more scoped type '{}'", - value, value.getClass()); + logger.trace("transformIn: Converted value '{}' from StringType to more scoped type '{}'", value, + value.getClass()); } return value; @@ -464,41 +427,34 @@ private TransformationService getOutTransformationService() { BundleContext context = MiosActivator.getContext(); - outTransformationService = TransformationHelper - .getTransformationService(context, name); + outTransformationService = TransformationHelper.getTransformationService(context, name); if (outTransformationService == null) { - logger.warn( - "Transformation Service (out) '{}' not found for declaration '{}'.", - name, getOutTransform()); + logger.warn("Transformation Service (out) '{}' not found for declaration '{}'.", name, getOutTransform()); } return outTransformationService; } /** - * Transform data in an openHAB Item into a form suitable for use in calls - * made to a MiOS Unit. + * Transform data in an openHAB Item into a form suitable for use in calls made to a MiOS Unit. *

        * - * In order to calls a MiOS Unit, we may need to transform an Item's current - * value from it's openHAB State to a form suitable for transmission to - * remote MiOS Unit. + * In order to calls a MiOS Unit, we may need to transform an Item's current value from it's openHAB State to a form + * suitable for transmission to remote MiOS Unit. *

        - * This method is responsible for transforming an Item's State value, using - * metadata supplied by the user, via the out: parameter, in - * the Binding Configuration. + * This method is responsible for transforming an Item's State value, using metadata supplied by the user, via the + * out: parameter, in the Binding Configuration. *

        - * If the out: parameter is missing, then no transformation - * will occur, and the source-value will be returned. + * If the out: parameter is missing, then no transformation will occur, and the source-value will be + * returned. *

        - * If the out: parameter is present, then it's value is used to - * determine which openHAB TransformationService should be used to transform - * the value. + * If the out: parameter is present, then it's value is used to determine which openHAB + * TransformationService should be used to transform the value. * - * @return the transformed value, or the input (value) if no - * transformation has been specified in the Binding Configuration. + * @return the transformed value, or the input (value) if no transformation has been specified in the + * Binding Configuration. * * @throws TransformationException * if the underlying Transformation fails in any manner. @@ -507,44 +463,37 @@ public State transformOut(State value) throws TransformationException { TransformationService ts = getOutTransformationService(); if (ts != null) { - return createState(ts.transform(getOutTransformParam(), - value.toString())); + return createState(ts.transform(getOutTransformParam(), value.toString())); } else { return value; } } /** - * Transform an openHAB {@link Command} into a call suitable for invoking a - * service on a MiOS Unit. + * Transform an openHAB {@link Command} into a call suitable for invoking a service on a MiOS Unit. *

        * - * In order to call a MiOS Unit, we need the openHAB {@link Command} in the - * format they understand. This method is responsible for transforming the - * Command, using the metadata supplied by the user in the - * command: parameter of the Binding Configuration. Internally, - * this method uses that metadata to perform a transformation, using the - * openHAB Transformation service, to perform the mapping. + * In order to call a MiOS Unit, we need the openHAB {@link Command} in the format they understand. This method is + * responsible for transforming the Command, using the metadata supplied by the user in the command: + * parameter of the Binding Configuration. Internally, this method uses that metadata to perform a transformation, + * using the openHAB Transformation service, to perform the mapping. *

        - * If the command: parameter is missing, then no commands can - * be delivered to the MiOS Unit, and null is returned. + * If the command: parameter is missing, then no commands can be delivered to the MiOS Unit, and + * null is returned. *

        - * If the command: parameter is present, then the associated - * openHAB Transformation Service is invoked to perform the required - * mapping, and the transformed value is returned. + * If the command: parameter is present, then the associated openHAB Transformation Service is invoked + * to perform the required mapping, and the transformed value is returned. * - * @return the transformed value, or null if no transformation has been - * specified in the Binding Configuration. + * @return the transformed value, or null if no transformation has been specified in the Binding Configuration. * * @throws TransformationException * if the underlying Transformation fails in any manner. */ - public abstract String transformCommand(Command command) - throws TransformationException; + public abstract String transformCommand(Command command) throws TransformationException; /** - * Implementation method to be overridden by sub-classes when they have a - * different "format" of output for toProperty(). + * Implementation method to be overridden by sub-classes when they have a different "format" of output for + * toProperty(). *

        */ protected void initialize() { @@ -560,8 +509,7 @@ protected void initialize() { unit = (unit == null) ? "" : "unit:" + unit + ','; if (stuff != null) { - result.append(unit).append(getMiosType()).append(':').append(id) - .append('/').append(stuff); + result.append(unit).append(getMiosType()).append(':').append(id).append('/').append(stuff); } else { result.append(unit).append(getMiosType()).append(':').append(id); } @@ -590,11 +538,11 @@ protected void initialize() { * Return the Command Transformation binding parameter. *

        * - * If the Binding configuration has the command: parameter - * specified, then return that value. Otherwise return null. + * If the Binding configuration has the command: parameter specified, then return that value. Otherwise + * return null. * - * @return the value of the command: Binding configuration - * parameter, or null if not specified. + * @return the value of the command: Binding configuration parameter, or null if not + * specified. */ protected String getCommandTransform() { @@ -612,31 +560,27 @@ public String toString() { * Validate the Item's data type against the BindingConfig. *

        * - * If this validation fails, then a BindingConfigParseException - * is thrown. By default, this method will succeed if the Item is a - * StringItem, NumberItem, SwitchItem - * , DimmerItem, ContactItem, - * DataTimeItem. + * If this validation fails, then a BindingConfigParseException is thrown. By default, this method will + * succeed if the Item is a StringItem, NumberItem, SwitchItem , + * DimmerItem, ContactItem, DataTimeItem. *

        - * Subclasses can augment this behavior or replace it, so that Bindings can - * reconfigure their support for Item Types. + * Subclasses can augment this behavior or replace it, so that Bindings can reconfigure their support for Item + * Types. * * @param item * the Item that requiring validation. * @exception BindingConfigParseException - * when the validation of the BindingConfig - * fails for the Item. + * when the validation of the BindingConfig fails for the Item. */ public void validateItemType(Item item) throws BindingConfigParseException { Class t = getItemType(); - if (!((t == StringItem.class) || (t == SwitchItem.class) - || (t == DimmerItem.class) || (t == NumberItem.class) - || (t == ContactItem.class) || (t == DateTimeItem.class))) { + if (!((t == StringItem.class) || (t == SwitchItem.class) || (t == DimmerItem.class) || (t == NumberItem.class) + || (t == ContactItem.class) || (t == DateTimeItem.class) || (t == RollershutterItem.class))) { throw new BindingConfigParseException( String.format( - "Item %s is of type %s, but only String, Switch, Dimmer, Number, Contact and DataTime Items are allowed.", + "Item %s is of type %s, but only String, Switch, Dimmer, Number, Contact, DataTime, and Rollershutter Items are allowed.", item.getName(), item.getClass().getSimpleName())); } diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/ParameterDefaults.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/ParameterDefaults.java index 4c24bed60a2..311542b6dd9 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/ParameterDefaults.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/ParameterDefaults.java @@ -14,8 +14,7 @@ public class ParameterDefaults { private String mCommandTransform; private String mFormatted; - private ParameterDefaults(String formatted, String in, String out, - String command) { + private ParameterDefaults(String formatted, String in, String out, String command) { mFormatted = formatted; mInTransform = in; mOutTransform = out; diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/RoomBindingConfig.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/RoomBindingConfig.java index 6a816da64ef..f533026b1be 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/RoomBindingConfig.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/RoomBindingConfig.java @@ -20,12 +20,9 @@ */ public class RoomBindingConfig extends MiosBindingConfig { - private RoomBindingConfig(String context, String itemName, String unitName, - int id, String stuff, Class itemType, - String inTransform, String outTransform) - throws BindingConfigParseException { - super(context, itemName, unitName, id, stuff, itemType, null, - inTransform, outTransform); + private RoomBindingConfig(String context, String itemName, String unitName, int id, String stuff, + Class itemType, String inTransform, String outTransform) throws BindingConfigParseException { + super(context, itemName, unitName, id, stuff, itemType, null, inTransform, outTransform); } /** @@ -33,12 +30,11 @@ private RoomBindingConfig(String context, String itemName, String unitName, * * @return an initialized MiOS Room Binding Configuration object. */ - public static final MiosBindingConfig create(String context, - String itemName, String unitName, int id, String stuff, - Class itemType, String inTransform, - String outTransform) throws BindingConfigParseException { - MiosBindingConfig c = new RoomBindingConfig(context, itemName, - unitName, id, stuff, itemType, inTransform, outTransform); + public static final MiosBindingConfig create(String context, String itemName, String unitName, int id, + String stuff, Class itemType, String inTransform, String outTransform) + throws BindingConfigParseException { + MiosBindingConfig c = new RoomBindingConfig(context, itemName, unitName, id, stuff, itemType, inTransform, + outTransform); c.initialize(); return c; @@ -55,15 +51,12 @@ public String getMiosType() { } /** - * This method throws a {@link TransformationException}, as MiOS Room - * attributes don't support being called. + * This method throws a {@link TransformationException}, as MiOS Room attributes don't support being called. * * @throws TransformationException */ @Override - public String transformCommand(Command command) - throws TransformationException { - throw new TransformationException( - "Room attributes don't support Command Transformations"); + public String transformCommand(Command command) throws TransformationException { + throw new TransformationException("Room attributes don't support Command Transformations"); } } diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/SceneBindingConfig.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/SceneBindingConfig.java index 9e15ca46a89..fa71f70aa66 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/SceneBindingConfig.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/SceneBindingConfig.java @@ -11,6 +11,7 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import org.openhab.core.items.Item; @@ -23,8 +24,7 @@ * * The scene-specific form of a MiOS Binding is:
        *

          - *
        • - * mios="unit:unitName,scene:sceneId/attrName,optionalTransformations + *
        • mios="unit:unitName,scene:sceneId/attrName,optionalTransformations * *
        *

        @@ -42,16 +42,14 @@ * * Optional Transformations *

        - * See the Optional Transformations section of the JavaDoc for - * {@link DeviceBindingConfig} for a description of the main options here. + * See the Optional Transformations section of the JavaDoc for {@link DeviceBindingConfig} for a description of the main + * options here. * * The one addition is that Scene Bindings also support: *

          - *
        • command: - map any openHAB Command sent to the Item, - * and use it to trigger Scene execution. - *
        • command:ON - map only the ON Command - * sent to the Item, and use it to trigger Scene execution ("ON" - * can be any openHAB Command string) + *
        • command: - map any openHAB Command sent to the Item, and use it to trigger Scene execution. + *
        • command:ON - map only the ON Command sent to the Item, and use it to trigger + * Scene execution ("ON" can be any openHAB Command string) *
        * * @author Mark Clark @@ -72,29 +70,22 @@ public class SceneBindingConfig extends MiosBindingConfig { Properties tmp = new Properties(); tmp.load(input); - for (Map.Entry e : tmp.entrySet()) { - paramDefaults.put((String) e.getKey(), - ParameterDefaults.parse((String) e.getValue())); + for (Entry e : tmp.entrySet()) { + paramDefaults.put((String) e.getKey(), ParameterDefaults.parse((String) e.getValue())); } - logger.debug( - "Successfully loaded Scene Parameter defaults from '{}', entries '{}'", - PARAM_DEFAULTS, paramDefaults.size()); + logger.debug("Successfully loaded Scene Parameter defaults from '{}', entries '{}'", PARAM_DEFAULTS, + paramDefaults.size()); } catch (Exception e) { // Pre-shipped with the Binding, so it should never error out. - logger.error( - "Failed to load Scene Parameter defaults file '{}', Exception", - PARAM_DEFAULTS, e); + logger.error("Failed to load Scene Parameter defaults file '{}', Exception", PARAM_DEFAULTS, e); } } - private SceneBindingConfig(String context, String itemName, - String unitName, int id, String stuff, - Class itemType, String commandTransform, - String inTransform, String outTransform) + private SceneBindingConfig(String context, String itemName, String unitName, int id, String stuff, + Class itemType, String commandTransform, String inTransform, String outTransform) throws BindingConfigParseException { - super(context, itemName, unitName, id, stuff, itemType, - commandTransform, inTransform, outTransform); + super(context, itemName, unitName, id, stuff, itemType, commandTransform, inTransform, outTransform); } /** @@ -102,41 +93,30 @@ private SceneBindingConfig(String context, String itemName, * * @return an initialized MiOS Scene Binding Configuration object. */ - public static final MiosBindingConfig create(String context, - String itemName, String unitName, int id, String stuff, - Class itemType, String commandTransform, - String inTransform, String outTransform) - throws BindingConfigParseException { + public static final MiosBindingConfig create(String context, String itemName, String unitName, int id, + String stuff, Class itemType, String commandTransform, String inTransform, + String outTransform) throws BindingConfigParseException { ParameterDefaults pd = paramDefaults.get(stuff); if (pd != null) { - logger.trace("Scene ParameterDefaults FOUND '{}' for '{}', '{}'", - itemName, stuff, pd); + logger.trace("Scene ParameterDefaults FOUND '{}' for '{}', '{}'", itemName, stuff, pd); if (commandTransform == null) { commandTransform = pd.getCommandTransform(); - logger.trace( - "Scene ParameterDefaults '{}' defaulted command: to '{}'", - itemName, commandTransform); + logger.trace("Scene ParameterDefaults '{}' defaulted command: to '{}'", itemName, commandTransform); } if (inTransform == null) { inTransform = pd.getInTransform(); - logger.trace( - "Scene ParameterDefaults '{}' defaulted in: to '{}'", - itemName, inTransform); + logger.trace("Scene ParameterDefaults '{}' defaulted in: to '{}'", itemName, inTransform); } if (outTransform == null) { outTransform = pd.getOutTransform(); - logger.trace( - "Scene ParameterDefaults '{}' defaulted out: to '{}'", - itemName, outTransform); + logger.trace("Scene ParameterDefaults '{}' defaulted out: to '{}'", itemName, outTransform); } } else { - logger.trace("Scene ParameterDefaults NOT FOUND '{}' for '{}'", - itemName, stuff); + logger.trace("Scene ParameterDefaults NOT FOUND '{}' for '{}'", itemName, stuff); } - MiosBindingConfig c = new SceneBindingConfig(context, itemName, - unitName, id, stuff, itemType, commandTransform, inTransform, - outTransform); + MiosBindingConfig c = new SceneBindingConfig(context, itemName, unitName, id, stuff, itemType, + commandTransform, inTransform, outTransform); c.initialize(); return c; @@ -153,8 +133,7 @@ public String getMiosType() { } @Override - public String transformCommand(Command command) - throws TransformationException { + public String transformCommand(Command command) throws TransformationException { String key = command.toString(); String cThing = getCommandTransform(); diff --git a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/SystemBindingConfig.java b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/SystemBindingConfig.java index 54f3667c2f5..34cbcde0162 100644 --- a/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/SystemBindingConfig.java +++ b/bundles/binding/org.openhab.binding.mios/src/main/java/org/openhab/binding/mios/internal/config/SystemBindingConfig.java @@ -11,6 +11,7 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import org.openhab.core.items.Item; @@ -23,8 +24,7 @@ * * The system-specific form of a MiOS Binding is:
        *
          - *
        • mios="unit:unitName,system:/attrName - * + *
        • mios="unit:unitName,system:/attrName *
        *

        * @@ -68,28 +68,21 @@ public class SystemBindingConfig extends MiosBindingConfig { Properties tmp = new Properties(); tmp.load(input); - for (Map.Entry e : tmp.entrySet()) { - paramDefaults.put((String) e.getKey(), - ParameterDefaults.parse((String) e.getValue())); + for (Entry e : tmp.entrySet()) { + paramDefaults.put((String) e.getKey(), ParameterDefaults.parse((String) e.getValue())); } - logger.debug( - "Successfully loaded System Parameter defaults from '{}', entries '{}'", - PARAM_DEFAULTS, paramDefaults.size()); + logger.debug("Successfully loaded System Parameter defaults from '{}', entries '{}'", PARAM_DEFAULTS, + paramDefaults.size()); } catch (Exception e) { // Pre-shipped with the Binding, so it should never error out. - logger.error( - "Failed to load System Parameter defaults file '{}', Exception", - PARAM_DEFAULTS, e); + logger.error("Failed to load System Parameter defaults file '{}', Exception", PARAM_DEFAULTS, e); } } - private SystemBindingConfig(String context, String itemName, - String unitName, String stuff, Class itemType, - String inTransform, String outTransform) - throws BindingConfigParseException { - super(context, itemName, unitName, 0, stuff, itemType, null, - inTransform, outTransform); + private SystemBindingConfig(String context, String itemName, String unitName, String stuff, + Class itemType, String inTransform, String outTransform) throws BindingConfigParseException { + super(context, itemName, unitName, 0, stuff, itemType, null, inTransform, outTransform); } /** @@ -97,33 +90,25 @@ private SystemBindingConfig(String context, String itemName, * * @return an initialized MiOS System Binding Configuration object. */ - public static final MiosBindingConfig create(String context, - String itemName, String unitName, String stuff, - Class itemType, String inTransform, - String outTransform) throws BindingConfigParseException { + public static final MiosBindingConfig create(String context, String itemName, String unitName, String stuff, + Class itemType, String inTransform, String outTransform) throws BindingConfigParseException { ParameterDefaults pd = paramDefaults.get(stuff); if (pd != null) { - logger.trace("System ParameterDefaults FOUND '{}' for '{}', '{}'", - itemName, stuff, pd); + logger.trace("System ParameterDefaults FOUND '{}' for '{}', '{}'", itemName, stuff, pd); if (inTransform == null) { inTransform = pd.getInTransform(); - logger.trace( - "System ParameterDefaults '{}' defaulted in: to '{}'", - itemName, inTransform); + logger.trace("System ParameterDefaults '{}' defaulted in: to '{}'", itemName, inTransform); } if (outTransform == null) { outTransform = pd.getOutTransform(); - logger.trace( - "System ParameterDefaults '{}' defaulted out: to '{}'", - itemName, outTransform); + logger.trace("System ParameterDefaults '{}' defaulted out: to '{}'", itemName, outTransform); } } else { - logger.trace("System ParameterDefaults NOT FOUND '{}' for '{}'", - itemName, stuff); + logger.trace("System ParameterDefaults NOT FOUND '{}' for '{}'", itemName, stuff); } - MiosBindingConfig c = new SystemBindingConfig(context, itemName, - unitName, stuff, itemType, inTransform, outTransform); + MiosBindingConfig c = new SystemBindingConfig(context, itemName, unitName, stuff, itemType, inTransform, + outTransform); c.initialize(); return c; @@ -140,15 +125,12 @@ public String getMiosType() { } /** - * This method throws a {@link TransformationException}, as MiOS System - * attributes don't support being called. + * This method throws a {@link TransformationException}, as MiOS System attributes don't support being called. * * @throws TransformationException */ @Override - public String transformCommand(Command command) - throws TransformationException { - throw new TransformationException( - "System attributes don't support Command Transformations"); + public String transformCommand(Command command) throws TransformationException { + throw new TransformationException("System attributes don't support Command Transformations"); } } diff --git a/bundles/binding/org.openhab.binding.mochadx10/.classpath b/bundles/binding/org.openhab.binding.mochadx10/.classpath new file mode 100644 index 00000000000..fb7623f5951 --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.mochadx10/.project b/bundles/binding/org.openhab.binding.mochadx10/.project new file mode 100644 index 00000000000..49119f1f721 --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/.project @@ -0,0 +1,33 @@ + + + org.openhab.binding.mochadx10 + This is the HTTP binding of the open Home Automation Bus (openHAB) + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/bundles/core/org.openhab.core.drools/.settings/org.eclipse.jdt.core.prefs b/bundles/binding/org.openhab.binding.mochadx10/.settings/org.eclipse.jdt.core.prefs similarity index 100% rename from bundles/core/org.openhab.core.drools/.settings/org.eclipse.jdt.core.prefs rename to bundles/binding/org.openhab.binding.mochadx10/.settings/org.eclipse.jdt.core.prefs diff --git a/bundles/core/org.openhab.core.drools/.settings/org.maven.ide.eclipse.prefs b/bundles/binding/org.openhab.binding.mochadx10/.settings/org.maven.ide.eclipse.prefs similarity index 88% rename from bundles/core/org.openhab.core.drools/.settings/org.maven.ide.eclipse.prefs rename to bundles/binding/org.openhab.binding.mochadx10/.settings/org.maven.ide.eclipse.prefs index 056f2faa88d..cf9105dd0b0 100644 --- a/bundles/core/org.openhab.core.drools/.settings/org.maven.ide.eclipse.prefs +++ b/bundles/binding/org.openhab.binding.mochadx10/.settings/org.maven.ide.eclipse.prefs @@ -1,4 +1,4 @@ -#Fri Feb 19 20:27:47 CET 2010 +#Fri Feb 19 20:28:11 CET 2010 activeProfiles= eclipse.preferences.version=1 fullBuildGoals=process-test-resources diff --git a/bundles/binding/org.openhab.binding.mochadx10/META-INF/MANIFEST.MF b/bundles/binding/org.openhab.binding.mochadx10/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..e840815f0de --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/META-INF/MANIFEST.MF @@ -0,0 +1,30 @@ +Manifest-Version: 1.0 +Private-Package: org.openhab.binding.mochadx10.internal +Ignore-Package: org.openhab.binding.mochadx10.internal +Bundle-Name: openHAB Mochad X10 Binding +Bundle-Vendor: openHAB.org +Bundle-Version: 1.7.0.qualifier +Bundle-Activator: org.openhab.binding.mochadx10.internal.MochadX10Activator +Bundle-ManifestVersion: 2 +Bundle-License: http://www.eclipse.org/legal/epl-v10.html +Bundle-Description: This is the Mochad X10 binding of the open Home Aut + omation Bus (openHAB) +Import-Package: com.sun.jersey.api.client, + org.apache.commons.io, + org.apache.commons.lang, + org.codehaus.jackson.map, + org.openhab.core.binding, + org.openhab.core.events, + org.openhab.core.items, + org.openhab.core.library.items, + org.openhab.core.library.types, + org.openhab.core.types, + org.openhab.model.item.binding, + org.osgi.framework, + org.osgi.service.cm, + org.slf4j +Bundle-SymbolicName: org.openhab.binding.mochadx10 +Bundle-DocURL: http://www.openhab.org +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Service-Component: OSGI-INF/genericbindingprovider.xml, OSGI-INF/mochadx10binding.xml +Bundle-ClassPath: . diff --git a/bundles/binding/org.openhab.binding.mochadx10/OSGI-INF/genericbindingprovider.xml b/bundles/binding/org.openhab.binding.mochadx10/OSGI-INF/genericbindingprovider.xml new file mode 100644 index 00000000000..5c2ab17678f --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/OSGI-INF/genericbindingprovider.xml @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/bundles/core/org.openhab.core.drools/OSGI-INF/ruleservice.xml b/bundles/binding/org.openhab.binding.mochadx10/OSGI-INF/mochadx10binding.xml similarity index 53% rename from bundles/core/org.openhab.core.drools/OSGI-INF/ruleservice.xml rename to bundles/binding/org.openhab.binding.mochadx10/OSGI-INF/mochadx10binding.xml index b902a237b3d..a9b5c10bb0c 100644 --- a/bundles/core/org.openhab.core.drools/OSGI-INF/ruleservice.xml +++ b/bundles/binding/org.openhab.binding.mochadx10/OSGI-INF/mochadx10binding.xml @@ -1,7 +1,7 @@ - - + + + + - - + + + + + + diff --git a/bundles/binding/org.openhab.binding.mochadx10/build.properties b/bundles/binding/org.openhab.binding.mochadx10/build.properties new file mode 100644 index 00000000000..c476064e7aa --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/build.properties @@ -0,0 +1,7 @@ +output.. = target/classes/ +bin.includes = .,\ + OSGI-INF/genericbindingprovider.xml,\ + OSGI-INF/mochadx10binding.xml,\ + META-INF/ +source.. = src/main/java/,\ + src/main/resources/ diff --git a/bundles/binding/org.openhab.binding.mochadx10/pom.xml b/bundles/binding/org.openhab.binding.mochadx10/pom.xml new file mode 100644 index 00000000000..9b6d316b141 --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/pom.xml @@ -0,0 +1,36 @@ + + + + + org.openhab.bundles + binding + 1.6.0-SNAPSHOT + + + openHAB Mochad X10 Binding + + + org.openhab.binding.mochadx10 + org.openhab.binding.mochadx10 + openhab-addon-binding-mochadx10 + ${project.name} + + + 4.0.0 + org.openhab.binding + org.openhab.binding.mochadx10 + + eclipse-plugin + + + + + org.vafer + jdeb + + + + + diff --git a/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/MochadX10BindingProvider.java b/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/MochadX10BindingProvider.java new file mode 100644 index 00000000000..49734183a97 --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/MochadX10BindingProvider.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.mochadx10; + +import java.util.List; + +import org.openhab.binding.mochadx10.internal.MochadX10BindingConfig; +import org.openhab.core.binding.BindingProvider; + +/** + * This interface is implemented by classes that can provide mapping information + * between openHAB items and the Mochad X10 Daemon + * (http://sourceforge.net/projects/mochad/). + * + * @author Jack Sleuters + * @since 1.7.0 + */ +public interface MochadX10BindingProvider extends BindingProvider { + + /** + * Returns the configuration for the item with the given name. + * + * @param itemName + * @return The configuration if there is an item with the given name, null + * otherwise. + */ + public MochadX10BindingConfig getItemConfig(String itemName); + + /** + * Returns a list of item names + * + * @return List of item names mapped to a Hue-Binding + */ + public List getInBindingItemNames(); +} diff --git a/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10Activator.java b/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10Activator.java new file mode 100644 index 00000000000..f9372937cbf --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10Activator.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.mochadx10.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Extension of the default OSGi bundle activator. + * + * @author Jack Sleuters + * @since 1.7.0 + */ +public final class MochadX10Activator implements BundleActivator { + + private static Logger logger = LoggerFactory.getLogger(MochadX10Activator.class); + + /** + * Called whenever the OSGi framework starts our bundle + */ + public void start(BundleContext bc) throws Exception { + logger.debug("Mochad X10 binding has been started."); + } + + /** + * Called whenever the OSGi framework stops our bundle + */ + public void stop(BundleContext bc) throws Exception { + logger.debug("Mochad X10 binding has been stopped."); + } +} diff --git a/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10Binding.java b/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10Binding.java new file mode 100644 index 00000000000..bd9fb47932c --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10Binding.java @@ -0,0 +1,204 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.mochadx10.internal; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.Socket; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.openhab.binding.mochadx10.MochadX10BindingProvider; +import org.openhab.core.binding.AbstractBinding; +import org.openhab.core.library.items.DimmerItem; +import org.openhab.core.library.items.RollershutterItem; +import org.openhab.core.library.types.IncreaseDecreaseType; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.StopMoveType; +import org.openhab.core.library.types.UpDownType; +import org.openhab.core.types.Command; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This binding is able to do the following tasks with the mochad X10 System: + * + *

          + *
        • X10 Appliance modules: switch on, switch off.
        • + *
        • X10 Dimmer modules: switch on, switch off, dim
        • + *
        • X10 Shutter modules: open, close, stop, move
        • + *
        + * + * @author Jack Sleuters + * @since 1.7.0 + */ +public class MochadX10Binding extends AbstractBinding implements ManagedService { + static final Logger logger = LoggerFactory.getLogger(MochadX10Binding.class); + + private String hostIp = "127.0.0.1"; // default mochad host ip address + private int hostPort = 1099; // default mochad host port + private Map lastIssuedCommand = new HashMap(); // required to determine the X10 command for STOP + + private static final String IPADDRESS_PATTERN = + "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"; + + + @Override + public void updated(Dictionary properties) throws ConfigurationException { + if ( properties != null ) { + String ip = (String) properties.get( "hostIp" ); + if ( StringUtils.isNotBlank( ip ) ) { + if ( isValidIpAddress( ip ) ) { + this.hostIp = ip; + } + else { + throw new ConfigurationException(hostIp, "The specified hostIp address \"" + ip + "\" is not a valid ip address"); + } + } + + String port = (String) properties.get("hostPort"); + if ( StringUtils.isNotBlank( port ) ) { + if ( isValidPort( port ) ) { + this.hostPort = Integer.parseInt(port); + } + else { + throw new ConfigurationException(port, "The specified port \"" + port + "\" is not a valid port number."); + } + } + } + } + + private boolean isValidPort(String port) { + try { + int portNumber = Integer.parseInt(port); + + if ( ( portNumber >= 1024 ) && ( portNumber <= 65535) ) { + return true; + } + } + catch (NumberFormatException e) { + return false; + } + + return false; + } + + private boolean isValidIpAddress(String hostIp) { + if ( hostIp.matches(IPADDRESS_PATTERN) ) { + return true; + } + + return false; + } + + /** + * Lookup of the configuration of the named item. + * + * @param itemName + * @return The configuration, null otherwise. + */ + private MochadX10BindingConfig getConfigForItemName(String itemName) { + for (MochadX10BindingProvider provider : this.providers) { + if (provider.getItemConfig(itemName) != null) { + return provider.getItemConfig(itemName); + } + } + logger.warn("No configuration found for item '" + itemName + "'"); + + return null; + } + + @Override + protected void internalReceiveCommand(String itemName, Command command) { + MochadX10BindingConfig deviceConfig = getConfigForItemName(itemName); + + if (deviceConfig == null) { + return; + } + + String address = deviceConfig.getAddress(); + String tm = deviceConfig.getTransmitMethod(); + String commandStr = "none"; + Command previousCommand = lastIssuedCommand.get( address ); + int nrLinesToRead = 2; + + if ( command instanceof OnOffType ) { + commandStr = OnOffType.ON.equals( command ) ? "on" : "off"; + } + else if ( command instanceof UpDownType ) { + commandStr = UpDownType.UP.equals( command ) ? "bright" : "dim"; + } + else if ( command instanceof StopMoveType ) { + if ( StopMoveType.STOP.equals( command ) ) { + commandStr = UpDownType.UP.equals( previousCommand ) ? "dim" : "bright"; + } + else { + // Move not supported yet + commandStr = "none"; + } + } + else if ( command instanceof PercentType ) { + if ( deviceConfig.getItemType() == DimmerItem.class ) { + if ( ((PercentType) command).intValue() == 0 ) { + // If percent value equals 0 the x10 "off" command is used instead of xdim + commandStr = "off"; + } + else { + // 100% maps to value 63 so we need to do scaling + long dim_value = Math.round(((PercentType) command).doubleValue() * 63.0/100); + commandStr = "xdim " + dim_value; + } + } + else if ( deviceConfig.getItemType() == RollershutterItem.class ) { + Double invert_level = 100 - ((PercentType) command).doubleValue(); + long level = Math.round(invert_level * 25.0/100); + commandStr = "extended_code_1 0 1 " + level; + } + nrLinesToRead = 1; + } + else if ( command instanceof IncreaseDecreaseType ) { + // Increase decrease not yet supported + commandStr = "none"; + } + + try { + if ( !commandStr.equals( "none" ) ) { + Socket client = new Socket( hostIp, hostPort ); + client.setSoTimeout(3000); + + BufferedReader br = new BufferedReader( new InputStreamReader( client.getInputStream() ) ); + DataOutputStream out = new DataOutputStream( client.getOutputStream() ); + + out.writeBytes(tm + " " + address + " " + commandStr + "\n"); + logger.debug(tm + " " + address + " " + commandStr); + out.flush(); + + for (int i = 0; i < nrLinesToRead; i++) { + logger.debug( br.readLine() ); + } + + out.close(); + client.close(); + } + } catch (IOException e) { + logger.error(e.getMessage()); + } + lastIssuedCommand.put(address, command); + } +} diff --git a/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10BindingConfig.java b/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10BindingConfig.java new file mode 100644 index 00000000000..9dc0bc2927d --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10BindingConfig.java @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.mochadx10.internal; + +import org.openhab.core.binding.BindingConfig; +import org.openhab.core.items.Item; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This represents the configuration of an openHAB item that is binded to an + * X10 module. It contains the following information: + * + *
          + *
        • The address of the module. Syntax: . Example: a12 or m3 + *
        • The transmission method for the command: pl for powerline, rf for radio. If no + * transmission method is specified, powerline will be used.
        • + *
        + * + * Examples: + *
          + *
        • a12 to address the module with house code 'a' and unit code '12' via power line
        • + *
        • m3 rf to address the module with house code 'm' and unit code '3' via radio
        • + *
        + * + * @author Jack Sleuters + */ +public class MochadX10BindingConfig implements BindingConfig { + + static final Logger logger = LoggerFactory.getLogger(MochadX10BindingConfig.class); + + /** + * Address of the module with syntax + */ + private String address; + + /** + * Transmission method + * Value 'pl': transmit command via powerline + * Value 'rf': transmit command via radio + */ + private String transmitMethod; + + private Class itemType; + + /** + * Constructor of the MochadX10BindingConfig. + * + * @param item + * @param transmitMethod + * The optional transmission method for the X10 command. + * @param address + * The address of the X10 module + */ + public MochadX10BindingConfig(Class itemType, String transmitMethod, String address) { + this.itemType = itemType; + this.address = address.toLowerCase(); + this.transmitMethod = transmitMethod.toLowerCase(); + } + + /** + * @return the X10 address specified in the binding + */ + public String getAddress() { + return address; + } + + /** + * @return the item class + */ + protected Class getItemType() { + return itemType; + } + + /** + * @return the transmission method specified in the binding + */ + public String getTransmitMethod() { + return transmitMethod; + } +} diff --git a/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10GenericBindingProvider.java b/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10GenericBindingProvider.java new file mode 100644 index 00000000000..2aeac3a9ad8 --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/src/main/java/org/openhab/binding/mochadx10/internal/MochadX10GenericBindingProvider.java @@ -0,0 +1,155 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.mochadx10.internal; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.openhab.binding.mochadx10.MochadX10BindingProvider; +import org.openhab.core.binding.BindingConfig; +import org.openhab.core.items.Item; +import org.openhab.core.library.items.DimmerItem; +import org.openhab.core.library.items.RollershutterItem; +import org.openhab.core.library.items.SwitchItem; +import org.openhab.model.item.binding.AbstractGenericBindingProvider; +import org.openhab.model.item.binding.BindingConfigParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

        + * This class can parse information from the generic binding format. It + * registers as a {@link MochadX10BindingProvider} service as well. + *

        + * + * Here are some examples for valid binding configuration strings: + *
          + *
        • {mochadx10="a12"} - Connects to X10 module with address 'a12' and use powerline (default) as transmission method.
        • + *
        • {mochadx10="m3:rf"} - Connects to X10 module with address 'm3' and use rf as transmission method.
        • + *
        + * @author Jack Sleuters + * @since 1.7.0 + * + */ +public class MochadX10GenericBindingProvider extends AbstractGenericBindingProvider + implements MochadX10BindingProvider { + + static final Logger logger = LoggerFactory.getLogger(MochadX10GenericBindingProvider.class); + + /** + * The regular expression that specifies an X10 address + */ + private static final Pattern X10_ADDRESS_PATTERN = Pattern.compile("[a-p]([1-9]|1[0-6])"); + + @Override + public String getBindingType() { + return "mochadx10"; + } + + @Override + public void validateItemType(Item item, String bindingConfig) + throws BindingConfigParseException { + + if ( !(item instanceof SwitchItem || + item instanceof DimmerItem || + item instanceof RollershutterItem )) { + throw new BindingConfigParseException( + "Item '" + + item.getName() + + "' is of type '" + + item.getClass().getSimpleName() + + "', only SwitchItems, DimmerItems and RollershutterItems are allowed - please check your *.items configuration"); + } + } + + @Override + public void processBindingConfiguration(String context, Item item, + String bindingConfig) throws BindingConfigParseException { + + super.processBindingConfiguration(context, item, bindingConfig); + + try { + if (bindingConfig != null) { + String[] configParts = bindingConfig.split(":"); + String address = null; + String transmitMethod = "pl"; // the default + + switch (configParts.length) { + case 2: + transmitMethod = configParts[1]; // intentional fall-through + case 1: + address = configParts[0]; + break; + + default: + logger.warn("bindingConfig should only contain x10 address and optional transmission method (item=" + item + + ") -> processing bindingConfig aborted!"); + return; + } + + validateAddress(address); + validateTransmitMethod(transmitMethod); + + BindingConfig mochadX10BindingConfig = (BindingConfig) new MochadX10BindingConfig(item.getClass(), transmitMethod, address); + addBindingConfig(item, mochadX10BindingConfig); + } else { + throw new BindingConfigParseException("No binding config specified (item=" + item + + ") -> processing bindingConfig aborted!"); + } + } catch ( ArrayIndexOutOfBoundsException e ) { + throw new BindingConfigParseException("bindingConfig is invalid (item=" + item + + ") -> processing bindingConfig aborted!"); + } + } + + /** + * Check whether the specified transmit method is valid. + * + * @param transmitMethod + * @throws BindingConfigParseException + */ + private void validateTransmitMethod(String transmitMethod) throws BindingConfigParseException { + String lowerCaseTransmitMethod = transmitMethod.toLowerCase(); + if ( !(lowerCaseTransmitMethod.equals("pl") || lowerCaseTransmitMethod.equals("rf")) ) { + throw new BindingConfigParseException("The specified transmit method '" + transmitMethod + "' is not a valid transmission method."); + } + } + + /** + * Check whether the specified address is a valid x10 address + * + * @param address + * @throws BindingConfigParseException + */ + private void validateAddress(String address) throws BindingConfigParseException { + Matcher matcher = X10_ADDRESS_PATTERN.matcher(address.toLowerCase()); + + if ( !matcher.matches() ) { + throw new BindingConfigParseException("The specified address '" + address + "' is not a valid X10 address."); + } + } + + @Override + public MochadX10BindingConfig getItemConfig(String itemName) { + return (MochadX10BindingConfig) bindingConfigs.get(itemName); + } + + /** + * {@inheritDoc} + */ + public List getInBindingItemNames() { + List inBindings = new ArrayList(); + for (String itemName : bindingConfigs.keySet()) { + inBindings.add(itemName); + } + return inBindings; + } +} diff --git a/bundles/binding/org.openhab.binding.mochadx10/src/main/resources/readme.txt b/bundles/binding/org.openhab.binding.mochadx10/src/main/resources/readme.txt new file mode 100644 index 00000000000..98698c670dc --- /dev/null +++ b/bundles/binding/org.openhab.binding.mochadx10/src/main/resources/readme.txt @@ -0,0 +1 @@ +Bundle resources go in here! \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.modbus/.classpath b/bundles/binding/org.openhab.binding.modbus/.classpath index 82e2381d911..6bf0297984d 100644 --- a/bundles/binding/org.openhab.binding.modbus/.classpath +++ b/bundles/binding/org.openhab.binding.modbus/.classpath @@ -3,6 +3,5 @@ - diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/Modbus.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/Modbus.java index a0f4842d220..180b3b7146d 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/Modbus.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/Modbus.java @@ -227,5 +227,11 @@ public interface Modbus { */ public static final String DEFAULT_SERIAL_ENCODING = SERIAL_ENCODING_ASCII; + /** + * presents a list of valid modbus serial encoding options + */ + public static final String[] validSerialEncodings = { + SERIAL_ENCODING_ASCII, SERIAL_ENCODING_RTU, SERIAL_ENCODING_BIN }; + }//class Modbus diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ASCIIInputStream.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ASCIIInputStream.java index ea90cea9b8f..ce9c541b578 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ASCIIInputStream.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ASCIIInputStream.java @@ -16,12 +16,13 @@ package net.wimpi.modbus.io; -import net.wimpi.modbus.Modbus; - import java.io.IOException; import java.io.InputStream; import java.io.FilterInputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Class implementing a specialized InputStream which * decodes characters read from the raw stream into bytes. @@ -39,6 +40,7 @@ public class ASCIIInputStream extends FilterInputStream { + private static final Logger logger = LoggerFactory.getLogger(ASCIIInputStream.class); /** * Constructs a new ASCIIInputStream instance * reading from the given InputStream. @@ -57,7 +59,7 @@ public ASCIIInputStream(InputStream in) { */ public int read() throws IOException { StringBuffer sbuf = new StringBuffer(2); - int ch = in.read(); + int ch = in.read(); //!@todo that thing blocks until something was received if(ch == -1) { return -1; } @@ -78,12 +80,13 @@ public int read() throws IOException { } else { try { sbuf.append((char) in.read()); - //System.out.println("Read byte: " + sbuf.toString().toLowerCase()); + logger.trace("Read byte: {}", sbuf.toString().toLowerCase()); return Integer.parseInt(sbuf.toString().toLowerCase(), 16); } catch (NumberFormatException ex) { //malformed stream - if(Modbus.debug) System.out.println(sbuf.toString()); - throw new IOException("Malformed Stream - Wrong Characters"); + final String errMsg = "Malformed Stream - Wrong Characters"; + logger.debug("{}: {}", errMsg, sbuf.toString()); + throw new IOException(errMsg); } } } diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusASCIITransport.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusASCIITransport.java index 838fd0783c7..d3ce7be905e 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusASCIITransport.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusASCIITransport.java @@ -29,6 +29,9 @@ import java.io.InputStream; import java.io.OutputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Class that implements the Modbus/ASCII transport * flavor. @@ -40,6 +43,8 @@ public class ModbusASCIITransport extends ModbusSerialTransport { + private static final Logger logger = LoggerFactory.getLogger(ModbusASCIITransport.class); + private DataInputStream m_InputStream; //used to read from private ASCIIOutputStream m_OutputStream; //used to write to @@ -73,8 +78,7 @@ public void writeMessage(ModbusMessage msg) //write message m_OutputStream.write(FRAME_START); //FRAMESTART m_OutputStream.write(buf, 0, len); //PDU - if(Modbus.debug) - System.out.println("Writing: " + ModbusUtil.toHex(buf, 0, len)); + logger.debug("Writing: {}", ModbusUtil.toHex(buf, 0, len)); m_OutputStream.write(ModbusUtil.calculateLRC(buf, 0, len)); //LRC m_OutputStream.write(FRAME_END); //FRAMEEND m_OutputStream.flush(); @@ -136,8 +140,9 @@ public ModbusRequest readRequest() } while (!done); return request; } catch (Exception ex) { - if(Modbus.debug) System.out.println(ex.getMessage()); - throw new ModbusIOException("readRequest: I/O exception - failed to read."); + final String errMsg = "I/O exception - failed to read"; + logger.debug("{}: {}", errMsg, ex.getMessage()); + throw new ModbusIOException("readRequest: " + errMsg); } }//readRequest @@ -167,15 +172,12 @@ public ModbusResponse readResponse() m_ByteInOut.writeByte(in); } int len = m_ByteInOut.size(); - if (Modbus.debug) - System.out.println("Received: " + - ModbusUtil.toHex(m_InBuffer, 0, len)); + logger.debug("Received: {}", ModbusUtil.toHex(m_InBuffer, 0, len)); //check LRC if (((int)m_InBuffer[len-1] & 0xff) != ModbusUtil.calculateLRC(m_InBuffer, 0, len - 1)) { - if (Modbus.debug) - System.out.println("LRC is wrong: received=" + - ((int)m_InBuffer[len-1] & 0xff) + - " calculated=" + ModbusUtil.calculateLRC(m_InBuffer, 0, len - 1)); + logger.debug("LRC is wrong: received={} calculated={}", + ((int)m_InBuffer[len-1] & 0xff), + ModbusUtil.calculateLRC(m_InBuffer, 0, len - 1)); continue; } @@ -201,8 +203,9 @@ public ModbusResponse readResponse() } while (!done); return response; } catch (Exception ex) { - if(Modbus.debug) System.out.println(ex.getMessage()); - throw new ModbusIOException("readResponse I/O exception - failed to read."); + final String errMsg = "I/O exception - failed to read"; + logger.debug("{}: {}", errMsg, ex.getMessage()); + throw new ModbusIOException("readResponse " + errMsg); } }//readResponse diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusBINTransport.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusBINTransport.java index 2f03486f48a..b2153a809c7 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusBINTransport.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusBINTransport.java @@ -29,6 +29,9 @@ import java.io.InputStream; import java.io.OutputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Class that implements the Modbus/BIN transport * flavor. @@ -39,6 +42,7 @@ public class ModbusBINTransport extends ModbusSerialTransport { + private static final Logger logger = LoggerFactory.getLogger(ModbusBINTransport.class); private DataInputStream m_InputStream; //used to read from private ASCIIOutputStream m_OutputStream; //used to write to @@ -136,8 +140,9 @@ public ModbusRequest readRequest() } while (!done); return request; } catch (Exception ex) { - if(Modbus.debug) System.out.println(ex.getMessage()); - throw new ModbusIOException("I/O exception - failed to read."); + final String errMsg = "failed to read"; + logger.debug("{}: {}", errMsg, ex.getMessage()); + throw new ModbusIOException("I/O exception - " + errMsg); } }//readRequest @@ -191,8 +196,9 @@ public ModbusResponse readResponse() } while (!done); return response; } catch (Exception ex) { - if(Modbus.debug) System.out.println(ex.getMessage()); - throw new ModbusIOException("I/O exception - failed to read."); + final String errMsg = "failed to read"; + logger.debug("{}: {}", errMsg, ex.getMessage()); + throw new ModbusIOException("I/O exception - " + errMsg); } }//readResponse diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusRTUTransport.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusRTUTransport.java index d530f49687e..e2d1100e101 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusRTUTransport.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusRTUTransport.java @@ -27,6 +27,9 @@ import java.io.InputStream; import java.io.OutputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Class that implements the ModbusRTU transport @@ -40,6 +43,8 @@ public class ModbusRTUTransport extends ModbusSerialTransport { + private static final Logger logger = LoggerFactory.getLogger(ModbusRTUTransport.class); + private InputStream m_InputStream; //wrap into filter input private OutputStream m_OutputStream; //wrap into filter output @@ -69,7 +74,7 @@ public void writeMessage(ModbusMessage msg) throws ModbusIOException { byte buf[] = m_ByteOut.getBuffer(); m_OutputStream.write(buf, 0, len); //PDU + CRC m_OutputStream.flush(); - if(Modbus.debug) System.out.println("Sent: " + ModbusUtil.toHex(buf, 0, len)); + logger.debug("Sent: {}", ModbusUtil.toHex(buf, 0, len)); // clears out the echoed message // for RS485 if (m_Echo) { @@ -100,8 +105,7 @@ public void clearInput() throws IOException { int len = m_InputStream.available(); byte buf[] = new byte[len]; m_InputStream.read(buf, 0, len); - if(Modbus.debug) System.out.println("Clear input: " + - ModbusUtil.toHex(buf, 0, len)); + logger.debug("Clear input: {}", ModbusUtil.toHex(buf, 0, len)); } }//cleanInput @@ -134,8 +138,7 @@ public ModbusResponse readResponse() // timeout and to message specific parsing to read a response. getResponse(fc, m_ByteInOut); dlength = m_ByteInOut.size() - 2; // less the crc - if (Modbus.debug) System.out.println("Response: " + - ModbusUtil.toHex(m_ByteInOut.getBuffer(), 0, dlength + 2)); + logger.debug("Response: {}", ModbusUtil.toHex(m_ByteInOut.getBuffer(), 0, dlength + 2)); m_ByteIn.reset(m_InBuffer, dlength); @@ -159,9 +162,10 @@ public ModbusResponse readResponse() } while (!done); return response; } catch (Exception ex) { - System.err.println("Last request: " + ModbusUtil.toHex(lastRequest)); - System.err.println(ex.getMessage()); - throw new ModbusIOException("I/O exception - failed to read"); + final String errMsg = "failed to read"; + logger.error("Last request: {}", ModbusUtil.toHex(lastRequest)); + logger.error("{}: {}", errMsg, ex.getMessage()); + throw new ModbusIOException("I/O exception - " + errMsg); } }//readResponse @@ -215,8 +219,7 @@ private void getResponse(int fn, BytesOutputStream out) out.write(inpBuf, 0, inpBytes); m_CommPort.disableReceiveThreshold(); if (inpBytes != bc+2) { - System.out.println("Error: looking for " + (bc+2) + - " bytes, received " + inpBytes); + logger.error("awaited {} bytes, but received {}", (bc+2), inpBytes); } break; case 0x05: diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusSerialTransaction.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusSerialTransaction.java index be12c0b0c74..4718fecabe6 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusSerialTransaction.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusSerialTransaction.java @@ -16,6 +16,9 @@ package net.wimpi.modbus.io; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.wimpi.modbus.Modbus; import net.wimpi.modbus.ModbusException; import net.wimpi.modbus.ModbusIOException; @@ -37,6 +40,7 @@ public class ModbusSerialTransaction implements ModbusTransaction { + private static final Logger logger = LoggerFactory.getLogger(ModbusSerialTransaction.class); //class attributes private static AtomicCounter c_TransactionID = new AtomicCounter(Modbus.DEFAULT_TRANSACTION_ID); @@ -178,7 +182,7 @@ public void execute() throws ModbusIOException, try { Thread.sleep(m_TransDelayMS); } catch (InterruptedException ex) { - System.err.println("InterruptedException: " + ex.getMessage()); + logger.error("InterruptedException: {}", ex.getMessage()); } } //write request message @@ -190,8 +194,7 @@ public void execute() throws ModbusIOException, if (++tries >= m_Retries) { throw e; } - System.err.println("execute try " + tries + " error: " + - e.getMessage()); + logger.error("execute try {} error: {}", tries, e.getMessage()); } } while (!finished); } diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusSerialTransport.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusSerialTransport.java index f0167175360..470e31e8c22 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusSerialTransport.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusSerialTransport.java @@ -24,9 +24,15 @@ import net.wimpi.modbus.util.ModbusUtil; import java.io.IOException; + import gnu.io.CommPort; + import java.io.InputStream; import java.io.OutputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import gnu.io.UnsupportedCommOperationException; /** @@ -40,6 +46,8 @@ */ abstract public class ModbusSerialTransport implements ModbusTransport { + + private static final Logger logger = LoggerFactory.getLogger(ModbusSerialTransport.class); protected CommPort m_CommPort; protected boolean m_Echo = false; // require RS-485 echo processing @@ -135,7 +143,7 @@ public void setReceiveThreshold(int th) { try { m_CommPort.enableReceiveThreshold(th); /* chars */ } catch (UnsupportedCommOperationException e) { - System.out.println(e.getMessage()); + logger.error("Failed to setReceiveThreshold: {}", e.getMessage()); } } @@ -148,7 +156,7 @@ public void setReceiveTimeout(int ms) { try { m_CommPort.enableReceiveTimeout(ms); /* milliseconds */ } catch (UnsupportedCommOperationException e) { - System.out.println(e.getMessage()); + logger.error("Failed to setReceiveTimeout: {}", e.getMessage()); } } @@ -166,14 +174,13 @@ public void readEcho(int len) throws IOException { byte echoBuf[] = new byte[len]; setReceiveThreshold(len); int echoLen = m_CommPort.getInputStream().read(echoBuf, 0, len); - if (Modbus.debug) - System.out.println("Echo: " + - ModbusUtil.toHex(echoBuf, 0, echoLen)); + + logger.debug("Echo: {}", ModbusUtil.toHex(echoBuf, 0, echoLen)); m_CommPort.disableReceiveThreshold(); if (echoLen != len) { - if (Modbus.debug) - System.err.println("Error: Transmit echo not received."); - throw new IOException("Echo not received."); + final String errMsg = "Echo not received"; + logger.error("Transmit {}", errMsg); + throw new IOException(errMsg); } }//readEcho diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusTCPTransport.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusTCPTransport.java index bd8228132ae..46918b7838b 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusTCPTransport.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/io/ModbusTCPTransport.java @@ -26,6 +26,9 @@ import java.net.Socket; import java.net.SocketException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.wimpi.modbus.Modbus; import net.wimpi.modbus.ModbusIOException; import net.wimpi.modbus.msg.ModbusMessage; @@ -43,6 +46,7 @@ public class ModbusTCPTransport implements ModbusTransport { + private static final Logger logger = LoggerFactory.getLogger(ModbusTCPTransport.class); //instance attributes private DataInputStream m_Input; //input stream private DataOutputStream m_Output; //output stream @@ -58,9 +62,10 @@ public ModbusTCPTransport(Socket socket) { try { setSocket(socket); } catch (IOException ex) { - if(Modbus.debug) System.out.println("ModbusTCPTransport::Socket invalid."); + final String errMsg = "Socket invalid"; + logger.debug(errMsg); //@commentstart@ - throw new IllegalStateException("Socket invalid."); + throw new IllegalStateException(errMsg); //@commentend@ } }//constructor diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusSerialListener.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusSerialListener.java index 13fce8c23fd..6a9785ca1ab 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusSerialListener.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusSerialListener.java @@ -16,6 +16,9 @@ package net.wimpi.modbus.net; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.wimpi.modbus.Modbus; import net.wimpi.modbus.ModbusCoupler; import net.wimpi.modbus.ModbusIOException; @@ -34,6 +37,7 @@ */ public class ModbusSerialListener { + private static final Logger logger = LoggerFactory.getLogger(ModbusSerialListener.class); //Members private boolean m_Listening; //Flag for toggling listening/!listening private SerialConnection m_SerialCon; @@ -46,7 +50,7 @@ public class ModbusSerialListener { */ public ModbusSerialListener(SerialParameters params) { m_SerialCon = new SerialConnection(params); - //System.out.println("Created connection."); + logger.trace("Created connection"); listen(); }//constructor @@ -57,7 +61,8 @@ private void listen() { try { m_Listening = true; m_SerialCon.open(); - //System.out.println("Opened Serial connection."); + logger.trace("Opened Serial connection."); + ModbusTransport transport = m_SerialCon.getModbusTransport(); do { if (m_Listening) { @@ -74,10 +79,8 @@ private void listen() { response = request.createResponse(); } - if (Modbus.debug) - System.out.println("Request:" + request.getHexMessage()); - if (Modbus.debug) - System.out.println("Response:" + response.getHexMessage()); + logger.debug("Request:{}", request.getHexMessage()); + logger.debug("Response:{}", response.getHexMessage()); transport.writeMessage(response); diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusTCPListener.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusTCPListener.java index 060839c9059..b4dca179571 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusTCPListener.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusTCPListener.java @@ -23,6 +23,9 @@ import java.net.SocketException; import java.net.UnknownHostException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.wimpi.modbus.Modbus; import net.wimpi.modbus.util.ThreadPool; @@ -37,6 +40,7 @@ public class ModbusTCPListener implements Runnable { + private static final Logger logger = LoggerFactory.getLogger(ModbusTCPListener.class); private static int c_RequestCounter = 0; private ServerSocket m_ServerSocket = null; @@ -128,12 +132,12 @@ public void run() { program logins can probably be prevented. */ m_ServerSocket = new ServerSocket(m_Port, m_FloodProtection, m_Address); - if(Modbus.debug) System.out.println("Listenening to " + m_ServerSocket.toString() + "(Port " + m_Port + ")"); + logger.debug("Listenening to {} (Port {})", m_ServerSocket.toString(), m_Port); //Infinite loop, taking care of resources in case of a lot of parallel logins do { Socket incoming = m_ServerSocket.accept(); - if (Modbus.debug) System.out.println("Making new connection " + incoming.toString()); + logger.debug("Making new connection {}", incoming.toString()); if (m_Listening) { //FIXME: Replace with object pool due to resource issues m_ThreadPool.execute( diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusUDPListener.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusUDPListener.java index c3bdd2d3b93..7c73072c411 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusUDPListener.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/ModbusUDPListener.java @@ -18,6 +18,9 @@ import java.net.InetAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.wimpi.modbus.Modbus; import net.wimpi.modbus.ModbusCoupler; import net.wimpi.modbus.ModbusIOException; @@ -32,6 +35,7 @@ * @version @version@ (@date@) */ public class ModbusUDPListener { + private static final Logger logger = LoggerFactory.getLogger(ModbusUDPListener.class); private UDPSlaveTerminal m_Terminal; private ModbusUDPHandler m_Handler; @@ -136,7 +140,7 @@ public void run() { do { //1. read the request ModbusRequest request = m_Transport.readRequest(); - //System.out.println("Request:" + request.getHexMessage()); + logger.trace("Request: {}", request.getHexMessage()); ModbusResponse response = null; //test if Process image exists @@ -146,11 +150,9 @@ public void run() { } else { response = request.createResponse(); } - /*DEBUG*/ - if (Modbus.debug) System.out.println("Request:" + request.getHexMessage()); - if (Modbus.debug) System.out.println("Response:" + response.getHexMessage()); + logger.debug("Request: {}", request.getHexMessage()); + logger.debug("Response: {}", response.getHexMessage()); - //System.out.println("Response:" + response.getHexMessage()); m_Transport.writeMessage(response); } while (m_Continue); } catch (ModbusIOException ex) { diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/SerialConnection.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/SerialConnection.java index d51c01b7c8a..968e07a2eed 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/SerialConnection.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/SerialConnection.java @@ -19,7 +19,6 @@ import net.wimpi.modbus.Modbus; import net.wimpi.modbus.io.*; import net.wimpi.modbus.util.SerialParameters; - import gnu.io.*; import java.io.File; @@ -28,6 +27,8 @@ import java.util.TooManyListenersException; import org.apache.commons.lang.SystemUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Class that implements a serial connection which @@ -39,6 +40,7 @@ */ public class SerialConnection implements SerialPortEventListener { + private static final Logger logger = LoggerFactory.getLogger(SerialConnection.class); private SerialParameters m_Parameters; private ModbusSerialTransport m_Transport; @@ -101,21 +103,22 @@ public void open() throws Exception { m_PortIdentifyer = CommPortIdentifier.getPortIdentifier(m_Parameters.getPortName()); } catch (NoSuchPortException e) { - if(Modbus.debug) System.out.println(e.getMessage()); - throw new Exception(e.getMessage()); + final String errMsg = "Could not get port identifier, maybe insufficient permissions. " + e.getMessage(); + logger.debug(errMsg); + throw new Exception(errMsg); } - //System.out.println("Got Port Identifier"); + logger.trace("Got Port Identifier"); //2. open the port, wait for given timeout try { m_SerialPort = (SerialPort) m_PortIdentifyer.open("Modbus Serial Master", 30000); } catch (PortInUseException e) { - if(Modbus.debug) System.out.println(e.getMessage()); + logger.debug("open port failed: " + e.getMessage()); throw new Exception(e.getMessage()); } - //System.out.println("Got Serial Port"); + logger.trace("Got Serial Port"); //3. set the parameters @@ -124,7 +127,7 @@ public void open() throws Exception { } catch (Exception e) { //ensure it is closed m_SerialPort.close(); - if(Modbus.debug) System.out.println(e.getMessage()); + logger.debug("parameter setup failed: " + e.getMessage()); throw e; } @@ -147,19 +150,20 @@ public void open() throws Exception { // m_SerialPort.getOutputStream()); } catch (IOException e) { m_SerialPort.close(); - if(Modbus.debug) System.out.println(e.getMessage()); + logger.debug(e.getMessage()); throw new Exception("Error opening i/o streams"); } - //System.out.println("i/o Streams prepared"); + logger.trace("i/o Streams prepared"); // Add this object as an event listener for the serial port. try { m_SerialPort.addEventListener(this); } catch (TooManyListenersException e) { m_SerialPort.close(); - if(Modbus.debug) System.out.println(e.getMessage()); - throw new Exception("too many listeners added"); + final String errMsg = "too many listeners added"; + logger.debug("{}: {}", errMsg, e.getMessage()); + throw new Exception(errMsg); } // Set notifyOnBreakInterrup to allow event driven break handling. @@ -175,7 +179,7 @@ public void setReceiveTimeout(int ms) { try { m_SerialPort.enableReceiveTimeout(ms); } catch (UnsupportedCommOperationException e) { - if(Modbus.debug) System.out.println(e.getMessage()); + logger.error("Failed to set receive timeout: {}", e.getMessage()); } }//setReceiveTimeout /** @@ -207,9 +211,11 @@ public void setConnectionParameters() throws Exception { m_Parameters.setDatabits(oldDatabits); m_Parameters.setStopbits(oldStopbits); m_Parameters.setParity(oldParity); - if(Modbus.debug) System.out.println(e.getMessage()); + final String errMsg = "Unsupported parameter"; + logger.debug("{} failed to set up one of [baudRate, dataBits, stopBits, parity]: {}", + errMsg, e.getMessage()); - throw new Exception("Unsupported parameter"); + throw new Exception(errMsg); } // Set flow control. @@ -217,9 +223,10 @@ public void setConnectionParameters() throws Exception { m_SerialPort.setFlowControlMode(m_Parameters.getFlowControlIn() | m_Parameters.getFlowControlOut()); } catch (UnsupportedCommOperationException e) { - if(Modbus.debug) System.out.println(e.getMessage()); + final String errMsg = "Unsupported flow control"; + logger.debug("{}: {}", errMsg, e.getMessage()); - throw new Exception("Unsupported flow control"); + throw new Exception(errMsg); } }//setConnectionParameters @@ -238,7 +245,7 @@ public void close() { m_Transport.close(); m_SerialIn.close(); } catch (IOException e) { - System.err.println(e); + logger.error(e.getMessage()); } // Close the port. m_SerialPort.close(); @@ -272,7 +279,7 @@ public void serialEvent(SerialPortEvent e) { } amount = m_SerialIn.available(); } catch (IOException ex) { - System.err.println("Error: Comm event read: " + ex); + logger.error("Error: Comm event read: {}", ex); ex.printStackTrace(); return; } @@ -284,10 +291,10 @@ public void serialEvent(SerialPortEvent e) { */ break; case SerialPortEvent.BI: - if (Modbus.debug) System.out.println("Serial port break detected"); + logger.debug("Serial port break detected"); break; default: - if (Modbus.debug) System.out.println("Serial port event: " + e.getEventType()); + logger.debug("Serial port event: {}", e.getEventType()); } }//serialEvent diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPConnectionHandler.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPConnectionHandler.java index d9d5dc52ea2..7a8a7409478 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPConnectionHandler.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPConnectionHandler.java @@ -16,6 +16,9 @@ package net.wimpi.modbus.net; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.wimpi.modbus.Modbus; import net.wimpi.modbus.ModbusCoupler; import net.wimpi.modbus.ModbusIOException; @@ -30,6 +33,7 @@ * @version @version@ (@date@) */ public class TCPConnectionHandler implements Runnable { + private static final Logger logger = LoggerFactory.getLogger(TCPConnectionHandler.class); private TCPSlaveConnection m_Connection; private ModbusTransport m_Transport; @@ -59,7 +63,7 @@ public void run() { do { //1. read the request ModbusRequest request = m_Transport.readRequest(); - //System.out.println("Request:" + request.getHexMessage()); + logger.trace("Request:{}", request.getHexMessage()); ModbusResponse response = null; //test if Process image exists @@ -69,11 +73,9 @@ public void run() { } else { response = request.createResponse(); } - /*DEBUG*/ - if (Modbus.debug) System.out.println("Request:" + request.getHexMessage()); - if (Modbus.debug) System.out.println("Response:" + response.getHexMessage()); + logger.debug("Request:{}", request.getHexMessage()); + logger.debug("Response:{}", response.getHexMessage()); - //System.out.println("Response:" + response.getHexMessage()); m_Transport.writeMessage(response); } while (true); } catch (ModbusIOException ex) { diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPMasterConnection.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPMasterConnection.java index 21444ee31f7..4182bcc8e01 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPMasterConnection.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPMasterConnection.java @@ -20,6 +20,9 @@ import java.net.InetAddress; import java.net.Socket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.wimpi.modbus.Modbus; import net.wimpi.modbus.io.ModbusTCPTransport; import net.wimpi.modbus.io.ModbusTransport; @@ -31,6 +34,7 @@ * @version @version@ (@date@) */ public class TCPMasterConnection { + private static final Logger logger = LoggerFactory.getLogger(TCPMasterConnection.class); //instance attributes private Socket m_Socket; @@ -61,7 +65,7 @@ public TCPMasterConnection(InetAddress adr) { public synchronized void connect() throws Exception { if(!m_Connected) { - if(Modbus.debug) System.out.println("connect()"); + logger.debug("connect()"); m_Socket = new Socket(m_Address, m_Port); setTimeout(m_Timeout); prepareTransport(); @@ -77,7 +81,7 @@ public void close() { try { m_ModbusTransport.close(); } catch (IOException ex) { - if(Modbus.debug) System.out.println("close()"); + logger.debug("close()"); } m_Connected = false; } diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPSlaveConnection.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPSlaveConnection.java index 04445d8b408..607355e3bc4 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPSlaveConnection.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/TCPSlaveConnection.java @@ -20,6 +20,9 @@ import java.net.InetAddress; import java.net.Socket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.wimpi.modbus.Modbus; import net.wimpi.modbus.io.ModbusTCPTransport; import net.wimpi.modbus.io.ModbusTransport; @@ -31,6 +34,7 @@ * @version @version@ (@date@) */ public class TCPSlaveConnection { + private static final Logger logger = LoggerFactory.getLogger(TCPSlaveConnection.class); //instance attributes private Socket m_Socket; @@ -48,9 +52,10 @@ public TCPSlaveConnection(Socket socket) { try { setSocket(socket); } catch (IOException ex) { - if(Modbus.debug) System.out.println("TCPSlaveConnection::Socket invalid."); + final String errMsg = "Socket invalid"; + logger.debug(errMsg); //@commentstart@ - throw new IllegalStateException("Socket invalid."); + throw new IllegalStateException(errMsg); //@commentend@ } }//constructor diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/UDPMasterTerminal.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/UDPMasterTerminal.java index 241dc62d790..424348f3cf8 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/UDPMasterTerminal.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/UDPMasterTerminal.java @@ -20,6 +20,9 @@ import java.net.DatagramSocket; import java.net.InetAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.wimpi.modbus.Modbus; import net.wimpi.modbus.io.ModbusUDPTransport; @@ -31,6 +34,7 @@ */ class UDPMasterTerminal implements UDPTerminal { + private static final Logger logger = LoggerFactory.getLogger(UDPMasterTerminal.class); private DatagramSocket m_Socket; private int m_Timeout = Modbus.DEFAULT_TIMEOUT; @@ -122,7 +126,8 @@ public boolean isActive() { public synchronized void activate() throws Exception { if (!isActive()) { - if (Modbus.debug) System.out.println("UDPMasterTerminal::activate()::laddr=:" + m_LocalAddress.toString() + ":lport=" + m_LocalPort); + logger.debug("UDPMasterTerminal::activate()::laddr=:{}:lport={}", m_LocalAddress.toString(), m_LocalPort); + if (m_Socket == null) { if (m_LocalAddress != null && m_LocalPort != -1) { m_Socket = new DatagramSocket(m_LocalPort, m_LocalAddress); @@ -132,9 +137,9 @@ public synchronized void activate() m_LocalAddress = m_Socket.getLocalAddress(); } } - if (Modbus.debug) System.out.println("UDPMasterTerminal::haveSocket():" + m_Socket.toString()); - if (Modbus.debug) System.out.println("UDPMasterTerminal::laddr=:" + m_LocalAddress.toString() + ":lport=" + m_LocalPort); - if (Modbus.debug) System.out.println("UDPMasterTerminal::raddr=:" + m_RemoteAddress.toString() + ":rport=" + m_RemotePort); + logger.debug("UDPMasterTerminal::haveSocket():{}", m_Socket.toString()); + logger.debug("UDPMasterTerminal::laddr=:{}:lport={}", m_LocalAddress.toString(), m_LocalPort); + logger.debug("UDPMasterTerminal::raddr=:{}:rport={}", m_RemoteAddress.toString(), m_RemotePort); m_Socket.setReceiveBufferSize(1024); m_Socket.setSendBufferSize(1024); @@ -142,7 +147,7 @@ public synchronized void activate() m_ModbusTransport = new ModbusUDPTransport(this); m_Active = true; } - if (Modbus.debug) System.out.println("UDPMasterTerminal::activated"); + logger.info("UDPMasterTerminal::activated"); }//activate /** @@ -150,7 +155,7 @@ public synchronized void activate() */ public void deactivate() { try { - if (Modbus.debug) System.out.println("UDPMasterTerminal::deactivate()"); + logger.debug("UDPMasterTerminal::deactivate()"); //close socket m_Socket.close(); m_ModbusTransport = null; diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/UDPSlaveTerminal.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/UDPSlaveTerminal.java index b90ae903bde..9a8c7196e63 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/UDPSlaveTerminal.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/net/UDPSlaveTerminal.java @@ -26,6 +26,9 @@ import java.net.InetAddress; import java.util.Hashtable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Class implementing a UDPSlaveTerminal. * @@ -34,6 +37,7 @@ */ class UDPSlaveTerminal implements UDPTerminal { + private static final Logger logger = LoggerFactory.getLogger(UDPSlaveTerminal.class); //instance attributes private DatagramSocket m_Socket; @@ -97,7 +101,7 @@ public boolean isActive() { public synchronized void activate() throws Exception { if (!isActive()) { - if (Modbus.debug) System.out.println("UDPSlaveTerminal::activate()"); + logger.debug("UDPSlaveTerminal::activate()"); if (m_Socket == null) { if (m_LocalAddress != null && m_LocalPort != -1) { m_Socket = new DatagramSocket(m_LocalPort, m_LocalAddress); @@ -107,8 +111,10 @@ public synchronized void activate() m_LocalAddress = m_Socket.getLocalAddress(); } } - if (Modbus.debug) System.out.println("UDPSlaveTerminal::haveSocket():" + m_Socket.toString()); - if (Modbus.debug) System.out.println("UDPSlaveTerminal::addr=:" + m_LocalAddress.toString() + ":port=" + m_LocalPort); + if (logger.isDebugEnabled()) { + logger.debug("UDPSlaveTerminal::haveSocket():{}", m_Socket.toString()); + logger.debug("UDPSlaveTerminal::addr=:{}:port={}", m_LocalAddress.toString(), m_LocalPort); + } m_Socket.setReceiveBufferSize(1024); @@ -116,16 +122,16 @@ public synchronized void activate() m_PacketReceiver = new PacketReceiver(); m_Receiver = new Thread(m_PacketReceiver); m_Receiver.start(); - if (Modbus.debug) System.out.println("UDPSlaveTerminal::receiver started()"); + logger.debug("UDPSlaveTerminal::receiver started()"); m_PacketSender = new PacketSender(); m_Sender = new Thread(m_PacketSender); m_Sender.start(); - if (Modbus.debug) System.out.println("UDPSlaveTerminal::sender started()"); + logger.debug("UDPSlaveTerminal::sender started()"); m_ModbusTransport = new ModbusUDPTransport(this); - if (Modbus.debug) System.out.println("UDPSlaveTerminal::transport created"); + logger.debug("UDPSlaveTerminal::transport created"); m_Active = true; } - if (Modbus.debug) System.out.println("UDPSlaveTerminal::activated"); + logger.info("UDPSlaveTerminal::activated"); }//activate /** @@ -239,7 +245,7 @@ public void run() { req.getAddress(), req.getPort()); m_Socket.send(res); - if (Modbus.debug) System.out.println("Sent package from queue."); + logger.trace("Sent package from queue"); } catch (Exception ex) { DEBUG:ex.printStackTrace(); } @@ -273,7 +279,7 @@ public void run() { m_Requests.put(tid, packet); //3. place the data buffer in the queue m_ReceiveQueue.put(buffer); - if (Modbus.debug) System.out.println("Received package to queue."); + logger.trace("Received package placed in queue"); } catch (Exception ex) { DEBUG:ex.printStackTrace(); } diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/BitVector.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/BitVector.java index 665dc83a26f..f10acc365a9 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/BitVector.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/BitVector.java @@ -16,6 +16,8 @@ package net.wimpi.modbus.util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Class that implements a collection for @@ -27,6 +29,7 @@ * @version @version@ (@date@) */ public final class BitVector { + private static final Logger logger = LoggerFactory.getLogger(BitVector.class); //instance attributes private int m_Size; @@ -131,7 +134,7 @@ public final void setBytes(byte[] data, int size) { public final boolean getBit(int index) throws IndexOutOfBoundsException { index = translateIndex(index); - //System.out.println("Get bit #" + index); + logger.trace("Get bit #{}", index); return ( (m_Data[byteIndex(index)] & (0x01 << bitIndex(index))) != 0 @@ -151,7 +154,7 @@ public final boolean getBit(int index) public final void setBit(int index, boolean b) throws IndexOutOfBoundsException { index = translateIndex(index); - //System.out.println("Set bit #"+index); + logger.trace("Set bit #{}", index); int value = ((b) ? 1 : 0); int byteNum = byteIndex(index); int bitNum = bitIndex(index); diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/SerialParameterValidator.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/SerialParameterValidator.java new file mode 100644 index 00000000000..520504a66ac --- /dev/null +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/SerialParameterValidator.java @@ -0,0 +1,70 @@ +/*** +Copyright (c) 2010-${year}, openHAB.org and others. + +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 net.wimpi.modbus.util; +import gnu.io.SerialPort; + +import java.util.Arrays; + +import net.wimpi.modbus.Modbus; + +/** + * Data validation helper encapsulation for the + * modbus.util.SerialParameters class + * + * @author Nick Mayerhofer + */ +public class SerialParameterValidator { + public static final Integer[] COMMON_BAUD_RATES = { 75, 110, 300, 1200, + 2400, 4800, 9600, 19200, 38400, 57600, 115200 }; + /** + * validating the given baudRate + * + * @param baudRate value to be checked + * @return whether if the value is valid or not + */ + public static boolean isBaudRateValid(int baudRate) { + return Arrays.asList(COMMON_BAUD_RATES).contains(baudRate); + } + + public static boolean isDataBitsValid(int databits) { + return (databits >= SerialPort.DATABITS_5) && (databits <= SerialPort.DATABITS_8); + } + + public static final Double[] VALID_STOP_BITS = {1.0, 1.5, 2.0}; + public static boolean isStopbitsValid(double stopbits) { + return Arrays.asList(VALID_STOP_BITS).contains(stopbits); + } + + public static final Integer[] VALID_PARITYS = { SerialPort.PARITY_NONE, + SerialPort.PARITY_EVEN, SerialPort.PARITY_ODD }; + public static boolean isParityValid(int parity) { + return Arrays.asList(VALID_PARITYS).contains(parity); + } + + public static boolean isEncodingValid(String enc) { + return Arrays.asList(Modbus.validSerialEncodings).contains(enc); + } + + public static boolean isReceiveTimeoutValid(int receiveTimeout) { + return (receiveTimeout > 0); + } + + public static final String[] VALID_FLOWCONTROL_STRINGS = { "none", + "xon/xoff out", "xon/xoff in", "rts/cts in", "rts/cts out" }; + public static boolean isFlowControlValid(String flowcontrol) { + return Arrays.asList(VALID_FLOWCONTROL_STRINGS).contains(flowcontrol); + } + + public static final Integer[] VALID_FLOWCONTROL_INT = { 0, (1 << 0), + (1 << 1), (1 << 2), (1 << 3) }; + public static boolean isFlowControlValid(int flowcontrol) { + return Arrays.asList(VALID_FLOWCONTROL_INT).contains(flowcontrol); + } +} diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/SerialParameters.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/SerialParameters.java index 02a8f0319d1..36b42d6273f 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/SerialParameters.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/SerialParameters.java @@ -16,11 +16,12 @@ package net.wimpi.modbus.util; -import net.wimpi.modbus.Modbus; - import gnu.io.SerialPort; + import java.util.Properties; +import net.wimpi.modbus.Modbus; + /** * Helper class wrapping all serial port communication parameters. * Very similar to the gnu.io demos, however, not the same. @@ -45,7 +46,7 @@ public class SerialParameters { /** * Constructs a new SerialParameters instance with - * default values. + * default values: 9600 boud - 8N1 - ASCII. */ public SerialParameters() { m_PortName = ""; @@ -141,7 +142,10 @@ public String getPortName() { * * @param rate the new baud rate. */ - public void setBaudRate(int rate) { + public void setBaudRate(int rate) throws IllegalArgumentException { + if ( !SerialParameterValidator.isBaudRateValid(rate)) { + throw new IllegalArgumentException("invalid baud rate: " + Integer.toString(rate)); + } m_BaudRate = rate; }//setBaudRate @@ -150,8 +154,15 @@ public void setBaudRate(int rate) { * * @param rate the new baud rate. */ - public void setBaudRate(String rate) { - m_BaudRate = Integer.parseInt(rate); + public void setBaudRate(String rate) throws IllegalArgumentException { + int intBaudRate = 0; + try { + intBaudRate = Integer.parseInt(rate); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("baudString '" + rate + + "' can not be converted to a number: " + e.getMessage()); + } + setBaudRate(intBaudRate); }//setBaudRate /** @@ -178,7 +189,12 @@ public String getBaudRateString() { * * @param flowcontrol the new flow control type. */ - public void setFlowControlIn(int flowcontrol) { + public void setFlowControlIn(int flowcontrol) throws IllegalArgumentException { + if (!SerialParameterValidator.isFlowControlValid(flowcontrol)) { + throw new IllegalArgumentException("flowcontrol int '" + + flowcontrol + "' invalid"); + } + m_FlowControlIn = flowcontrol; }//setFlowControl @@ -188,8 +204,13 @@ public void setFlowControlIn(int flowcontrol) { * * @param flowcontrol the flow control for reading type. */ - public void setFlowControlIn(String flowcontrol) { - m_FlowControlIn = stringToFlow(flowcontrol); + public void setFlowControlIn(String flowcontrol) throws IllegalArgumentException { + if (!SerialParameterValidator.isFlowControlValid(flowcontrol)) { + throw new IllegalArgumentException("flowcontrolIn string '" + + flowcontrol + "' unknown"); + } + + setFlowControlIn(stringToFlow(flowcontrol)); }//setFlowControlIn /** @@ -216,7 +237,12 @@ public String getFlowControlInString() { * * @param flowControlOut new output flow control type as int. */ - public void setFlowControlOut(int flowControlOut) { + public void setFlowControlOut(int flowControlOut) throws IllegalArgumentException { + if (!SerialParameterValidator.isFlowControlValid(flowControlOut)) { + throw new IllegalArgumentException("flowcontrol int '" + + flowControlOut + "' unknown"); + } + m_FlowControlOut = flowControlOut; }//setFlowControlOut @@ -226,7 +252,12 @@ public void setFlowControlOut(int flowControlOut) { * * @param flowControlOut the new output flow control type as String. */ - public void setFlowControlOut(String flowControlOut) { + public void setFlowControlOut(String flowControlOut) throws IllegalArgumentException { + if (!SerialParameterValidator.isFlowControlValid(flowControlOut)) { + throw new IllegalArgumentException("flowcontrol string '" + + flowControlOut + "' unknown"); + } + m_FlowControlOut = stringToFlow(flowControlOut); }//setFlowControlOut @@ -253,8 +284,28 @@ public String getFlowControlOutString() { * * @param databits the new number of data bits. */ - public void setDatabits(int databits) { - m_Databits = databits; + public void setDatabits(int databits) throws IllegalArgumentException { + if (!SerialParameterValidator.isDataBitsValid(databits)) { + throw new IllegalArgumentException("Databit '" + databits + "' invalid"); + } + + switch (databits) { + case 5: + m_Databits = SerialPort.DATABITS_5; + break; + case 6: + m_Databits = SerialPort.DATABITS_6; + break; + case 7: + m_Databits = SerialPort.DATABITS_7; + break; + case 8: + m_Databits = SerialPort.DATABITS_8; + break; + default: + m_Databits = SerialPort.DATABITS_8; + break; + } }//setDatabits /** @@ -262,19 +313,16 @@ public void setDatabits(int databits) { * * @param databits the new number of data bits as String. */ - public void setDatabits(String databits) { - if (databits.equals("5")) { - m_Databits = SerialPort.DATABITS_5; - } - if (databits.equals("6")) { - m_Databits = SerialPort.DATABITS_6; - } - if (databits.equals("7")) { - m_Databits = SerialPort.DATABITS_7; - } - if (databits.equals("8")) { - m_Databits = SerialPort.DATABITS_8; + public void setDatabits(String databits) throws IllegalArgumentException { + int intDataBits = 0; + try { + intDataBits = Integer.parseInt(databits); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("databitsString '" + databits + + "' can not be converted to a number: " + e.getMessage()); } + + setDatabits(intDataBits); }//setDatabits /** @@ -311,8 +359,21 @@ public String getDatabitsString() { * * @param stopbits the new number of stop bits setting. */ - public void setStopbits(int stopbits) { - m_Stopbits = stopbits; + public void setStopbits(double stopbits) throws IllegalArgumentException { + if (!SerialParameterValidator.isStopbitsValid(stopbits)) { + throw new IllegalArgumentException("stopbit value '" + + stopbits + "' not valid"); + } + + if (stopbits == 1) { + m_Stopbits = SerialPort.STOPBITS_1; + } else if (stopbits == 1.5) { + m_Stopbits = SerialPort.STOPBITS_1_5; + } else if (stopbits == 2) { + m_Stopbits = SerialPort.STOPBITS_2; + } else { + m_Stopbits = SerialPort.STOPBITS_1; + } }//setStopbits /** @@ -320,16 +381,16 @@ public void setStopbits(int stopbits) { * * @param stopbits the number of stop bits as String. */ - public void setStopbits(String stopbits) { - if (stopbits.equals("1")) { - m_Stopbits = SerialPort.STOPBITS_1; - } - if (stopbits.equals("1.5")) { - m_Stopbits = SerialPort.STOPBITS_1_5; - } - if (stopbits.equals("2")) { - m_Stopbits = SerialPort.STOPBITS_2; + public void setStopbits(String stopbits) throws IllegalArgumentException { + double doubleStopBits = 1.0; + try { + doubleStopBits = Double.parseDouble(stopbits); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("stopbitsString '" + stopbits + + "' can not be converted to a number: " + e.getMessage()); } + + setStopbits(doubleStopBits); }//setStopbits /** @@ -365,6 +426,10 @@ public String getStopbitsString() { * @param parity the new parity schema as int. */ public void setParity(int parity) { + if (!SerialParameterValidator.isParityValid(parity)) { + throw new IllegalArgumentException("parity value '" + + parity + "' not valid"); + } m_Parity = parity; }//setParity @@ -374,17 +439,22 @@ public void setParity(int parity) { * * @param parity the new parity schema as String. */ - public void setParity(String parity) { + public void setParity(String parity) throws IllegalArgumentException { parity = parity.toLowerCase(); - if (parity.equals("none")) { - m_Parity = SerialPort.PARITY_NONE; - } - if (parity.equals("even")) { - m_Parity = SerialPort.PARITY_EVEN; - } - if (parity.equals("odd")) { - m_Parity = SerialPort.PARITY_ODD; + int intParity = SerialPort.PARITY_NONE; + + if (parity.equals("none") || parity.equals("n")) { + intParity = SerialPort.PARITY_NONE; + } else if (parity.equals("even") || parity.equals("e")) { + intParity = SerialPort.PARITY_EVEN; + } else if (parity.equals("odd") || parity.equals("o")) { + intParity = SerialPort.PARITY_ODD; + } else { + throw new IllegalArgumentException( + "unknown parity string '" + parity + "'"); } + + setParity(intParity); }//setParity /** @@ -422,16 +492,14 @@ public String getParityString() { * @see Modbus#SERIAL_ENCODING_RTU * @see Modbus#SERIAL_ENCODING_BIN */ - public void setEncoding(String enc) { + public void setEncoding(String enc) throws IllegalArgumentException { enc = enc.toLowerCase(); - if (enc.equals(Modbus.SERIAL_ENCODING_ASCII) || - enc.equals(Modbus.SERIAL_ENCODING_RTU) || - enc.equals(Modbus.SERIAL_ENCODING_BIN) - ) { - m_Encoding = enc; - } else { - m_Encoding = Modbus.DEFAULT_SERIAL_ENCODING; + if (!SerialParameterValidator.isEncodingValid(enc)) { + throw new IllegalArgumentException("encoding value '" + enc + + "' not valid"); } + + m_Encoding = enc; }//setEncoding /** @@ -479,6 +547,11 @@ public int getReceiveTimeout() { * @param receiveTimeout the receiveTimeout in milliseconds. */ public void setReceiveTimeout(int receiveTimeout) { + if (!SerialParameterValidator.isReceiveTimeoutValid(receiveTimeout)) { + throw new IllegalArgumentException("negative values like '" + + receiveTimeout + "' invalid as timeout"); + } + m_ReceiveTimeout = receiveTimeout; }//setReceiveTimeout @@ -489,7 +562,7 @@ public void setReceiveTimeout(int receiveTimeout) { * @param str the timeout as String. */ public void setReceiveTimeout(String str) { - m_ReceiveTimeout = Integer.parseInt(str); + setReceiveTimeout(Integer.parseInt(str)); }//setReceiveTimeout /** diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/ThreadPool.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/ThreadPool.java index 89612e0620b..1a6a9896e11 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/ThreadPool.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/ThreadPool.java @@ -79,10 +79,9 @@ private class PoolThread extends Thread { * up available tasks from the LinkedQueue. */ public void run() { - //System.out.println("Running PoolThread"); + // Running PoolThread do { try { - //System.out.println(this.toString()); ((Runnable) m_TaskPool.take()).run(); } catch (Exception ex) { //FIXME: Handle somehow!? diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusBinding.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusBinding.java index 4a53de26828..74ebe3b4941 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusBinding.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusBinding.java @@ -29,6 +29,7 @@ import org.openhab.binding.modbus.internal.ModbusGenericBindingProvider.ModbusBindingConfig; import org.openhab.core.binding.AbstractActiveBinding; import org.openhab.core.binding.BindingProvider; +import org.openhab.core.library.items.NumberItem; import org.openhab.core.library.items.SwitchItem; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; @@ -55,8 +56,9 @@ public class ModbusBinding extends AbstractActiveBinding private static final String TCP_PREFIX = "tcp"; private static final String SERIAL_PREFIX = "serial"; + private static final String VALID_COFIG_KEYS = "connection|id|start|length|type|valuetype|rawdatamultiplier|writemultipleregisters"; private static final Pattern EXTRACT_MODBUS_CONFIG_PATTERN = - Pattern.compile("^("+TCP_PREFIX+"|"+UDP_PREFIX+"|"+SERIAL_PREFIX+"|)\\.(.*?)\\.(connection|id|pollInterval|start|length|type|valuetype)$"); + Pattern.compile("^("+TCP_PREFIX+"|"+UDP_PREFIX+"|"+SERIAL_PREFIX+"|)\\.(.*?)\\.(" + VALID_COFIG_KEYS + ")$"); /** Stores instances of all the slaves defined in cfg file */ private static Map modbusSlaves = new ConcurrentHashMap(); @@ -106,20 +108,30 @@ protected void internalReceiveCommand(String itemName, Command command) { protected void internalUpdateItem(String slaveName, InputRegister[] registers, String itemName) { for (ModbusBindingProvider provider : providers) { - if (provider.providesBindingFor(itemName)) { - ModbusBindingConfig config = provider.getConfig(itemName); - if (config.slaveName.equals(slaveName)) { - String slaveValueType = modbusSlaves.get(slaveName).getValueType(); + if ( !provider.providesBindingFor(itemName) ) { + continue; + } + ModbusBindingConfig config = provider.getConfig(itemName); + if ( !config.slaveName.equals(slaveName)) { + continue; + } - State newState = extractStateFromRegisters(registers, config.readRegister, slaveValueType); - if (config.getItem() instanceof SwitchItem) { - newState = newState.equals(DecimalType.ZERO) ? OnOffType.OFF : OnOffType.ON; - } + String slaveValueType = modbusSlaves.get(slaveName).getValueType(); + double rawDataMultiplier = modbusSlaves.get(slaveName).getRawDataMultiplier(); - State currentState = config.getItemState(); - if (! newState.equals(currentState)) - eventPublisher.postUpdate(itemName, newState); - } + State newState = extractStateFromRegisters(registers, config.readRegister, slaveValueType); + /* receive data manipulation */ + if (config.getItem() instanceof SwitchItem) { + newState = newState.equals(DecimalType.ZERO) ? OnOffType.OFF : OnOffType.ON; + } + if (( rawDataMultiplier != 1 ) && (config.getItem() instanceof NumberItem)) { + double tmpValue = (double)((DecimalType)newState).doubleValue() * rawDataMultiplier; + newState = new DecimalType( String.valueOf(tmpValue) ); + } + + State currentState = config.getItemState(); + if (! newState.equals(currentState)) { + eventPublisher.postUpdate(itemName, newState); } } } @@ -245,8 +257,8 @@ public void updated(Dictionary config) throws ConfigurationException } else if ("writemultipleregisters".equals(key)) { ModbusSlave.setWriteMultipleRegisters(Boolean.valueOf(config.get(key).toString())); } else { - logger.debug("given modbus-slave-config-key '" + key - + "' does not follow the expected pattern 'pollInterval' or '.'"); + logger.debug("given modbus-slave-config-key '{}' does not follow the expected pattern or 'serial..<{}>'", + key, VALID_COFIG_KEYS); } continue; } @@ -260,13 +272,14 @@ public void updated(Dictionary config) throws ConfigurationException if (modbusSlave == null) { if (matcher.group(1).equals(TCP_PREFIX)) { modbusSlave = new ModbusTcpSlave(slave); - } else if (matcher.group(1).equals(UDP_PREFIX)) { + } else if (matcher.group(1).equals(UDP_PREFIX)) { modbusSlave = new ModbusUdpSlave(slave); } else if (matcher.group(1).equals(SERIAL_PREFIX)) { modbusSlave = new ModbusSerialSlave(slave); } else { throw new ConfigurationException(slave, "the given slave type '" + slave + "' is unknown"); } + logger.debug("modbusSlave '{}' instanciated", slave); modbusSlaves.put(slave,modbusSlave); } @@ -276,11 +289,15 @@ public void updated(Dictionary config) throws ConfigurationException if ("connection".equals(configKey)) { String[] chunks = value.split(":"); if (modbusSlave instanceof ModbusIPSlave) { + // expecting: + // : ((ModbusIPSlave) modbusSlave).setHost(chunks[0]); if (chunks.length == 2) { ((ModbusIPSlave) modbusSlave).setPort(Integer.valueOf(chunks[1])); } } else if (modbusSlave instanceof ModbusSerialSlave) { + // expecting: + // [:::::] ((ModbusSerialSlave) modbusSlave).setPort(chunks[0]); if (chunks.length >= 2) { ((ModbusSerialSlave) modbusSlave).setBaud(Integer.valueOf(chunks[1])); @@ -291,8 +308,11 @@ public void updated(Dictionary config) throws ConfigurationException if (chunks.length >= 4) { ((ModbusSerialSlave) modbusSlave).setParity(chunks[3]); } - if (chunks.length == 5) { - ((ModbusSerialSlave) modbusSlave).setStopbits(Integer.valueOf(chunks[4])); + if (chunks.length >= 5) { + ((ModbusSerialSlave) modbusSlave).setStopbits(Double.valueOf(chunks[4])); + } + if (chunks.length == 6) { + ((ModbusSerialSlave) modbusSlave).setEncoding(chunks[5]); } } } else if ("start".equals(configKey)) { @@ -313,12 +333,15 @@ public void updated(Dictionary config) throws ConfigurationException } else { throw new ConfigurationException(configKey, "the given value type '" + value + "' is invalid"); } + } else if ("rawdatamultiplier".equals(configKey)) { + modbusSlave.setRawDataMultiplier(Double.valueOf(value.toString()) ); } else { throw new ConfigurationException(configKey, "the given configKey '" + configKey + "' is unknown"); } } + logger.debug("config looked good, proceeding with slave-connections"); // connect instances to modbus slaves for (ModbusSlave slave : modbusSlaves.values()) { slave.connect(); diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusGenericBindingProvider.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusGenericBindingProvider.java index 6fa8a61e8a3..a32b83256a2 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusGenericBindingProvider.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusGenericBindingProvider.java @@ -85,7 +85,7 @@ public void processBindingConfiguration(String context, Item item, String bindin addBindingConfig(item, config); } else { - logger.warn("bindingConfig is NULL (item=" + item + ") -> processing bindingConfig aborted!"); + logger.warn("bindingConfig is NULL (item={}) -> processing bindingConfig aborted!", item); } } diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusSerialSlave.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusSerialSlave.java index 0809cf21d3d..9c96cab0a6a 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusSerialSlave.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusSerialSlave.java @@ -8,12 +8,7 @@ */ package org.openhab.binding.modbus.internal; -import java.util.Enumeration; - -import gnu.io.CommPortIdentifier; - import net.wimpi.modbus.Modbus; -import net.wimpi.modbus.ModbusCoupler; import net.wimpi.modbus.io.ModbusSerialTransaction; import net.wimpi.modbus.net.SerialConnection; import net.wimpi.modbus.util.SerialParameters; @@ -33,33 +28,62 @@ public class ModbusSerialSlave extends ModbusSlave { private static final Logger logger = LoggerFactory.getLogger(ModbusSerialSlave.class); + //TODO replace through a none static modbus.utils.SerialParameters instance private static String port = null; private static int baud = 9600; private static int dataBits = 8; private static String parity = "None"; // "none", "even" or "odd" - private static int stopBits = 1; + private static Double stopBits = 1.0; + private static String serialEncoding = Modbus.DEFAULT_SERIAL_ENCODING; public void setPort(String port) { + if ((port != null) && (ModbusSerialSlave.port != port)) { + logger.debug("overriding modbus port: " + ModbusSerialSlave.port + + " by: " + port + + "but there is currently only one port supported"); + } ModbusSerialSlave.port = port; } public void setBaud(int baud) { + //TODO replace by modbus.utils.SerialParameters setter ModbusSerialSlave.baud = baud; } public void setDatabits(int dataBits) { + //TODO replace by modbus.utils.SerialParameters setter ModbusSerialSlave.dataBits = dataBits; } // Parity string should be "none", "even" or "odd" public void setParity(String parity) { + //TODO replace by modbus.utils.SerialParameters setter ModbusSerialSlave.parity = parity; } - public void setStopbits(int stopBits) { + public void setStopbits(Double stopBits) { + //TODO replace by modbus.utils.SerialParameters setter ModbusSerialSlave.stopBits = stopBits; } - // String port = null; + + private boolean isEncodingValid(String serialEncoding) { + for (String str : Modbus.validSerialEncodings) { + if (str.trim().contains(serialEncoding)) + return true; + } + return false; + } + + public void setEncoding(String serialEncoding) { + serialEncoding = serialEncoding.toLowerCase(); + + //TODO replace by modbus.utils.SerialParameters setter + if ( isEncodingValid(serialEncoding) ) { + ModbusSerialSlave.serialEncoding = serialEncoding; + } else { + logger.info("Encoding '{}' is unknown", serialEncoding); + } + } private static SerialConnection connection = null; @@ -90,23 +114,23 @@ public boolean connect() { // } if (connection == null) { + logger.debug("connection was null, going to create a new one"); SerialParameters params = new SerialParameters(); params.setPortName(port); params.setBaudRate(baud); params.setDatabits(dataBits); params.setParity(parity); params.setStopbits(stopBits); - params.setEncoding(Modbus.SERIAL_ENCODING_RTU); + params.setEncoding(serialEncoding); params.setEcho(false); connection = new SerialConnection(params); - connection.open(); } if (!connection.isOpen()) { connection.open(); } ((ModbusSerialTransaction)transaction).setSerialConnection(connection); } catch (Exception e) { - logger.debug("ModbusSlave: Error connecting to master: " + e.getMessage()); + logger.error("ModbusSlave: Error connecting to master: {}", e.getMessage()); return false; } return true; diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusSlave.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusSlave.java index ea702a18e32..b2f3b38b340 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusSlave.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusSlave.java @@ -84,6 +84,16 @@ public static void setWriteMultipleRegisters(boolean setwmr) { */ private String valueType = ModbusBindingProvider.VALUE_TYPE_UINT16; + /** + * A multiplier for the raw incoming data + * @note rawMultiplier can also be used for divisions, by simply + * setting the value smaller than zero. + * + * E.g.: + * - data/100 ... rawDataMultiplier=0.01 + */ + private double rawDataMultiplier = 1.0; + private Object storage; protected ModbusTransaction transaction = null; @@ -203,10 +213,11 @@ else if (command.equals(OnOffType.OFF)) transaction.setRequest(request); try { - logger.debug("ModbusSlave: FC" +request.getFunctionCode()+" ref=" + writeRegister + " value=" + newValue.getValue()); + logger.debug("ModbusSlave: FC{} ref={} value={}", + request.getFunctionCode(), writeRegister, newValue.getValue()); transaction.execute(); } catch (Exception e) { - logger.debug("ModbusSlave:" + e.getMessage()); + logger.debug("ModbusSlave: {}", e.getMessage()); return; } } @@ -232,10 +243,10 @@ public void doSetCoil(int writeRegister, boolean b) { request.setUnitID(getId()); transaction.setRequest(request); try { - logger.debug("ModbusSlave: FC05 ref=" + writeRegister + " value=" + b); + logger.debug("ModbusSlave: FC05 ref={} value={}", writeRegister, b); transaction.execute(); } catch (Exception e) { - logger.debug("ModbusSlave:" + e.getMessage()); + logger.debug("ModbusSlave:{}", e.getMessage()); return; } } @@ -323,7 +334,7 @@ private ModbusResponse getModbusData(ModbusRequest request) { try { transaction.execute(); } catch (Exception e) { - logger.debug("ModbusSlave:" + e.getMessage()); + logger.debug("ModbusSlave:{}", e.getMessage()); return null; } @@ -375,4 +386,11 @@ void setValueType(String valueType) { this.valueType = valueType; } + void setRawDataMultiplier(double value) { + this.rawDataMultiplier = value; + } + + double getRawDataMultiplier() { + return rawDataMultiplier; + } } diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusTcpSlave.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusTcpSlave.java index 28a449fb589..fe3f82b5d91 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusTcpSlave.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusTcpSlave.java @@ -54,7 +54,7 @@ public boolean connect() { if (connection == null) connection = new TCPMasterConnection(InetAddress.getByName(getHost())); } catch (UnknownHostException e) { - logger.debug("ModbusSlave: Error connecting to master: " + e.getMessage()); + logger.debug("ModbusSlave: Error connecting to master: {}", e.getMessage()); connection = null; return false; } @@ -65,7 +65,7 @@ public boolean connect() { ((ModbusTCPTransaction)transaction).setConnection(connection); ((ModbusTCPTransaction)transaction).setReconnecting(false); } catch (Exception e) { - logger.debug("ModbusSlave: Error connecting to master: " + e.getMessage()); + logger.debug("ModbusSlave: Error connecting to master: {}", e.getMessage()); return false; } return true; diff --git a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusUdpSlave.java b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusUdpSlave.java index 72ac2b440c1..13cb11b3b10 100644 --- a/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusUdpSlave.java +++ b/bundles/binding/org.openhab.binding.modbus/src/main/java/org/openhab/binding/modbus/internal/ModbusUdpSlave.java @@ -46,7 +46,7 @@ public boolean connect() { if (connection == null) connection = new UDPMasterConnection(InetAddress.getByName(getHost())); } catch (UnknownHostException e) { - logger.debug("ModbusSlave: Error connecting to master: " + e.getMessage()); + logger.debug("ModbusSlave: Error connecting to master: {}", e.getMessage()); connection = null; return false; } @@ -56,7 +56,7 @@ public boolean connect() { connection.connect(); ((ModbusUDPTransaction)transaction).setTerminal(connection.getTerminal()); } catch (Exception e) { - logger.debug("ModbusSlave: Error connecting to master: " + e.getMessage()); + logger.debug("ModbusSlave: Error connecting to master: {}", e.getMessage()); return false; } return true; diff --git a/bundles/binding/org.openhab.binding.nest/.classpath b/bundles/binding/org.openhab.binding.nest/.classpath new file mode 100644 index 00000000000..6b8b019a79d --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.nest/.project b/bundles/binding/org.openhab.binding.nest/.project new file mode 100644 index 00000000000..1eb17812266 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/.project @@ -0,0 +1,33 @@ + + + org.openhab.binding.nest + This is the Nest binding of the open Home Automation Bus (openHAB) + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/bundles/binding/org.openhab.binding.nest/.settings/org.eclipse.jdt.core.prefs b/bundles/binding/org.openhab.binding.nest/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..f42de363afa --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/bundles/binding/org.openhab.binding.nest/.settings/org.eclipse.jdt.ui.prefs b/bundles/binding/org.openhab.binding.nest/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000000..243459222cb --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.ui.javadoc=false +org.eclipse.jdt.ui.text.custom_code_templates= diff --git a/bundles/binding/org.openhab.binding.nest/META-INF/MANIFEST.MF b/bundles/binding/org.openhab.binding.nest/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..c6185c0a209 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/META-INF/MANIFEST.MF @@ -0,0 +1,47 @@ +Manifest-Version: 1.0 +Private-Package: org.openhab.binding.nest.internal +Ignore-Package: org.openhab.binding.nest.internal +Bundle-License: http://www.eclipse.org/legal/epl-v10.html +Bundle-Name: openHAB Nest Binding +Bundle-SymbolicName: org.openhab.binding.nest +Bundle-Vendor: openHAB.org +Bundle-Version: 1.7.0.qualifier +Bundle-Activator: org.openhab.binding.nest.internal.NestActivator +Bundle-ManifestVersion: 2 +Bundle-Description: This is the Nest binding of the open Home Aut + omation Bus (openHAB) +Import-Package: com.google.common.base, + com.google.common.io, + org.apache.commons.httpclient, + org.apache.commons.httpclient.auth, + org.apache.commons.httpclient.methods, + org.apache.commons.httpclient.params, + org.apache.commons.httpclient.util, + org.apache.commons.io, + org.apache.commons.lang, + org.apache.commons.lang.builder, + org.apache.commons.logging, + org.codehaus.jackson, + org.codehaus.jackson.annotate, + org.codehaus.jackson.map, + org.openhab.binding.nest, + org.openhab.core.binding, + org.openhab.core.events, + org.openhab.core.items, + org.openhab.core.library.items, + org.openhab.core.library.types, + org.openhab.core.types, + org.openhab.io.net.http, + org.openhab.model.item.binding, + org.osgi.framework, + org.osgi.service.cm, + org.osgi.service.component, + org.osgi.service.event, + org.slf4j +Export-Package: org.openhab.binding.nest +Bundle-DocURL: http://www.openhab.org +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Service-Component: OSGI-INF/binding.xml, OSGI-INF/genericbindingprovider.xml +Bundle-ClassPath: lib/commons-beanutils-1.8.3.jar, + . +Require-Bundle: org.openhab.io.rest.lib diff --git a/bundles/binding/org.openhab.binding.nest/OSGI-INF/binding.xml b/bundles/binding/org.openhab.binding.nest/OSGI-INF/binding.xml new file mode 100644 index 00000000000..f8b1c83f6b8 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/OSGI-INF/binding.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.nest/OSGI-INF/genericbindingprovider.xml b/bundles/binding/org.openhab.binding.nest/OSGI-INF/genericbindingprovider.xml new file mode 100644 index 00000000000..b6a5b27f531 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/OSGI-INF/genericbindingprovider.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.nest/build.properties b/bundles/binding/org.openhab.binding.nest/build.properties new file mode 100644 index 00000000000..008e33bdc67 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/build.properties @@ -0,0 +1,7 @@ +source.. = src/main/java/,\ + src/main/resources/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/,\ + lib/commons-beanutils-1.8.3.jar +output.. = target/classes/ diff --git a/bundles/binding/org.openhab.binding.nest/lib/commons-beanutils-1.8.3.jar b/bundles/binding/org.openhab.binding.nest/lib/commons-beanutils-1.8.3.jar new file mode 100644 index 00000000000..218510bc5d6 Binary files /dev/null and b/bundles/binding/org.openhab.binding.nest/lib/commons-beanutils-1.8.3.jar differ diff --git a/bundles/binding/org.openhab.binding.nest/pom.xml b/bundles/binding/org.openhab.binding.nest/pom.xml new file mode 100644 index 00000000000..a95dc11e7a5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/pom.xml @@ -0,0 +1,35 @@ + + + + + org.openhab.bundles + binding + 1.7.0-SNAPSHOT + + + + org.openhab.binding.nest + org.openhab.binding.nest + openhab-addon-binding-nest + openhab addon binding Nest + + + 4.0.0 + org.openhab.binding + org.openhab.binding.nest + + openHAB Nest Binding + + eclipse-plugin + + + + + org.vafer + jdeb + + + + + diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/NestBindingProvider.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/NestBindingProvider.java new file mode 100644 index 00000000000..a92779bdd66 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/NestBindingProvider.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest; + +import org.openhab.core.binding.BindingProvider; + +/** + * This interface is implemented by classes that can provide mapping information between openHAB items and Nest items. + * + * @author John Cocula + * @since 1.7.0 + */ +public interface NestBindingProvider extends BindingProvider { + + /** + * Queries the Nest property of the given {@code itemName}. + * + * @param itemName + * the itemName to query + * @return the Nest property of the Item identified by {@code itemName} if it has a Nest binding, null + * otherwise + */ + String getProperty(String itemName); + + /** + * Queries whether this item can be read from the Nest API, for the given {@code itemName}. + * + * @param itemName + * the itemName to query + * @return true if this property can be read from the Nest API. + */ + boolean isInBound(String itemName); + + /** + * Queries whether this item can be written to the Nest API, for the given {@code itemName}. + * + * @param itemName + * the itemName to query + * @return true if this property can be written to the Nest API. + */ + boolean isOutBound(String itemName); +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestActivator.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestActivator.java new file mode 100644 index 00000000000..5a902dcbda4 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestActivator.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Extension of the default OSGi bundle activator + * + * @author John Cocula + * @since 1.7.0 + */ +public final class NestActivator implements BundleActivator { + + private static Logger logger = LoggerFactory.getLogger(NestActivator.class); + + private static BundleContext context; + + /** + * Called whenever the OSGi framework starts our bundle + */ + public void start(BundleContext bc) throws Exception { + context = bc; + logger.debug("Nest binding has been started."); + } + + /** + * Called whenever the OSGi framework stops our bundle + */ + public void stop(BundleContext bc) throws Exception { + context = null; + logger.debug("Nest binding has been stopped."); + } + + /** + * Returns the bundle context of this bundle + * + * @return the bundle context + */ + public static BundleContext getContext() { + return context; + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestBinding.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestBinding.java new file mode 100644 index 00000000000..5609894c687 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestBinding.java @@ -0,0 +1,588 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.prefs.Preferences; + +import org.openhab.binding.nest.NestBindingProvider; +import org.openhab.binding.nest.internal.messages.AccessTokenRequest; +import org.openhab.binding.nest.internal.messages.AccessTokenResponse; +import org.openhab.binding.nest.internal.messages.DataModel; +import org.openhab.binding.nest.internal.messages.DataModelRequest; +import org.openhab.binding.nest.internal.messages.DataModelResponse; +import org.openhab.binding.nest.internal.messages.UpdateDataModelRequest; + +import static org.apache.commons.lang.StringUtils.isNotBlank; + +import org.openhab.core.binding.AbstractActiveBinding; +import org.openhab.core.binding.BindingProvider; +import org.openhab.core.library.types.DateTimeType; +import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.StringType; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Binding that retrieves information about objects we're interested in every few minutes, and sends updates and + * commands to Nest as they are made. + * + * @author John Cocula + * @since 1.7.0 + */ +public class NestBinding extends AbstractActiveBinding implements ManagedService { + + private static final String DEFAULT_USER_ID = "DEFAULT_USER"; + + private static final Logger logger = LoggerFactory.getLogger(NestBinding.class); + + protected static final String CONFIG_REFRESH = "refresh"; + protected static final String CONFIG_CLIENT_ID = "client_id"; + protected static final String CONFIG_CLIENT_SECRET = "client_secret"; + protected static final String CONFIG_PIN_CODE = "pin_code"; + + /** + * the refresh interval which is used to poll values from the Nest server (optional, defaults to 60000ms) + */ + private long refreshInterval = 60000; + + /** + * A map of userids from the openhab.cfg file to OAuth credentials used to communicate with each app instance. + * Multiple accounts is not implemented in the Nest binding due to the current prohibition 3 in the Terms of + * Service, but some code is here for if/when that restriction is lifted. + */ + private Map credentialsCache = new HashMap(); + + /** + * used to store events that we have sent ourselves; we need to remember them for not reacting to them + */ + private List ignoreEventList = Collections.synchronizedList(new ArrayList()); + + /** + * The most recently received data model, or null if none have been retrieved yet. + */ + private DataModel oldDataModel = null; + + public NestBinding() { + } + + /** + * {@inheritDoc} + */ + @Override + public void activate() { + super.activate(); + } + + /** + * {@inheritDoc} + */ + @Override + public void deactivate() { + // deallocate resources here that are no longer needed and + // should be reset when activating this binding again + } + + /** + * {@inheritDoc} + */ + @Override + protected long getRefreshInterval() { + return refreshInterval; + } + + /** + * {@inheritDoc} + */ + @Override + protected String getName() { + return "Nest Refresh Service"; + } + + /** + * {@inheritDoc} + */ + @Override + protected void execute() { + logger.trace("Querying Nest API"); + + try { + for (String userid : credentialsCache.keySet()) { + OAuthCredentials oauthCredentials = getOAuthCredentials(userid); + + if (oauthCredentials.noAccessToken()) { + if (!oauthCredentials.retrieveAccessToken()) { + logger.warn("Periodic poll skipped."); + continue; + } + } + + readNest(oauthCredentials); + } + } catch (Exception e) { + logger.error("Error reading from Nest:", e); + } + } + + /** + * Given the credentials to use and what to select from the Nest API, read any changed information from Nest and + * update the affected items. + * + * @param oauthCredentials + * the credentials to use + */ + private void readNest(OAuthCredentials oauthCredentials) throws Exception { + + DataModelRequest dmreq = new DataModelRequest(oauthCredentials.accessToken); + DataModelResponse dmres = dmreq.execute(); + + if (dmres.isError()) { + logger.error("Error retrieving data model: {}", dmres.getError()); + return; + } + + DataModel newDataModel = dmres; + this.oldDataModel = newDataModel; + + // Iterate through bindings and update all inbound values. + for (final NestBindingProvider provider : this.providers) { + for (final String itemName : provider.getItemNames()) { + if (provider.isInBound(itemName)) { + final String property = provider.getProperty(itemName); + final State newState = getState(newDataModel, property); + + logger.trace("Updating itemName '{}' with newState '{}'", itemName, newState); + + /* + * we need to make sure that we won't send out this event to Nest again, when receiving it on the + * openHAB bus + */ + ignoreEventList.add(itemName + newState.toString()); + logger.trace("Added event (item='{}', newState='{}') to the ignore event list", itemName, newState); + this.eventPublisher.postUpdate(itemName, newState); + } + } + } + } + + /** + * Give a binding provider, a data model, and an item name, return the corresponding state object. + * + * @param provider + * the Nest binding provider + * @param dataModel + * a data model from which to retrieve the value + * @param itemName + * the item name from the items file. + * @return the State object for the named item + */ + private State getState(final DataModel dataModel, final String property) { + + if (dataModel != null) { + try { + return createState(dataModel.getProperty(property)); + } catch (Exception e) { + logger.error("Unable to get state from data model", e); + } + } + return UnDefType.NULL; + } + + /** + * Creates an openHAB {@link State} in accordance to the class of the given {@code propertyValue}. Currently + * {@link Date}, {@link BigDecimal}, {@link Temperature} and {@link Boolean} are handled explicitly. All other + * {@code dataTypes} are mapped to {@link StringType}. + *

        + * If {@code propertyValue} is {@code null}, {@link UnDefType#NULL} will be returned. + * + * Copied/adapted from the Koubachi binding. + * + * @param propertyValue + * + * @return the new {@link State} in accordance with {@code dataType}. Will never be {@code null}. + */ + private State createState(Object propertyValue) { + if (propertyValue == null) { + return UnDefType.NULL; + } + + Class dataType = propertyValue.getClass(); + + if (Date.class.isAssignableFrom(dataType)) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime((Date) propertyValue); + return new DateTimeType(calendar); + } else if (Integer.class.isAssignableFrom(dataType)) { + return new DecimalType((Integer) propertyValue); + } else if (BigDecimal.class.isAssignableFrom(dataType)) { + return new DecimalType((BigDecimal) propertyValue); + } else if (Boolean.class.isAssignableFrom(dataType)) { + if ((Boolean) propertyValue) { + return OnOffType.ON; + } else { + return OnOffType.OFF; + } + } else { + return new StringType(propertyValue.toString()); + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void internalReceiveCommand(String itemName, Command command) { + logger.trace("internalReceiveCommand(item='{}', command='{}')", itemName, command); + commandNest(itemName, command); + } + + /** + * {@inheritDoc} + */ + @Override + protected void internalReceiveUpdate(final String itemName, final State newState) { + logger.trace("Received update (item='{}', state='{}')", itemName, newState); + if (!isEcho(itemName, newState)) { + updateNest(itemName, newState); + } + } + + /** + * Perform the given {@code command} against all targets referenced in {@code itemName}. + * + * @param command + * the command to execute + * @param the + * target(s) against which to execute this command + */ + private void commandNest(final String itemName, final Command command) { + if (command instanceof State) { + updateNest(itemName, (State) command); + } + } + + private boolean isEcho(String itemName, State state) { + String ignoreEventListKey = itemName + state.toString(); + if (ignoreEventList.remove(ignoreEventListKey)) { + logger.debug( + "We received this event (item='{}', state='{}') from Nest, so we don't send it back again -> ignore!", + itemName, state); + return true; + } else { + return false; + } + } + + /** + * Send the {@code newState} for the given {@code itemName} to Nest. + * + * @param itemName + * @param newState + */ + private void updateNest(final String itemName, final State newState) { + + // Find the first binding provider for this itemName. + NestBindingProvider provider = null; + String property = null; + for (NestBindingProvider p : this.providers) { + property = p.getProperty(itemName); + if (property != null) { + provider = p; + break; + } + } + + if (provider == null) { + logger.warn("no matching binding provider found [itemName={}, newState={}]", itemName, newState); + return; + } else { + + try { + logger.debug("About to set property '{}' to '{}'", property, newState); + + // Ask the old DataModel to generate a new DataModel that only contains the update we want to send + DataModel updateDataModel = oldDataModel.updateDataModel(property, newState); + + logger.trace("Data model for update: {}", updateDataModel); + + if (updateDataModel == null) { + return; + } + + OAuthCredentials oauthCredentials = getOAuthCredentials(DEFAULT_USER_ID); + + if (oauthCredentials == null) { + logger.warn("Unable to locate credentials for item {}; aborting update.", itemName); + return; + } + + // If we don't have an access token yet, retrieve one. + if (oauthCredentials.noAccessToken()) { + if (!oauthCredentials.retrieveAccessToken()) { + logger.warn("Sending update skipped."); + return; + } + } + + UpdateDataModelRequest request = new UpdateDataModelRequest(oauthCredentials.accessToken, + updateDataModel); + DataModelResponse response = request.execute(); + if (response.isError()) { + logger.error("Error updating data model: {}", response); + } + } catch (Exception e) { + logger.error("Unable to update data model", e); + } + } + } + + /** + * {@inheritDoc} + */ + public void bindingChanged(BindingProvider provider, String itemName) { + + if (provider instanceof NestBindingProvider) { + this.oldDataModel = null; + } + } + + /** + * {@inheritDoc} + */ + public void allBindingsChanged(BindingProvider provider) { + + if (provider instanceof NestBindingProvider) { + this.oldDataModel = null; + } + } + + /** + * Returns the cached {@link OAuthCredentials} for the given {@code userid}. If their is no such cached + * {@link OAuthCredentials} element, the cache is searched with the {@code DEFAULT_USER_ID}. If there is still no + * cached element found {@code NULL} is returned. + * + * @param userid + * the userid to find the {@link OAuthCredentials} + * @return the cached {@link OAuthCredentials} or {@code NULL} + */ + private OAuthCredentials getOAuthCredentials(String userid) { + if (credentialsCache.containsKey(userid)) { + return credentialsCache.get(userid); + } else { + return credentialsCache.get(DEFAULT_USER_ID); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void updated(Dictionary config) throws ConfigurationException { + if (config != null) { + + // to override the default refresh interval one has to add a + // parameter to openhab.cfg like nest:refresh=120000 + String refreshIntervalString = (String) config.get(CONFIG_REFRESH); + if (isNotBlank(refreshIntervalString)) { + refreshInterval = Long.parseLong(refreshIntervalString); + } + + Enumeration configKeys = config.keys(); + while (configKeys.hasMoreElements()) { + String configKey = (String) configKeys.nextElement(); + + // the config-key enumeration contains additional keys that we + // don't want to process here ... + if (CONFIG_REFRESH.equals(configKey) || "service.pid".equals(configKey)) { + continue; + } + + String userid = DEFAULT_USER_ID; + String configKeyTail = configKey; + + OAuthCredentials credentials = credentialsCache.get(userid); + if (credentials == null) { + credentials = new OAuthCredentials(userid); + credentialsCache.put(userid, credentials); + } + + String value = (String) config.get(configKey); + + if (CONFIG_CLIENT_ID.equals(configKeyTail)) { + credentials.clientId = value; + } else if (CONFIG_CLIENT_SECRET.equals(configKeyTail)) { + credentials.clientSecret = value; + } else if (CONFIG_PIN_CODE.equals(configKeyTail)) { + credentials.pinCode = value; + } else { + throw new ConfigurationException(configKey, "the given configKey '" + configKey + "' is unknown"); + } + } + + // Verify the completeness of each OAuthCredentials entry + // to make sure we can get started. + + boolean properlyConfigured = true; + + for (String userid : credentialsCache.keySet()) { + OAuthCredentials oauthCredentials = getOAuthCredentials(userid); + String userString = (DEFAULT_USER_ID.equals(userid)) ? "" : (userid + "."); + if (oauthCredentials.clientId == null) { + logger.error("Required nest:{}{} is missing.", userString, CONFIG_CLIENT_ID); + properlyConfigured = false; + break; + } + if (oauthCredentials.clientSecret == null) { + logger.error("Required nest:{}{} is missing.", userString, CONFIG_CLIENT_SECRET); + properlyConfigured = false; + break; + } + if (oauthCredentials.pinCode == null) { + logger.error("Required nest:{}{} is missing.", userString, CONFIG_PIN_CODE); + properlyConfigured = false; + break; + } + // Load persistently stored values for this credential set + oauthCredentials.load(); + } + + setProperlyConfigured(properlyConfigured); + } + } + + /** + * This internal class holds the credentials necessary for the OAuth2 flow to work. It also provides basic methods + * to retrieve an access token. + * + * @author John Cocula + * @since 1.7.0 + */ + static class OAuthCredentials { + + private static final String ACCESS_TOKEN = "accessToken"; + private static final String PIN_CODE = "pinCode"; + + private String userid; + + /** + * The private client_id needed in order to interact with the Nest API. This must be provided in the + * openhab.cfg file. + */ + private String clientId; + + /** + * The client_secret needed when authorizing this client to the Nest API. + * + * @see AccessTokenRequest + */ + private String clientSecret; + + /** + * The pincode needed when authorizing this client to the Nest API. + * + * @see AccessTokenRequest + */ + private String pinCode; + + /** + * The access token to access the Nest API. Automatically renewed from the API using the refresh token and + * persisted for use across activations. + * + * @see #refreshTokens() + */ + private String accessToken; + + public OAuthCredentials(String userid) { + + try { + this.userid = userid; + } catch (Exception e) { + throw new NestException("Cannot create OAuthCredentials.", e); + } + } + + private Preferences getPrefsNode() { + return Preferences.userRoot().node("org.openhab.nest." + userid); + } + + /** + * Only load the accessToken if the pinCode that was saved with it matches the current pinCode. Otherwise, we + * could continue to try to use an accessToken that does not match the credentials in openhab.cfg. + */ + private void load() { + Preferences prefs = getPrefsNode(); + String pinCode = prefs.get(PIN_CODE, null); + if (this.pinCode.equals(pinCode)) { + this.accessToken = prefs.get(ACCESS_TOKEN, null); + } + } + + private void save() { + Preferences prefs = getPrefsNode(); + if (this.accessToken != null) { + prefs.put(ACCESS_TOKEN, this.accessToken); + } else { + prefs.remove(ACCESS_TOKEN); + } + if (this.pinCode != null) { + prefs.put(PIN_CODE, this.pinCode); + } else { + prefs.remove(PIN_CODE); + } + } + + /** + * Determine if we have an access token. + * + * @return true if we have an access token; false otherwise. + */ + public boolean noAccessToken() { + return this.accessToken == null; + } + + /** + * Retrieve an access token from the Nest API. + * + * @return true if we were successful, false otherwise + */ + public boolean retrieveAccessToken() { + logger.trace("Retrieving access token in order to access the Nest API."); + + final AccessTokenRequest request = new AccessTokenRequest(clientId, clientSecret, pinCode); + logger.trace("Request: {}", request); + + final AccessTokenResponse response = request.execute(); + logger.trace("Response: {}", response); + + if (response.isError()) { + logger.error("Error retrieving access token: {}'", response); + } + + this.accessToken = response.getAccessToken(); + save(); + + return !noAccessToken(); + } + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestException.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestException.java new file mode 100644 index 00000000000..c877f7b9fea --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestException.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal; + +/** + * @author John Cocula + * @since 1.7.0 + */ +public class NestException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public NestException(final String message, final Throwable cause) { + super(message, cause); + } + + public NestException(final Throwable cause) { + super(cause); + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestGenericBindingProvider.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestGenericBindingProvider.java new file mode 100644 index 00000000000..3da6dfd6166 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestGenericBindingProvider.java @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.openhab.binding.nest.NestBindingProvider; +import org.openhab.core.binding.BindingConfig; +import org.openhab.core.items.Item; +import org.openhab.model.item.binding.AbstractGenericBindingProvider; +import org.openhab.model.item.binding.BindingConfigParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is responsible for parsing the binding configuration. + * + *

        + * Nest bindings start with a <, > or =, to indicate if the item receives values from the API (in binding), + * sends values to the API (out binding), or both (bidirectional binding), respectively. + * + *

        + * The first character is then followed by BeanUtils-style property reference: + * + *

        + * <property> + * + *

        + * property is one of a long list of structures, thermostats or smoke_co_alarms properties + * that you can read and optionally change. + * + * @author John Cocula + * @since 1.7.0 + */ +public class NestGenericBindingProvider extends AbstractGenericBindingProvider implements NestBindingProvider { + + private static class NestBindingConfig implements BindingConfig { + String property; + boolean inBound = false; + boolean outBound = false; + + public NestBindingConfig(final String property, + final boolean inBound, final boolean outBound) { + this.property = property; + this.inBound = inBound; + this.outBound = outBound; + } + + @Override + public String toString() { + return "NestBindingConfig [property=" + this.property + ", inBound=" + this.inBound + ", outBound=" + this.outBound + "]"; + } + } + + private static Logger logger = LoggerFactory.getLogger(NestGenericBindingProvider.class); + + private static final Pattern CONFIG_PATTERN = Pattern.compile(".\\[(.*)\\]"); + + // the first character in the above pattern + private static final String IN_BOUND = "<"; + private static final String OUT_BOUND = ">"; + private static final String BIDIRECTIONAL = "="; + + /** + * {@inheritDoc} + */ + public String getBindingType() { + return "nest"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getProperty(final String itemName) { + NestBindingConfig config = (NestBindingConfig) this.bindingConfigs.get(itemName); + return config != null ? config.property : null; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isInBound(final String itemName) { + NestBindingConfig config = (NestBindingConfig) this.bindingConfigs.get(itemName); + return config != null ? config.inBound : false; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isOutBound(final String itemName) { + NestBindingConfig config = (NestBindingConfig) this.bindingConfigs.get(itemName); + return config != null ? config.outBound : false; + } + + /** + * {@inheritDoc} + */ + @Override + public void processBindingConfiguration(final String context, final Item item, final String bindingConfig) + throws BindingConfigParseException { + logger.debug("Processing binding configuration: '{}'", bindingConfig); + + super.processBindingConfiguration(context, item, bindingConfig); + + boolean inBound = false; + boolean outBound = false; + + if (bindingConfig.startsWith(IN_BOUND)) { + inBound = true; + } else if (bindingConfig.startsWith(OUT_BOUND)) { + outBound = true; + } else if (bindingConfig.startsWith(BIDIRECTIONAL)) { + inBound = true; + outBound = true; + } else { + throw new BindingConfigParseException("Item \"" + item.getName() + "\" does not start with " + IN_BOUND + + ", " + OUT_BOUND + " or " + BIDIRECTIONAL + "."); + } + + Matcher matcher = CONFIG_PATTERN.matcher(bindingConfig); + + if (!matcher.matches() || matcher.groupCount() != 1) + throw new BindingConfigParseException("Config for item '" + item.getName() + "' could not be parsed."); + + String property = matcher.group(1); + + NestBindingConfig config = new NestBindingConfig(property, inBound, outBound); + + addBindingConfig(item, config); + } + + /** + * {@inheritDoc} + */ + @Override + public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException { + + logger.trace("validateItemType called with bindingConfig={}", bindingConfig); + + Matcher matcher = CONFIG_PATTERN.matcher(bindingConfig); + + if (!matcher.matches() || matcher.groupCount() != 1) + throw new BindingConfigParseException("Config for item '" + item.getName() + "' could not be parsed."); + + String property = matcher.group(1); + + logger.trace("validateItemType called with property={}", property); + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractDevice.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractDevice.java new file mode 100644 index 00000000000..6cd60d689ed --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractDevice.java @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import java.util.Date; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * The AbstractDevice Java Bean represents an abstract Nest device. + * + * @see API Reference + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class AbstractDevice extends AbstractMessagePart implements DataModelElement { + + private String device_id; + private String locale; + private String software_version; + private String structure_id; + private Structure structure; + private String name; + private String name_long; + private Date last_connection; + private Boolean is_online; + + public AbstractDevice(@JsonProperty("device_id") String device_id) { + this.device_id = device_id; + } + + /** + * @return the unique thermostat identifier. + */ + @JsonProperty("device_id") + public String getDevice_id() { + return this.device_id; + } + + /** + * @return Country and language preference, in IETF Language Tag format + */ + @JsonProperty("locale") + public String getLocale() { + return this.locale; + } + + /** + * @return Software version + */ + @JsonProperty("software_version") + public String getSoftware_version() { + return this.software_version; + } + + /** + * @return Unique structure identifier + */ + @JsonProperty("structure_id") + public String getStructure_id() { + return this.structure_id; + } + + /** + * @return the structure + */ + public Structure getStructure() { + return this.structure; + } + + /** + * @return Display name of the device + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @return Long display name of the device + */ + @JsonProperty("name_long") + public String getName_long() { + return this.name_long; + } + + /** + * @return Time of the last successful interaction with the Nest service + */ + @JsonProperty("last_connection") + public Date getLast_connection() { + return this.last_connection; + } + + /** + * @return Device connection status with the Nest Service + */ + @JsonProperty("is_online") + public Boolean getIs_online() { + return this.is_online; + } + + @Override + public void sync(DataModel dataModel) { + // Link to structure + this.structure = dataModel.getStructures_by_id().get(this.structure_id); + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("device_id", this.device_id); + builder.append("name", this.name); + builder.append("locale", this.locale); + builder.append("software_version", this.software_version); + builder.append("structure_id", this.structure_id); + builder.append("name", this.name); + builder.append("name_long", this.name_long); + builder.append("last_connection", this.last_connection); + builder.append("is_online", this.is_online); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractMessage.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractMessage.java new file mode 100644 index 00000000000..153dbd71d49 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractMessage.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import static org.apache.commons.lang.builder.ToStringStyle.SHORT_PREFIX_STYLE; + +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * Base class for all messages. + * + * @author John Cocula + * @since 1.7.0 + */ +public class AbstractMessage { + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + + return builder.toString(); + } + + protected final ToStringBuilder createToStringBuilder() { + return new ToStringBuilder(this, SHORT_PREFIX_STYLE); + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractMessagePart.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractMessagePart.java new file mode 100644 index 00000000000..3824e4a7ad2 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractMessagePart.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import static org.apache.commons.lang.builder.ToStringStyle.SHORT_PREFIX_STYLE; + +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * Base class for all message parts; i.e., objects within a response. + * + * @author John Cocula + * @since 1.7.0 + */ +public class AbstractMessagePart { + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + + return builder.toString(); + } + + protected final ToStringBuilder createToStringBuilder() { + return new ToStringBuilder(this, SHORT_PREFIX_STYLE); + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractRequest.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractRequest.java new file mode 100644 index 00000000000..04b0c0f0a03 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AbstractRequest.java @@ -0,0 +1,180 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Properties; +import java.util.TimeZone; +import java.util.zip.GZIPInputStream; +import java.util.zip.InflaterInputStream; + +import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HeaderElement; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpMethod; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.URIException; +import org.apache.commons.httpclient.methods.EntityEnclosingMethod; +import org.apache.commons.httpclient.methods.InputStreamRequestEntity; +import org.apache.commons.httpclient.params.HttpMethodParams; +import org.apache.commons.io.IOUtils; +import org.codehaus.jackson.map.JsonMappingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion; +import org.openhab.binding.nest.internal.NestException; +import org.openhab.io.net.http.HttpUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base class for all Nest API requests. + * + * @author John Cocula + * @since 1.7.0 + */ +public abstract class AbstractRequest extends AbstractMessage implements Request { + + private static final Logger logger = LoggerFactory.getLogger(AbstractRequest.class); + + private static final Properties HTTP_HEADERS; + + private static final int HTTP_REQUEST_TIMEOUT = 10000; + + protected static final String HTTP_GET = "GET"; + + protected static final String HTTP_POST = "POST"; + + protected static final String HTTP_PUT = "PUT"; + + protected static final String API_BASE_URL = "https://developer-api.nest.com/"; + + protected static final ObjectMapper JSON = new ObjectMapper(); + + static { + HTTP_HEADERS = new Properties(); + HTTP_HEADERS.put("Accept", "application/json"); + + // do not serialize null values + JSON.setSerializationInclusion(Inclusion.NON_NULL); + + // dates in the JSON are in ISO 8601 format + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + df.setTimeZone(tz); + JSON.setDateFormat(df); + } + + protected final RuntimeException newException(final String message, final Exception cause, final String url, + final String json) { + if (cause instanceof JsonMappingException) { + return new NestException("Could not parse JSON from URL '" + url + "': " + json, cause); + } + + return new NestException(message, cause); + } + + /** + * Executes the given url with the given httpMethod. In the case of httpMethods that do + * not support automatic redirection, manually handle the HTTP temporary redirect (307) and retry with the new URL. + * + * @param httpMethod + * the HTTP method to use + * @param url + * the url to execute (in milliseconds) + * @param contentString + * the content to be sent to the given url or null if no content should be + * sent. + * @param contentType + * the content type of the given contentString + * @return the response body or NULL when the request went wrong + */ + protected final String executeUrl(final String httpMethod, final String url, final String contentString, + final String contentType) { + + HttpClient client = new HttpClient(); + + HttpMethod method = HttpUtil.createHttpMethod(httpMethod, url); + method.getParams().setSoTimeout(HTTP_REQUEST_TIMEOUT); + method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false)); + + for (String httpHeaderKey : HTTP_HEADERS.stringPropertyNames()) { + method.addRequestHeader(new Header(httpHeaderKey, HTTP_HEADERS.getProperty(httpHeaderKey))); + } + + // add content if a valid method is given ... + if (method instanceof EntityEnclosingMethod && contentString != null) { + EntityEnclosingMethod eeMethod = (EntityEnclosingMethod) method; + InputStream content = new ByteArrayInputStream(contentString.getBytes()); + eeMethod.setRequestEntity(new InputStreamRequestEntity(content, contentType)); + } + + if (logger.isDebugEnabled()) { + try { + logger.trace("About to execute '" + method.getURI().toString() + "'"); + } catch (URIException e) { + logger.trace(e.getMessage()); + } + } + + try { + + int statusCode = client.executeMethod(method); + if (statusCode == HttpStatus.SC_NO_CONTENT || statusCode == HttpStatus.SC_ACCEPTED) { + // perfectly fine but we cannot expect any answer... + return null; + } + + // Manually handle 307 redirects with a little tail recursion + if (statusCode == HttpStatus.SC_TEMPORARY_REDIRECT) { + Header[] headers = method.getResponseHeaders("Location"); + String newUrl = headers[headers.length - 1].getValue(); + return executeUrl(httpMethod, newUrl, contentString, contentType); + } + + if (statusCode != HttpStatus.SC_OK) { + logger.warn("Method failed: " + method.getStatusLine()); + } + + InputStream tmpResponseStream = method.getResponseBodyAsStream(); + Header encodingHeader = method.getResponseHeader("Content-Encoding"); + if (encodingHeader != null) { + for (HeaderElement ehElem : encodingHeader.getElements()) { + if (ehElem.toString().matches(".*gzip.*")) { + tmpResponseStream = new GZIPInputStream(tmpResponseStream); + logger.trace("GZipped InputStream from {}", url); + } else if (ehElem.toString().matches(".*deflate.*")) { + tmpResponseStream = new InflaterInputStream(tmpResponseStream); + logger.trace("Deflated InputStream from {}", url); + } + } + } + + String responseBody = IOUtils.toString(tmpResponseStream); + if (!responseBody.isEmpty()) { + logger.trace(responseBody); + } + + return responseBody; + } catch (HttpException he) { + logger.error("Fatal protocol violation: {}", he.toString()); + } catch (IOException ioe) { + logger.error("Fatal transport error: {}", ioe.toString()); + } finally { + method.releaseConnection(); + } + + return null; + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AccessTokenRequest.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AccessTokenRequest.java new file mode 100644 index 00000000000..f93c9083fa7 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AccessTokenRequest.java @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import org.apache.commons.httpclient.util.URIUtil; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.openhab.binding.nest.internal.NestException; + +/** + * + * @see AccessTokenResponse + * @author John Cocula + * @since 1.7.0 + */ +public class AccessTokenRequest extends AbstractRequest { + + private static final String RESOURCE_URL = "https://api.home.nest.com/oauth2/access_token"; + + private String clientId; + private String clientSecret; + private String pinCode; + + /** + * Construct a request to obtain an access code to the Nest API. + * + * @param client_id + * the Client ID shown in you Nest Clients screen and you pasted into openhab.cfg at + * nest:client_id + * @param client_secret + * the Client Secret shown in you Nest Clients screen and you pasted into openhab.cfg at + * nest:client_secret + * @param pincode + * the PIN that Nest showed on-screen and you pasted into openhab.cfg at nest:pincode + * + * @see Clients screen + */ + public AccessTokenRequest(final String clientId, final String clientSecret, final String pinCode) { + this.clientId = clientId; + this.clientSecret = clientSecret; + this.pinCode = pinCode; + } + + @Override + public AccessTokenResponse execute() { + final String url = buildQueryString(); + String json = null; + + try { + json = executeQuery(url); + + final AccessTokenResponse response = JSON.readValue(json, AccessTokenResponse.class); + + return response; + } catch (final Exception e) { + throw newException("Could not get access token.", e, url, json); + } + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("pinCode", this.pinCode); + builder.append("clientId", this.clientId); + builder.append("clientSecret", this.clientSecret); + return builder.toString(); + } + + protected String executeQuery(final String url) { + return executeUrl(HTTP_POST, url, null, null); + } + + private String buildQueryString() { + final StringBuilder urlBuilder = new StringBuilder(RESOURCE_URL); + + try { + urlBuilder.append("?code="); + urlBuilder.append(this.pinCode); + urlBuilder.append("&client_id="); + urlBuilder.append(this.clientId); + urlBuilder.append("&client_secret="); + urlBuilder.append(this.clientSecret); + urlBuilder.append("&grant_type=authorization_code"); + return URIUtil.encodeQuery(urlBuilder.toString()); + } catch (final Exception e) { + throw new NestException(e); + } + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AccessTokenResponse.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AccessTokenResponse.java new file mode 100644 index 00000000000..76386fec46b --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/AccessTokenResponse.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * @see AccessTokenRequest + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class AccessTokenResponse extends AbstractMessage implements Response { + + @JsonProperty("access_token") + private String accessToken; + @JsonProperty("expires_in") + private Integer expiresIn; + @JsonProperty("error") + private String error; + @JsonProperty("error_description") + private String errorDescription; + + /** + * @return the access_token returned from the AuthorizeResponse + */ + public String getAccessToken() { + return this.accessToken; + } + + /** + * @return the number of minutes until the PIN expires. Ensure you inform the user how much time they have. + */ + public Integer getExpiresIn() { + return this.expiresIn; + } + + @Override + public String getError() { + return this.error; + } + + @Override + public boolean isError() { + return this.error != null; + } + + public String getErrorDescription() { + return this.errorDescription; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("accessToken", this.accessToken); + builder.append("expiresIn", this.expiresIn); + builder.append("error", this.error); + builder.append("errorDescription", this.errorDescription); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModel.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModel.java new file mode 100644 index 00000000000..73193a1d4d5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModel.java @@ -0,0 +1,517 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import java.io.UnsupportedEncodingException; +import java.lang.reflect.InvocationTargetException; +import java.net.URLDecoder; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.beanutils.BeanUtilsBean; +import org.apache.commons.beanutils.ConvertUtilsBean; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.beanutils.PropertyUtilsBean; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnore; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.openhab.binding.nest.internal.messages.Structure.AwayState; +import org.openhab.binding.nest.internal.messages.Thermostat.HvacMode; +import org.openhab.binding.nest.internal.messages.SmokeCOAlarm.AlarmState; +import org.openhab.binding.nest.internal.messages.SmokeCOAlarm.BatteryHealth; +import org.openhab.binding.nest.internal.messages.SmokeCOAlarm.ColorState; +import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.StringType; + +/** + * The DataModel Java Bean represents the entire Nest API data model. + * + * @see API Reference + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class DataModel extends AbstractMessagePart { + + private static BeanUtilsBean beanUtils; + private static PropertyUtilsBean propertyUtils; + static { + /** + * Configure BeanUtilsBean to use our converters and resolver. + */ + ConvertUtilsBean convertUtils = new ConvertUtilsBean(); + + // Register bean type converters + convertUtils.register(new Converter() { + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof StringType) { + return AwayState.forValue(value.toString()); + } else { + return null; + } + } + }, AwayState.class); + convertUtils.register(new Converter() { + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof StringType) { + return HvacMode.forValue(value.toString()); + } else { + return null; + } + } + }, HvacMode.class); + convertUtils.register(new Converter() { + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof StringType) { + return BatteryHealth.forValue(value.toString()); + } else { + return null; + } + } + }, BatteryHealth.class); + convertUtils.register(new Converter() { + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof StringType) { + return AlarmState.forValue(value.toString()); + } else { + return null; + } + } + }, AlarmState.class); + convertUtils.register(new Converter() { + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof StringType) { + return ColorState.forValue(value.toString()); + } else { + return null; + } + } + }, ColorState.class); + convertUtils.register(new Converter() { + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof DecimalType) { + return ((DecimalType) value).intValue(); + } else { + return null; + } + } + }, Integer.class); + convertUtils.register(new Converter() { + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + if (value instanceof OnOffType) { + return ((OnOffType) value) == OnOffType.ON; + } else { + return null; + } + } + }, Boolean.class); + convertUtils.register(new Converter() { + @SuppressWarnings("rawtypes") + @Override + public Object convert(Class type, Object value) { + return value.toString(); + } + }, String.class); + + propertyUtils = new PropertyUtilsBean(); + propertyUtils.setResolver(new DataModelPropertyResolver()); + beanUtils = new BeanUtilsBean(convertUtils, propertyUtils); + } + + @JsonProperty("devices") + private Devices devices; + @JsonProperty("structures") + private Map structures_by_id; + @JsonIgnore + private Map structures_by_name; + @JsonIgnore + Date last_connection; + + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Devices extends AbstractMessagePart implements DataModelElement { + private Map thermostats_by_id; + @JsonIgnore + private Map thermostats_by_name; + private Map smoke_co_alarms_by_id; + @JsonIgnore + private Map smoke_co_alarms_by_name; + + /** + * @return the thermostats_by_id + */ + @JsonProperty("thermostats") + public Map getThermostats_by_id() { + return this.thermostats_by_id; + } + + /** + * @param thermostats + * the thermostats to set (mapped by ID) + */ + @JsonProperty("thermostats") + public void setThermostats_by_id(Map thermostats_by_id) { + this.thermostats_by_id = thermostats_by_id; + } + + /** + * Return the thermostats map, mapped by name. + * + * @return the thermostats_by_name; + */ + @JsonIgnore + public Map getThermostats() { + return this.thermostats_by_name; + } + + /** + * @return the smoke_co_alarms_by_id + */ + @JsonProperty("smoke_co_alarms") + public Map getSmoke_co_alarms_by_id() { + return this.smoke_co_alarms_by_id; + } + + /** + * @param smoke_co_alarms + * the smoke_co_alarms to set (mapped by ID) + */ + @JsonProperty("smoke_co_alarms") + public void setSmoke_co_alarms_by_id(Map smoke_co_alarms_by_id) { + this.smoke_co_alarms_by_id = smoke_co_alarms_by_id; + } + + /** + * @return the smoke_co_alarms_by_name + */ + @JsonIgnore + public Map getSmoke_co_alarms() { + return this.smoke_co_alarms_by_name; + } + + /** + * {@inheritDoc} + */ + @Override + public void sync(DataModel dataModel) { + // Create our map of Thermostat names to objects + this.thermostats_by_name = new HashMap(); + if (this.thermostats_by_id != null) { + for (Thermostat thermostat : this.thermostats_by_id.values()) { + thermostat.sync(dataModel); + this.thermostats_by_name.put(thermostat.getName(), thermostat); + } + } + // Create our map of SmokeCOAlarm names to objects + this.smoke_co_alarms_by_name = new HashMap(); + if (this.smoke_co_alarms_by_id != null) { + for (SmokeCOAlarm smoke_co_alarm : this.smoke_co_alarms_by_id.values()) { + smoke_co_alarm.sync(dataModel); + this.smoke_co_alarms_by_name.put(smoke_co_alarm.getName(), smoke_co_alarm); + } + } + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("thermostats", this.thermostats_by_id); + builder.append("smoke_co_alarms", this.smoke_co_alarms_by_id); + + return builder.toString(); + } + } + + public DataModel() { + } + + /** + * Use a dialect of the BeanUtils property resolver that URL-decodes the keys that are used to retrieve mapped + * objects. + */ + public static class DataModelPropertyResolver extends org.apache.commons.beanutils.expression.DefaultResolver { + /** + * {@inheritDoc} + */ + @SuppressWarnings("deprecation") + public String getKey(String expression) { + String key = super.getKey(expression); + if (key != null) { + try { + return URLDecoder.decode(key, "UTF-8"); + } catch (UnsupportedEncodingException ex) { + return URLDecoder.decode(key); + } + } + return null; + } + } + + /** + * Return a JavaBean property by name. + * + * @param name + * the named property to return + * @return the named property's value + * @see PropertyUtils#getProperty() + * @throws IllegalAccessException + * if the caller does not have access to the property accessor method + * @throws InvocationTargetException + * if the property accessor method throws an exception + * @throws NoSuchMethodException + * if the accessor method for this property cannot be found + */ + public Object getProperty(String name) throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + + return propertyUtils.getProperty(this, name); + } + + /** + * Set the specified property value, performing type conversions as required to conform to the type of the + * destination property. + * + * @param name + * property name (can be nested/indexed/mapped/combo) + * @param value + * value to be set + * @throws IllegalAccessException + * if the caller does not have access to the property accessor method + * @throws InvocationTargetException + * if the property accessor method throws an exception + */ + public void setProperty(String name, Object value) throws IllegalAccessException, InvocationTargetException { + + beanUtils.setProperty(this, name, value); + } + + /** + * @return the devices + */ + @JsonProperty("devices") + public Devices getDevices() { + return this.devices; + } + + /** + * @param devices + * the devices to set + */ + @JsonProperty("devices") + public void setDevices(Devices devices) { + this.devices = devices; + } + + /** + * Convenience method so property specs don't have to include "devices." in each one. + * + * @return name-based map of thermostats + */ + @JsonIgnore + public Map getThermostats() { + return (devices == null) ? null : devices.getThermostats(); + } + + /** + * Convenience method so property specs don't have to include "devices." in each one. + * + * @return name-based map of smoke_co_alarms + */ + @JsonIgnore + public Map getSmoke_co_alarms() { + return (devices == null) ? null : devices.getSmoke_co_alarms(); + } + + /** + * @return the structures + */ + @JsonProperty("structures") + public Map getStructures_by_id() { + return this.structures_by_id; + } + + /** + * @param structures_by_id + * the ID-keyed structure map to set + */ + @JsonProperty("structures") + public void setStructures_by_id(Map structures_by_id) { + this.structures_by_id = structures_by_id; + } + + @JsonIgnore + public Map getStructures() { + return this.structures_by_name; + } + + /** + * @param structures_by_name + * the name-keyed structure map to set + */ + public void setStructures_by_name(final Map structures_by_name) { + this.structures_by_name = structures_by_name; + } + + /** + * @param last_connection + * the last time we obtained the data model from the Nest API + */ + @JsonIgnore + public void setLast_connection(final Date last_connection) { + this.last_connection = last_connection; + } + + /** + * @return the last_connection + */ + @JsonIgnore + public Date getLast_connection() { + return this.last_connection; + } + + /** + * Visit each data model element and call its sync method with the root data model element (this). Do this right + * after it's been unmarshalled from JSON. + */ + public void sync() { + this.structures_by_name = new HashMap(); + if (this.structures_by_id != null) { + for (Structure st : this.structures_by_id.values()) { + this.structures_by_name.put(st.getName(), st); + st.sync(this); + } + } + if (this.devices != null) { + this.devices.sync(this); + } + } + + /** + * This method returns a new data model containing only the affected Structure, Thermostat or SmokeCOAlarm, and only + * the property of the bean that was changed. This new DataModel object can be sent to the Nest API in order to + * perform an update via HTTP PUT. + * + * @param property + * the property to change + * @param newState + * the new state to set for the property + * @return a new data model that only contains the affected bean and only the property set + * @throws IllegalAccessException + * @throws InvocationTargetException + * @throws NoSuchMethodException + */ + public DataModel updateDataModel(String property, Object newState) throws IllegalAccessException, + InvocationTargetException, NoSuchMethodException { + + /** + * Find the Structure, Thermostat or SmokeCOAlarm that the given property is trying to update. + */ + Object oldObject = null; + String beanProperty = property; + do { + Object obj = this.getProperty(beanProperty); + if (obj instanceof Structure || obj instanceof Thermostat || obj instanceof SmokeCOAlarm) { + oldObject = obj; + break; + } + if (beanProperty.indexOf('.') != -1) { + beanProperty = beanProperty.substring(0, beanProperty.lastIndexOf('.')); + } else { + break; + } + } while (beanProperty.length() > 0); + + /** + * Now based on the type of the object, create a new DataModel that has an empty one, properly mapped by ID and + * by name. + */ + DataModel updateDataModel = null; + + if (oldObject != null) { + if (oldObject instanceof Structure) { + String structureId = ((Structure) oldObject).getStructure_id(); + String structureName = ((Structure) oldObject).getName(); + + updateDataModel = new DataModel(); + Structure structure = new Structure(null); + updateDataModel.structures_by_id = new HashMap(); + updateDataModel.structures_by_id.put(structureId, structure); + updateDataModel.structures_by_name = new HashMap(); + updateDataModel.structures_by_name.put(structureName, structure); + } else if (oldObject instanceof Thermostat) { + String deviceId = ((Thermostat) oldObject).getDevice_id(); + String deviceName = ((Thermostat) oldObject).getName(); + + updateDataModel = new DataModel(); + updateDataModel.devices = new Devices(); + Thermostat thermostat = new Thermostat(null); + updateDataModel.devices.thermostats_by_id = new HashMap(); + updateDataModel.devices.thermostats_by_id.put(deviceId, thermostat); + updateDataModel.devices.thermostats_by_name = new HashMap(); + updateDataModel.devices.thermostats_by_name.put(deviceName, thermostat); + } else if (oldObject instanceof SmokeCOAlarm) { + String deviceId = ((SmokeCOAlarm) oldObject).getDevice_id(); + String deviceName = ((SmokeCOAlarm) oldObject).getName(); + + updateDataModel = new DataModel(); + updateDataModel.devices = new Devices(); + SmokeCOAlarm smokeCOAlarm = new SmokeCOAlarm(null); + updateDataModel.devices.smoke_co_alarms_by_id = new HashMap(); + updateDataModel.devices.smoke_co_alarms_by_id.put(deviceId, smokeCOAlarm); + updateDataModel.devices.smoke_co_alarms_by_name = new HashMap(); + updateDataModel.devices.smoke_co_alarms_by_name.put(deviceName, smokeCOAlarm); + } + } + + /** + * Lastly, set the property into the update data model + * + * TODO: cannot update a binding string of the form "=[structures(Name).thermostats(Name).X]" or + * "=[structures(Name).smoke_co_alarms(Name).X]" because the name-based map of structures is not present in the + * updateDataModel + */ + if (updateDataModel != null) { + updateDataModel.setProperty(property, newState); + updateDataModel.structures_by_name = null; + if (updateDataModel.devices != null) { + updateDataModel.devices.smoke_co_alarms_by_name = null; + updateDataModel.devices.thermostats_by_name = null; + } + } + + return updateDataModel; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("devices", this.devices); + builder.append("structures", this.structures_by_id); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModelElement.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModelElement.java new file mode 100644 index 00000000000..a2bae42cc7b --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModelElement.java @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +public interface DataModelElement { + public void sync(DataModel dataModel); +} \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModelRequest.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModelRequest.java new file mode 100644 index 00000000000..e4c1ba9503c --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModelRequest.java @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import java.util.Date; + +import org.apache.commons.httpclient.util.URIUtil; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonIgnore; +import org.openhab.binding.nest.internal.NestException; + +/** + * Queries the Nest API for the entire data model. + * + * @author John Cocula + * @since 1.7.0 + */ +public class DataModelRequest extends AbstractRequest { + + private static final String RESOURCE_URL = API_BASE_URL; + + @JsonIgnore + private final String accessToken; + + /** + * Creates a request for the measurements of a device or module. + * + * If you don't specify a moduleId you will retrieve the device's measurements. If you do specify a moduleId you + * will retrieve the module's measurements. + * + * @param accessToken + * @param selection + * @param page + * optional, may be null + */ + public DataModelRequest(final String accessToken) { + assert accessToken != null : "accessToken must not be null!"; + + this.accessToken = accessToken; + } + + @Override + public DataModelResponse execute() { + final String url = buildQueryString(); + String json = null; + + try { + json = executeQuery(url); + + final DataModelResponse response = JSON.readValue(json, DataModelResponse.class); + + // note the time we received the data model + response.setLast_connection(new Date()); + + // sync the returned data model so its internal pointers are pointing + response.sync(); + + return response; + } catch (final Exception e) { + throw newException("Could not get data model.", e, url, json); + } + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("accessToken", this.accessToken); + + return builder.toString(); + } + + protected String executeQuery(final String url) { + return executeUrl(HTTP_GET, url, null, null); + } + + private String buildQueryString() { + final StringBuilder urlBuilder = new StringBuilder(RESOURCE_URL); + + try { + urlBuilder.append("?auth="); + urlBuilder.append(this.accessToken); + return URIUtil.encodeQuery(urlBuilder.toString()); + } catch (final Exception e) { + throw new NestException(e); + } + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModelResponse.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModelResponse.java new file mode 100644 index 00000000000..752b1283666 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/DataModelResponse.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class DataModelResponse extends DataModel implements Response { + + @JsonProperty("error") + private String error; + + @Override + @JsonProperty("error") + public String getError() { + return error; + } + + @Override + public boolean isError() { + return this.error != null; + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Request.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Request.java new file mode 100644 index 00000000000..b03c1b819c3 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Request.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +/** + * Base interface for all Nest API requests. + * + * @author John Cocula + * @since 1.7.0 + */ +public interface Request { + + /** + * Send this request to the Nest API. Implementations specify a more concrete {@link Request} class. + * + * @return a {@link Response} containing the requested data or an error + */ + Response execute(); +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Response.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Response.java new file mode 100644 index 00000000000..4b65643bdd8 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Response.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +/** + * Base interface for all Nest API responses. + * + * @author John Cocula + * @since 1.7.0 + */ +public interface Response { + + /** + * Return the response message, or null if there is none. + * + * @return the response message + */ + String getError(); + + /** + * Checks if this response contained an error. + * + * @return true if the response contained an error instead of actual data. + */ + boolean isError(); +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/SmokeCOAlarm.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/SmokeCOAlarm.java new file mode 100644 index 00000000000..b116a14a848 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/SmokeCOAlarm.java @@ -0,0 +1,232 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import java.util.Date; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.annotate.JsonValue; + +/** + * The SmokeCOAlarm Java Bean represents a Nest smoke+CO alarm. All objects relate in one way or another to a real + * smoke+CO alarm. The SmokeCOAlarm class defines the real smoke+CO device. + * + * @see API Reference + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class SmokeCOAlarm extends AbstractDevice { + + /** + * Battery life/health; estimate of time to end of life. + * + * Possible values for battery_health: + * + *

        + *
        ok
        + *
        Battery OK
        + *
        replace
        + *
        Battery low - replace soon
        + *
        + */ + public static enum BatteryHealth { + OK("ok"), REPLACE("replace"); + + private final String state; + + private BatteryHealth(String state) { + this.state = state; + } + + @JsonValue + public String value() { + return state; + } + + @JsonCreator + public static BatteryHealth forValue(String v) { + for (BatteryHealth bs : BatteryHealth.values()) { + if (bs.state.equals(v)) { + return bs; + } + } + throw new IllegalArgumentException("Invalid battery_state: " + v); + } + + @Override + public String toString() { + return this.state; + } + } + + /** + * Possible values for *_alarm_state: + * + *
        + *
        ok
        + *
        OK
        + *
        warning
        + *
        Warning - CO Detected
        + *
        emergency
        + *
        Emergency - * Detected - move to fresh air
        + *
        + */ + public static enum AlarmState { + OK("ok"), WARNING("warning"), EMERGENCY("emergency"); + + private final String state; + + private AlarmState(String state) { + this.state = state; + } + + @JsonValue + public String value() { + return state; + } + + @JsonCreator + public static AlarmState forValue(String v) { + for (AlarmState as : AlarmState.values()) { + if (as.state.equals(v)) { + return as; + } + } + throw new IllegalArgumentException("Invalid alarm_state: " + v); + } + + @Override + public String toString() { + return this.state; + } + } + + /** + * Indicates device status by color in the Nest app UI; it is an aggregate condition for battery+smoke+co states, + * and reflects the actual color indicators displayed in the Nest app + * + * Possible values for ui_color_state + *
        + *
        gray
        + *
        Offline
        + *
        green
        + *
        OK
        + *
        yellow
        + *
        Warning
        + *
        red
        + *
        Emergency
        + *
        + */ + public static enum ColorState { + OFFLINE("gray"), OK("green"), WARNING("yellow"), EMERGENCY("red"); + + private final String state; + + private ColorState(String state) { + this.state = state; + } + + @JsonValue + public String value() { + return state; + } + + @JsonCreator + public static ColorState forValue(String v) { + for (ColorState cs : ColorState.values()) { + if (cs.state.equals(v)) { + return cs; + } + } + throw new IllegalArgumentException("Invalid color_state: " + v); + } + + @Override + public String toString() { + return this.state; + } + } + + private BatteryHealth battery_health; + private AlarmState co_alarm_state; + private AlarmState smoke_alarm_state; + private Boolean is_manual_test_active; + private Date last_manual_test_time; + private ColorState ui_color_state; + + public SmokeCOAlarm(@JsonProperty("device_id") String device_id) { + super(device_id); + } + + /** + * @return Battery life/health; estimate of time to end of life + */ + @JsonProperty("battery_health") + public BatteryHealth getBattery_health() { + return this.battery_health; + } + + /** + * @return CO alarm status + */ + @JsonProperty("co_alarm_state") + public AlarmState getCo_alarm_state() { + return this.co_alarm_state; + } + + /** + * @return Smoke alarm status + */ + @JsonProperty("smoke_alarm_state") + public AlarmState getSmoke_alarm_state() { + return this.smoke_alarm_state; + } + + /** + * @return State of the manual smoke and CO alarm test. + */ + @JsonProperty("is_manual_test_active") + public Boolean getIs_manual_test_active() { + return this.is_manual_test_active; + } + + /** + * @return Timestamp of the last successful manual test. + */ + @JsonProperty("last_manual_test_time") + public Date getLast_manual_test_time() { + return this.last_manual_test_time; + } + + /** + * @return Indicates device status by color in the Nest app UI; it is an aggregate condition for battery+smoke+co + * states, and reflects the actual color indicators displayed in the Nest app. + */ + @JsonProperty("ui_color_state") + public ColorState getUi_color_state() { + return this.ui_color_state; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("battery_health", this.battery_health); + builder.append("co_alarm_state", this.co_alarm_state); + builder.append("smoke_alarm_state", this.smoke_alarm_state); + builder.append("is_manual_test_active", this.is_manual_test_active); + builder.append("last_manual_test_time", this.last_manual_test_time); + builder.append("ui_color_state", this.ui_color_state); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Structure.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Structure.java new file mode 100644 index 00000000000..0e51dafebe3 --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Structure.java @@ -0,0 +1,311 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.annotate.JsonValue; + +/** + * The Structure Java Bean represents a Nest structure. + * + * @see API Reference + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Structure extends AbstractMessagePart implements DataModelElement { + + /** + * Describes the Structure state; see the Away Guide for more information. + * + * @see Structure state + * @see Away Guide + * @see API Overview + */ + public static enum AwayState { + HOME("home"), AWAY("away"), AUTO_AWAY("auto-away"), UNKNOWN("unknown"); + + private final String state; + + private AwayState(String state) { + this.state = state; + } + + @JsonValue + public String value() { + return state; + } + + @JsonCreator + public static AwayState forValue(String v) { + for (AwayState s : AwayState.values()) { + if (s.state.equals(v)) { + return s; + } + } + throw new IllegalArgumentException("Invalid state: " + v); + } + + @Override + public String toString() { + return this.state; + } + } + + public static class ETA { + String trip_id; // Unique identifier for this ETA instance + Date estimated_arrival_window_begin; // Beginning time of the estimated arrival window + Date estimated_arrival_window_end; // End time of the estimated arrival window + + /** + * @return the trip_id + */ + @JsonProperty("trip_id") + public String getTrip_id() { + return this.trip_id; + } + + /** + * @param trip_id + * the trip_id to set + */ + @JsonProperty("trip_id") + public void setTrip_id(String trip_id) { + this.trip_id = trip_id; + } + + /** + * @return the estimated_arrival_window_begin + */ + @JsonProperty("estimated_arrival_window_begin") + public Date getEstimated_arrival_window_begin() { + return this.estimated_arrival_window_begin; + } + + /** + * @param estimated_arrival_window_begin + * the estimated_arrival_window_begin to set + */ + @JsonProperty("estimated_arrival_window_begin") + public void setEstimated_arrival_window_begin(Date estimated_arrival_window_begin) { + this.estimated_arrival_window_begin = estimated_arrival_window_begin; + } + + /** + * @return the estimated_arrival_window_end + */ + @JsonProperty("estimated_arrival_window_end") + public Date getEstimated_arrival_window_end() { + return this.estimated_arrival_window_end; + } + + /** + * @param estimated_arrival_window_end + * the estimated_arrival_window_end to set + */ + @JsonProperty("estimated_arrival_window_end") + public void setEstimated_arrival_window_end(Date estimated_arrival_window_end) { + this.estimated_arrival_window_end = estimated_arrival_window_end; + } + } + + private String structure_id; + @JsonProperty("thermostats") + private List thermostat_id_list; + private Map thermostats_by_name; + @JsonProperty("smoke_co_alarms") + private List smoke_co_alarm_id_list; + private Map smoke_co_alarms_by_name; + private AwayState away; + private String name; + private String country_code; + private String postal_code; + private Date peak_period_start_time; + private Date peak_period_end_time; + private String time_zone; + private ETA eta; + + public Structure(@JsonProperty("structure_id") String structure_id) { + this.structure_id = structure_id; + } + + /** + * @return the structure_id + */ + @JsonProperty("structure_id") + public String getStructure_id() { + return this.structure_id; + } + + /** + * @return the thermostats + */ + @JsonProperty("thermostats") + public List getThermostat_id_list() { + return this.thermostat_id_list; + } + + public Map getThermostats() { + return this.thermostats_by_name; + } + + public void setThermostats_by_name(Map thermostats_by_name) { + this.thermostats_by_name = thermostats_by_name; + } + + /** + * @return the smoke_co_alarms + */ + @JsonProperty("smoke_co_alarms") + public List getSmoke_co_alarm_id_list() { + return this.smoke_co_alarm_id_list; + } + + public Map getSmoke_co_alarms() { + return this.smoke_co_alarms_by_name; + } + + public void setSmoke_co_alarms_by_name(Map smoke_co_alarms_by_name) { + this.smoke_co_alarms_by_name = smoke_co_alarms_by_name; + } + + /** + * @return the away state + */ + @JsonProperty("away") + public AwayState getAway() { + return this.away; + } + + /** + * @param away + * the away to set + */ + @JsonProperty("away") + public void setAway(AwayState away) { + this.away = away; + } + + /** + * @return the name + */ + @JsonProperty("name") + public String getName() { + return this.name; + } + + /** + * @return the country_code + */ + @JsonProperty("country_code") + public String getCountry_code() { + return this.country_code; + } + + /** + * @return the postal_code + */ + @JsonProperty("postal_code") + public String getPostal_code() { + return this.postal_code; + } + + /** + * @return the peak_period_start_time + */ + @JsonProperty("peak_period_start_time") + public Date getPeak_period_start_time() { + return this.peak_period_start_time; + } + + /** + * @return the peak_period_end_time + */ + @JsonProperty("peak_period_end_time") + public Date getPeak_period_end_time() { + return this.peak_period_end_time; + } + + /** + * @return the time_zone + */ + @JsonProperty("time_zone") + public String getTime_zone() { + return this.time_zone; + } + + /** + * @return the eta + */ + @JsonProperty("eta") + public ETA getEta() { + return this.eta; + } + + /** + * Set the eta. + */ + @JsonProperty("eta") + public void setEta(ETA eta) { + this.eta = eta; + } + + /** + * This method creates maps to device objects, using the list of device IDs that were unmarshalled from JSON. + */ + @Override + public void sync(DataModel dataModel) { + // Build named-based maps from ID-based maps + this.thermostats_by_name = new HashMap(); + if (this.thermostat_id_list != null) { + for (String id : this.thermostat_id_list) { + Thermostat th = dataModel.getDevices().getThermostats_by_id().get(id); + if (th != null) { + this.thermostats_by_name.put(th.getName(), th); + } + } + } + this.smoke_co_alarms_by_name = new HashMap(); + if (this.smoke_co_alarm_id_list != null) { + for (String id : this.smoke_co_alarm_id_list) { + SmokeCOAlarm sm = dataModel.getDevices().getSmoke_co_alarms_by_id().get(id); + if (sm != null) { + this.smoke_co_alarms_by_name.put(sm.getName(), sm); + } + } + } + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("structure_id", this.structure_id); + builder.append("thermostats", this.thermostat_id_list); + builder.append("smoke_co_alarms", this.smoke_co_alarm_id_list); + builder.append("away", this.away); + builder.append("name", this.name); + builder.append("country_code", this.country_code); + builder.append("postal_code", this.postal_code); + builder.append("peak_period_start_time", this.peak_period_start_time); + builder.append("peak_period_end_time", this.peak_period_end_time); + builder.append("time_zone", this.time_zone); + builder.append("eta", this.eta); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Thermostat.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Thermostat.java new file mode 100644 index 00000000000..00f9e04986f --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/Thermostat.java @@ -0,0 +1,363 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +import java.math.BigDecimal; +import java.util.Date; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.annotate.JsonValue; + +/** + * The Thermostat Java Bean represents a Nest thermostat. All objects relate in one way or another to a real thermostat. + * The Thermostat class and its component classes define the real thermostat device. + * + * @see API Reference + * @author John Cocula + * @since 1.7.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Thermostat extends AbstractDevice { + + /** + * Possible values for hvac_mode + */ + public static enum HvacMode { + HEAT("heat"), COOL("cool"), HEAT_COOL("heat-cool"), OFF("off"); + + private final String mode; + + private HvacMode(String mode) { + this.mode = mode; + } + + @JsonValue + public String value() { + return mode; + } + + @JsonCreator + public static HvacMode forValue(String v) { + for (HvacMode hm : HvacMode.values()) { + if (hm.mode.equals(v)) { + return hm; + } + } + throw new IllegalArgumentException("Invalid hvac_mode: " + v); + } + + @Override + public String toString() { + return this.mode; + } + } + + private Boolean can_cool; + private Boolean can_heat; + private Boolean is_using_emergency_heat; + private Boolean has_fan; + private Boolean fan_timer_active; + private Date fan_timer_timeout; + private Boolean has_leaf; + private String temperature_scale; + private BigDecimal target_temperature_f; + private BigDecimal target_temperature_c; + private BigDecimal target_temperature_high_f; + private BigDecimal target_temperature_high_c; + private BigDecimal target_temperature_low_f; + private BigDecimal target_temperature_low_c; + private BigDecimal away_temperature_high_f; + private BigDecimal away_temperature_high_c; + private BigDecimal away_temperature_low_f; + private BigDecimal away_temperature_low_c; + private HvacMode hvac_mode; + private BigDecimal ambient_temperature_f; + private BigDecimal ambient_temperature_c; + private BigDecimal humidity; + + public Thermostat(@JsonProperty("device_id") String device_id) { + super(device_id); + } + + /** + * @return System ability to cool (AC) + */ + @JsonProperty("can_cool") + public Boolean getCan_cool() { + return this.can_cool; + } + + /** + * @return System ability to heat + */ + @JsonProperty("can_heat") + public Boolean getCan_heat() { + return this.can_heat; + } + + /** + * @return Emergency Heat status in systems with heat pumps + */ + @JsonProperty("is_using_emergency_heat") + public Boolean getIs_using_emergency_heat() { + return this.is_using_emergency_heat; + } + + /** + * @return System ability to control the fan separately from heating or cooling + */ + @JsonProperty("has_fan") + public Boolean getHas_fan() { + return this.has_fan; + } + + /** + * @return Indicates if the fan timer is engaged; used with 'fan_timer_timeout' to turn on the fan for a + * (user-specified) preset duration + */ + @JsonProperty("fan_timer_active") + public Boolean getFan_timer_active() { + return this.fan_timer_active; + } + + /** + * Sets if the fan timer is engaged; used with 'fan_timer_timeout' to turn on the fan for a (user-specified) preset + * duration + */ + @JsonProperty("fan_timer_active") + public void setFan_timer_active(Boolean fan_timer_active) { + this.fan_timer_active = fan_timer_active; + } + + /** + * @return Timestamp, showing when the fan timer reaches 0 (end of timer duration) + */ + @JsonProperty("fan_timer_timeout") + public Date getFan_timer_timeout() { + return this.fan_timer_timeout; + } + + /** + * @return Displayed when users choose an energy-saving temperature + */ + @JsonProperty("has_leaf") + public Boolean getHas_leaf() { + return this.has_leaf; + } + + /** + * @return Celsius or Fahrenheit; used with temperature display + */ + @JsonProperty("temperature_scale") + public String getTemperature_scale() { + return this.temperature_scale; + } + + /** + * @return Desired temperature, displayed in whole degrees Fahrenheit (1°F) + */ + @JsonProperty("target_temperature_f") + public BigDecimal getTarget_temperature_f() { + return this.target_temperature_f; + } + + /** + * Desired temperature, displayed in whole degrees Fahrenheit (1°F) + */ + @JsonProperty("target_temperature_f") + public void setTarget_temperature_f(BigDecimal target_temperature_f) { + this.target_temperature_f = target_temperature_f; + } + + /** + * @return Desired temperature, displayed in half degrees Celsius (0.5°C) + */ + @JsonProperty("target_temperature_c") + public BigDecimal getTarget_temperature_c() { + return this.target_temperature_c; + } + + /** + * Desired temperature, displayed in half degrees Celsius (0.5°C) + */ + @JsonProperty("target_temperature_c") + public void setTarget_temperature_c(BigDecimal target_temperature_c) { + this.target_temperature_c = target_temperature_c; + } + + /** + * @return Maximum target temperature, displayed in whole degrees Fahrenheit (1°F); used with Heat • Cool mode + */ + @JsonProperty("target_temperature_high_f") + public BigDecimal getTarget_temperature_high_f() { + return this.target_temperature_high_f; + } + + /** + * Maximum target temperature, displayed in whole degrees Fahrenheit (1°F); used with Heat • Cool mode + */ + @JsonProperty("target_temperature_high_f") + public void setTarget_temperature_high_f(BigDecimal target_temperature_high_f) { + this.target_temperature_high_f = target_temperature_high_f; + } + + /** + * @return Maximum target temperature, displayed in half degrees Celsius (0.5°C); used with Heat • Cool mode + */ + @JsonProperty("target_temperature_high_c") + public BigDecimal getTarget_temperature_high_c() { + return this.target_temperature_high_c; + } + + /** + * Maximum target temperature, displayed in half degrees Celsius (0.5°C); used with Heat • Cool mode + */ + @JsonProperty("target_temperature_high_c") + public void setTarget_temperature_high_c(BigDecimal target_temperature_high_c) { + this.target_temperature_high_c = target_temperature_high_c; + } + + /** + * @return Minimum target temperature, displayed in whole degrees Fahrenheit (1°F); used with Heat • Cool mode + */ + @JsonProperty("target_temperature_low_f") + public BigDecimal getTarget_temperature_low_f() { + return this.target_temperature_low_f; + } + + /** + * Minimum target temperature, displayed in whole degrees Fahrenheit (1°F); used with Heat • Cool mode + */ + @JsonProperty("target_temperature_low_f") + public void setTarget_temperature_low_f(BigDecimal target_temperature_low_f) { + this.target_temperature_low_f = target_temperature_low_f; + } + + /** + * @return Minimum target temperature, displayed in half degrees Celsius (0.5°C); used with Heat • Cool mode + */ + @JsonProperty("target_temperature_low_c") + public BigDecimal getTarget_temperature_low_c() { + return this.target_temperature_low_c; + } + + /** + * Minimum target temperature, displayed in half degrees Celsius (0.5°C); used with Heat • Cool mode + */ + @JsonProperty("target_temperature_low_c") + public void setTarget_temperature_low_c(BigDecimal target_temperature_low_c) { + this.target_temperature_low_c = target_temperature_low_c; + } + + /** + * @return Maximum 'away' temperature, displayed in whole degrees Fahrenheit (1°F) + */ + @JsonProperty("away_temperature_high_f") + public BigDecimal getAway_temperature_high_f() { + return this.away_temperature_high_f; + } + + /** + * @return Maximum 'away' temperature, displayed in half degrees Celsius (0.5°C) + */ + @JsonProperty("away_temperature_high_c") + public BigDecimal getAway_temperature_high_c() { + return this.away_temperature_high_c; + } + + /** + * @return Minimum 'away' temperature, displayed in whole degrees Fahrenheit (1°F) + */ + @JsonProperty("away_temperature_low_f") + public BigDecimal getAway_temperature_low_f() { + return this.away_temperature_low_f; + } + + /** + * @return Minimum 'away' temperature, displayed in half degrees Celsius (0.5°C) + */ + @JsonProperty("away_temperature_low_c") + public BigDecimal getAway_temperature_low_c() { + return this.away_temperature_low_c; + } + + /** + * @return Indicates HVAC system heating/cooling modes; for systems with both heating and cooling capability, use + * 'heat-cool': (Heat • Cool mode) + */ + @JsonProperty("hvac_mode") + public HvacMode getHvac_mode() { + return this.hvac_mode; + } + + /** + * Indicates HVAC system heating/cooling modes; for systems with both heating and cooling capability, use + * 'heat-cool': (Heat • Cool mode) + */ + @JsonProperty("hvac_mode") + public void setHvac_mode(HvacMode hvac_mode) { + this.hvac_mode = hvac_mode; + } + + /** + * @return Temperature, measured at the device, in whole degrees Fahrenheit (1°F) + */ + @JsonProperty("ambient_temperature_f") + public BigDecimal getAmbient_temperature_f() { + return this.ambient_temperature_f; + } + + /** + * @return Temperature, measured at the device, in half degrees Celsius (0.5°C) + */ + @JsonProperty("ambient_temperature_c") + public BigDecimal getAmbient_temperature_c() { + return this.ambient_temperature_c; + } + + /** + * @return Humidity, in percent (%) format, measured at the device. + */ + @JsonProperty("humidity") + public BigDecimal getHumidity() { + return this.humidity; + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("can_cool", this.can_cool); + builder.append("can_heat", this.can_heat); + builder.append("is_using_emergency_heat", this.is_using_emergency_heat); + builder.append("has_fan", this.has_fan); + builder.append("fan_timer_active", this.fan_timer_active); + builder.append("fan_timer_timeout", this.fan_timer_timeout); + builder.append("has_leaf", this.has_leaf); + builder.append("temperature_scale", this.temperature_scale); + builder.append("target_temperature_f", this.target_temperature_f); + builder.append("target_temperature_c", this.target_temperature_c); + builder.append("target_temperature_high_f", this.target_temperature_high_f); + builder.append("target_temperature_high_c", this.target_temperature_high_c); + builder.append("target_temperature_low_f", this.target_temperature_low_f); + builder.append("target_temperature_low_c", this.target_temperature_low_c); + builder.append("away_temperature_high_f", this.away_temperature_high_f); + builder.append("away_temperature_high_c", this.away_temperature_high_c); + builder.append("away_temperature_low_f", this.away_temperature_low_f); + builder.append("away_temperature_low_c", this.away_temperature_low_c); + builder.append("hvac_mode", this.hvac_mode); + builder.append("ambient_temperature_f", this.ambient_temperature_f); + builder.append("ambient_temperature_c", this.ambient_temperature_c); + builder.append("humidity", this.humidity); + + return builder.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/UpdateDataModelRequest.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/UpdateDataModelRequest.java new file mode 100644 index 00000000000..4027015ae1b --- /dev/null +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/messages/UpdateDataModelRequest.java @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.nest.internal.messages; + +//import static org.openhab.io.net.http.HttpUtil.executeUrl; + +import java.io.IOException; + +import org.apache.commons.httpclient.util.URIUtil; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.annotate.JsonIgnore; +import org.codehaus.jackson.map.JsonMappingException; +import org.openhab.binding.nest.internal.NestException; + +/** + * Updates the data model in the Nest API. + * + * @author John Cocula + * @since 1.7.0 + */ +public class UpdateDataModelRequest extends AbstractRequest { + + private static final String RESOURCE_URL = API_BASE_URL; + + @JsonIgnore + private final String accessToken; + + private final DataModel dataModel; + + /** + * Creates a request for the measurements of a device or module. + * + * If you don't specify a moduleId you will retrieve the device's measurements. If you do specify a moduleId you + * will retrieve the module's measurements. + * + * @param accessToken + * the access token that permits this API call + * @param selection + * which thermostats will be updated + * @param functions + * optional, a list of functions to send + * @param thermostat + * optional, a thermostat that has writable properties specified + */ + public UpdateDataModelRequest(final String accessToken, final DataModel dataModel) { + assert accessToken != null : "accessToken must not be null!"; + + this.accessToken = accessToken; + this.dataModel = dataModel; + } + + @Override + public DataModelResponse execute() { + final String url = buildQueryString(); + String json = null; + + try { + json = executeQuery(url); + + final DataModelResponse response = JSON.readValue(json, DataModelResponse.class); + + return response; + } catch (final Exception e) { + throw newException("Could not update data model.", e, url, json); + } + } + + @Override + public String toString() { + final ToStringBuilder builder = createToStringBuilder(); + builder.appendSuper(super.toString()); + builder.append("accessToken", this.accessToken); + if (this.dataModel != null) { + builder.append("dataModel", this.dataModel); + } + + return builder.toString(); + } + + protected String executeQuery(final String url) throws JsonGenerationException, JsonMappingException, IOException { + return executeUrl(HTTP_PUT, url, JSON.writeValueAsString(this.dataModel), "application/json"); + } + + private String buildQueryString() { + final StringBuilder urlBuilder = new StringBuilder(RESOURCE_URL); + + try { + urlBuilder.append("?auth="); + urlBuilder.append(this.accessToken); + return URIUtil.encodeQuery(urlBuilder.toString()); + } catch (final Exception e) { + throw new NestException(e); + } + } +} diff --git a/bundles/binding/org.openhab.binding.netatmo.test/src/test/java/org/openhab/binding/netatmo/internal/messages/DeviceListTest.java b/bundles/binding/org.openhab.binding.netatmo.test/src/test/java/org/openhab/binding/netatmo/internal/messages/DeviceListTest.java index 308e0071399..98106136326 100644 --- a/bundles/binding/org.openhab.binding.netatmo.test/src/test/java/org/openhab/binding/netatmo/internal/messages/DeviceListTest.java +++ b/bundles/binding/org.openhab.binding.netatmo.test/src/test/java/org/openhab/binding/netatmo/internal/messages/DeviceListTest.java @@ -40,7 +40,7 @@ public void testSuccess() throws Exception { final DeviceListResponse response = request.execute(); assertFalse(response.isError()); - assertEquals("http://api.netatmo.net/api/devicelist?access_token=" + assertEquals("https://api.netatmo.net/api/devicelist?access_token=" + ACCESS_TOKEN, request.getQuery()); assertEquals("ok", response.getStatus()); diff --git a/bundles/binding/org.openhab.binding.netatmo.test/src/test/java/org/openhab/binding/netatmo/internal/messages/MeasurementTest.java b/bundles/binding/org.openhab.binding.netatmo.test/src/test/java/org/openhab/binding/netatmo/internal/messages/MeasurementTest.java index 21baa59ead7..56177c91054 100644 --- a/bundles/binding/org.openhab.binding.netatmo.test/src/test/java/org/openhab/binding/netatmo/internal/messages/MeasurementTest.java +++ b/bundles/binding/org.openhab.binding.netatmo.test/src/test/java/org/openhab/binding/netatmo/internal/messages/MeasurementTest.java @@ -57,7 +57,7 @@ public void testSuccess() throws Exception { assertFalse(response.isError()); assertNull(response.getError()); - assertEquals("http://api.netatmo.net/api/getmeasure?access_token=" + assertEquals("https://api.netatmo.net/api/getmeasure?access_token=" + encodeQuery(ACCESS_TOKEN) + "&scale=max&date_end=last&device_id=" + DEVICE_ID + "&module_id=" + MODULE_ID + "&type=Humidity,Temperature", diff --git a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoBinding.java b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoBinding.java index 49e6bccd460..81d0f542bda 100644 --- a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoBinding.java +++ b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoBinding.java @@ -32,10 +32,11 @@ import org.openhab.binding.netatmo.internal.messages.NetatmoError; import org.openhab.binding.netatmo.internal.messages.RefreshTokenRequest; import org.openhab.binding.netatmo.internal.messages.RefreshTokenResponse; -import org.openhab.binding.netatmo.internal.NetatmoMeasureType; import org.openhab.core.binding.AbstractActiveBinding; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.PointType; +import org.openhab.core.library.types.StringType; import org.openhab.core.types.State; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedService; @@ -44,480 +45,573 @@ /** * Binding that gets measurements from the Netatmo API every couple of minutes. - * + * * @author Andreas Brenk * @author Thomas.Eichstaedt-Engelen * @author Gaël L'hopital * @since 1.4.0 */ public class NetatmoBinding extends - AbstractActiveBinding implements ManagedService { - - private static final String DEFAULT_USER_ID = "DEFAULT_USER"; - - private static final Logger logger = - LoggerFactory.getLogger(NetatmoBinding.class); - - protected static final String CONFIG_CLIENT_ID = "clientid"; - protected static final String CONFIG_CLIENT_SECRET = "clientsecret"; - protected static final String CONFIG_REFRESH = "refresh"; - protected static final String CONFIG_REFRESH_TOKEN = "refreshtoken"; - - /** - * The refresh interval which is used to poll values from the Netatmo server - * (optional, defaults to 300000ms) - */ - private long refreshInterval = 300000; - - private Map credentialsCache = new HashMap(); - - /** - * {@inheritDoc} - */ - @Override - protected String getName() { - return "Netatmo Refresh Service"; - } - - /** - * {@inheritDoc} - */ - @Override - protected long getRefreshInterval() { - return this.refreshInterval; - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("incomplete-switch") - @Override - protected void execute() { - logger.debug("Querying Netatmo API"); - for (String userid : credentialsCache.keySet()) { - - OAuthCredentials oauthCredentials = getOAuthCredentials(userid); - if (oauthCredentials.noAccessToken()) { - // initial run after a restart, so get an access token first - oauthCredentials.refreshAccessToken(); - } - - try { - if (oauthCredentials.firstExecution) { - processDeviceList(oauthCredentials); - } - - DeviceMeasureValueMap deviceMeasureValueMap = processMeasurements(oauthCredentials); - for (final NetatmoBindingProvider provider : this.providers) { - for (final String itemName : provider.getItemNames()) { - final String deviceId = provider.getDeviceId(itemName); - final String moduleId = provider.getModuleId(itemName); - final NetatmoMeasureType measureType = provider.getMeasureType(itemName); - - State state = null; - switch (measureType) { - case TIMESTAMP: - state = deviceMeasureValueMap.timeStamp; - break; - case TEMPERATURE: case CO2: case HUMIDITY: case NOISE: case PRESSURE: case RAIN: - final String requestKey = createKey(deviceId, moduleId); - final BigDecimal value = deviceMeasureValueMap.get(requestKey).get(measureType.getMeasure()); - // Protect that sometimes Netatmo returns null where numeric value is awaited (issue #1848) - if (value != null) { - state = new DecimalType(value); - } - break; - case BATTERYVP: case RFSTATUS: - for (Module module : oauthCredentials.deviceListResponse.getModules()) { - if (module.getId().equals(moduleId)) { - switch (measureType) { - case BATTERYVP: state = new DecimalType(module.getBatteryVp()); break; - case RFSTATUS: state = new DecimalType(module.getRfStatus()); break; - } - } - } - break; - case ALTITUDE: case LATITUDE: case LONGITUDE: case WIFISTATUS: - for (Device device : oauthCredentials.deviceListResponse.getDevices()) { - if (device.getId().equals(deviceId)) { - switch (measureType) { - case ALTITUDE: state = new DecimalType(device.getAltitude()); break; - case LATITUDE: state = new DecimalType(device.getLatitude()); break; - case LONGITUDE: state = new DecimalType(device.getLongitude()); break; - case WIFISTATUS: state = new DecimalType(device.getWifiStatus()); break; - } - } - } - break; - } - - if (state != null) { - this.eventPublisher.postUpdate(itemName, state); - } - } - } - } catch (NetatmoException ne) { - logger.error(ne.getMessage()); - } - } - } - - static class DeviceMeasureValueMap extends HashMap> { + AbstractActiveBinding implements ManagedService { + + private static final String DEFAULT_USER_ID = "DEFAULT_USER"; + + private static final Logger logger = LoggerFactory + .getLogger(NetatmoBinding.class); + + protected static final String CONFIG_CLIENT_ID = "clientid"; + protected static final String CONFIG_CLIENT_SECRET = "clientsecret"; + protected static final String CONFIG_REFRESH = "refresh"; + protected static final String CONFIG_REFRESH_TOKEN = "refreshtoken"; + + /** + * The refresh interval which is used to poll values from the Netatmo server + * (optional, defaults to 300000ms) + */ + private long refreshInterval = 300000; + + private PointType stationPosition = null; + + private Map credentialsCache = new HashMap(); + + /** + * {@inheritDoc} + */ + @Override + protected String getName() { + return "Netatmo Refresh Service"; + } + + /** + * {@inheritDoc} + */ + @Override + protected long getRefreshInterval() { + return this.refreshInterval; + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("incomplete-switch") + @Override + protected void execute() { + logger.debug("Querying Netatmo API"); + for (String userid : credentialsCache.keySet()) { + + OAuthCredentials oauthCredentials = getOAuthCredentials(userid); + if (oauthCredentials.noAccessToken()) { + // initial run after a restart, so get an access token first + oauthCredentials.refreshAccessToken(); + } + + try { + if (oauthCredentials.firstExecution) { + processDeviceList(oauthCredentials); + } + + DeviceMeasureValueMap deviceMeasureValueMap = processMeasurements(oauthCredentials); + for (final NetatmoBindingProvider provider : this.providers) { + for (final String itemName : provider.getItemNames()) { + final String deviceId = provider.getDeviceId(itemName); + final String moduleId = provider.getModuleId(itemName); + final NetatmoMeasureType measureType = provider + .getMeasureType(itemName); + + State state = null; + switch (measureType) { + case MODULENAME: + if (moduleId == null) // we're on the main device + for (Device device : oauthCredentials.deviceListResponse + .getDevices()) { + if (device.getId().equals(deviceId)) { + state = new StringType( + device.getModuleName()); + break; + } + } + else { + for (Module module : oauthCredentials.deviceListResponse + .getModules()) { + if (module.getId().equals(moduleId)) { + state = new StringType( + module.getModuleName()); + break; + } + } + } + break; + case TIMESTAMP: + state = deviceMeasureValueMap.timeStamp; + break; + case TEMPERATURE: + case CO2: + case HUMIDITY: + case NOISE: + case PRESSURE: + case RAIN: + final String requestKey = createKey(deviceId, + moduleId); + final BigDecimal value = deviceMeasureValueMap.get( + requestKey).get(measureType.getMeasure()); + // Protect that sometimes Netatmo returns null where + // numeric value is awaited (issue #1848) + if (value != null) { + state = new DecimalType(value); + } + break; + case BATTERYVP: + case RFSTATUS: + for (Module module : oauthCredentials.deviceListResponse + .getModules()) { + if (module.getId().equals(moduleId)) { + switch (measureType) { + case BATTERYVP: + state = new DecimalType( + module.getBatteryLevel()); + break; + case RFSTATUS: + state = new DecimalType( + module.getRfLevel()); + break; + case MODULENAME: + state = new StringType( + module.getModuleName()); + break; + } + } + } + break; + case ALTITUDE: + case LATITUDE: + case LONGITUDE: + case WIFISTATUS: + case COORDINATE: + case STATIONNAME: + for (Device device : oauthCredentials.deviceListResponse + .getDevices()) { + if (stationPosition == null) { + stationPosition = new PointType( + new DecimalType( + device.getLatitude()), + new DecimalType(device + .getLongitude()), + new DecimalType(device + .getAltitude())); + } + if (device.getId().equals(deviceId)) { + switch (measureType) { + case LATITUDE: + state = stationPosition.getLatitude(); + break; + case LONGITUDE: + state = stationPosition.getLongitude(); + break; + case ALTITUDE: + state = stationPosition.getAltitude(); + break; + case WIFISTATUS: + state = new DecimalType( + device.getWifiLevel()); + break; + case COORDINATE: + state = stationPosition; + break; + case STATIONNAME: + state = new StringType( + device.getStationName()); + break; + } + } + } + break; + } + + if (state != null) { + this.eventPublisher.postUpdate(itemName, state); + } + } + } + } catch (NetatmoException ne) { + logger.error(ne.getMessage()); + } + } + } + + static class DeviceMeasureValueMap extends + HashMap> { /** - * + * */ private static final long serialVersionUID = 1L; - DateTimeType timeStamp = null; - } - - private DeviceMeasureValueMap processMeasurements(OAuthCredentials oauthCredentials) { - //Map> deviceMeasureValueMap = new HashMap>(); - DeviceMeasureValueMap deviceMeasureValueMap = new DeviceMeasureValueMap(); - - for (final MeasurementRequest request : createMeasurementRequests()) { - final MeasurementResponse response = request.execute(); - - logger.debug("Request: {}", request); - logger.debug("Response: {}", response); - - if (response.isError()) { - final NetatmoError error = response.getError(); - - if (error.isAccessTokenExpired()) { - oauthCredentials.refreshAccessToken(); - execute(); - } else { - throw new NetatmoException(error.getMessage()); - } - - break; // abort processing measurement requests - } else { - processMeasurementResponse(request, response, deviceMeasureValueMap); - } - } - - return deviceMeasureValueMap; - } - - - private void processDeviceList(OAuthCredentials oauthCredentials) { - logger.debug("Request: {}", oauthCredentials.deviceListRequest); - logger.debug("Response: {}", oauthCredentials.deviceListResponse); - - if (oauthCredentials.deviceListResponse.isError()) { - final NetatmoError error = oauthCredentials.deviceListResponse.getError(); - - if (error.isAccessTokenExpired()) { - oauthCredentials.refreshAccessToken(); - execute(); - } else { - throw new NetatmoException(error.getMessage()); - } - - return; // abort processing - } else { - processDeviceListResponse(oauthCredentials.deviceListResponse); - oauthCredentials.firstExecution = false; - } - } - - /** - * Processes an incoming {@link DeviceListResponse}. - *

        - */ - private void processDeviceListResponse(final DeviceListResponse response) { - // Prepare a map of all known device measurements - final Map deviceMap = new HashMap(); - final Map> deviceMeasurements = new HashMap>(); - - for (final Device device : response.getDevices()) { - final String deviceId = device.getId(); - deviceMap.put(deviceId, device); - - for (final String measurement : device.getMeasurements()) { - if (!deviceMeasurements.containsKey(deviceId)) { - deviceMeasurements.put(deviceId, new HashSet()); - } - - deviceMeasurements.get(deviceId).add(measurement); - } - } - - // Prepare a map of all known module measurements - final Map moduleMap = new HashMap(); - final Map> moduleMeasurements = new HashMap>(); - - for (final Module module : response.getModules()) { - final String moduleId = module.getId(); - moduleMap.put(moduleId, module); - - for (final String measurement : module.getMeasurements()) { - if (!moduleMeasurements.containsKey(moduleId)) { - moduleMeasurements.put(moduleId, new HashSet()); - } - - moduleMeasurements.get(moduleId).add(measurement); - } - } - - // Remove all configured items from the maps - for (final NetatmoBindingProvider provider : this.providers) { - for (final String itemName : provider.getItemNames()) { - final String deviceId = provider.getDeviceId(itemName); - final String moduleId = provider.getModuleId(itemName); - final NetatmoMeasureType measureType = provider.getMeasureType(itemName); - - final Set measurements; - - if (moduleId != null) { - measurements = moduleMeasurements.get(moduleId); - } else { - measurements = deviceMeasurements.get(deviceId); - } - - if (measurements != null) { - measurements.remove(measureType.getMeasure()); - } - } - } - - // Log all unconfigured measurements - final StringBuilder message = new StringBuilder(); - for (Entry> entry : deviceMeasurements.entrySet()) { - final String deviceId = entry.getKey(); - final Device device = deviceMap.get(deviceId); - - for (String measurement : entry.getValue()) { - message.append("\t" + deviceId + "#" + measurement + " (" - + device.getModuleName() + ")\n"); - } - } - - for (Entry> entry : moduleMeasurements.entrySet()) { - final String moduleId = entry.getKey(); - final Module module = moduleMap.get(moduleId); - - for (String measurement : entry.getValue()) { - message.append("\t" + module.getMainDevice() + "#" + moduleId - + "#" + measurement + " (" + module.getModuleName() - + ")\n"); - } - } - if (message.length() > 0) { - message.insert(0,"The following Netatmo measurements are not yet configured:\n"); - logger.info(message.toString()); - } - } - - /** - * Creates the necessary requests to query the Netatmo API for all measures - * that have a binding. One request can query all measures of a single - * device or module. - */ - private Collection createMeasurementRequests() { - final Map requests = new HashMap(); - - for (final NetatmoBindingProvider provider : this.providers) { - for (final String itemName : provider.getItemNames()) { - - final String userid = provider.getUserid(itemName); - final String deviceId = provider.getDeviceId(itemName); - final String moduleId = provider.getModuleId(itemName); - final NetatmoMeasureType measureType = provider.getMeasureType(itemName); - - final String requestKey = createKey(deviceId, moduleId); - - switch (measureType) { - case TEMPERATURE: case CO2: case HUMIDITY: case NOISE: case PRESSURE: case RAIN: - OAuthCredentials oauthCredentials = getOAuthCredentials(userid); - if (oauthCredentials != null) { - if (!requests.containsKey(requestKey)) { - requests.put(requestKey, - new MeasurementRequest(oauthCredentials.accessToken, deviceId, moduleId)); - } - requests.get(requestKey).addMeasure(measureType); - break; - } - default: - break; - } - } - } - - return requests.values(); - } - - private void processMeasurementResponse(final MeasurementRequest request, final MeasurementResponse response, DeviceMeasureValueMap deviceMeasureValueMap) { - final List values = response.getBody().get(0).getValues().get(0); - final Map valueMap = new HashMap(); - - int index = 0; - for (final String measure : request.getMeasures()) { - final BigDecimal value = values.get(index); - valueMap.put(measure, value); - index++; - } - - deviceMeasureValueMap.put(request.getKey(), valueMap); - deviceMeasureValueMap.timeStamp = new DateTimeType(response.getTimeStamp()); - } - - /** - * Returns the cached {@link OAuthCredentials} for the given {@code userid}. - * If their is no such cached {@link OAuthCredentials} element, the cache is - * searched with the {@code DEFAULT_USER}. If there is still no cached element - * found {@code NULL} is returned. - * - * @param userid the userid to find the {@link OAuthCredentials} - * @return the cached {@link OAuthCredentials} or {@code NULL} - */ - private OAuthCredentials getOAuthCredentials(String userid) { - if (credentialsCache.containsKey(userid)) { - return credentialsCache.get(userid); - } else { - return credentialsCache.get(DEFAULT_USER_ID); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void updated(final Dictionary config) throws ConfigurationException { - if (config != null) { - - final String refreshIntervalString = (String) config.get(CONFIG_REFRESH); - if (isNotBlank(refreshIntervalString)) { - this.refreshInterval = Long.parseLong(refreshIntervalString); - } - - Enumeration configKeys = config.keys(); - while (configKeys.hasMoreElements()) { - String configKey = (String) configKeys.nextElement(); - - // the config-key enumeration contains additional keys that we - // don't want to process here ... - if (CONFIG_REFRESH.equals(configKey) || "service.pid".equals(configKey)) { - continue; - } - - String userid; - String configKeyTail; - - if (configKey.contains(".")) { - String[] keyElements = configKey.split("\\."); - userid = keyElements[0]; - configKeyTail = keyElements[1]; - - } else { - userid = DEFAULT_USER_ID; - configKeyTail = configKey; - } - - OAuthCredentials credentials = credentialsCache.get(userid); - if (credentials == null) { - credentials = new OAuthCredentials(); - credentialsCache.put(userid, credentials); - } - - String value = (String) config.get(configKeyTail); - - if (CONFIG_CLIENT_ID.equals(configKeyTail)) { - credentials.clientId = value; - } - else if (CONFIG_CLIENT_SECRET.equals(configKeyTail)) { - credentials.clientSecret= value; - } - else if (CONFIG_REFRESH_TOKEN.equals(configKeyTail)) { - credentials.refreshToken = value; - } - else { - throw new ConfigurationException( - configKey, "the given configKey '" + configKey + "' is unknown"); - } - } - - setProperlyConfigured(true); - } - } - - - /** - * This internal class holds the different crendentials necessary for the - * OAuth2 flow to work. It also provides basic methods to refresh the access - * token. - * - * @author Thomas.Eichstaedt-Engelen - * @since 1.6.0 - */ - static class OAuthCredentials { - - /** - * The client id to access the Netatmo API. Normally set in - * openhab.cfg. - * - * @see Client - * Credentials - */ - String clientId; - - /** - * The client secret to access the Netatmo API. Normally set in - * openhab.cfg. - * - * @see Client - * Credentials - */ - String clientSecret; - - /** - * The refresh token to access the Netatmo API. Normally set in - * openhab.cfg. - * - * @see Client Credentials - * @see Refresh Token - */ - String refreshToken; - - /** - * The access token to access the Netatmo API. Automatically renewed from - * the API using the refresh token. - * - * @see Refresh - * Token - * @see #refreshAccessToken() - */ - String accessToken; - - DeviceListResponse deviceListResponse = null; - DeviceListRequest deviceListRequest = null; - - boolean firstExecution = true; - - public boolean noAccessToken() { - return this.accessToken == null; - } - - public void refreshAccessToken() { - logger.debug("Refreshing access token."); - - final RefreshTokenRequest request = - new RefreshTokenRequest(this.clientId, this.clientSecret, this.refreshToken); - logger.debug("Request: {}", request); - - final RefreshTokenResponse response = request.execute(); - logger.debug("Response: {}", response); - - this.accessToken = response.getAccessToken(); - - deviceListRequest = new DeviceListRequest(this.accessToken); - deviceListResponse = deviceListRequest.execute(); - } - - } + DateTimeType timeStamp = null; + } + + private DeviceMeasureValueMap processMeasurements( + OAuthCredentials oauthCredentials) { + DeviceMeasureValueMap deviceMeasureValueMap = new DeviceMeasureValueMap(); + + for (final MeasurementRequest request : createMeasurementRequests()) { + final MeasurementResponse response = request.execute(); + + logger.debug("Request: {}", request); + logger.debug("Response: {}", response); + + if (response.isError()) { + final NetatmoError error = response.getError(); + + if (error.isAccessTokenExpired()) { + oauthCredentials.refreshAccessToken(); + execute(); + } else { + throw new NetatmoException(error.getMessage()); + } + + break; // abort processing measurement requests + } else { + processMeasurementResponse(request, response, + deviceMeasureValueMap); + } + } + + return deviceMeasureValueMap; + } + + private void processDeviceList(OAuthCredentials oauthCredentials) { + logger.debug("Request: {}", oauthCredentials.deviceListRequest); + logger.debug("Response: {}", oauthCredentials.deviceListResponse); + + if (oauthCredentials.deviceListResponse.isError()) { + final NetatmoError error = oauthCredentials.deviceListResponse + .getError(); + + if (error.isAccessTokenExpired()) { + oauthCredentials.refreshAccessToken(); + execute(); + } else { + throw new NetatmoException(error.getMessage()); + } + + return; // abort processing + } else { + processDeviceListResponse(oauthCredentials.deviceListResponse); + oauthCredentials.firstExecution = false; + } + } + + /** + * Processes an incoming {@link DeviceListResponse}. + *

        + */ + private void processDeviceListResponse(final DeviceListResponse response) { + // Prepare a map of all known device measurements + final Map deviceMap = new HashMap(); + final Map> deviceMeasurements = new HashMap>(); + + for (final Device device : response.getDevices()) { + final String deviceId = device.getId(); + deviceMap.put(deviceId, device); + + for (final String measurement : device.getMeasurements()) { + if (!deviceMeasurements.containsKey(deviceId)) { + deviceMeasurements.put(deviceId, new HashSet()); + } + + deviceMeasurements.get(deviceId).add(measurement); + } + } + + // Prepare a map of all known module measurements + final Map moduleMap = new HashMap(); + final Map> moduleMeasurements = new HashMap>(); + + for (final Module module : response.getModules()) { + final String moduleId = module.getId(); + moduleMap.put(moduleId, module); + + for (final String measurement : module.getMeasurements()) { + if (!moduleMeasurements.containsKey(moduleId)) { + moduleMeasurements.put(moduleId, new HashSet()); + } + + moduleMeasurements.get(moduleId).add(measurement); + } + } + + // Remove all configured items from the maps + for (final NetatmoBindingProvider provider : this.providers) { + for (final String itemName : provider.getItemNames()) { + final String deviceId = provider.getDeviceId(itemName); + final String moduleId = provider.getModuleId(itemName); + final NetatmoMeasureType measureType = provider + .getMeasureType(itemName); + + final Set measurements; + + if (moduleId != null) { + measurements = moduleMeasurements.get(moduleId); + } else { + measurements = deviceMeasurements.get(deviceId); + } + + if (measurements != null) { + measurements.remove(measureType.getMeasure()); + } + } + } + + // Log all unconfigured measurements + final StringBuilder message = new StringBuilder(); + for (Entry> entry : deviceMeasurements.entrySet()) { + final String deviceId = entry.getKey(); + final Device device = deviceMap.get(deviceId); + + for (String measurement : entry.getValue()) { + message.append("\t" + deviceId + "#" + measurement + " (" + + device.getModuleName() + ")\n"); + } + } + + for (Entry> entry : moduleMeasurements.entrySet()) { + final String moduleId = entry.getKey(); + final Module module = moduleMap.get(moduleId); + + for (String measurement : entry.getValue()) { + message.append("\t" + module.getMainDevice() + "#" + moduleId + + "#" + measurement + " (" + module.getModuleName() + + ")\n"); + } + } + if (message.length() > 0) { + message.insert(0, + "The following Netatmo measurements are not yet configured:\n"); + logger.info(message.toString()); + } + } + + /** + * Creates the necessary requests to query the Netatmo API for all measures + * that have a binding. One request can query all measures of a single + * device or module. + */ + private Collection createMeasurementRequests() { + final Map requests = new HashMap(); + + for (final NetatmoBindingProvider provider : this.providers) { + for (final String itemName : provider.getItemNames()) { + + final String userid = provider.getUserid(itemName); + final String deviceId = provider.getDeviceId(itemName); + final String moduleId = provider.getModuleId(itemName); + final NetatmoMeasureType measureType = provider + .getMeasureType(itemName); + + final String requestKey = createKey(deviceId, moduleId); + + switch (measureType) { + case TEMPERATURE: + case CO2: + case HUMIDITY: + case NOISE: + case PRESSURE: + case RAIN: + OAuthCredentials oauthCredentials = getOAuthCredentials(userid); + if (oauthCredentials != null) { + if (!requests.containsKey(requestKey)) { + requests.put(requestKey, new MeasurementRequest( + oauthCredentials.accessToken, deviceId, + moduleId)); + } + requests.get(requestKey).addMeasure(measureType); + break; + } + default: + break; + } + } + } + + return requests.values(); + } + + private void processMeasurementResponse(final MeasurementRequest request, + final MeasurementResponse response, + DeviceMeasureValueMap deviceMeasureValueMap) { + final List values = response.getBody().get(0).getValues() + .get(0); + final Map valueMap = new HashMap(); + + int index = 0; + for (final String measure : request.getMeasures()) { + final BigDecimal value = values.get(index); + valueMap.put(measure, value); + index++; + } + + deviceMeasureValueMap.put(request.getKey(), valueMap); + deviceMeasureValueMap.timeStamp = new DateTimeType( + response.getTimeStamp()); + } + + /** + * Returns the cached {@link OAuthCredentials} for the given {@code userid}. + * If their is no such cached {@link OAuthCredentials} element, the cache is + * searched with the {@code DEFAULT_USER}. If there is still no cached + * element found {@code NULL} is returned. + * + * @param userid + * the userid to find the {@link OAuthCredentials} + * @return the cached {@link OAuthCredentials} or {@code NULL} + */ + private OAuthCredentials getOAuthCredentials(String userid) { + if (credentialsCache.containsKey(userid)) { + return credentialsCache.get(userid); + } else { + return credentialsCache.get(DEFAULT_USER_ID); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void updated(final Dictionary config) + throws ConfigurationException { + if (config != null) { + + final String refreshIntervalString = (String) config + .get(CONFIG_REFRESH); + if (isNotBlank(refreshIntervalString)) { + this.refreshInterval = Long.parseLong(refreshIntervalString); + } + + Enumeration configKeys = config.keys(); + while (configKeys.hasMoreElements()) { + String configKey = configKeys.nextElement(); + + // the config-key enumeration contains additional keys that we + // don't want to process here ... + if (CONFIG_REFRESH.equals(configKey) + || "service.pid".equals(configKey)) { + continue; + } + + String userid; + String configKeyTail; + + if (configKey.contains(".")) { + String[] keyElements = configKey.split("\\."); + userid = keyElements[0]; + configKeyTail = keyElements[1]; + + } else { + userid = DEFAULT_USER_ID; + configKeyTail = configKey; + } + + OAuthCredentials credentials = credentialsCache.get(userid); + if (credentials == null) { + credentials = new OAuthCredentials(); + credentialsCache.put(userid, credentials); + } + + String value = (String) config.get(configKeyTail); + + if (CONFIG_CLIENT_ID.equals(configKeyTail)) { + credentials.clientId = value; + } else if (CONFIG_CLIENT_SECRET.equals(configKeyTail)) { + credentials.clientSecret = value; + } else if (CONFIG_REFRESH_TOKEN.equals(configKeyTail)) { + credentials.refreshToken = value; + } else { + throw new ConfigurationException(configKey, + "the given configKey '" + configKey + + "' is unknown"); + } + } + + setProperlyConfigured(true); + } + } + + /** + * This internal class holds the different crendentials necessary for the + * OAuth2 flow to work. It also provides basic methods to refresh the access + * token. + * + * @author Thomas.Eichstaedt-Engelen + * @since 1.6.0 + */ + static class OAuthCredentials { + + /** + * The client id to access the Netatmo API. Normally set in + * openhab.cfg. + * + * @see Client + * Credentials + */ + String clientId; + + /** + * The client secret to access the Netatmo API. Normally set in + * openhab.cfg. + * + * @see Client + * Credentials + */ + String clientSecret; + + /** + * The refresh token to access the Netatmo API. Normally set in + * openhab.cfg. + * + * @see Client Credentials + * @see Refresh Token + */ + String refreshToken; + + /** + * The access token to access the Netatmo API. Automatically renewed + * from the API using the refresh token. + * + * @see Refresh + * Token + * @see #refreshAccessToken() + */ + String accessToken; + + DeviceListResponse deviceListResponse = null; + DeviceListRequest deviceListRequest = null; + + boolean firstExecution = true; + + public boolean noAccessToken() { + return this.accessToken == null; + } + + public void refreshAccessToken() { + logger.debug("Refreshing access token."); + + final RefreshTokenRequest request = new RefreshTokenRequest( + this.clientId, this.clientSecret, this.refreshToken); + logger.debug("Request: {}", request); + + final RefreshTokenResponse response = request.execute(); + logger.debug("Response: {}", response); + + this.accessToken = response.getAccessToken(); + + deviceListRequest = new DeviceListRequest(this.accessToken); + deviceListResponse = deviceListRequest.execute(); + } + + } } diff --git a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoGenericBindingProvider.java b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoGenericBindingProvider.java index 1e08b61a4c9..6b43bb0a1df 100644 --- a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoGenericBindingProvider.java +++ b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoGenericBindingProvider.java @@ -12,7 +12,9 @@ import org.openhab.core.binding.BindingConfig; import org.openhab.core.items.Item; import org.openhab.core.library.items.DateTimeItem; +import org.openhab.core.library.items.LocationItem; import org.openhab.core.library.items.NumberItem; +import org.openhab.core.library.items.StringItem; import org.openhab.model.item.binding.AbstractGenericBindingProvider; import org.openhab.model.item.binding.BindingConfigParseException; import org.slf4j.Logger; @@ -20,7 +22,7 @@ /** * This class is responsible for parsing the binding configuration. - * + * *

        * Valid bindings for the main device are: *

          @@ -54,7 +56,7 @@ *
        • { netatmo="00:00:00:00:00:00#00:00:00:00:00:00#TimeStamp" }
        • *
        *
      - * + * * @author Andreas Brenk * @author Thomas.Eichstaedt-Engelen * @author Gaël L'hopital @@ -63,8 +65,8 @@ public class NetatmoGenericBindingProvider extends AbstractGenericBindingProvider implements NetatmoBindingProvider { - private static Logger logger = - LoggerFactory.getLogger(NetatmoGenericBindingProvider.class); + private static Logger logger = LoggerFactory + .getLogger(NetatmoGenericBindingProvider.class); /** * {@inheritDoc} @@ -78,31 +80,36 @@ public String getBindingType() { * @{inheritDoc */ @Override - public void validateItemType(final Item item, final String bindingConfig) throws BindingConfigParseException { - if (!(item instanceof NumberItem || item instanceof DateTimeItem)) { + public void validateItemType(final Item item, final String bindingConfig) + throws BindingConfigParseException { + if (!(item instanceof NumberItem || item instanceof DateTimeItem + || item instanceof LocationItem || item instanceof StringItem)) { throw new BindingConfigParseException( - "item '" + item.getName() + "' is of type '" + item.getClass().getSimpleName() + - "', only NumberItems and DateTimeItems are allowed - please check your *.items configuration"); + "item '" + + item.getName() + + "' is of type '" + + item.getClass().getSimpleName() + + "', only NumberItems, DateTimeItems, StringItems and LocationItems are allowed - please check your *.items configuration"); } } - + /** * {@inheritDoc} */ @Override public String getUserid(final String itemName) { - final NetatmoBindingConfig config = - (NetatmoBindingConfig) this.bindingConfigs.get(itemName); + final NetatmoBindingConfig config = (NetatmoBindingConfig) this.bindingConfigs + .get(itemName); return config != null ? config.userid : null; } - + /** * {@inheritDoc} */ @Override public String getDeviceId(final String itemName) { - final NetatmoBindingConfig config = - (NetatmoBindingConfig) this.bindingConfigs.get(itemName); + final NetatmoBindingConfig config = (NetatmoBindingConfig) this.bindingConfigs + .get(itemName); return config != null ? config.deviceId : null; } @@ -110,9 +117,9 @@ public String getDeviceId(final String itemName) { * {@inheritDoc} */ @Override - public NetatmoMeasureType getMeasureType(String itemName){ - final NetatmoBindingConfig config = - (NetatmoBindingConfig) this.bindingConfigs.get(itemName); + public NetatmoMeasureType getMeasureType(String itemName) { + final NetatmoBindingConfig config = (NetatmoBindingConfig) this.bindingConfigs + .get(itemName); return config != null ? config.measureType : null; } @@ -121,8 +128,8 @@ public NetatmoMeasureType getMeasureType(String itemName){ */ @Override public String getModuleId(final String itemName) { - final NetatmoBindingConfig config = - (NetatmoBindingConfig) this.bindingConfigs.get(itemName); + final NetatmoBindingConfig config = (NetatmoBindingConfig) this.bindingConfigs + .get(itemName); return config != null ? config.moduleId : null; } @@ -131,7 +138,8 @@ public String getModuleId(final String itemName) { */ @Override public void processBindingConfiguration(final String context, - final Item item, final String bindingConfig) throws BindingConfigParseException { + final Item item, final String bindingConfig) + throws BindingConfigParseException { logger.debug("Processing binding configuration: '{}'", bindingConfig); super.processBindingConfiguration(context, item, bindingConfig); @@ -164,8 +172,7 @@ public void processBindingConfiguration(final String context, addBindingConfig(item, config); } - - + private static class NetatmoBindingConfig implements BindingConfig { String userid; @@ -175,13 +182,11 @@ private static class NetatmoBindingConfig implements BindingConfig { @Override public String toString() { - return "NetatmoBindingConfig [userid=" + this.userid - + ", deviceId=" + this.deviceId - + ", moduleId=" + this.moduleId + ", measure=" + return "NetatmoBindingConfig [userid=" + this.userid + + ", deviceId=" + this.deviceId + ", moduleId=" + + this.moduleId + ", measure=" + this.measureType.getMeasure() + "]"; } } - - } diff --git a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoMeasureType.java b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoMeasureType.java index 7817f389116..af764d59fb9 100644 --- a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoMeasureType.java +++ b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoMeasureType.java @@ -13,25 +13,17 @@ /** * @author Gaël L'hopital * @since 1.6.0 - * - * This enum holds all the different measures and states available - * to be retrieved by the Netatmo binding + * + * This enum holds all the different measures and states available to be + * retrieved by the Netatmo binding */ public enum NetatmoMeasureType { - CO2("Co2"), - TEMPERATURE("Temperature"), - HUMIDITY("Humidity"), - NOISE("Noise"), - PRESSURE("Pressure"), - RAIN("Rain"), - WIFISTATUS("WifiStatus"), - ALTITUDE("Altitude"), - LATITUDE("Latitude"), - LONGITUDE("Longitude"), - RFSTATUS("RfStatus"), - BATTERYVP("BatteryVp"), - TIMESTAMP("TimeStamp"); - + CO2("CO2"), TEMPERATURE("Temperature"), HUMIDITY("Humidity"), NOISE("Noise"), PRESSURE( + "Pressure"), RAIN("Rain"), WIFISTATUS("WifiStatus"), ALTITUDE( + "Altitude"), LATITUDE("Latitude"), LONGITUDE("Longitude"), RFSTATUS( + "RfStatus"), BATTERYVP("BatteryVp"), TIMESTAMP("TimeStamp"), MODULENAME( + "ModuleName"), STATIONNAME("StationName"), COORDINATE("Coordinate"); + String measure; private NetatmoMeasureType(String measure) { @@ -41,7 +33,7 @@ private NetatmoMeasureType(String measure) { public String getMeasure() { return measure; } - + public static NetatmoMeasureType fromString(String measure) { if (!StringUtils.isEmpty(measure)) { for (NetatmoMeasureType measureType : NetatmoMeasureType.values()) { diff --git a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/AbstractRequest.java b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/AbstractRequest.java index 83c1e27bc67..6b6c360869d 100644 --- a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/AbstractRequest.java +++ b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/AbstractRequest.java @@ -25,6 +25,8 @@ public abstract class AbstractRequest extends AbstractMessage implements Request protected static final String HTTP_GET = "GET"; protected static final String HTTP_POST = "POST"; + + protected static final String API_BASE_URL = "https://api.netatmo.net/api/"; protected static final Properties HTTP_HEADERS; diff --git a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/DeviceListRequest.java b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/DeviceListRequest.java index d0f4d65cf04..d7c0e284d6c 100644 --- a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/DeviceListRequest.java +++ b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/DeviceListRequest.java @@ -25,7 +25,7 @@ */ public class DeviceListRequest extends AbstractRequest { - private static final String RESOURCE_URL = "http://api.netatmo.net/api/devicelist"; + private static final String RESOURCE_URL = API_BASE_URL + "devicelist"; private final String accessToken; diff --git a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/DeviceListResponse.java b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/DeviceListResponse.java index 467aea1bd1b..f6b460ef7c6 100644 --- a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/DeviceListResponse.java +++ b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/DeviceListResponse.java @@ -20,7 +20,7 @@ * method call. *

      * Sample response: - * + * *

        * {
        *   "status":  "ok",
      @@ -43,10 +43,10 @@
        *            "country":  "FR",
        *            "location":  [
        *             2.35222,
      - *              48.85661 
      + *              48.85661
        *           ],
        *            "timezone":  "Europe/Paris",
      - *            "trust_location":  true 
      + *            "trust_location":  true
        *         },
        *          "public_ext_data":  true,
        *         "station_name":  "LA",
      @@ -71,7 +71,7 @@
        *   "time_exec":  0.019799947738647
        * }
        * 
      - * + * * @author Andreas Brenk * @since 1.4.0 */ @@ -129,7 +129,6 @@ public class DeviceListResponse extends AbstractResponse { /** * wifi_status threshold constant: good signal */ - @SuppressWarnings("unused") private static final int WIFI_STATUS_THRESHOLD_2 = 56; /** @@ -150,7 +149,6 @@ public class DeviceListResponse extends AbstractResponse { /** * rf_status threshold constant: full signal */ - @SuppressWarnings("unused") private static final int RF_STATUS_THRESHOLD_3 = 60; /** @@ -332,10 +330,10 @@ public List getOwner() { * "country": "FR", * "location": [ * 2.35222, - * 48.85661 + * 48.85661 * ], * "timezone": "Europe/Paris", - * "trust_location": true + * "trust_location": true * } * */ @@ -387,34 +385,44 @@ public String toString() { builder.append("stationName", this.stationName); builder.append("type", this.type); builder.append("owner", this.owner); + builder.append("wifistatus", this.wifiStatus); return builder.toString(); } - + /** * "wifi_status" */ - @JsonProperty("wifi_status") - public Integer getWifiStatus() { - switch (this.wifiStatus) { - case WIFI_STATUS_THRESHOLD_0 : return 0; - case WIFI_STATUS_THRESHOLD_1 : return 1; - default : return 2; - } - } - - public Integer getAltitude() { - return this.place.altitude; - } - - public Double getLatitude() { - return this.place.location.get(0); - } - - public Double getLongitude() { - return this.place.location.get(1); - } - + @JsonProperty("wifi_status") + public Integer getWifiStatus() { + return this.wifiStatus; + } + + public int getWifiLevel() { + int level = this.wifiStatus.intValue(); + int result = 3; + if (level < WIFI_STATUS_THRESHOLD_2) + result = 2; + else if (level < WIFI_STATUS_THRESHOLD_1) + result = 1; + else if (level < WIFI_STATUS_THRESHOLD_0) + result = 0; + + return result; + } + + public Integer getAltitude() { + return this.place.altitude; + } + + public Double getLatitude() { + return this.place.location.get(1); + } + + public Double getLongitude() { + return this.place.location.get(0); + } + } @JsonIgnoreProperties(ignoreUnknown = true) @@ -475,33 +483,52 @@ public String getModuleName() { */ @JsonProperty("rf_status") public Integer getRfStatus() { - switch (this.rfStatus) { - case RF_STATUS_THRESHOLD_0 : return 0; - case RF_STATUS_THRESHOLD_1 : return 1; - case RF_STATUS_THRESHOLD_2 : return 2; - default : return 3; - } + return this.rfStatus; + } + + public int getRfLevel() { + int level = this.rfStatus.intValue(); + int result = 4; // not found + + if (level < RF_STATUS_THRESHOLD_3) + result = 3; + else if (level < RF_STATUS_THRESHOLD_2) + result = 2; + else if (level < RF_STATUS_THRESHOLD_1) + result = 1; + else if (level < RF_STATUS_THRESHOLD_0) + result = 0; + + return result; } - + /** * "battery_vp" */ @JsonProperty("battery_vp") - public Double getBatteryVp() { + public Integer getBatteryVp() { + return this.batteryVp; + } + + public Double getBatteryLevel() { int value; int minima; int spread; if (this.type.equalsIgnoreCase(TYPE_MODULE_1)) { value = Math.min(this.batteryVp, BATTERY_MODULE_1_THRESHOLD_0); - minima = BATTERY_MODULE_1_THRESHOLD_3 + BATTERY_MODULE_1_THRESHOLD_2 - BATTERY_MODULE_1_THRESHOLD_1; - spread = BATTERY_MODULE_1_THRESHOLD_0 - minima; + minima = BATTERY_MODULE_1_THRESHOLD_3 + + BATTERY_MODULE_1_THRESHOLD_2 + - BATTERY_MODULE_1_THRESHOLD_1; + spread = BATTERY_MODULE_1_THRESHOLD_0 - minima; } else { value = Math.min(this.batteryVp, BATTERY_MODULE_4_THRESHOLD_0); - minima = BATTERY_MODULE_4_THRESHOLD_3 + BATTERY_MODULE_4_THRESHOLD_2 - BATTERY_MODULE_4_THRESHOLD_1; + minima = BATTERY_MODULE_4_THRESHOLD_3 + + BATTERY_MODULE_4_THRESHOLD_2 + - BATTERY_MODULE_4_THRESHOLD_1; spread = BATTERY_MODULE_4_THRESHOLD_0 - minima; } double percent = 100 * (value - minima) / spread; - return new Double( percent ); + return new Double(percent); } /** @@ -565,7 +592,7 @@ public String getCountry() { *
       		 * "location": [
       		 *   2.35222,
      -		 *   48.85661 
      +		 *   48.85661
       		 * ]
       		 * 
      */ diff --git a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/MeasurementRequest.java b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/MeasurementRequest.java index 7d09858f923..c43e6587112 100644 --- a/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/MeasurementRequest.java +++ b/bundles/binding/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/messages/MeasurementRequest.java @@ -30,7 +30,7 @@ */ public class MeasurementRequest extends AbstractRequest { - private static final String RESOURCE_URL = "http://api.netatmo.net/api/getmeasure"; + private static final String RESOURCE_URL = API_BASE_URL + "getmeasure"; /** * @param deviceId diff --git a/bundles/binding/org.openhab.binding.networkupstools/.classpath b/bundles/binding/org.openhab.binding.networkupstools/.classpath new file mode 100644 index 00000000000..b438d7f8a90 --- /dev/null +++ b/bundles/binding/org.openhab.binding.networkupstools/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.networkupstools/.project b/bundles/binding/org.openhab.binding.networkupstools/.project new file mode 100644 index 00000000000..cf578a4063f --- /dev/null +++ b/bundles/binding/org.openhab.binding.networkupstools/.project @@ -0,0 +1,33 @@ + + + org.openhab.binding.networkupstools + This is the NetworkUpsTools binding of the open Home Automation Bus (openHAB) + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/bundles/binding/org.openhab.binding.networkupstools/META-INF/MANIFEST.MF b/bundles/binding/org.openhab.binding.networkupstools/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..931ee8a9a58 --- /dev/null +++ b/bundles/binding/org.openhab.binding.networkupstools/META-INF/MANIFEST.MF @@ -0,0 +1,34 @@ +Manifest-Version: 1.0 +Private-Package: org.openhab.binding.networkupstools.internal +Ignore-Package: org.openhab.binding.networkupstools.internal +Bundle-License: http://www.eclipse.org/legal/epl-v10.html +Bundle-Name: openHAB NetworkUpsTools Binding +Bundle-SymbolicName: org.openhab.binding.networkupstools +Bundle-Vendor: openHAB.org +Bundle-Version: 1.7.0.qualifier +Bundle-Activator: org.openhab.binding.networkupstools.internal.NetworkUpsToolsActivator +Bundle-ManifestVersion: 2 +Bundle-Description: This is the NetworkUpsTools binding of the open Home Aut + omation Bus (openHAB) +Import-Package: com.google.common.base, + com.google.common.collect, + org.apache.commons.lang, + org.openhab.core.binding, + org.openhab.core.events, + org.openhab.core.items, + org.openhab.core.library.items, + org.openhab.core.library.types, + org.openhab.core.types, + org.openhab.model.item.binding, + org.osgi.framework, + org.osgi.service.cm, + org.osgi.service.component, + org.osgi.service.event, + org.slf4j +Export-Package: org.openhab.binding.networkupstools +Bundle-DocURL: http://www.openhab.org +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Service-Component: OSGI-INF/binding.xml, OSGI-INF/genericbindingprovider.xml +Bundle-ClassPath: ., + lib/jNut-0.2-SNAPSHOT.jar + diff --git a/bundles/binding/org.openhab.binding.networkupstools/OSGI-INF/binding.xml b/bundles/binding/org.openhab.binding.networkupstools/OSGI-INF/binding.xml new file mode 100644 index 00000000000..a576fdc7ec1 --- /dev/null +++ b/bundles/binding/org.openhab.binding.networkupstools/OSGI-INF/binding.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.networkupstools/OSGI-INF/genericbindingprovider.xml b/bundles/binding/org.openhab.binding.networkupstools/OSGI-INF/genericbindingprovider.xml new file mode 100644 index 00000000000..76cab703224 --- /dev/null +++ b/bundles/binding/org.openhab.binding.networkupstools/OSGI-INF/genericbindingprovider.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.networkupstools/build.properties b/bundles/binding/org.openhab.binding.networkupstools/build.properties new file mode 100644 index 00000000000..902212d8762 --- /dev/null +++ b/bundles/binding/org.openhab.binding.networkupstools/build.properties @@ -0,0 +1,7 @@ +source.. = src/main/java/,\ + src/main/resources/ +bin.includes = META-INF/,\ + .,\ + lib/jNut-0.2-SNAPSHOT.jar,\ + OSGI-INF/ +output.. = target/classes/ diff --git a/bundles/binding/org.openhab.binding.networkupstools/lib/jNut-0.2-SNAPSHOT.jar b/bundles/binding/org.openhab.binding.networkupstools/lib/jNut-0.2-SNAPSHOT.jar new file mode 100644 index 00000000000..76b01a9ff69 Binary files /dev/null and b/bundles/binding/org.openhab.binding.networkupstools/lib/jNut-0.2-SNAPSHOT.jar differ diff --git a/bundles/binding/org.openhab.binding.networkupstools/pom.xml b/bundles/binding/org.openhab.binding.networkupstools/pom.xml new file mode 100644 index 00000000000..540529e4b3f --- /dev/null +++ b/bundles/binding/org.openhab.binding.networkupstools/pom.xml @@ -0,0 +1,35 @@ + + + + + org.openhab.bundles + binding + 1.7.0-SNAPSHOT + + + + org.openhab.binding.networkupstools + org.openhab.binding.networkupstools + openhab-addon-binding-NetworkUpsTools + openhab addon binding NetworkUpsTools + + + 4.0.0 + org.openhab.binding + org.openhab.binding.networkupstools + + openHAB NetworkUpsTools Binding + + eclipse-plugin + + + + + org.vafer + jdeb + + + + + diff --git a/bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/NetworkUpsToolsBindingProvider.java b/bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/NetworkUpsToolsBindingProvider.java new file mode 100644 index 00000000000..ff9cca272e0 --- /dev/null +++ b/bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/NetworkUpsToolsBindingProvider.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.networkupstools; + +import org.openhab.core.binding.BindingProvider; +import org.openhab.core.items.Item; + +/** + * This interface is implemented by classes that can provide mapping information + * between openHAB items and NetworkUpsTools items. + * + * Implementing classes should register themselves as a service in order to be + * taken into account. + * + * @author jaroslawmazgaj + * @since 1.7.0 + */ +public interface NetworkUpsToolsBindingProvider extends BindingProvider { + /** + * Returns the Type of the Item identified by {@code itemName} + * + * @param itemName the name of the item to find the type for + * @return the type of the Item identified by {@code itemName} + */ + public Class getItemType(String itemName); + + /** + * Returns the UPS name identified by {@code itemName} + * + * @param itemName the name of the item to find the type for + * @return the UPS name identified by {@code itemName} + */ + public String getUps(String itemName); + + /** + * Returns the UPS property identified by {@code itemName} + * + * @param itemName the name of the item to find the type for + * @return the UPS property identified by {@code itemName} + */ + public String getProperty(String itemName); + +} diff --git a/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/src/main/java/internal/__binding-name__Activator.java b/bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/internal/NetworkUpsToolsActivator.java similarity index 69% rename from bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/src/main/java/internal/__binding-name__Activator.java rename to bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/internal/NetworkUpsToolsActivator.java index cbf703218a8..639b1c18550 100644 --- a/bundles/archetype/org.openhab.archetype.binding/src/main/resources/archetype-resources/src/main/java/internal/__binding-name__Activator.java +++ b/bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/internal/NetworkUpsToolsActivator.java @@ -6,10 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -#set( $symbol_pound = '#' ) -#set( $symbol_dollar = '$' ) -#set( $symbol_escape = '\' ) -package ${artifactId}.internal; +package org.openhab.binding.networkupstools.internal; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; @@ -19,13 +16,14 @@ /** * Extension of the default OSGi bundle activator + * Provides OSGi lifecycle callbacks * - * @author ${author} - * @since ${version} + * @author jaroslawmazgaj + * @since 1.7.0 */ -public final class ${binding-name}Activator implements BundleActivator { +public final class NetworkUpsToolsActivator implements BundleActivator { - private static Logger logger = LoggerFactory.getLogger(${binding-name}Activator.class); + private static Logger logger = LoggerFactory.getLogger(NetworkUpsToolsActivator.class); private static BundleContext context; @@ -34,7 +32,7 @@ public final class ${binding-name}Activator implements BundleActivator { */ public void start(BundleContext bc) throws Exception { context = bc; - logger.debug("${binding-name} binding has been started."); + logger.debug("NetworkUpsTools binding has been started."); } /** @@ -42,7 +40,7 @@ public void start(BundleContext bc) throws Exception { */ public void stop(BundleContext bc) throws Exception { context = null; - logger.debug("${binding-name} binding has been stopped."); + logger.debug("NetworkUpsTools binding has been stopped."); } /** diff --git a/bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/internal/NetworkUpsToolsBinding.java b/bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/internal/NetworkUpsToolsBinding.java new file mode 100644 index 00000000000..a14da3e28d5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/internal/NetworkUpsToolsBinding.java @@ -0,0 +1,216 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.networkupstools.internal; + +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +import org.networkupstools.jnut.Client; +import org.networkupstools.jnut.Device; +import org.networkupstools.jnut.Variable; +import org.openhab.binding.networkupstools.NetworkUpsToolsBindingProvider; + +import org.apache.commons.lang.StringUtils; +import org.openhab.core.binding.AbstractActiveBinding; +import org.openhab.core.items.Item; +import org.openhab.core.library.items.NumberItem; +import org.openhab.core.library.items.StringItem; +import org.openhab.core.library.items.SwitchItem; +import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.StringType; +import org.openhab.core.types.State; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; + + +/** + * The RefreshService polls all configured ups parameters with a configurable + * interval and post all values to the internal event bus. The interval is 1 + * minute by default and can be changed via openhab.cfg. + * + * @author jaroslawmazgaj + * @since 1.7.0 + */ +public class NetworkUpsToolsBinding extends AbstractActiveBinding implements ManagedService { + + private static final Logger logger = + LoggerFactory.getLogger(NetworkUpsToolsBinding.class); + + private Map upses = new HashMap(); + + /** + * the refresh interval which is used to poll values from the NetworkUpsTools + * server (optional, defaults to 60000ms) + */ + private long refreshInterval = 60000; + + + /** + * @{inheritDoc} + */ + @Override + protected long getRefreshInterval() { + return refreshInterval; + } + + /** + * @{inheritDoc} + */ + @Override + protected String getName() { + return "NetworkUpsTools Refresh Service"; + } + + /** + * @{inheritDoc} + */ + @Override + protected void execute() { + Multimap items = HashMultimap.create(); + for (NetworkUpsToolsBindingProvider provider : providers) { + for (String itemName : provider.getItemNames()) { + String name = provider.getUps(itemName); + Class itemType = provider.getItemType(itemName); + String property = provider.getProperty(itemName); + items.put(name, new ItemDefinition(itemName, itemType, property)); + } + } + + for(String name : items.keySet()) { + NutConfig nut = upses.get(name); + if (nut == null) { + logger.error("No configuration for UPS with name: '{}'", name); + continue; + } + Client client = null; + try { + client = new Client(nut.host, nut.port, nut.login, nut.pass); + Device device = client.getDevice(nut.device); + + for(ItemDefinition definition : items.get(name)) { + Variable variable = device.getVariable(definition.property); + String value = variable.getValue(); + Class itemType = definition.itemType; + String itemName = definition.itemName; + + + // Change to a state + State state = null; + if (itemType.isAssignableFrom(StringItem.class)) { + state = StringType.valueOf(value); + } else if (itemType.isAssignableFrom(NumberItem.class)) { + state = DecimalType.valueOf(value); + } else if (itemType.isAssignableFrom(SwitchItem.class)) { + state = OnOffType.valueOf(value); + } + + if (state != null) { + eventPublisher.postUpdate(itemName, state); + } else { + logger.error( + "'{}' couldn't be parsed to a State. Valid State-Types are String, Number and Switch", + variable.toString()); + } + } + } catch(Exception ex) { + logger.error("Nut processing error", ex); + } finally { + if (client != null) { + client.disconnect(); + } + } + } + } + + /** + * @{inheritDoc} + */ + @Override + public void updated(Dictionary config) throws ConfigurationException { + if (config != null) { + String refreshIntervalString = (String) config.get("refresh"); + if (StringUtils.isNotBlank(refreshIntervalString)) { + refreshInterval = Long.parseLong(refreshIntervalString); + } + + Map newUpses = new HashMap(); + + Enumeration keys = config.keys(); + + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + + if ("refresh".equals(key) || "service.pid".equals(key)) { + continue; + } + + String[] parts = key.split("\\."); + String name = parts[0]; + String prop = parts[1]; + String value = (String) config.get(key); + + NutConfig nutConfig = newUpses.get(name); + if (nutConfig == null) { + nutConfig = new NutConfig(); + newUpses.put(name, nutConfig); + } + + if ("device".equalsIgnoreCase(prop)) { + nutConfig.device = value; + } else if ("host".equalsIgnoreCase(prop)) { + nutConfig.host = value; + } else if ("login".equalsIgnoreCase(prop)) { + nutConfig.login = value; + } else if ("pass".equalsIgnoreCase(prop)) { + nutConfig.pass = value; + } else if ("port".equalsIgnoreCase(prop)) { + nutConfig.port = Integer.parseInt(value); + } + } + + upses = newUpses; + + setProperlyConfigured(true); + } + } + + /** + * This is an internal data structure to store nut server configuration + */ + class NutConfig { + String device; + String host = "localhost"; + String login = ""; + String pass = ""; + int port = 3493; + } + + /** + * This is an internal data structure to store item definition details for given nut server + */ + class ItemDefinition { + String itemName; + Class itemType; + String property; + + public ItemDefinition(String itemName, Class itemType, String property) { + this.itemName = itemName; + this.itemType = itemType; + this.property = property; + } + } +} diff --git a/bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/internal/NetworkUpsToolsGenericBindingProvider.java b/bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/internal/NetworkUpsToolsGenericBindingProvider.java new file mode 100644 index 00000000000..c62db813303 --- /dev/null +++ b/bundles/binding/org.openhab.binding.networkupstools/src/main/java/org/openhab/binding/networkupstools/internal/NetworkUpsToolsGenericBindingProvider.java @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.networkupstools.internal; + +import org.openhab.binding.networkupstools.NetworkUpsToolsBindingProvider; +import org.openhab.core.binding.BindingConfig; +import org.openhab.core.items.Item; +import org.openhab.core.library.items.NumberItem; +import org.openhab.core.library.items.StringItem; +import org.openhab.core.library.items.SwitchItem; +import org.openhab.model.item.binding.AbstractGenericBindingProvider; +import org.openhab.model.item.binding.BindingConfigParseException; + + +/** + *

      This class parses information from the generic binding format and + * provides NetworkUpsTools binding information from it. It registers as a + * {@link NetworkUpsToolsBindingProvider} service as well.

      + * + *

      Here is an examples for valid binding configuration string: + *

        + *
      • { networkupstools = "nas:output.voltage" } - binds to "output.voltage" property of UPS defined as "nas" in openhab.cfg
      • + *
      + * + * @author jaroslawmazgaj + * @since 1.7.0 + */ +public class NetworkUpsToolsGenericBindingProvider extends AbstractGenericBindingProvider implements NetworkUpsToolsBindingProvider { + + /** + * {@inheritDoc} + */ + public String getBindingType() { + return "networkupstools"; + } + + /** + * @{inheritDoc} + */ + @Override + public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException { + if (!(item instanceof StringItem || item instanceof NumberItem || item instanceof SwitchItem)) { + throw new BindingConfigParseException("item '" + item.getName() + + "' is of type '" + item.getClass().getSimpleName() + + "', only String-, Switch- and NumberItem are allowed - please check your *.items configuration"); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void processBindingConfiguration(String context, Item item, String bindingConfig) throws BindingConfigParseException { + super.processBindingConfiguration(context, item, bindingConfig); + + String[] configParts = bindingConfig.trim().split(":"); + if (configParts.length > 2) { + throw new BindingConfigParseException("NetworkHealth configuration can contain three parts at max"); + } + + NetworkUpsToolsBindingConfig config = new NetworkUpsToolsBindingConfig(); + config.ups = configParts[0]; + config.property = configParts[1]; + config.itemType = item.getClass(); + + addBindingConfig(item, config); + } + + + @Override + public String getUps(String itemName) { + NetworkUpsToolsBindingConfig config = (NetworkUpsToolsBindingConfig) bindingConfigs.get(itemName); + return config.ups; + } + + @Override + public String getProperty(String itemName) { + NetworkUpsToolsBindingConfig config = (NetworkUpsToolsBindingConfig) bindingConfigs.get(itemName); + return config.property; + } + + @Override + public Class getItemType(String itemName) { + NetworkUpsToolsBindingConfig config = (NetworkUpsToolsBindingConfig) bindingConfigs.get(itemName); + return config.itemType; + }; + + + /** + * This is an internal data structure to store information from the binding + * config strings and use it to answer the requests to the NetworkUpsTools + * binding provider. + * + */ + class NetworkUpsToolsBindingConfig implements BindingConfig { + public Class itemType; + public String ups; + public String property; + } + + +} diff --git a/bundles/binding/org.openhab.binding.networkupstools/src/main/resources/readme.txt b/bundles/binding/org.openhab.binding.networkupstools/src/main/resources/readme.txt new file mode 100644 index 00000000000..98698c670dc --- /dev/null +++ b/bundles/binding/org.openhab.binding.networkupstools/src/main/resources/readme.txt @@ -0,0 +1 @@ +Bundle resources go in here! \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.nikobus/.classpath b/bundles/binding/org.openhab.binding.nikobus/.classpath index 4033112b349..6d224cd3d0d 100644 --- a/bundles/binding/org.openhab.binding.nikobus/.classpath +++ b/bundles/binding/org.openhab.binding.nikobus/.classpath @@ -4,6 +4,5 @@ - diff --git a/bundles/binding/org.openhab.binding.novelanheatpump/OSGI-INF/heatpumpbinding.xml b/bundles/binding/org.openhab.binding.novelanheatpump/OSGI-INF/heatpumpbinding.xml index 7d3b9e2ccd3..76f8d25f852 100644 --- a/bundles/binding/org.openhab.binding.novelanheatpump/OSGI-INF/heatpumpbinding.xml +++ b/bundles/binding/org.openhab.binding.novelanheatpump/OSGI-INF/heatpumpbinding.xml @@ -14,7 +14,9 @@ + + diff --git a/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/HeatpumpCommandType.java b/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/HeatpumpCommandType.java index e8cd5b185f1..30b5e6a54b6 100644 --- a/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/HeatpumpCommandType.java +++ b/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/HeatpumpCommandType.java @@ -304,7 +304,37 @@ public enum HeatpumpCommandType { command = "temperature_solar_storage"; itemClass = NumberItem.class; } + }, + + //in german Heizung Betriebsart + TYPE_HEATING_OPERATION_MODE { + { + command = "heating_operation_mode"; + itemClass = NumberItem.class; + } + }, + //in german Heizung Temperatur (Parallelverschiebung) + TYPE_HEATING_TEMPERATURE { + { + command = "heating_temperature"; + itemClass = NumberItem.class; + } + }, + //in german Warmwasser Betriebsart + TYPE_WARMWATER_OPERATION_MODE { + { + command = "warmwater_operation_mode"; + itemClass = NumberItem.class; + } + }, + //in german Warmwasser Temperatur + TYPE_WARMWATER_TEMPERATURE { + { + command = "warmwater_temperature"; + itemClass = NumberItem.class; + } }; + /** Represents the heatpump command as it will be used in *.items configuration */ diff --git a/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/HeatpumpOperationMode.java b/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/HeatpumpOperationMode.java new file mode 100644 index 00000000000..7eb20be7b0d --- /dev/null +++ b/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/HeatpumpOperationMode.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.novelanheatpump; + +public enum HeatpumpOperationMode { + // in german Automatik + AUTOMATIC(0), + // in german Aus + OFF(4), + // in german Party + PARTY(2), + // in german Urlaub + HOLIDAY(3), + // in german Zuzeizer + AUXILIARY_HEATER(1); + + private int value; + + private HeatpumpOperationMode(int value){ + this.value = value; + } + + public int getValue(){ + return value; + } + + public static HeatpumpOperationMode fromValue(int value){ + for(HeatpumpOperationMode mode : HeatpumpOperationMode.values()){ + if(mode.value == value){ + return mode; + } + } + return null; + } + + +} diff --git a/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatPumpBinding.java b/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatPumpBinding.java index bcdd71ad7fb..c1cf860c401 100644 --- a/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatPumpBinding.java +++ b/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatPumpBinding.java @@ -13,14 +13,19 @@ import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Dictionary; +import java.util.Iterator; +import org.apache.commons.collections.IteratorUtils; import org.apache.commons.lang.StringUtils; import org.openhab.binding.novelanheatpump.HeatPumpBindingProvider; import org.openhab.binding.novelanheatpump.HeatpumpCommandType; +import org.openhab.binding.novelanheatpump.HeatpumpOperationMode; import org.openhab.binding.novelanheatpump.i18n.Messages; +import org.openhab.binding.novelanheatpump.internal.HeatPumpGenericBindingProvider.HeatPumpBindingConfig; import org.openhab.core.binding.AbstractActiveBinding; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.StringType; +import org.openhab.core.types.Command; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedService; import org.slf4j.Logger; @@ -39,6 +44,16 @@ public class HeatPumpBinding extends AbstractActiveBinding it = providers.iterator(); + while(it.hasNext()){ + HeatPumpBindingProvider provider = it.next(); + if(provider instanceof HeatPumpGenericBindingProvider){ + return (HeatPumpGenericBindingProvider)provider; + } + } + return null; + } } diff --git a/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatPumpGenericBindingProvider.java b/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatPumpGenericBindingProvider.java index 4d7911d8864..b04a9162515 100644 --- a/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatPumpGenericBindingProvider.java +++ b/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatPumpGenericBindingProvider.java @@ -109,6 +109,10 @@ public String[] getItemNamesForType(HeatpumpCommandType eventType) { return itemNames.toArray(new String[itemNames.size()]); } + public HeatPumpBindingConfig getHeatPumpBindingConfig(String itemName){ + return (HeatPumpBindingConfig)bindingConfigs.get(itemName); + } + static class HeatPumpBindingConfig implements BindingConfig { diff --git a/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatpumpConnector.java b/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatpumpConnector.java index 51a4b4cb4ca..55bb1d551e4 100644 --- a/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatpumpConnector.java +++ b/bundles/binding/org.openhab.binding.novelanheatpump/src/main/java/org/openhab/binding/novelanheatpump/internal/HeatpumpConnector.java @@ -56,6 +56,62 @@ public void connect() throws UnknownHostException, IOException { logger.debug("Novelan Heatpump connect"); } + /** + * read the parameters of the heatpump + * @return + * @throws IOException + */ + public int[] getParams() throws IOException { + int[] heatpump_values = null; + while (datain.available() > 0){ + datain.readByte(); + } + dataout.writeInt(3003); + dataout.writeInt(0); + dataout.flush(); + if (datain.readInt() != 3003) { + return null; + } + //int stat = datain.readInt(); + int arraylength = datain.readInt(); + heatpump_values = new int[arraylength]; + + + for (int i = 0; i < arraylength; i++) + heatpump_values[i] = datain.readInt(); + return heatpump_values; + } + + /** + * set a parameter of the heatpump + * @param param + * @param value + * @return + * @throws IOException + */ + public boolean setParam(int param, int value) throws IOException { + while (datain.available() > 0){ + datain.readByte(); + } + dataout.writeInt(3002); + dataout.writeInt(param); + dataout.writeInt(value); + dataout.flush(); + + int cmd = datain.readInt(); + int resp = datain.readInt(); + if (cmd != 3002) { + logger.error("can't write parameter " + param + " with value " + value +" to heatpump."); + return false; + }else{ + if(logger.isDebugEnabled()){ + logger.debug("successful parameter" + param + " with value " + value +" to heatpump written."); + } + return true; + } + + } + /** * read the internal state of the heatpump * @return a array with all internal data of the heatpump diff --git a/bundles/binding/org.openhab.binding.omnilink/src/main/java/org/openhab/binding/omnilink/internal/OmniLinkBinding.java b/bundles/binding/org.openhab.binding.omnilink/src/main/java/org/openhab/binding/omnilink/internal/OmniLinkBinding.java index 9f2cdf1bf0d..8aef93e8c86 100644 --- a/bundles/binding/org.openhab.binding.omnilink/src/main/java/org/openhab/binding/omnilink/internal/OmniLinkBinding.java +++ b/bundles/binding/org.openhab.binding.omnilink/src/main/java/org/openhab/binding/omnilink/internal/OmniLinkBinding.java @@ -399,6 +399,8 @@ public void notConnectedEvent(Exception e) { omni = c.reqSystemInformation().getModel() < 36; + celius = c.reqSystemFormats().getTempFormat() > 1; + /* * We need to explicitly tell the controller to send us * real time notifications diff --git a/bundles/binding/org.openhab.binding.onkyo/src/main/java/org/openhab/binding/onkyo/internal/eiscp/Eiscp.java b/bundles/binding/org.openhab.binding.onkyo/src/main/java/org/openhab/binding/onkyo/internal/eiscp/Eiscp.java index b773ccce4df..007d3132780 100644 --- a/bundles/binding/org.openhab.binding.onkyo/src/main/java/org/openhab/binding/onkyo/internal/eiscp/Eiscp.java +++ b/bundles/binding/org.openhab.binding.onkyo/src/main/java/org/openhab/binding/onkyo/internal/eiscp/Eiscp.java @@ -216,8 +216,7 @@ public boolean closeSocket() { private StringBuilder getEiscpMessage(String eiscpCmd) { StringBuilder sb = new StringBuilder(); - int eiscpDataSize = eiscpCmd.length() + 2; // this is the eISCP data size - int eiscpMsgSize = eiscpDataSize + 1 + 16; // this is the eISCP data size + int eiscpDataSize = 2 + eiscpCmd.length() + 1; // this is the eISCP data size /* * This is where I construct the entire message character by character. @@ -233,10 +232,10 @@ private StringBuilder getEiscpMessage(String eiscpCmd) { sb.append((char) 0x10); // 4 char Big Endian data size - sb.append( (char) ((eiscpMsgSize >> 24) & 0xFF) ); - sb.append( (char) ((eiscpMsgSize >> 16) & 0xFF) ); - sb.append( (char) ((eiscpMsgSize >> 8) & 0xFF) ); - sb.append( (char) (eiscpMsgSize & 0xFF) ); + sb.append( (char) ((eiscpDataSize >> 24) & 0xFF) ); + sb.append( (char) ((eiscpDataSize >> 16) & 0xFF) ); + sb.append( (char) ((eiscpDataSize >> 8) & 0xFF) ); + sb.append( (char) (eiscpDataSize & 0xFF) ); // eiscp_version = "01"; sb.append((char) 0x01); @@ -247,6 +246,7 @@ private StringBuilder getEiscpMessage(String eiscpCmd) { sb.append((char) 0x00); // eISCP data + // Start Character sb.append("!"); diff --git a/bundles/binding/org.openhab.binding.openenergymonitor/.classpath b/bundles/binding/org.openhab.binding.openenergymonitor/.classpath index 132626bd45e..cc8aac5de31 100644 --- a/bundles/binding/org.openhab.binding.openenergymonitor/.classpath +++ b/bundles/binding/org.openhab.binding.openenergymonitor/.classpath @@ -5,6 +5,5 @@ - diff --git a/bundles/binding/org.openhab.binding.pilight.test/.classpath b/bundles/binding/org.openhab.binding.pilight.test/.classpath new file mode 100644 index 00000000000..f0724f5c6a4 --- /dev/null +++ b/bundles/binding/org.openhab.binding.pilight.test/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/binding/org.openhab.binding.pilight.test/.project b/bundles/binding/org.openhab.binding.pilight.test/.project new file mode 100644 index 00000000000..7c46e3cb8b9 --- /dev/null +++ b/bundles/binding/org.openhab.binding.pilight.test/.project @@ -0,0 +1,28 @@ + + + org.openhab.binding.pilight.test + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/binding/org.openhab.binding.pilight.test/.settings/org.eclipse.jdt.core.prefs b/bundles/binding/org.openhab.binding.pilight.test/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..4ede96d8a73 --- /dev/null +++ b/bundles/binding/org.openhab.binding.pilight.test/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning diff --git a/bundles/binding/org.openhab.binding.pilight.test/.settings/org.maven.ide.eclipse.prefs b/bundles/binding/org.openhab.binding.pilight.test/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 00000000000..5fed4cf5aed --- /dev/null +++ b/bundles/binding/org.openhab.binding.pilight.test/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,8 @@ +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/bundles/binding/org.openhab.binding.pilight.test/META-INF/MANIFEST.MF b/bundles/binding/org.openhab.binding.pilight.test/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..4cfdf9e0b60 --- /dev/null +++ b/bundles/binding/org.openhab.binding.pilight.test/META-INF/MANIFEST.MF @@ -0,0 +1,9 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Tests for the pilight binding +Bundle-SymbolicName: org.openhab.binding.pilight.test +Bundle-Version: 1.7.0.qualifier +Bundle-Vendor: openHAB.org +Fragment-Host: org.openhab.binding.pilight +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Require-Bundle: org.junit;bundle-version="4.8.1" diff --git a/bundles/binding/org.openhab.binding.pilight.test/build.properties b/bundles/binding/org.openhab.binding.pilight.test/build.properties new file mode 100644 index 00000000000..9aa7f188f2f --- /dev/null +++ b/bundles/binding/org.openhab.binding.pilight.test/build.properties @@ -0,0 +1,3 @@ +source.. = src/test/java/ +output.. = target/test-classes/ +bin.includes = META-INF/ diff --git a/bundles/binding/org.openhab.binding.pilight.test/pom.xml b/bundles/binding/org.openhab.binding.pilight.test/pom.xml new file mode 100644 index 00000000000..db2675adb94 --- /dev/null +++ b/bundles/binding/org.openhab.binding.pilight.test/pom.xml @@ -0,0 +1,35 @@ + + + + + org.openhab.bundles + binding + 1.7.0-SNAPSHOT + + + + org.openhab.binding.pilight.test + org.openhab.binding.pilight.test + + + 4.0.0 + org.openhab.binding + org.openhab.binding.pilight.test + + openHAB pilight Binding Tests + + eclipse-test-plugin + + + + + org.eclipse.tycho + tycho-surefire-plugin + ${tycho-version} + + + + + diff --git a/bundles/binding/org.openhab.binding.pilight.test/src/test/java/org/openhab/binding/pilight/internal/PilightGenericBindingProviderTest.java b/bundles/binding/org.openhab.binding.pilight.test/src/test/java/org/openhab/binding/pilight/internal/PilightGenericBindingProviderTest.java new file mode 100644 index 00000000000..fce2038cc55 --- /dev/null +++ b/bundles/binding/org.openhab.binding.pilight.test/src/test/java/org/openhab/binding/pilight/internal/PilightGenericBindingProviderTest.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.pilight.internal; + +import java.math.BigDecimal; + +import junit.framework.Assert; + +import org.junit.Before; +import org.junit.Test; +import org.openhab.binding.pilight.internal.PilightBinding; +import org.openhab.binding.pilight.internal.PilightBindingConfig; +import org.openhab.binding.pilight.internal.PilightGenericBindingProvider; +import org.openhab.core.items.Item; +import org.openhab.core.library.items.NumberItem; +import org.openhab.core.library.types.DecimalType; +import org.openhab.model.item.binding.BindingConfigParseException; + +/** + * @author Jeroen Idserda + * @since 1.7.0 + */ +public class PilightGenericBindingProviderTest { + + private PilightGenericBindingProvider provider; + private PilightBinding binding; + private Item testItem; + + @Before + public void init() { + provider = new PilightGenericBindingProvider(); + binding = new PilightBinding(); + testItem = new NumberItem("NumberItem");; + } + + @Test + public void testNumberItemScale() throws BindingConfigParseException { + + String bindingConfig = "kaku#outside:weather,property=temperature"; + + PilightBindingConfig config = provider.parseBindingConfig(testItem, bindingConfig); + Assert.assertNotNull(config); + + DecimalType number0 = (DecimalType) binding.getState("23", config); + Assert.assertEquals(number0.toBigDecimal().compareTo(new BigDecimal("23")), 0); + + config.setScale(1); + DecimalType number1 = (DecimalType) binding.getState("233", config); + Assert.assertEquals(number1.toBigDecimal().compareTo(new BigDecimal("23.3")), 0); + + config.setScale(2); + DecimalType number2 = (DecimalType) binding.getState("2233", config); + Assert.assertEquals(number2.toBigDecimal().compareTo(new BigDecimal("22.33")), 0); + + config.setScale(-1); + DecimalType number3 = (DecimalType) binding.getState("233", config); + Assert.assertEquals(number3.toBigDecimal().compareTo(new BigDecimal("2330")), 0); + } +} diff --git a/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightBinding.java b/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightBinding.java index 6af7be354ae..489a536e565 100644 --- a/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightBinding.java +++ b/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightBinding.java @@ -22,6 +22,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import org.apache.commons.lang.StringUtils; import org.codehaus.jackson.JsonGenerator.Feature; import org.codehaus.jackson.map.ObjectMapper; import org.openhab.binding.pilight.PilightBindingProvider; @@ -34,7 +35,6 @@ import org.openhab.binding.pilight.internal.communication.Update; import org.openhab.binding.pilight.internal.communication.Values; import org.openhab.core.binding.AbstractBinding; -import org.openhab.core.binding.BindingChangeListener; import org.openhab.core.binding.BindingProvider; import org.openhab.core.library.items.NumberItem; import org.openhab.core.library.items.StringItem; @@ -57,7 +57,7 @@ * @author Jeroen Idserda * @since 1.0 */ -public class PilightBinding extends AbstractBinding implements ManagedService,BindingChangeListener { +public class PilightBinding extends AbstractBinding implements ManagedService { private static final Logger logger = LoggerFactory.getLogger(PilightBinding.class); @@ -105,21 +105,28 @@ private void processValueEvent(List configs, Status status String property = config.getProperty(); if (status.getValues().containsKey(property)) { String value = status.getValues().get(property); - State state = getStateFromProperty(value, config); - eventPublisher.postUpdate(config.getItemName(), state); + State state = getState(value, config); + + if (state != null) { + eventPublisher.postUpdate(config.getItemName(), state); + } } } } - private State getStateFromProperty(String value, PilightBindingConfig config) { + protected State getState(String value, PilightBindingConfig config) { State state = null; if (config.getItemType().equals(StringItem.class)) { state = new StringType(value); } else if (config.getItemType().equals(NumberItem.class)) { - BigDecimal numberValue = new BigDecimal(value).setScale(config.getScale()); - numberValue = numberValue.divide(new BigDecimal(config.getScale()*10), config.getScale(), RoundingMode.HALF_UP); - state = new DecimalType(numberValue); + if (!StringUtils.isBlank(value)) { + // Number values are always received as an integer with an optional parameter describing + // the number of decimals (scale, default = 0). + BigDecimal numberValue = new BigDecimal(value); + numberValue = numberValue.divide(new BigDecimal(Math.pow(10,config.getScale())), config.getScale(), RoundingMode.HALF_UP); + state = new DecimalType(numberValue); + } } return state; @@ -320,6 +327,7 @@ public void messageReceived(PilightConnection connection, } })); connection.getListener().start(); + setInitialState(); } /** @@ -348,12 +356,14 @@ private State getStateFromConfig(Config pilightConfig, PilightBindingConfig bind return state; } else if (devType.equals(DeviceType.VALUE)) { - bindingConfig.setScale(dev.getScale()); + if (dev.getScale() != null) { + bindingConfig.setScale(dev.getScale()); + } String property = bindingConfig.getProperty(); if (dev.getProperties().containsKey(property)) { String value = dev.getProperties().get(property); - return getStateFromProperty(value, bindingConfig); + return getState(value, bindingConfig); } } } @@ -366,8 +376,25 @@ private State getStateFromConfig(Config pilightConfig, PilightBindingConfig bind */ @Override public void bindingChanged(BindingProvider provider, String itemName) { + logger.debug("Binding changed for item {}", itemName); checkItemState(provider, itemName); - super.bindingChanged(provider, itemName); + } + + /** + * @{inheritDoc} + */ + @Override + public void allBindingsChanged(BindingProvider provider) { + logger.debug("All bindings changed"); + for (String itemName : provider.getItemNames()) { + checkItemState(provider, itemName); + } + } + + private void setInitialState() { + for (PilightBindingProvider provider : providers) { + allBindingsChanged(provider); + } } /** diff --git a/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightBindingConfig.java b/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightBindingConfig.java index c22ba5a9dc0..e8b52bb9cf5 100644 --- a/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightBindingConfig.java +++ b/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightBindingConfig.java @@ -31,7 +31,7 @@ public class PilightBindingConfig implements BindingConfig { private String property; - private Integer scale = 1; + private int scale = 0; public String getItemName() { return itemName; @@ -82,11 +82,11 @@ public void setProperty(String value) { this.property = value; } - public Integer getScale() { + public int getScale() { return scale; } - public void setScale(Integer scale) { + public void setScale(int scale) { this.scale = scale; } diff --git a/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightGenericBindingProvider.java b/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightGenericBindingProvider.java index 57d775e2726..aabf39b22b2 100644 --- a/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightGenericBindingProvider.java +++ b/bundles/binding/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightGenericBindingProvider.java @@ -70,8 +70,15 @@ public void validateItemType(Item item, String bindingConfig) throws BindingConf public void processBindingConfiguration(String context, Item item, String bindingConfig) throws BindingConfigParseException { super.processBindingConfiguration(context, item, bindingConfig); + PilightBindingConfig config = parseBindingConfig(item, bindingConfig); + + if (config != null) { + addBindingConfig(item, config); + } + } + + protected PilightBindingConfig parseBindingConfig(Item item, String bindingConfig) { bindingConfig = bindingConfig.replace(" ", ""); - Matcher matcher = CONFIG_PATTERN.matcher(bindingConfig); if (matcher.matches()) { @@ -108,11 +115,13 @@ public void processBindingConfiguration(String context, Item item, String bindin } else { logger.info("pilight:{} item {} bound to device {} in location {}{}", config.getInstance(), config.getItemName(), config.getDevice(), config.getLocation(), config.getProperty() != null ? ", property " + config.getProperty() : ""); - addBindingConfig(item, config); + return config; } } else { logger.error("Item config {} does not match instance#location:device,property=optional pattern", bindingConfig); } + + return null; } public PilightBindingConfig getBindingConfig(String itemName) { diff --git a/bundles/binding/org.openhab.binding.plcbus/.classpath b/bundles/binding/org.openhab.binding.plcbus/.classpath index 0164594ab76..dab876036aa 100644 --- a/bundles/binding/org.openhab.binding.plcbus/.classpath +++ b/bundles/binding/org.openhab.binding.plcbus/.classpath @@ -3,6 +3,5 @@ - diff --git a/bundles/binding/org.openhab.binding.rfxcom/.classpath b/bundles/binding/org.openhab.binding.rfxcom/.classpath index 4033112b349..6d224cd3d0d 100644 --- a/bundles/binding/org.openhab.binding.rfxcom/.classpath +++ b/bundles/binding/org.openhab.binding.rfxcom/.classpath @@ -4,6 +4,5 @@ - diff --git a/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComBlinds1Message.java b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComBlinds1Message.java index 0580aa519f1..177005525a1 100644 --- a/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComBlinds1Message.java +++ b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComBlinds1Message.java @@ -70,7 +70,10 @@ public enum SubType { RF01(2), AC114(3), YR1326(4), //Additional commands. - MEDIAMOUNT(5), //MEDIA MOUNT have different direction commands then the rest!! needs to bee fixed. + MEDIAMOUNT(5), //MEDIA MOUNT have different direction commands than the rest!! Needs to be fixed. + DC106(6), + FOREST(7), + CS4330(8), // Chamberlain CS4330 UNKNOWN(255); diff --git a/bundles/binding/org.openhab.binding.rme/.classpath b/bundles/binding/org.openhab.binding.rme/.classpath index d57d64530d6..a55cfc54405 100644 --- a/bundles/binding/org.openhab.binding.rme/.classpath +++ b/bundles/binding/org.openhab.binding.rme/.classpath @@ -4,6 +4,5 @@ - diff --git a/bundles/binding/org.openhab.binding.samsungac.test/src/test/java/org/openhab/binding/samsungac/communicator/ResponseParserTest.java b/bundles/binding/org.openhab.binding.samsungac.test/src/test/java/org/openhab/binding/samsungac/communicator/ResponseParserTest.java index 56260caae38..f1728d22730 100644 --- a/bundles/binding/org.openhab.binding.samsungac.test/src/test/java/org/openhab/binding/samsungac/communicator/ResponseParserTest.java +++ b/bundles/binding/org.openhab.binding.samsungac.test/src/test/java/org/openhab/binding/samsungac/communicator/ResponseParserTest.java @@ -69,12 +69,13 @@ public void shouldCheckIfItIsCorrectResponseCommand() { @Test public void shouldParseXMLStatusResponseCorrectly() throws SAXException { - String response = ""; + String response = ""; Map result = ResponseParser.parseStatusResponse(response); assertEquals("On", result.get(CommandEnum.AC_FUN_POWER)); assertEquals("21", result.get(CommandEnum.AC_FUN_TEMPNOW)); assertEquals("20", result.get(CommandEnum.AC_FUN_TEMPSET)); + assertEquals("45010D00", result.get(CommandEnum.AC_FUN_ERROR)); } @Test diff --git a/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/SamsungAcBindingProvider.java b/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/SamsungAcBindingProvider.java index b117978815a..7eb9f255c3a 100644 --- a/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/SamsungAcBindingProvider.java +++ b/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/SamsungAcBindingProvider.java @@ -21,5 +21,5 @@ public interface SamsungAcBindingProvider extends BindingProvider { String getAirConditionerInstance(String itemname); CommandEnum getProperty(String itemname); - String getItemName(CommandEnum property); + String getItemName(String acName, CommandEnum property); } diff --git a/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/CommandEnum.java b/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/CommandEnum.java index b2cef2f1680..d5ce94b3baa 100644 --- a/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/CommandEnum.java +++ b/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/CommandEnum.java @@ -17,8 +17,21 @@ * @since 1.6.0 */ public enum CommandEnum { - AC_FUN_OPMODE, AC_FUN_TEMPSET, AC_FUN_WINDLEVEL, AC_FUN_TEMPNOW, AC_FUN_POWER, AC_FUN_COMODE, AC_FUN_DIRECTION, AC_FUN_ENABLE, AC_FUN_SLEEP; - + AC_FUN_OPMODE, AC_FUN_TEMPSET, AC_FUN_WINDLEVEL, + AC_FUN_TEMPNOW, AC_FUN_POWER, AC_FUN_COMODE, + AC_FUN_DIRECTION, AC_FUN_ENABLE, AC_FUN_SLEEP, + AC_FUN_ERROR, AC_SG_VENDER01, AC_SG_VENDER02, AC_SG_VENDER03, + AC_ADD2_VERSION, AC_SG_INTERNET, + AC_SG_WIFI, AC_ADD_SPI, AC_ADD_STARTWPS, AC_ADD_APMODE_END, + AC_ADD_AUTOCLEAN, AC_FUN_SUPPORTED, + AC_ADD_SETKWH, AC_ADD_CLEAR_FILTER_ALARM, + AC_OUTDOOR_TEMP, AC_COOL_CAPABILITY, + AC_WARM_CAPABILITY, AC_ADD2_USEDWATT, + AC_SG_MACHIGH, AC_SG_MACMID, AC_SG_MACLOW, + AC_ADD2_PANEL_VERSION, AC_ADD2_OUT_VERSION, + AC_FUN_MODEL, AC_ADD2_OPTIONCODE, AC_ADD2_USEDPOWER, + AC_ADD2_USEDTIME, AC_ADD2_CLEAR_POWERTIME, AC_ADD2_FILTERTIME, + AC_ADD2_FILTER_USE_TIME } enum ConvenientModeEnum { diff --git a/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/SamsungAcBinding.java b/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/SamsungAcBinding.java index 353d05c5e8c..5ba08a8f86b 100644 --- a/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/SamsungAcBinding.java +++ b/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/SamsungAcBinding.java @@ -13,6 +13,7 @@ import java.util.HashMap; import java.util.Map; +import org.apache.commons.lang.StringUtils; import org.binding.openhab.samsungac.communicator.AirConditioner; import org.binding.openhab.samsungac.communicator.SsdpDiscovery; import org.openhab.binding.samsungac.SamsungAcBindingProvider; @@ -20,6 +21,7 @@ import org.openhab.core.binding.BindingProvider; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.StringType; import org.openhab.core.types.Command; import org.openhab.core.types.State; import org.osgi.service.cm.ConfigurationException; @@ -99,6 +101,8 @@ private String getCmdStringFromEnumValue(Command command, String cmd = null; switch (property) { case AC_FUN_POWER: + case AC_ADD_SPI: + case AC_ADD_AUTOCLEAN: cmd = "ON".equals(command.toString()) ? "On" : "Off"; break; case AC_FUN_WINDLEVEL: @@ -114,8 +118,7 @@ private String getCmdStringFromEnumValue(Command command, cmd = DirectionEnum.getFromValue(command).toString(); break; case AC_FUN_TEMPSET: - cmd = command.toString(); - break; + case AC_FUN_ERROR: default: cmd = command.toString(); break; @@ -159,11 +162,11 @@ private CommandEnum getProperty(String itemName) { return null; } - private String getItemName(CommandEnum property) { + private String getItemName(String acName, CommandEnum property) { for (BindingProvider provider : providers) { if (provider instanceof SamsungAcBindingProvider) { SamsungAcBindingProvider acProvider = (SamsungAcBindingProvider) provider; - return acProvider.getItemName(property); + return acProvider.getItemName(acName, property); } } return null; @@ -176,9 +179,18 @@ public void updated(Dictionary config) throws ConfigurationException { Enumeration keys = config.keys(); + String refreshIntervalString = (String) config.get("refresh"); + if (StringUtils.isNotBlank(refreshIntervalString)) { + refreshInterval = Long.parseLong(refreshIntervalString); + logger.info("Refresh interval set to " + refreshIntervalString + " ms"); + } else { + logger.info("No refresh interval configured, using default: " + refreshInterval + " ms"); + } + Map hosts = new HashMap(); while (keys.hasMoreElements()) { String key = keys.nextElement(); + logger.debug("Configuration key is: " + key); if ("service.pid".equals(key)) { continue; } @@ -236,8 +248,9 @@ protected void execute() { for (Map.Entry entry : nameHostMapper .entrySet()) { AirConditioner host = entry.getValue(); + String acName = entry.getKey(); if (host.isConnected()) { - getAndUpdateStatusForAirConditioner(host); + getAndUpdateStatusForAirConditioner(acName, host); } else { reconnectToAirConditioner(entry.getKey(), host); } @@ -258,9 +271,10 @@ private void reconnectToAirConditioner(String key, AirConditioner host) { } } - private void getAndUpdateStatusForAirConditioner(AirConditioner host) { + private void getAndUpdateStatusForAirConditioner(String acName, AirConditioner host) { Map status = new HashMap(); try { + logger.debug("Getting status for ac: '" + acName + "'"); status = host.getStatus(); } catch (Exception e) { logger.debug("Could not get status.. returning.."); @@ -268,7 +282,8 @@ private void getAndUpdateStatusForAirConditioner(AirConditioner host) { } for (CommandEnum cmd : status.keySet()) { - String item = getItemName(cmd); + logger.debug("Trying to find item for: " + acName + " and cmd: " + cmd.toString()); + String item = getItemName(acName, cmd); String value = status.get(cmd); if (item != null && value != null) { updateItemWithValue(cmd, item, value); @@ -283,6 +298,8 @@ private void updateItemWithValue(CommandEnum cmd, String item, String value) { postUpdate(item, DecimalType.valueOf(value)); break; case AC_FUN_POWER: + case AC_ADD_SPI: + case AC_ADD_AUTOCLEAN: postUpdate( item, value.toUpperCase().equals("ON") ? OnOffType.ON @@ -312,9 +329,9 @@ private void updateItemWithValue(CommandEnum cmd, String item, String value) { .toString(DirectionEnum .valueOf(value).value))); break; + case AC_FUN_ERROR: default: - logger.debug("Not implementation for updating: '" - + cmd + "'"); + postUpdate(item, StringType.valueOf(value)); break; } } @@ -323,6 +340,8 @@ private void postUpdate(String item, State state) { if (item != null && state != null) { logger.debug(item + " gets updated to: " + state); eventPublisher.postUpdate(item, state); + } else { + logger.debug("Could not update item: '" + item + "' with state: '" + state.toString() + "'"); } } diff --git a/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/SamsungAcGenericBindingProvider.java b/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/SamsungAcGenericBindingProvider.java index ef60a905f7c..535a00df78c 100644 --- a/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/SamsungAcGenericBindingProvider.java +++ b/bundles/binding/org.openhab.binding.samsungac/src/main/java/org/openhab/binding/samsungac/internal/SamsungAcGenericBindingProvider.java @@ -15,6 +15,7 @@ import org.openhab.core.binding.BindingConfig; import org.openhab.core.items.Item; import org.openhab.core.library.items.NumberItem; +import org.openhab.core.library.items.StringItem; import org.openhab.core.library.items.SwitchItem; import org.openhab.model.item.binding.AbstractGenericBindingProvider; import org.openhab.model.item.binding.BindingConfigParseException; @@ -34,6 +35,7 @@ * Number ac_set_temp "Set temp [%.1f]" {samsungac="[|AC_FUN_TEMPSET]"} * Number ac_direction "Direction" {samsungac="[|AC_FUN_DIRECTION]"} * Number ac_windlevel "Windlevel" {samsungac="[|AC_FUN_WINDLEVEL]"} + * String ac_error "Error" {samsungac="[|AC_FUN_ERROR]"} * * * @author Stein Tore Tøsse @@ -60,10 +62,10 @@ public String getBindingType() { */ public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException { - if (!(item instanceof SwitchItem) && !(item instanceof NumberItem)) { + if (!(item instanceof SwitchItem) && !(item instanceof NumberItem) && !(item instanceof StringItem)) { throw new BindingConfigParseException("item '" + item.getName() + "' is of type '" + item.getClass().getSimpleName() - + "', but only Number and Switchs items are allowed."); + + "', but only Number, Strings and Switchs items are allowed."); } } @@ -93,17 +95,17 @@ private SamsungAcBindingConfig parseBindingConfig(Item item, return new SamsungAcBindingConfig(acInstance, item.getName(), property); } - public BindingConfig getItem(CommandEnum property) { + public BindingConfig getItem(String acName, CommandEnum property) { for (BindingConfig config : bindingConfigs.values()) { SamsungAcBindingConfig con = (SamsungAcBindingConfig) config; - if (property.equals(con.getProperty())) + if (property.equals(con.getProperty()) && con.acInstance.equals(acName) ) return con; } return null; } - - public String getItemName(CommandEnum property) { - SamsungAcBindingConfig con = (SamsungAcBindingConfig) getItem(property); + + public String getItemName(String acName, CommandEnum property) { + SamsungAcBindingConfig con = (SamsungAcBindingConfig) getItem(acName, property); if (con != null && property.equals(con.getProperty())) return con.getItemName(); return null; diff --git a/bundles/binding/org.openhab.binding.satel/.classpath b/bundles/binding/org.openhab.binding.satel/.classpath new file mode 100644 index 00000000000..f92b13310e0 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/binding/org.openhab.binding.satel/.project b/bundles/binding/org.openhab.binding.satel/.project new file mode 100644 index 00000000000..9ca72defbf8 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/.project @@ -0,0 +1,33 @@ + + + org.openhab.binding.satel + This is the Satel binding of the open Home Automation Bus (openHAB) + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/bundles/binding/org.openhab.binding.satel/META-INF/MANIFEST.MF b/bundles/binding/org.openhab.binding.satel/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..4a3b69595a4 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/META-INF/MANIFEST.MF @@ -0,0 +1,32 @@ +Manifest-Version: 1.0 +Private-Package: org.openhab.binding.satel.internal +Ignore-Package: org.openhab.binding.satel.internal +Bundle-License: http://www.eclipse.org/legal/epl-v10.html +Bundle-Name: openHAB Satel Binding +Bundle-SymbolicName: org.openhab.binding.satel +Bundle-Vendor: openHAB.org +Bundle-Version: 1.7.0.qualifier +Bundle-Activator: org.openhab.binding.satel.internal.SatelActivator +Bundle-ManifestVersion: 2 +Bundle-Description: This is the Satel binding of the open Home Aut + omation Bus (openHAB) +Import-Package: gnu.io, + org.apache.commons.lang, + org.openhab.core.autoupdate, + org.openhab.core.binding, + org.openhab.core.events, + org.openhab.core.items, + org.openhab.core.library.items, + org.openhab.core.library.types, + org.openhab.core.types, + org.openhab.model.item.binding, + org.osgi.framework, + org.osgi.service.cm, + org.osgi.service.component, + org.osgi.service.event, + org.slf4j +Export-Package: org.openhab.binding.satel +Bundle-DocURL: http://www.openhab.org +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Service-Component: OSGI-INF/binding.xml, OSGI-INF/genericbindingprovider.xml +Bundle-ClassPath: . diff --git a/bundles/binding/org.openhab.binding.satel/OSGI-INF/binding.xml b/bundles/binding/org.openhab.binding.satel/OSGI-INF/binding.xml new file mode 100644 index 00000000000..828c3ca3f22 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/OSGI-INF/binding.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.satel/OSGI-INF/genericbindingprovider.xml b/bundles/binding/org.openhab.binding.satel/OSGI-INF/genericbindingprovider.xml new file mode 100644 index 00000000000..2078c450197 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/OSGI-INF/genericbindingprovider.xml @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.satel/build.properties b/bundles/binding/org.openhab.binding.satel/build.properties new file mode 100644 index 00000000000..741aa1f7794 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/build.properties @@ -0,0 +1,5 @@ +source.. = src/main/java/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/ +output.. = target/classes/ diff --git a/bundles/binding/org.openhab.binding.satel/pom.xml b/bundles/binding/org.openhab.binding.satel/pom.xml new file mode 100644 index 00000000000..c64a4b822ea --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/pom.xml @@ -0,0 +1,35 @@ + + + + + org.openhab.bundles + binding + 1.7.0-SNAPSHOT + + + openHAB Satel Binding + + + org.openhab.binding.satel + org.openhab.binding.satel + openhab-addon-binding-satel + ${project.name} + + + 4.0.0 + org.openhab.binding + org.openhab.binding.satel + + eclipse-plugin + + + + + org.vafer + jdeb + + + + + diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/SatelBindingConfig.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/SatelBindingConfig.java new file mode 100644 index 00000000000..dcdcb2458db --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/SatelBindingConfig.java @@ -0,0 +1,168 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.openhab.binding.satel.internal.event.SatelEvent; +import org.openhab.binding.satel.internal.protocol.SatelMessage; +import org.openhab.binding.satel.internal.types.IntegraType; +import org.openhab.core.binding.BindingConfig; +import org.openhab.core.items.Item; +import org.openhab.core.library.items.ContactItem; +import org.openhab.core.library.items.NumberItem; +import org.openhab.core.library.items.SwitchItem; +import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.OpenClosedType; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.model.item.binding.BindingConfigParseException; + +/** + * Base class that all Satel configuration classes must extend. Provides methods + * to convert data between openHAB and Satel module. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public abstract class SatelBindingConfig implements BindingConfig { + + private static final DecimalType DECIMAL_ONE = new DecimalType(1); + + /** + * Converts data from {@link SatelEvent} to openHAB state of specified item. + * + * @param item + * an item to get new state for + * @param event + * incoming event + * @return new item state + */ + public abstract State convertEventToState(Item item, SatelEvent event); + + /** + * Converts openHAB command to proper Satel message that changes state of + * bound object (output, zone). + * + * @param command + * command to convert + * @param integraType + * type of connected Integra + * @param userCode + * user's password + * @return a message to send + */ + public abstract SatelMessage convertCommandToMessage(Command command, IntegraType integraType, String userCode); + + /** + * Returns message needed to get current state of bound object. + * + * @param integraType + * type of connected Integra + * @return a message to send + */ + public abstract SatelMessage buildRefreshMessage(IntegraType integraType); + + /** + * Helper class to iterate over elements of binding configuration. + */ + protected static class ConfigIterator implements Iterator { + private String bindingConfig; + private String[] configElements; + private int idx; + + public ConfigIterator(String bindingConfig) { + this.bindingConfig = bindingConfig; + this.configElements = bindingConfig.split(":"); + this.idx = 0; + } + + public String getBindingConfig() { + return this.bindingConfig; + } + + public String nextUpperCase() { + return next().toUpperCase(); + } + + public > T nextOfType(Class enumType, String description) + throws BindingConfigParseException { + try { + return Enum.valueOf(enumType, next().toUpperCase()); + } catch (Exception e) { + throw new BindingConfigParseException(String.format("Invalid %s: %s", description, this.bindingConfig)); + } + } + + @Override + public boolean hasNext() { + return idx < this.configElements.length; + } + + @Override + public String next() { + return this.configElements[idx++]; + } + + @Override + public void remove() { + // ignore + } + } + + /** + * Parses binding configuration options. This must be the last element of + * the configuration. + * + * @param iterator + * config iterator + * @return parsed options as a map + * @throws BindingConfigParseException + * in case there are more elements after options + */ + protected static Map parseOptions(ConfigIterator iterator) throws BindingConfigParseException { + // parse options: comma separated pairs of = + Map options = new HashMap(); + + if (iterator.hasNext()) { + + for (String option : iterator.next().split(",")) { + if (option.contains("=")) { + String[] keyVal = option.split("=", 2); + options.put(keyVal[0].toUpperCase(), keyVal[1]); + } else { + options.put(option, ""); + } + } + + if (iterator.hasNext()) { + // options are always the last element + // if anything left, throw exception + throw new BindingConfigParseException(String.format("Too many elements: %s", + iterator.getBindingConfig())); + } + } + return options; + } + + protected State booleanToState(Item item, boolean value) { + if (item instanceof ContactItem) { + return value ? OpenClosedType.OPEN : OpenClosedType.CLOSED; + } else if (item instanceof SwitchItem) { + return value ? OnOffType.ON : OnOffType.OFF; + } else if (item instanceof NumberItem) { + return value ? DECIMAL_ONE : DecimalType.ZERO; + } + + return null; + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/SatelBindingProvider.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/SatelBindingProvider.java new file mode 100644 index 00000000000..60c3802a370 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/SatelBindingProvider.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel; + +import org.openhab.core.binding.BindingProvider; +import org.openhab.core.items.Item; + +/** + * This interface is implemented by classes that can provide mapping information + * between openHAB items and Satel module. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public interface SatelBindingProvider extends BindingProvider { + + /** + * Returns the {@link Item} with the specified item name. Returns null if + * the item was not found. + * + * @param itemName + * the name of the item. + * @return the item. + */ + Item getItem(String itemName); + + /** + * Returns the {@link SatelBindingConfig} for the specified item name. + * Returns null if the item was not found. + * + * @param itemName + * the name of the item. + * @return the binding configuration for the item. + */ + SatelBindingConfig getItemConfig(String itemName); +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/config/IntegraStateBindingConfig.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/config/IntegraStateBindingConfig.java new file mode 100644 index 00000000000..e43347cbdf0 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/config/IntegraStateBindingConfig.java @@ -0,0 +1,242 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.config; + +import java.util.Map; + +import org.openhab.binding.satel.SatelBindingConfig; +import org.openhab.binding.satel.internal.event.IntegraStateEvent; +import org.openhab.binding.satel.internal.event.SatelEvent; +import org.openhab.binding.satel.internal.protocol.SatelMessage; +import org.openhab.binding.satel.internal.protocol.command.ControlObjectCommand; +import org.openhab.binding.satel.internal.protocol.command.IntegraStateCommand; +import org.openhab.binding.satel.internal.types.DoorsState; +import org.openhab.binding.satel.internal.types.IntegraType; +import org.openhab.binding.satel.internal.types.ObjectType; +import org.openhab.binding.satel.internal.types.OutputControl; +import org.openhab.binding.satel.internal.types.OutputState; +import org.openhab.binding.satel.internal.types.PartitionControl; +import org.openhab.binding.satel.internal.types.PartitionState; +import org.openhab.binding.satel.internal.types.StateType; +import org.openhab.binding.satel.internal.types.ZoneState; +import org.openhab.core.items.Item; +import org.openhab.core.library.items.ContactItem; +import org.openhab.core.library.items.NumberItem; +import org.openhab.core.library.items.SwitchItem; +import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.OpenClosedType; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.model.item.binding.BindingConfigParseException; + +/** + * This class implements binding configuration for all items that represent + * Integra zones/partitions/outputs state. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class IntegraStateBindingConfig extends SatelBindingConfig { + + private StateType stateType; + private int[] objectNumbers; + private Map options; + + private IntegraStateBindingConfig(StateType stateType, int[] objectNumbers, Map options) { + this.stateType = stateType; + this.objectNumbers = objectNumbers; + this.options = options; + } + + /** + * Parses given binding configuration and creates configuration object. + * + * @param bindingConfig + * config to parse + * @return parsed config object or null if config does not + * match + * @throws BindingConfigParseException + * in case of parse errors + */ + public static IntegraStateBindingConfig parseConfig(String bindingConfig) throws BindingConfigParseException { + ConfigIterator iterator = new ConfigIterator(bindingConfig); + ObjectType objectType; + + // parse object type, mandatory + try { + objectType = ObjectType.valueOf(iterator.nextUpperCase()); + } catch (Exception e) { + // wrong config type, skip parsing + return null; + } + + // parse state type, mandatory except for output + StateType stateType = null; + int[] objectNumbers = {}; + + switch (objectType) { + case ZONE: + stateType = iterator.nextOfType(ZoneState.class, "zone state type"); + break; + case PARTITION: + stateType = iterator.nextOfType(PartitionState.class, "partition state type"); + break; + case OUTPUT: + stateType = OutputState.OUTPUT; + break; + case DOORS: + stateType = iterator.nextOfType(DoorsState.class, "doors state type"); + break; + } + + // parse object numbers, if provided + if (iterator.hasNext()) { + try { + String[] objectNumbersStr = iterator.next().split(","); + objectNumbers = new int[objectNumbersStr.length]; + for (int i = 0; i < objectNumbersStr.length; ++i) { + int objectNumber = Integer.parseInt(objectNumbersStr[i]); + if (objectNumber < 1 || objectNumber > 256) { + throw new BindingConfigParseException(String.format("Invalid object number: %s", bindingConfig)); + } + objectNumbers[i] = objectNumber; + } + } catch (NumberFormatException e) { + throw new BindingConfigParseException(String.format("Invalid object number: %s", bindingConfig)); + } + } + + return new IntegraStateBindingConfig(stateType, objectNumbers, parseOptions(iterator)); + } + + /** + * {@inheritDoc} + */ + @Override + public State convertEventToState(Item item, SatelEvent event) { + if (!(event instanceof IntegraStateEvent)) { + return null; + } + + IntegraStateEvent stateEvent = (IntegraStateEvent) event; + if (stateEvent.getStateType() != this.stateType) { + return null; + } + + if (this.objectNumbers.length == 1) { + int bitNbr = this.objectNumbers[0] - 1; + return booleanToState(item, stateEvent.isSet(bitNbr)); + } else if (this.objectNumbers.length == 0) { + if (item instanceof ContactItem) { + return (stateEvent.statesSet() > 0) ? OpenClosedType.OPEN : OpenClosedType.CLOSED; + } else if (item instanceof SwitchItem) { + return (stateEvent.statesSet() > 0) ? OnOffType.ON : OnOffType.OFF; + } else if (item instanceof NumberItem) { + return new DecimalType(stateEvent.statesSet()); + } + } + + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public SatelMessage convertCommandToMessage(Command command, IntegraType integraType, String userCode) { + if (command instanceof OnOffType && this.objectNumbers.length == 1) { + boolean switchOn = ((OnOffType) command == OnOffType.ON); + boolean force_arm = this.options.containsKey("FORCE_ARM"); + + switch (this.stateType.getObjectType()) { + case OUTPUT: + byte[] outputs = getObjectBitset((integraType == IntegraType.I256_PLUS) ? 32 : 16); + return ControlObjectCommand.buildMessage(switchOn ? OutputControl.ON : OutputControl.OFF, outputs, + userCode); + + case DOORS: + break; + + case ZONE: + break; + + case PARTITION: + byte[] partitions = getObjectBitset(4); + switch ((PartitionState) this.stateType) { + // clear alarms on OFF command + case ALARM: + case ALARM_MEMORY: + case FIRE_ALARM: + case FIRE_ALARM_MEMORY: + case VERIFIED_ALARMS: + case WARNING_ALARMS: + if (switchOn) { + return null; + } else { + return ControlObjectCommand.buildMessage(PartitionControl.CLEAR_ALARM, partitions, userCode); + } + + // arm or disarm, depending on command + case ARMED: + case REALLY_ARMED: + return ControlObjectCommand.buildMessage(switchOn ? (force_arm ? PartitionControl.FORCE_ARM_MODE_0 + : PartitionControl.ARM_MODE_0) : PartitionControl.DISARM, partitions, userCode); + case ARMED_MODE_1: + return ControlObjectCommand.buildMessage(switchOn ? (force_arm ? PartitionControl.FORCE_ARM_MODE_1 + : PartitionControl.ARM_MODE_1) : PartitionControl.DISARM, partitions, userCode); + case ARMED_MODE_2: + return ControlObjectCommand.buildMessage(switchOn ? (force_arm ? PartitionControl.FORCE_ARM_MODE_2 + : PartitionControl.ARM_MODE_2) : PartitionControl.DISARM, partitions, userCode); + case ARMED_MODE_3: + return ControlObjectCommand.buildMessage(switchOn ? (force_arm ? PartitionControl.FORCE_ARM_MODE_3 + : PartitionControl.ARM_MODE_3) : PartitionControl.DISARM, partitions, userCode); + + // do nothing for other types of state + default: + break; + } + } + } + + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public SatelMessage buildRefreshMessage(IntegraType integraType) { + return IntegraStateCommand.buildMessage(this.stateType, integraType == IntegraType.I256_PLUS); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (int i : this.objectNumbers) { + if (sb.length() > 0) + sb.append(","); + sb.append(Integer.toString(i)); + } + return String.format("IntegraStateBindingConfig: object = %s, state = %s, object nbr = %s, options = %s", + this.stateType.getObjectType(), this.stateType, sb.toString(), this.options); + } + + private byte[] getObjectBitset(int size) { + byte[] bitset = new byte[size]; + for (int objectNumber : this.objectNumbers) { + int bitNbr = objectNumber - 1; + bitset[bitNbr / 8] |= (byte) (1 << (bitNbr % 8)); + } + return bitset; + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/config/IntegraStatusBindingConfig.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/config/IntegraStatusBindingConfig.java new file mode 100644 index 00000000000..2c893e7c57d --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/config/IntegraStatusBindingConfig.java @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.config; + +import java.util.Map; + +import org.openhab.binding.satel.SatelBindingConfig; +import org.openhab.binding.satel.internal.event.IntegraStatusEvent; +import org.openhab.binding.satel.internal.event.SatelEvent; +import org.openhab.binding.satel.internal.protocol.SatelMessage; +import org.openhab.binding.satel.internal.protocol.command.ClearTroublesCommand; +import org.openhab.binding.satel.internal.protocol.command.IntegraStatusCommand; +import org.openhab.binding.satel.internal.protocol.command.SetClockCommand; +import org.openhab.binding.satel.internal.types.IntegraType; +import org.openhab.core.items.Item; +import org.openhab.core.library.types.DateTimeType; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.StringType; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.model.item.binding.BindingConfigParseException; + +/** + * This class implements binding configuration for all items that represent + * Integra zones/partitions/outputs state. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class IntegraStatusBindingConfig extends SatelBindingConfig { + + enum StatusType { + DATE_TIME, SERVICE_MODE, TROUBLES, ACU100_PRESENT, INTRX_PRESENT, TROUBLES_MEMORY, GRADE23_SET + } + + private StatusType statusType; + private Map options; + + private IntegraStatusBindingConfig(StatusType statusType, Map options) { + this.statusType = statusType; + this.options = options; + } + + /** + * Parses given binding configuration and creates configuration object. + * + * @param bindingConfig + * config to parse + * @return parsed config object or null if config does not + * match + * @throws BindingConfigParseException + * in case of parse errors + */ + public static IntegraStatusBindingConfig parseConfig(String bindingConfig) throws BindingConfigParseException { + ConfigIterator iterator = new ConfigIterator(bindingConfig); + + // check if a status item + if (!"status".equalsIgnoreCase(iterator.next())) + return null; + + return new IntegraStatusBindingConfig(iterator.nextOfType(StatusType.class, "status type"), + parseOptions(iterator)); + } + + /** + * {@inheritDoc} + */ + @Override + public State convertEventToState(Item item, SatelEvent event) { + if (!(event instanceof IntegraStatusEvent)) { + return null; + } + + IntegraStatusEvent statusEvent = (IntegraStatusEvent) event; + + switch (this.statusType) { + case DATE_TIME: + if (item.getAcceptedDataTypes().contains(DateTimeType.class)) { + return new DateTimeType(statusEvent.getIntegraTime()); + } else { + return null; + } + case SERVICE_MODE: + return booleanToState(item, statusEvent.inServiceMode()); + case TROUBLES: + return booleanToState(item, statusEvent.troublesPresent()); + case TROUBLES_MEMORY: + return booleanToState(item, statusEvent.troublesMemory()); + case ACU100_PRESENT: + return booleanToState(item, statusEvent.isAcu100Present()); + case INTRX_PRESENT: + return booleanToState(item, statusEvent.isIntRxPresent()); + case GRADE23_SET: + return booleanToState(item, statusEvent.isGrade23Set()); + } + + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public SatelMessage convertCommandToMessage(Command command, IntegraType integraType, String userCode) { + if (command instanceof OnOffType) { + boolean switchOn = ((OnOffType) command == OnOffType.ON); + + switch (this.statusType) { + case TROUBLES: + case TROUBLES_MEMORY: + if (switchOn) { + return null; + } else { + return ClearTroublesCommand.buildMessage(userCode); + } + + // do nothing for other types of status + default: + break; + } + + } else if (this.statusType == StatusType.DATE_TIME) { + DateTimeType dateTime = null; + if (command instanceof StringType) { + dateTime = DateTimeType.valueOf(command.toString()); + } else if (command instanceof DateTimeType) { + // not possible, DateTimeType is not a command + dateTime = (DateTimeType) command; + } + if (dateTime != null) { + return SetClockCommand.buildMessage(dateTime.getCalendar(), userCode); + } + } + + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public SatelMessage buildRefreshMessage(IntegraType integraType) { + return IntegraStatusCommand.buildMessage(); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return String.format("IntegraStatusBindingConfig: status = %s, options = %s", this.statusType, this.options); + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/SatelActivator.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/SatelActivator.java new file mode 100644 index 00000000000..60b4f84a43e --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/SatelActivator.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Extension of the default OSGi bundle activator + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public final class SatelActivator implements BundleActivator { + + private static Logger logger = LoggerFactory.getLogger(SatelActivator.class); + + /** + * Called whenever the OSGi framework starts our bundle + */ + public void start(BundleContext bc) throws Exception { + logger.debug("Satel binding has been started."); + } + + /** + * Called whenever the OSGi framework stops our bundle + */ + public void stop(BundleContext bc) throws Exception { + logger.debug("Satel binding has been stopped."); + } + +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/SatelBinding.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/SatelBinding.java new file mode 100644 index 00000000000..cf195892620 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/SatelBinding.java @@ -0,0 +1,253 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal; + +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.openhab.binding.satel.SatelBindingConfig; +import org.openhab.binding.satel.SatelBindingProvider; +import org.openhab.binding.satel.internal.event.SatelEventListener; +import org.openhab.binding.satel.internal.event.NewStatesEvent; +import org.openhab.binding.satel.internal.event.SatelEvent; +import org.openhab.binding.satel.internal.protocol.Ethm1Module; +import org.openhab.binding.satel.internal.protocol.IntRSModule; +import org.openhab.binding.satel.internal.protocol.SatelMessage; +import org.openhab.binding.satel.internal.protocol.SatelModule; +import org.openhab.binding.satel.internal.protocol.command.IntegraStatusCommand; +import org.openhab.binding.satel.internal.protocol.command.NewStatesCommand; +import org.openhab.binding.satel.internal.types.IntegraType; +import org.openhab.core.binding.AbstractActiveBinding; +import org.openhab.core.items.Item; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This is main service class that helps exchanging data between openHAB and + * Satel module in both directions. Implements regular openHAB binding service. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class SatelBinding extends AbstractActiveBinding implements ManagedService, SatelEventListener { + + private static final Logger logger = LoggerFactory.getLogger(SatelBinding.class); + + private long refreshInterval = 10000; + private String userCode; + private SatelModule satelModule = null; + private SatelMessage newStatesCommand = null; + + /** + * {@inheritDoc} + */ + @Override + protected String getName() { + return "Satel Refresh Service"; + } + + /** + * {@inheritDoc} + */ + @Override + protected long getRefreshInterval() { + return refreshInterval; + } + + /** + * {@inheritDoc} + */ + @Override + public void execute() { + if (!this.satelModule.isInitialized()) { + logger.debug("Module not initialized yet, skipping refresh"); + return; + } + + // get list of states that have changed + logger.trace("Sending 'get new states' command"); + if (this.newStatesCommand == null) { + this.newStatesCommand = NewStatesCommand + .buildMessage(this.satelModule.getIntegraType() == IntegraType.I256_PLUS); + } + this.satelModule.sendCommand(this.newStatesCommand); + } + + /** + * {@inheritDoc} + */ + @Override + public void updated(Dictionary config) throws ConfigurationException { + logger.trace("Binding configuration updated"); + + if (config == null) { + return; + } + + this.refreshInterval = getLongValue(config, "refresh", 10000); + this.userCode = getStringValue(config, "user_code", null); + + int timeout = getIntValue(config, "timeout", 5000); + String host = getStringValue(config, "host", null); + if (StringUtils.isNotBlank(host)) { + this.satelModule = new Ethm1Module(host, getIntValue(config, "port", 7094), timeout, + (String) config.get("encryption_key")); + } else { + this.satelModule = new IntRSModule((String) config.get("port"), timeout); + } + + this.satelModule.addEventListener(this); + this.satelModule.open(); + setProperlyConfigured(true); + logger.trace("Binding properly configured"); + } + + /** + * {@inheritDoc} + */ + @Override + protected void internalReceiveCommand(String itemName, Command command) { + if (!isProperlyConfigured()) { + logger.warn("Binding not properly configured, exiting"); + return; + } + + if (!this.satelModule.isInitialized()) { + logger.debug("Module not initialized yet, ignoring command"); + return; + } + + for (SatelBindingProvider provider : providers) { + SatelBindingConfig itemConfig = provider.getItemConfig(itemName); + if (itemConfig != null) { + logger.trace("Sending internal command for item {}: {}", itemName, command); + SatelMessage message = itemConfig.convertCommandToMessage(command, this.satelModule.getIntegraType(), + this.userCode); + if (message != null) { + this.satelModule.sendCommand(message); + } + break; + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void incomingEvent(SatelEvent event) { + logger.trace("Handling incoming event: {}", event); + + // refresh all states that have changed + if (event instanceof NewStatesEvent) { + List commands = getRefreshCommands((NewStatesEvent) event); + for (SatelMessage message : commands) { + this.satelModule.sendCommand(message); + } + } + + // update items + for (SatelBindingProvider provider : providers) { + for (String itemName : provider.getItemNames()) { + SatelBindingConfig itemConfig = provider.getItemConfig(itemName); + Item item = provider.getItem(itemName); + State newState = itemConfig.convertEventToState(item, event); + if (newState != null) { + logger.debug("Updating item state: item = {}, state = {}, event = {}", itemName, newState, event); + eventPublisher.postUpdate(itemName, newState); + } + } + } + } + + /** + * Deactivates the binding by closing connected module. + */ + @Override + public void deactivate() { + if (this.satelModule != null) { + this.satelModule.close(); + this.satelModule = null; + } + this.newStatesCommand = null; + } + + private List getRefreshCommands(NewStatesEvent nse) { + logger.trace("Gathering refresh commands from all items"); + + List commands = new ArrayList(); + for (SatelBindingProvider provider : providers) { + for (String itemName : provider.getItemNames()) { + logger.trace("Getting refresh command from item: {}", itemName); + + SatelBindingConfig itemConfig = provider.getItemConfig(itemName); + SatelMessage message = itemConfig.buildRefreshMessage(this.satelModule.getIntegraType()); + + if (message == null || commands.contains(message)) { + continue; + } + + // either state has changed or this is status command, so likely + // RTC has changed or state is Undefined, so get the latest + // value from the module + Item item = provider.getItem(itemName); + if (item.getState() == UnDefType.UNDEF || (nse != null && nse.isNew(message.getCommand())) + || message.getCommand() == IntegraStatusCommand.COMMAND_CODE) { + commands.add(message); + } + } + } + + return commands; + } + + private static String getStringValue(Dictionary config, String name, String defaultValue) { + String val = (String) config.get(name); + if (StringUtils.isNotBlank(val)) { + return val; + } else { + return defaultValue; + } + } + + private static int getIntValue(Dictionary config, String name, int defaultValue) + throws ConfigurationException { + String val = (String) config.get(name); + try { + if (StringUtils.isNotBlank(val)) { + return Integer.parseInt(val); + } else { + return defaultValue; + } + } catch (Exception e) { + throw new ConfigurationException(name, "invalid integer value"); + } + } + + private static long getLongValue(Dictionary config, String name, long defaultValue) + throws ConfigurationException { + String val = (String) config.get(name); + try { + if (StringUtils.isNotBlank(val)) { + return Long.parseLong(val); + } else { + return defaultValue; + } + } catch (Exception e) { + throw new ConfigurationException(name, "invalid long value"); + } + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/SatelGenericBindingProvider.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/SatelGenericBindingProvider.java new file mode 100644 index 00000000000..56afdd03f1a --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/SatelGenericBindingProvider.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal; + +import java.util.Set; + +import org.openhab.binding.satel.SatelBindingConfig; +import org.openhab.binding.satel.SatelBindingProvider; +import org.openhab.binding.satel.config.IntegraStateBindingConfig; +import org.openhab.binding.satel.config.IntegraStatusBindingConfig; +import org.openhab.core.items.Item; +import org.openhab.model.item.binding.AbstractGenericBindingProvider; +import org.openhab.model.item.binding.BindingConfigParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is responsible for parsing the binding configuration. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class SatelGenericBindingProvider extends AbstractGenericBindingProvider implements SatelBindingProvider { + + private static final Logger logger = LoggerFactory.getLogger(SatelGenericBindingProvider.class); + + /** + * {@inheritDoc} + */ + @Override + public String getBindingType() { + return "satel"; + } + + /** + * {@inheritDoc} + */ + @Override + public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException { + } + + /** + * {@inheritDoc} + */ + @Override + public void processBindingConfiguration(String context, Item item, String bindingConfig) + throws BindingConfigParseException { + logger.trace("Processing binding configuration for item {}", item.getName()); + super.processBindingConfiguration(context, item, bindingConfig); + + SatelBindingConfig bc = this.createBindingConfig(bindingConfig); + logger.trace("Adding binding configuration for item {}: {}", item.getName(), bc); + addBindingConfig(item, bc); + } + + /** + * {@inheritDoc} + */ + @Override + public Item getItem(String itemName) { + for (Set items : contextMap.values()) { + if (items != null) { + for (Item item : items) { + if (itemName.equals(item.getName())) { + return item; + } + } + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public SatelBindingConfig getItemConfig(String itemName) { + return (SatelBindingConfig) this.bindingConfigs.get(itemName); + } + + private SatelBindingConfig createBindingConfig(String bindingConfig) throws BindingConfigParseException { + try { + SatelBindingConfig bc = null; + + // try IntegraStateBindingConfig first + bc = IntegraStateBindingConfig.parseConfig(bindingConfig); + if (bc != null) { + return bc; + } + + // try IntegraStatusBindingConfig + bc = IntegraStatusBindingConfig.parseConfig(bindingConfig); + if (bc != null) { + return bc; + } + + // no more options, throw parse exception + } catch (Exception e) { + // throw parse exception in case of any error + } + + throw new BindingConfigParseException(String.format("Invalid binding configuration: %s", bindingConfig)); + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/EventDispatcher.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/EventDispatcher.java new file mode 100644 index 00000000000..1bae959c3fa --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/EventDispatcher.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.event; + +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Allows distributing incoming event to all registered listeners. Listeners + * must implement {@link SatelEventListener} interface. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class EventDispatcher { + private static final Logger logger = LoggerFactory.getLogger(EventDispatcher.class); + + private final Set eventListeners = new CopyOnWriteArraySet(); + + /** + * Add a listener for Satel events. + * + * @param eventListener + * the event listener to add. + */ + public void addEventListener(SatelEventListener eventListener) { + this.eventListeners.add(eventListener); + } + + /** + * Remove a listener for Satel events. + * + * @param eventListener + * the event listener to remove. + */ + public void removeEventListener(SatelEventListener eventListener) { + this.eventListeners.remove(eventListener); + } + + /** + * Dispatch incoming event to all listeners. + * + * @param event + * the event to distribute. + */ + public void dispatchEvent(SatelEvent event) { + logger.debug("Distributing event: {}", event); + for (SatelEventListener listener : eventListeners) { + logger.trace("Distributing to {}", listener); + listener.incomingEvent(event); + } + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/IntegraStateEvent.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/IntegraStateEvent.java new file mode 100644 index 00000000000..6fd62dd0f02 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/IntegraStateEvent.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.event; + +import java.util.BitSet; + +import org.openhab.binding.satel.internal.types.DoorsState; +import org.openhab.binding.satel.internal.types.ZoneState; +import org.openhab.binding.satel.internal.types.OutputState; +import org.openhab.binding.satel.internal.types.StateType; +import org.openhab.binding.satel.internal.types.PartitionState; + +/** + * Event class describing current state of zones/partitions/outputs/doors. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class IntegraStateEvent implements SatelEvent { + + private StateType stateType; + private BitSet stateBits; + + /** + * Constructs new event instance from given state type and state bits. + * + * @param stateType + * type of state + * @param stateBits + * state bits as byte array + */ + public IntegraStateEvent(StateType stateType, byte[] stateBits) { + this.stateType = stateType; + this.stateBits = BitSet.valueOf(stateBits); + } + + /** + * Returns type of state described by this event object. + * + * @return type of state for this event + * @see ZoneState + * @see PartitionState + * @see OutputState + * @see DoorsState + */ + public StateType getStateType() { + return this.stateType; + } + + /** + * Returns state bits as {@link BitSet}. + * + * @return state bits + */ + public BitSet getStateBits() { + return stateBits; + } + + /** + * Returns true if specified state bit is set. + * + * @param nbr + * state bit number + * @return true if state bit is set + */ + public boolean isSet(int nbr) { + return stateBits.get(nbr); + } + + /** + * Returns number of state bits that are active. + * + * @return number of active states + */ + public int statesSet() { + return stateBits.cardinality(); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + StringBuilder bitsStr = new StringBuilder(); + for (int i = this.stateBits.nextSetBit(0); i >= 0; i = this.stateBits.nextSetBit(i + 1)) { + if (bitsStr.length() > 0) { + bitsStr.append(","); + } + bitsStr.append(Integer.toString(i + 1)); + } + return String.format("IntegraStateEvent: object = %s, state = %s, active = [%s]", stateType.getObjectType(), + stateType, bitsStr); + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/IntegraStatusEvent.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/IntegraStatusEvent.java new file mode 100644 index 00000000000..e3a22165e33 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/IntegraStatusEvent.java @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.event; + +import java.util.Calendar; + +/** + * Event class describing basic status bits and current time. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class IntegraStatusEvent implements SatelEvent { + + private Calendar integraTime; + private boolean serviceMode; + private boolean troubles; + private boolean acu100Present; + private boolean intRxPresent; + private boolean troublesMemory; + private boolean grade23Set; + private byte integraType; + + /** + * Constructs new event. + * + * @param integraTime + * current Integra date and time + * @param statusByte1 + * status bits, byte #1 + * @param statusByte2 + * status bits, byte #2 + */ + public IntegraStatusEvent(Calendar integraTime, byte statusByte1, byte statusByte2) { + this.integraTime = integraTime; + this.serviceMode = (statusByte1 & 0x80) != 0; + this.troubles = (statusByte1 & 0x40) != 0; + this.acu100Present = (statusByte2 & 0x80) != 0; + this.intRxPresent = (statusByte2 & 0x40) != 0; + this.troublesMemory = (statusByte2 & 0x20) != 0; + this.grade23Set = (statusByte2 & 0x10) != 0; + this.integraType = (byte) (statusByte2 & 0x0f); + } + + /** + * @return current date and time on connected Integra + */ + public Calendar getIntegraTime() { + return integraTime; + } + + /** + * @return true if service mode is enabled + */ + public boolean inServiceMode() { + return serviceMode; + } + + /** + * @return true if there are troubles in the system + */ + public boolean troublesPresent() { + return troubles; + } + + /** + * @return true if the are troubles in the memory + */ + public boolean troublesMemory() { + return troublesMemory; + } + + /** + * @return true if ACU-100 module is present in the system + */ + public boolean isAcu100Present() { + return acu100Present; + } + + /** + * @return true if INT-RX module is present in the system + */ + public boolean isIntRxPresent() { + return intRxPresent; + } + + /** + * @return true if Grade 2 or Grade 3 is enabled in Integra configuration + */ + public boolean isGrade23Set() { + return grade23Set; + } + + /** + * @return Integra board type + */ + public int getIntegraType() { + return integraType; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return String + .format("IntegraStatusEvent: type = %d, time = %s, service mode = %b, troubles = %b, troubles memory = %b, ACU-100 = %b, INT-RX = %b, grade 2/3 = %b", + this.integraType, this.integraTime.getTime(), this.serviceMode, this.troubles, + this.troublesMemory, this.acu100Present, this.intRxPresent, this.grade23Set); + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/IntegraVersionEvent.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/IntegraVersionEvent.java new file mode 100644 index 00000000000..da6e8dca77e --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/IntegraVersionEvent.java @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.event; + +import org.openhab.binding.satel.internal.types.IntegraType; + +/** + * Event class describing type and version of connected Integra system. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class IntegraVersionEvent implements SatelEvent { + + private byte type; + private String version; + private byte language; + private boolean settingsInFlash; + + /** + * Constructs new event class. + * + * @param type + * Integra type + * @param version + * string describing version number and firmware revision + * @param language + * firmware language: 1 - english + * @param settingsInFlash + * settings stored in flash memory + */ + public IntegraVersionEvent(byte type, String version, byte language, boolean settingsInFlash) { + this.type = type; + this.version = version; + this.language = language; + this.settingsInFlash = settingsInFlash; + } + + /** + * @return Integra type + * @see IntegraType + */ + public byte getType() { + return type; + } + + /** + * @return firmware version and date + */ + public String getVersion() { + return version; + } + + /** + * @return firmware language + */ + public byte getLanguage() { + return language; + } + + /** + * @return true if configuration is stored in flash memory + */ + public boolean getSettingsInflash() { + return this.settingsInFlash; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return String.format("IntegraVersionEvent: type = %d, version = %s, language = %d, settingsInFlash = %b", + this.type & 0xFF, this.version, this.language, this.settingsInFlash); + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/NewStatesEvent.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/NewStatesEvent.java new file mode 100644 index 00000000000..2980a308a62 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/NewStatesEvent.java @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.event; + +import java.util.BitSet; + +/** + * Event class describing changes in Integra state since last state read. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class NewStatesEvent implements SatelEvent { + + private BitSet newStates; + + /** + * Constructs event class from given {@link BitSet}. + * + * @param newStates + * changed states as {@link BitSet} + */ + public NewStatesEvent(BitSet newStates) { + this.newStates = newStates; + } + + /** + * Constructs event class from given byte array. + * + * @param newStates + * changed states as byte array + */ + public NewStatesEvent(byte[] newStates) { + this(BitSet.valueOf(newStates)); + } + + /** + * Checks if specified state has changed since last read. + * + * @param nbr + * state number to check + * @return true if state has changed + */ + public boolean isNew(int nbr) { + return newStates.get(nbr); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + StringBuilder newStatesStr = new StringBuilder(); + for (int i = this.newStates.nextSetBit(0); i >= 0; i = this.newStates.nextSetBit(i + 1)) { + if (newStatesStr.length() > 0) { + newStatesStr.append(","); + } + newStatesStr.append(String.format("%02X", i)); + } + return String.format("NewStatesEvent: changed = [%s]", newStatesStr); + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/SatelEvent.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/SatelEvent.java new file mode 100644 index 00000000000..6c2a93ace39 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/SatelEvent.java @@ -0,0 +1,18 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.event; + +/** + * Simple interface that all event classes must implement. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public interface SatelEvent { +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/SatelEventListener.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/SatelEventListener.java new file mode 100644 index 00000000000..d8c4fbed8e1 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/event/SatelEventListener.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.event; + +/** + * Event listener interface. All classes that want to receive Satel events must + * implement this interface. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public interface SatelEventListener { + + /** + * Event handler for Satel events. + * + * @param event + * incoming event to handle + */ + void incomingEvent(SatelEvent event); +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/EncryptionHelper.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/EncryptionHelper.java new file mode 100644 index 00000000000..9e28c0a1b92 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/EncryptionHelper.java @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol; + +import java.security.GeneralSecurityException; +import java.security.Key; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + +/** + * Helper class for encrypting ETHM-1 messages. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class EncryptionHelper { + private Key key; + private Cipher encipher; + private Cipher decipher; + + /** + * Creates new instance of encryption helper with given key. + * + * @param keyString + * key for integration encryption + * @throws GeneralSecurityException on JCE errors + */ + public EncryptionHelper(String keyString) throws GeneralSecurityException { + // we have to check if 192bit support is enabled + if (Cipher.getMaxAllowedKeyLength("AES") < 192) { + throw new GeneralSecurityException("JCE does not support 192-bit keys"); + } + + // build encryption/decryption key based on given password + byte passwordBytes[] = keyString.getBytes(); + byte[] keyBytes = new byte[24]; + + for (int i = 0; i < 12; ++i) + keyBytes[i] = keyBytes[i + 12] = (i < passwordBytes.length) ? passwordBytes[i] : 0x20; + + // create objects for encryption/decryption + this.key = new SecretKeySpec(keyBytes, "AES"); + this.encipher = Cipher.getInstance("AES/ECB/NoPadding"); + this.encipher.init(Cipher.ENCRYPT_MODE, this.key); + this.decipher = Cipher.getInstance("AES/ECB/NoPadding"); + this.decipher.init(Cipher.DECRYPT_MODE, this.key); + } + + /** + * Decrypts given buffer of bytes in place. + * + * @param buffer + * bytes to decrypt + * @throws GeneralSecurityException + * on decryption errors + */ + public void decrypt(byte buffer[]) throws GeneralSecurityException { + byte[] CV = new byte[16]; + byte[] C = new byte[16]; + byte[] TEMP = new byte[16]; + int count = buffer.length; + + CV = this.encipher.doFinal(CV); + for (int index = 0; count > 0;) { + if (count > 15) { + count -= 16; + System.arraycopy(buffer, index, TEMP, 0, 16); + System.arraycopy(buffer, index, C, 0, 16); + C = this.decipher.doFinal(C); + for (int i = 0; i < 16; ++i) { + C[i] ^= CV[i]; + CV[i] = TEMP[i]; + } + System.arraycopy(C, 0, buffer, index, 16); + index += 16; + } else { + System.arraycopy(buffer, index, C, 0, count); + CV = this.encipher.doFinal(CV); + for (int i = 0; i < 16; ++i) { + C[i] ^= CV[i]; + } + System.arraycopy(C, 0, buffer, index, count); + count = 0; + } + } + } + + /** + * Encrypts given buffer of bytes in place. + * + * @param buffer + * bytes to encrypt + * @throws GeneralSecurityException + * on encryption errors + */ + public void encrypt(byte buffer[]) throws GeneralSecurityException { + byte[] CV = new byte[16]; + byte[] P = new byte[16]; + int count = buffer.length; + + CV = this.encipher.doFinal(CV); + for (int index = 0; count > 0;) { + if (count > 15) { + count -= 16; + System.arraycopy(buffer, index, P, 0, 16); + for (int i = 0; i < 16; ++i) { + P[i] ^= CV[i]; + } + P = this.encipher.doFinal(P); + System.arraycopy(P, 0, CV, 0, 16); + System.arraycopy(P, 0, buffer, index, 16); + index += 16; + } else { + System.arraycopy(buffer, index, P, 0, count); + CV = this.encipher.doFinal(CV); + for (int i = 0; i < 16; ++i) { + P[i] ^= CV[i]; + } + System.arraycopy(P, 0, buffer, index, count); + count = 0; + } + } + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/Ethm1Module.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/Ethm1Module.java new file mode 100644 index 00000000000..752df64e7a6 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/Ethm1Module.java @@ -0,0 +1,252 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.Random; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.openhab.binding.satel.internal.protocol.EncryptionHelper; + +/** + * Represents Satel ETHM-1 module. Implements method required to connect and + * communicate with that module over TCP/IP protocol. The module must have + * integration protocol enable in DLOADX configuration options. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class Ethm1Module extends SatelModule { + private static final Logger logger = LoggerFactory.getLogger(Ethm1Module.class); + + private String host; + private int port; + private String encryptionKey; + + /** + * Creates new instance with host, port, timeout and encryption key set to + * specified values. + * + * @param host + * host name or IP of ETHM-1 module + * @param port + * TCP port the module listens on + * @param timeout + * timeout value in milliseconds for connect/read/write + * operations + * @param encryptionKey + * encryption key for encrypted communication + */ + public Ethm1Module(String host, int port, int timeout, String encryptionKey) { + super(timeout); + + this.host = host; + this.port = port; + this.encryptionKey = encryptionKey; + } + + @Override + protected CommunicationChannel connect() { + logger.info("Connecting to ETHM-1 module at {}:{}", this.host, this.port); + + try { + Socket socket = new Socket(); + socket.connect(new InetSocketAddress(this.host, this.port), this.getTimeout()); + logger.info("ETHM-1 module connected successfuly"); + + if (StringUtils.isBlank(this.encryptionKey)) { + return new TCPCommunicationChannel(socket); + } else { + return new EncryptedCommunicationChannel(socket, this.encryptionKey); + } + } catch (IOException e) { + logger.error("IO error occurred during connecting socket", e); + } + + return null; + } + + private class TCPCommunicationChannel implements CommunicationChannel { + + private Socket socket; + + public TCPCommunicationChannel(Socket socket) { + this.socket = socket; + } + + @Override + public InputStream getInputStream() throws IOException { + return this.socket.getInputStream(); + } + + @Override + public OutputStream getOutputStream() throws IOException { + return this.socket.getOutputStream(); + } + + @Override + public void disconnect() { + logger.info("Closing connection to ETHM-1 module"); + try { + this.socket.close(); + } catch (IOException e) { + logger.error("IO error occurred during closing socket", e); + } + } + } + + private class EncryptedCommunicationChannel extends TCPCommunicationChannel { + + private EncryptionHelper aesHelper; + private Random rand; + private byte id_s; + private byte id_r; + private int rollingCounter; + private InputStream inputStream; + private OutputStream outputStream; + + public EncryptedCommunicationChannel(final Socket socket, String encryptionKey) throws IOException { + super(socket); + + try { + this.aesHelper = new EncryptionHelper(encryptionKey); + } catch (Exception e) { + throw new IOException("General encryption failure", e); + } + this.rand = new Random(); + this.id_s = 0; + this.id_r = 0; + this.rollingCounter = 0; + + this.inputStream = new InputStream() { + private ByteArrayInputStream inputBuffer = null; + + @Override + public int read() throws IOException { + if (inputBuffer == null || inputBuffer.available() == 0) { + // read message and decrypt it + byte[] data = readMessage(socket.getInputStream()); + // create new buffer + inputBuffer = new ByteArrayInputStream(data, 6, data.length - 6); + + } + return inputBuffer.read(); + } + }; + + this.outputStream = new OutputStream() { + private ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream(256); + + @Override + public void write(int b) throws IOException { + outputBuffer.write(b); + } + + @Override + public void flush() throws IOException { + writeMessage(outputBuffer.toByteArray(), socket.getOutputStream()); + outputBuffer.reset(); + } + }; + } + + @Override + public InputStream getInputStream() throws IOException { + return this.inputStream; + } + + @Override + public OutputStream getOutputStream() throws IOException { + return this.outputStream; + } + + private synchronized byte[] readMessage(InputStream is) throws IOException { + logger.trace("Receiving data from ETHM-1"); + // read number of bytes + int bytesCount = is.read(); + logger.trace("Read count of bytes: {}", bytesCount); + if (bytesCount == -1) { + throw new IOException("End of input stream reached"); + } + byte[] data = new byte[bytesCount]; + // read encrypted data + int bytesRead = is.read(data); + if (bytesCount != bytesRead) { + throw new IOException( + String.format("Too few bytes read. Read: %d, expected: %d", bytesRead, bytesCount)); + } + // decrypt data + logger.trace("Decrypting data: {}", bytesToHex(data)); + try { + this.aesHelper.decrypt(data); + } catch (Exception e) { + throw new IOException("Decryption exception", e); + } + logger.debug("Decrypted data: {}", bytesToHex(data)); + // validate message + this.id_r = data[4]; + if (this.id_s != data[5]) { + throw new IOException(String.format("Invalid 'id_s' value. Got: %d, expected: %d", data[5], this.id_s)); + } + + return data; + } + + private synchronized void writeMessage(byte[] message, OutputStream os) throws IOException { + // prepare data for encryption + int bytesCount = 6 + message.length; + if (bytesCount < 16) { + bytesCount = 16; + } + byte[] data = new byte[bytesCount]; + int randomValue = this.rand.nextInt(); + data[0] = (byte) (randomValue >> 8); + data[1] = (byte) (randomValue & 0xff); + data[2] = (byte) (this.rollingCounter >> 8); + data[3] = (byte) (this.rollingCounter & 0xff); + data[4] = this.id_s = (byte) this.rand.nextInt(); + data[5] = this.id_r; + ++this.rollingCounter; + System.arraycopy(message, 0, data, 6, message.length); + + // encrypt data + logger.debug("Encrypting data: {}", bytesToHex(data)); + try { + this.aesHelper.encrypt(data); + } catch (Exception e) { + throw new IOException("Encryption exception", e); + } + logger.trace("Encrypted data: {}", bytesToHex(data)); + + // write encrypted data to output stream + os.write(bytesCount); + os.write(data); + os.flush(); + } + } + + private static String bytesToHex(byte[] bytes) { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < bytes.length; ++i) { + if (i > 0) + result.append(" "); + result.append(String.format("%02X", bytes[i])); + } + return result.toString(); + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/IntRSModule.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/IntRSModule.java new file mode 100644 index 00000000000..e75b3dca9bf --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/IntRSModule.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol; + +import org.osgi.service.cm.ConfigurationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Represents Satel INT-RS module. Implements method required to connect and + * communicate with that module over serial protocol. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class IntRSModule extends SatelModule { + private static final Logger logger = LoggerFactory.getLogger(Ethm1Module.class); + + /** + * Creates new instance with port and timeout set to specified values. + * + * @param port + * serial port the module is connected to + * @param timeout + * timeout value in milliseconds for connect/read/write + * operations + * @throws ConfigurationException + * unconditionally throws this exception as it is not + * implemented yet + */ + public IntRSModule(String port, int timeout) throws ConfigurationException { + super(timeout); + throw new ConfigurationException("port", "INT-RS module not supported yet"); + } + + @Override + protected CommunicationChannel connect() { + logger.error("Not implemented"); + return null; + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/SatelMessage.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/SatelMessage.java new file mode 100644 index 00000000000..437100fdad2 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/SatelMessage.java @@ -0,0 +1,191 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol; + +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Represents a message sent to (a command) or received from (a response) + * {@link SatelModule}. It consists of one byte that specifies command type or + * response status and certain number of payload bytes. Number of payload byte + * depends on command type. The class allows to serialize a command to bytes and + * deserialize a response from given bytes. It also computes and validates + * message checksum. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class SatelMessage { + private static final Logger logger = LoggerFactory.getLogger(SatelMessage.class); + + private byte command; + private byte[] payload; + + private static final byte[] EMPTY_PAYLOAD = new byte[0]; + + /** + * Creates new instance with specified command code and payload. + * + * @param command + * command code + * @param payload + * command payload + */ + public SatelMessage(byte command, byte[] payload) { + this.command = command; + this.payload = payload; + } + + /** + * Creates new instance with specified command code and empty payload. + * + * @param command + * command code + */ + public SatelMessage(byte command) { + this(command, EMPTY_PAYLOAD); + } + + /** + * Deserializes new message instance from specified byte buffer. + * + * @param buffer + * bytes to deserialize a message from + * @return deserialized message instance + */ + public static SatelMessage fromBytes(byte[] buffer) { + // we need at least command and checksum + if (buffer.length < 3) { + logger.error("Invalid message length: {}", buffer.length); + return null; + } + + // check crc + int receivedCrc = 0xffff & ((buffer[buffer.length - 2] << 8) | (buffer[buffer.length - 1] & 0xff)); + int expectedCrc = calculateChecksum(buffer, buffer.length - 2); + if (receivedCrc != expectedCrc) { + logger.error("Invalid message checksum: received = {}, expected = {}", receivedCrc, expectedCrc); + return null; + } + + SatelMessage message = new SatelMessage(buffer[0], new byte[buffer.length - 3]); + if (message.payload.length > 0) + System.arraycopy(buffer, 1, message.payload, 0, buffer.length - 3); + return message; + } + + /** + * Returns command byte. + * + * @return the command + */ + public byte getCommand() { + return this.command; + } + + /** + * Returns the payload bytes. + * + * @return payload as byte array + */ + public byte[] getPayload() { + return this.payload; + } + + /** + * Returns the message serialized as array of bytes with checksum calculated + * at last two bytes. + * + * @return the message as array of bytes + */ + public byte[] getBytes() { + byte buffer[] = new byte[this.payload.length + 3]; + buffer[0] = this.command; + if (this.payload.length > 0) + System.arraycopy(this.payload, 0, buffer, 1, this.payload.length); + int checksum = calculateChecksum(buffer, buffer.length - 2); + buffer[buffer.length - 2] = (byte) ((checksum >> 8) & 0xff); + buffer[buffer.length - 1] = (byte) (checksum & 0xff); + return buffer; + } + + private String getPayloadAsHex() { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < this.payload.length; ++i) { + if (i > 0) + result.append(" "); + result.append(String.format("%02X", this.payload[i])); + } + return result.toString(); + } + + /** + * Calculates a checksum for the specified buffer. + * + * @param buffer + * the buffer to calculate. + * @return the checksum value. + */ + private static int calculateChecksum(byte[] buffer, int length) { + int checkSum = 0x147a; + for (int i = 0; i < length; i++) { + checkSum = ((checkSum << 1) | ((checkSum >> 15) & 1)); + checkSum ^= 0xffff; + checkSum += ((checkSum >> 8) & 0xff) + (buffer[i] & 0xff); + } + checkSum &= 0xffff; + logger.trace("Calculated checksum = {}", String.format("%04X", checkSum)); + return checkSum; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return String.format("Message: command = %02X, payload = %s", this.command, getPayloadAsHex()); + }; + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + + if (obj == null) + return false; + + if (!obj.getClass().equals(this.getClass())) + return false; + + SatelMessage other = (SatelMessage) obj; + + if (other.command != this.command) + return false; + + if (!Arrays.equals(other.payload, this.payload)) + return false; + + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + command; + result = prime * result + Arrays.hashCode(payload); + return result; + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/SatelModule.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/SatelModule.java new file mode 100644 index 00000000000..b8c2ff0e5d8 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/SatelModule.java @@ -0,0 +1,468 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; + +import org.openhab.binding.satel.internal.event.EventDispatcher; +import org.openhab.binding.satel.internal.event.SatelEventListener; +import org.openhab.binding.satel.internal.event.IntegraVersionEvent; +import org.openhab.binding.satel.internal.event.SatelEvent; +import org.openhab.binding.satel.internal.protocol.command.ClearTroublesCommand; +import org.openhab.binding.satel.internal.protocol.command.ControlObjectCommand; +import org.openhab.binding.satel.internal.protocol.command.IntegraStateCommand; +import org.openhab.binding.satel.internal.protocol.command.IntegraStatusCommand; +import org.openhab.binding.satel.internal.protocol.command.IntegraVersionCommand; +import org.openhab.binding.satel.internal.protocol.command.NewStatesCommand; +import org.openhab.binding.satel.internal.protocol.command.SatelCommand; +import org.openhab.binding.satel.internal.protocol.command.SetClockCommand; +import org.openhab.binding.satel.internal.types.ControlType; +import org.openhab.binding.satel.internal.types.DoorsState; +import org.openhab.binding.satel.internal.types.IntegraType; +import org.openhab.binding.satel.internal.types.OutputControl; +import org.openhab.binding.satel.internal.types.OutputState; +import org.openhab.binding.satel.internal.types.PartitionControl; +import org.openhab.binding.satel.internal.types.PartitionState; +import org.openhab.binding.satel.internal.types.StateType; +import org.openhab.binding.satel.internal.types.ZoneState; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class represents abstract communication module and is responsible for + * exchanging data between the binding and connected physical module. + * Communication happens by sending commands and receiving response from the + * module. Each command class must extend {@link SatelCommand} and be added to + * SatelModule.supportedCommands map in + * SatelModule.registerCommands method. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public abstract class SatelModule extends EventDispatcher implements SatelEventListener { + private static final Logger logger = LoggerFactory.getLogger(SatelModule.class); + + private static final byte FRAME_SYNC = (byte) 0xfe; + private static final byte FRAME_SYNC_ESC = (byte) 0xf0; + private static final byte[] FRAME_START = { FRAME_SYNC, FRAME_SYNC }; + private static final byte[] FRAME_END = { FRAME_SYNC, (byte) 0x0d }; + + private final Map supportedCommands = new ConcurrentHashMap(); + private final BlockingQueue sendQueue = new LinkedBlockingQueue(); + + private IntegraType integraType; + private int timeout; + private String integraVersion; + private CommunicationChannel channel; + private CommunicationWatchdog communicationWatchdog; + + /* + * Helper interface for connecting and disconnecting to specific module + * type. Each module type should implement these methods to provide input + * and output streams and way to disconnect from the module. + */ + protected interface CommunicationChannel { + + InputStream getInputStream() throws IOException; + + OutputStream getOutputStream() throws IOException; + + void disconnect(); + } + + /* + * Helper interface to handle communication timeouts. + */ + protected interface TimeoutTimer { + + void start(); + + void stop(); + } + + /** + * Creates new instance of the class. + * + * @param timeout + * timeout value in milliseconds for connect/read/write + * operations + */ + public SatelModule(int timeout) { + this.integraType = IntegraType.UNKNOWN; + this.timeout = timeout; + + addEventListener(this); + registerCommands(); + } + + /** + * Returns type of Integra connected to the module. + * + * @return Integra type + */ + public IntegraType getIntegraType() { + return this.integraType; + } + + /** + * Returns configured timeout value. + * + * @return timeout value as milliseconds + */ + public int getTimeout() { + return this.timeout; + } + + public boolean isConnected() { + return this.channel != null; + } + + /** + * Returns status of initialization. + * + * @return true if module is properly initialized and ready for + * sending commands + */ + public boolean isInitialized() { + return this.integraType != IntegraType.UNKNOWN; + } + + protected abstract CommunicationChannel connect(); + + /** + * Starts communication. + */ + public synchronized void open() { + this.communicationWatchdog = new CommunicationWatchdog(); + } + + /** + * Stops communication by disconnecting from the module and stopping all + * background tasks. + */ + public synchronized void close() { + if (this.communicationWatchdog != null) { + this.communicationWatchdog.close(); + this.communicationWatchdog = null; + } + } + + /** + * Enqueues specified command in send queue if not already enqueued. + * + * @param cmd + * command to enqueue + * @return true if operation succeeded + */ + public boolean sendCommand(SatelMessage cmd) { + try { + if (this.sendQueue.contains(cmd)) { + logger.debug("Command already in the queue: {}", cmd); + } else { + this.sendQueue.put(cmd); + logger.trace("Command enqueued: {}", cmd); + } + return true; + } catch (InterruptedException e) { + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public void incomingEvent(SatelEvent event) { + if (event instanceof IntegraVersionEvent) { + IntegraVersionEvent versionEvent = (IntegraVersionEvent) event; + this.integraType = IntegraType.valueOf(versionEvent.getType() & 0xFF); + this.integraVersion = versionEvent.getVersion(); + logger.info("Connection to {} initialized. Version: {}.", this.integraType.getName(), this.integraVersion); + } + } + + private void registerCommands() { + this.supportedCommands.put(IntegraVersionCommand.COMMAND_CODE, new IntegraVersionCommand(this)); + this.supportedCommands.put(NewStatesCommand.COMMAND_CODE, new NewStatesCommand(this)); + for (StateType state : PartitionState.values()) { + this.supportedCommands.put(state.getRefreshCommand(), new IntegraStateCommand(state, this)); + } + for (StateType state : ZoneState.values()) { + this.supportedCommands.put(state.getRefreshCommand(), new IntegraStateCommand(state, this)); + } + for (StateType state : OutputState.values()) { + this.supportedCommands.put(state.getRefreshCommand(), new IntegraStateCommand(state, this)); + } + for (StateType state : DoorsState.values()) { + this.supportedCommands.put(state.getRefreshCommand(), new IntegraStateCommand(state, this)); + } + for (ControlType ct : PartitionControl.values()) { + this.supportedCommands.put(ct.getControlCommand(), new ControlObjectCommand(ct, this)); + } + for (ControlType ct : OutputControl.values()) { + this.supportedCommands.put(ct.getControlCommand(), new ControlObjectCommand(ct, this)); + } + this.supportedCommands.put(IntegraStatusCommand.COMMAND_CODE, new IntegraStatusCommand(this)); + this.supportedCommands.put(ClearTroublesCommand.COMMAND_CODE, new ClearTroublesCommand(this)); + this.supportedCommands.put(SetClockCommand.COMMAND_CODE, new SetClockCommand(this)); + } + + private SatelMessage readMessage() { + try { + InputStream is = this.channel.getInputStream(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + boolean inMessage = false; + int syncBytes = 0; + + while (true) { + byte b = (byte) is.read(); + + if (b == FRAME_SYNC) { + if (inMessage) { + if (syncBytes == 0) { + // special sequence or end of message + // wait for next byte + } else { + logger.warn("Received frame sync bytes, discarding input: {}", baos.size()); + // clear gathered bytes, we wait for new message + inMessage = false; + baos.reset(); + } + } + ++syncBytes; + } else { + if (inMessage) { + if (syncBytes == 0) { + // in sync, we have next message byte + baos.write(b); + } else if (syncBytes == 1) { + if (b == FRAME_SYNC_ESC) { + baos.write(FRAME_SYNC); + } else if (b == FRAME_END[1]) { + // end of message + break; + } else { + logger.warn("Received invalid byte {}, discarding input: {}", String.format("%02X", b), + baos.size()); + // clear gathered bytes, we have new message + inMessage = false; + baos.reset(); + } + } else { + logger.error("Sync bytes in message: {}", syncBytes); + } + } else if (syncBytes >= 2) { + // synced, we have first message byte + inMessage = true; + baos.write(b); + } else { + // discard all bytes until synced + } + syncBytes = 0; + } + + // if meanwhile thread has been interrupted, exit the loop + if (Thread.interrupted()) { + return null; + } + } + + // return read message + return SatelMessage.fromBytes(baos.toByteArray()); + + } catch (IOException e) { + if (! Thread.interrupted()) { + logger.error("Unexpected exception occurred during reading a message", e); + } + } + + return null; + } + + private boolean writeMessage(SatelMessage message) { + try { + OutputStream os = this.channel.getOutputStream(); + + os.write(FRAME_START); + for (byte b : message.getBytes()) { + os.write(b); + if (b == FRAME_SYNC) { + os.write(FRAME_SYNC_ESC); + } + } + os.write(FRAME_END); + os.flush(); + return true; + + } catch (IOException e) { + if (! Thread.interrupted()) { + logger.error("Unexpected exception occurred during writing a message", e); + } + } + + return false; + } + + private synchronized void disconnect() { + this.sendQueue.clear(); + if (this.channel != null) { + this.channel.disconnect(); + this.channel = null; + } + } + + private void communicationLoop(TimeoutTimer timeoutTimer) { + long reconnectionTime = 10 * 1000; + + try { + while (!Thread.interrupted()) { + SatelMessage message = this.sendQueue.take(), response = null; + SatelCommand command = this.supportedCommands.get(message.getCommand()); + + if (command == null) { + logger.error("Unsupported command: {}", message); + continue; + } + + if (this.channel == null) { + long connectStartTime = System.currentTimeMillis(); + synchronized (this) { + this.channel = connect(); + } + if (!this.isConnected()) { + Thread.sleep(reconnectionTime - System.currentTimeMillis() + connectStartTime); + continue; + } + } + + logger.debug("Sending message: {}", message); + timeoutTimer.start(); + boolean sent = writeMessage(message); + timeoutTimer.stop(); + + if (sent) { + logger.trace("Waiting for response"); + timeoutTimer.start(); + response = this.readMessage(); + timeoutTimer.stop(); + if (response != null) { + logger.debug("Got response: {}", response); + command.handleResponse(response); + } + } + + // if either send or receive failed, exit thread + if (!sent || response == null) { + break; + } + + } + } catch (InterruptedException e) { + // exit thread + } catch (Exception e) { + // unexpected error, log and exit thread + logger.info("Unhandled exception occurred in communication loop, disconnecting.", e); + } finally { + // stop counting if thread interrupted + timeoutTimer.stop(); + } + + disconnect(); + } + + /* + * Respawns communication thread in case on any error and interrupts it in + * case read/write operations take too long. + */ + private class CommunicationWatchdog extends Timer implements TimeoutTimer { + private Thread thread; + private volatile long lastActivity; + + public CommunicationWatchdog() { + this.thread = null; + this.lastActivity = 0; + + this.schedule(new TimerTask() { + @Override + public void run() { + CommunicationWatchdog.this.checkThread(); + } + }, 0, 1000); + } + + @Override + public void start() { + this.lastActivity = System.currentTimeMillis(); + } + + @Override + public void stop() { + this.lastActivity = 0; + } + + public void close() { + // cancel timer first to prevent reconnect + this.cancel(); + // then stop communication thread + if (this.thread != null) { + this.thread.interrupt(); + try { + this.thread.join(); + } catch (InterruptedException e) { + // ignore + } + } + } + + private void startCommunication() { + if (this.thread != null && this.thread.isAlive()) { + logger.error("Start communication canceled: communication thread is still alive"); + return; + } + // start new thread + this.thread = new Thread(new Runnable() { + @Override + public void run() { + logger.debug("Communication thread started"); + SatelModule.this.communicationLoop(CommunicationWatchdog.this); + logger.debug("Communication thread stopped"); + } + }); + this.thread.start(); + // if module is not initialized yet, send version command + if (!SatelModule.this.isInitialized()) { + SatelModule.this.sendCommand(IntegraVersionCommand.buildMessage()); + } + } + + private void checkThread() { + if (this.thread != null && this.thread.isAlive()) { + long timePassed = (this.lastActivity == 0) ? 0 : System.currentTimeMillis() - this.lastActivity; + + if (timePassed > SatelModule.this.timeout) { + logger.error("Send/receive timeout, disconnecting module."); + stop(); + this.thread.interrupt(); + SatelModule.this.disconnect(); + } + } else { + startCommunication(); + } + } + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/ClearTroublesCommand.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/ClearTroublesCommand.java new file mode 100644 index 00000000000..a9b9485d1da --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/ClearTroublesCommand.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol.command; + +import org.openhab.binding.satel.internal.event.EventDispatcher; +import org.openhab.binding.satel.internal.protocol.SatelMessage; + +/** + * Command class for command that clear troubles memory. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class ClearTroublesCommand extends SatelCommand { + + public static final byte COMMAND_CODE = (byte) 0x8b; + + /** + * Creates new command class instance. + * + * @param eventDispatcher + * event dispatcher for event distribution + */ + public ClearTroublesCommand(EventDispatcher eventDispatcher) { + super(eventDispatcher); + } + + /** + * Builds message to clear trouble memory. + * + * @param userCode + * code of the user on behalf the control is made + * @return built message object + */ + public static SatelMessage buildMessage(String userCode) { + return new SatelMessage(COMMAND_CODE, userCodeToBytes(userCode)); + } + + /** + * {@inheritDoc} + */ + @Override + public void handleResponse(SatelMessage response) { + if (commandSucceeded(response)) { + // TODO force refresh + } + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/ControlObjectCommand.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/ControlObjectCommand.java new file mode 100644 index 00000000000..626af5b9d4c --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/ControlObjectCommand.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol.command; + +import java.util.BitSet; + +import org.apache.commons.lang.ArrayUtils; +import org.openhab.binding.satel.internal.event.EventDispatcher; +import org.openhab.binding.satel.internal.event.NewStatesEvent; +import org.openhab.binding.satel.internal.protocol.SatelMessage; +import org.openhab.binding.satel.internal.types.ControlType; +import org.openhab.binding.satel.internal.types.OutputControl; +import org.openhab.binding.satel.internal.types.OutputState; + +/** + * Command class for commands that control (change) state of Integra objects, + * like partitions (arm, disarm), zones (bypass, unbypass) outputs (on, off, + * switch), etc. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class ControlObjectCommand extends SatelCommand { + private ControlType controlType; + + /** + * Creates new command class instance for specified type of control. + * + * @param controlType + * type of control + * @param eventDispatcher + * event dispatcher for event distribution + */ + public ControlObjectCommand(ControlType controlType, EventDispatcher eventDispatcher) { + super(eventDispatcher); + this.controlType = controlType; + } + + /** + * Builds message to control objects of specified type. + * + * @param controlType + * type of controlled objects + * @param objects + * bits that represents objects to control + * @param userCode + * code of the user on behalf the control is made + * @return built message object + */ + public static SatelMessage buildMessage(ControlType controlType, byte[] objects, String userCode) { + return new SatelMessage(controlType.getControlCommand(), ArrayUtils.addAll(userCodeToBytes(userCode), objects)); + } + + /** + * {@inheritDoc} + */ + @Override + public void handleResponse(SatelMessage response) { + if (commandSucceeded(response)) { + // force outputs refresh + BitSet newStates = new BitSet(); + // TODO generalize for all kinds of control + if (this.controlType instanceof OutputControl) { + newStates.set(OutputState.OUTPUT.getRefreshCommand()); + this.getEventDispatcher().dispatchEvent(new NewStatesEvent(newStates)); + } + } + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/IntegraStateCommand.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/IntegraStateCommand.java new file mode 100644 index 00000000000..cf2cd253fa6 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/IntegraStateCommand.java @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol.command; + +import org.openhab.binding.satel.internal.event.EventDispatcher; +import org.openhab.binding.satel.internal.event.IntegraStateEvent; +import org.openhab.binding.satel.internal.protocol.SatelMessage; +import org.openhab.binding.satel.internal.types.StateType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Command class for commands that return state of Integra objects, like partitions + * (armed, alarm, entry time), zones (violation, tamper, alarm), outputs and + * doors (opened, opened long). + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class IntegraStateCommand extends SatelCommand { + private static final Logger logger = LoggerFactory.getLogger(IntegraStateCommand.class); + + private StateType stateType; + + /** + * Creates new command class instance for specified type of state. + * + * @param stateType + * type of state + * @param eventDispatcher + * event dispatcher for event distribution + */ + public IntegraStateCommand(StateType stateType, EventDispatcher eventDispatcher) { + super(eventDispatcher); + this.stateType = stateType; + } + + /** + * Builds message to get stae of objects for specified type. + * + * @param stateType + * tpye of state to get + * @param extended + * if true command will be sent as extended (256 + * zones or outputs) + * @return built message object + */ + public static SatelMessage buildMessage(StateType stateType, boolean extended) { + return SatelCommand.buildMessage(stateType.getRefreshCommand(), extended); + } + + /** + * {@inheritDoc} + */ + @Override + public void handleResponse(SatelMessage response) { + // validate response + if (response.getCommand() != this.stateType.getRefreshCommand()) { + logger.error("Invalid response code: {}", response.getCommand()); + return; + } + if (!isPayloadLengthValid(response.getPayload().length)) { + logger.error("Invalid payload length for this object type {}: {}", this.stateType.getObjectType(), + response.getPayload().length); + return; + } + // dispatch event + this.getEventDispatcher().dispatchEvent(new IntegraStateEvent(this.stateType, response.getPayload())); + } + + private boolean isPayloadLengthValid(int length) { + switch (this.stateType.getObjectType()) { + case PARTITION: + return length == 4; + case ZONE: + case OUTPUT: + return length == 16 || length == 32; + case DOORS: + return length == 8; + } + return false; + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/IntegraStatusCommand.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/IntegraStatusCommand.java new file mode 100644 index 00000000000..7eae670add5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/IntegraStatusCommand.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol.command; + +import java.util.Calendar; + +import org.openhab.binding.satel.internal.event.EventDispatcher; +import org.openhab.binding.satel.internal.event.IntegraStatusEvent; +import org.openhab.binding.satel.internal.protocol.SatelMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Command class for command that returns Integra RTC and basic status. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class IntegraStatusCommand extends SatelCommand { + private static final Logger logger = LoggerFactory.getLogger(IntegraStatusCommand.class); + + public static final byte COMMAND_CODE = 0x1a; + + /** + * Creates new command class instance. + * + * @param eventDispatcher + * event dispatcher for event distribution + */ + public IntegraStatusCommand(EventDispatcher eventDispatcher) { + super(eventDispatcher); + } + + /** + * Builds message to get Integra RTC and status. + * + * @return built message object + */ + public static SatelMessage buildMessage() { + return new SatelMessage(COMMAND_CODE); + } + + /** + * {@inheritDoc} + */ + @Override + public void handleResponse(SatelMessage response) { + if (response.getCommand() != COMMAND_CODE) { + logger.error("Invalid response code: {}", response.getCommand()); + return; + } + if (response.getPayload().length != 9) { + logger.error("Invalid payload length: {}", response.getPayload().length); + return; + } + // parse current date and time + byte[] bytes = response.getPayload(); + Calendar c = Calendar.getInstance(); + c.set(Calendar.YEAR, bcdToInt(bytes, 0, 2)); + c.set(Calendar.MONTH, bcdToInt(bytes, 2, 1)-1); + c.set(Calendar.DAY_OF_MONTH, bcdToInt(bytes, 3, 1)); + c.set(Calendar.HOUR_OF_DAY, bcdToInt(bytes, 4, 1)); + c.set(Calendar.MINUTE, bcdToInt(bytes, 5, 1)); + c.set(Calendar.SECOND, bcdToInt(bytes, 6, 1)); + // dispatch version event + this.getEventDispatcher().dispatchEvent(new IntegraStatusEvent(c, bytes[7], bytes[8])); + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/IntegraVersionCommand.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/IntegraVersionCommand.java new file mode 100644 index 00000000000..49a1e99ea7e --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/IntegraVersionCommand.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol.command; + +import org.openhab.binding.satel.internal.event.EventDispatcher; +import org.openhab.binding.satel.internal.event.IntegraVersionEvent; +import org.openhab.binding.satel.internal.protocol.SatelMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Command class for command that returns Integra version and type. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class IntegraVersionCommand extends SatelCommand { + private static final Logger logger = LoggerFactory.getLogger(IntegraVersionCommand.class); + + public static final byte COMMAND_CODE = 0x7e; + + /** + * Creates new command class instance. + * + * @param eventDispatcher + * event dispatcher for event distribution + */ + public IntegraVersionCommand(EventDispatcher eventDispatcher) { + super(eventDispatcher); + } + + /** + * Builds message to get Integra version and type. + * + * @return built message object + */ + public static SatelMessage buildMessage() { + return new SatelMessage(COMMAND_CODE); + } + + /** + * {@inheritDoc} + */ + @Override + public void handleResponse(SatelMessage response) { + if (response.getCommand() != COMMAND_CODE) { + logger.error("Invalid response code: {}", response.getCommand()); + return; + } + if (response.getPayload().length != 14) { + logger.error("Invalid payload length: {}", response.getPayload().length); + return; + } + // build version string + String verStr = new String(response.getPayload(), 1, 1) + "." + new String(response.getPayload(), 2, 2) + " " + + new String(response.getPayload(), 4, 4) + "-" + new String(response.getPayload(), 8, 2) + "-" + + new String(response.getPayload(), 10, 2); + // dispatch version event + this.getEventDispatcher().dispatchEvent( + new IntegraVersionEvent(response.getPayload()[0], verStr, response.getPayload()[12], response + .getPayload()[13] == (byte) 0xFF)); + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/NewStatesCommand.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/NewStatesCommand.java new file mode 100644 index 00000000000..30d53b8ce93 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/NewStatesCommand.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol.command; + +import org.openhab.binding.satel.internal.event.EventDispatcher; +import org.openhab.binding.satel.internal.event.NewStatesEvent; +import org.openhab.binding.satel.internal.protocol.SatelMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Command class for command that returns list of states changed since last state read. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class NewStatesCommand extends SatelCommand { + private static final Logger logger = LoggerFactory.getLogger(NewStatesCommand.class); + + public static final byte COMMAND_CODE = 0x7f; + + /** + * Creates new command class instance. + * @param eventDispatcher event dispatcher for event distribution + */ + public NewStatesCommand(EventDispatcher eventDispatcher) { + super(eventDispatcher); + } + + /** + * Builds message to get list of new states. + * @param extended + * if true command will be sent as extended (256 + * zones or outputs) + * @return built message object + */ + public static SatelMessage buildMessage(boolean extended) { + return SatelCommand.buildMessage(COMMAND_CODE, extended); + } + + /** + * {@inheritDoc} + */ + @Override + public void handleResponse(SatelMessage response) { + // validate response + if (response.getCommand() != COMMAND_CODE) { + logger.error("Invalid response code: {}", response.getCommand()); + return; + } + if (response.getPayload().length < 5 || response.getPayload().length > 6) { + logger.error("Invalid payload length: {}", response.getPayload().length); + return; + } + // dispatch event + this.getEventDispatcher().dispatchEvent(new NewStatesEvent(response.getPayload())); + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/SatelCommand.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/SatelCommand.java new file mode 100644 index 00000000000..f03fe1def79 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/SatelCommand.java @@ -0,0 +1,181 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol.command; + +import org.openhab.binding.satel.internal.event.EventDispatcher; +import org.openhab.binding.satel.internal.protocol.SatelMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base class for all command classes. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public abstract class SatelCommand { + private static final Logger logger = LoggerFactory.getLogger(SatelCommand.class); + + /** + * Used in extended (INT-RS v2.xx) command version. + */ + protected static final byte[] EXTENDED_CMD_PAYLOAD = { 0x00 }; + + private static final byte RESPONSE_CODE = (byte) 0xef; + + private EventDispatcher eventDispatcher; + + /** + * Creates new instance with given event dispatcher. This dispatcher will be + * used to distribute events created during response handling. + * + * @param eventDispatcher + * event dispatcher object for all events created by this command + */ + public SatelCommand(EventDispatcher eventDispatcher) { + this.eventDispatcher = eventDispatcher; + } + + /** + * Must be overridden in derived classes to handle response for specific + * command or group of commands. + * + * @param response + * module response message + */ + public abstract void handleResponse(SatelMessage response); + + /** + * Builds a message for specific command. + * + * @param commandCode + * command code + * @param extended + * if true command will be sent as extended (256 + * zones or outputs) + * @return new instance of message class + */ + public static SatelMessage buildMessage(byte commandCode, boolean extended) { + if (extended) { + return new SatelMessage(commandCode, EXTENDED_CMD_PAYLOAD); + } else { + return new SatelMessage(commandCode); + } + } + + protected EventDispatcher getEventDispatcher() { + return this.eventDispatcher; + } + + protected static byte[] userCodeToBytes(String userCode) { + if (userCode.length() > 8) { + throw new IllegalArgumentException("User code too long"); + } + byte[] bytes = new byte[8]; + int digitsNbr = 2 * bytes.length; + for (int i = 0; i < digitsNbr; ++i) { + if (i < userCode.length()) { + char digit = userCode.charAt(i); + if (!Character.isDigit(digit)) { + throw new IllegalArgumentException("User code must contain digits only"); + } + if (i % 2 == 0) { + bytes[i / 2] = (byte) ((digit - '0') << 4); + } else { + bytes[i / 2] |= (byte) (digit - '0'); + } + } else if (i % 2 == 0) { + bytes[i / 2] = (byte) 0xff; + } else if (i == userCode.length()) { + bytes[i / 2] |= 0x0f; + } + } + + return bytes; + } + + protected boolean commandSucceeded(SatelMessage response) { + // validate response + if (response.getCommand() != RESPONSE_CODE) { + logger.error("Invalid response code: {}", response.getCommand()); + return false; + } + if (response.getPayload().length != 1) { + logger.error("Invalid payload length: {}", response.getPayload().length); + return false; + } + + byte responseCode = response.getPayload()[0]; + String errorMsg; + + switch (responseCode) { + case 0: + // success + return true; + case 0x01: + errorMsg = "Requesting user code not found"; + break; + case 0x02: + errorMsg = "No access"; + break; + case 0x03: + errorMsg = "Selected user does not exist"; + break; + case 0x04: + errorMsg = "Selected user already exists"; + break; + case 0x05: + errorMsg = "Wrong code or code already exists"; + break; + case 0x06: + errorMsg = "Telephone code already exists"; + break; + case 0x07: + errorMsg = "Changed code is the same"; + break; + case 0x08: + errorMsg = "Other error"; + break; + case 0x11: + errorMsg = "Can not arm, but can use force arm"; + break; + case 0x12: + errorMsg = "Can not arm"; + break; + case (byte) 0xff: + logger.trace("Command accepted"); + return true; + default: + if (responseCode >= 0x80 && responseCode <= 0x8f) { + errorMsg = String.format("Other error: %02X", responseCode); + } else { + errorMsg = String.format("Unknown response code: %02X", responseCode); + } + } + + logger.error(errorMsg); + return false; + } + + protected static int bcdToInt(byte[] bytes, int offset, int size) { + int result = 0, digit; + int byteIdx = offset; + int digits = size * 2; + for (int i = 0; i < digits; ++i) { + if (i % 2 == 0) + digit = (bytes[byteIdx] >> 4) & 0x0f; + else { + digit = (bytes[byteIdx]) & 0x0f; + byteIdx += 1; + } + result = result * 10 + digit; + } + return result; + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/SetClockCommand.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/SetClockCommand.java new file mode 100644 index 00000000000..7be59b46aad --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/protocol/command/SetClockCommand.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.protocol.command; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; + +import org.apache.commons.lang.ArrayUtils; +import org.openhab.binding.satel.internal.event.EventDispatcher; +import org.openhab.binding.satel.internal.protocol.SatelMessage; + +/** + * Command class for command to set RTC clock. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public class SetClockCommand extends SatelCommand { + + public static final byte COMMAND_CODE = (byte) 0x8e; + + private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss"); + + /** + * Creates new command class instance. + * + * @param eventDispatcher + * event dispatcher for event distribution + */ + public SetClockCommand(EventDispatcher eventDispatcher) { + super(eventDispatcher); + } + + /** + * Builds message to set RTC clock. + * + * @param dateTime + * date and time to set + * @param userCode + * code of the user on behalf the control is made + * @return built message object + */ + public static SatelMessage buildMessage(Calendar dateTime, String userCode) { + byte[] dateTimeBytes = DATETIME_FORMAT.format(dateTime.getTime()).getBytes(); + return new SatelMessage(COMMAND_CODE, ArrayUtils.addAll(userCodeToBytes(userCode), dateTimeBytes)); + } + + /** + * {@inheritDoc} + */ + @Override + public void handleResponse(SatelMessage response) { + if (commandSucceeded(response)) { + // TODO force refresh? + } + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/ControlType.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/ControlType.java new file mode 100644 index 00000000000..8bbe5f79463 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/ControlType.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.types; + +/** + * Interface for all types of control. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public interface ControlType { + + /** + * Returns Satel command to control state for this kind of object type. + * + * @return command identifier + */ + byte getControlCommand(); + + /** + * Returns object type for this kind of control. + * + * @return Integra object type + */ + ObjectType getObjectType(); +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/DoorsState.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/DoorsState.java new file mode 100644 index 00000000000..6303f2cca14 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/DoorsState.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.types; + +/** + * Available doors states. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public enum DoorsState implements StateType { + OPENED(0x18), OPENED_LONG(0x19); + + private byte refreshCommand; + + DoorsState(int refreshCommand) { + this.refreshCommand = (byte) refreshCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public byte getRefreshCommand() { + return refreshCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public ObjectType getObjectType() { + return ObjectType.DOORS; + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/IntegraType.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/IntegraType.java new file mode 100644 index 00000000000..56e301987b9 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/IntegraType.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.types; + +/** + * Available Integra types. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public enum IntegraType { + UNKNOWN(-1, "Unknown"), + I24(0, "Integra 24"), + I32(1, "Integra 32"), + I64(2, "Integra 64"), + I128(3, "Integra 128"), + I128_SIM300(4, "Integra 128-WRL SIM300"), + I128_LEON(132, "Integra 128-WRL LEON"), + I64_PLUS(66, "Integra 64 Plus"), + I128_PLUS(67, "Integra 128 Plus"), + I256_PLUS(72, "Integra 256 Plus"); + + private int code; + private String name; + + IntegraType(int code, String name) { + this.code = code; + this.name = name; + } + + /** + * @return name of Integra type + */ + public String getName() { + return this.name; + } + + /** + * Returns Integra type for given code. + * + * @param code + * code to get type for + * @return Integra type object + */ + public static IntegraType valueOf(int code) { + for (IntegraType val : IntegraType.values()) { + if (val.code == code) + return val; + } + return UNKNOWN; + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/ObjectType.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/ObjectType.java new file mode 100644 index 00000000000..fd47a90c771 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/ObjectType.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.types; + +/** + * Available object types: + *
        + *
      • ZONE - various kinds of devices connected to inputs, like reed switches, PIRs, etc
      • + *
      • PARTITION - group of zones and outputs
      • + *
      • OUTPUT - outputs to various devices like sirens, relays, etc.
      • + *
      • DOORS - inputs connected to reed switches mounted on doors
      • + *
      + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public enum ObjectType { + ZONE, PARTITION, OUTPUT, DOORS; +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/OutputControl.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/OutputControl.java new file mode 100644 index 00000000000..da6859b7618 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/OutputControl.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.types; + +/** + * Available output control types: + *
        + *
      • ON - sets an output
      • + *
      • OFF - resets an output
      • + *
      • TOGGLE - inverts output state
      • + *
      + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public enum OutputControl implements ControlType { + ON(0x88), OFF(0x89), TOGGLE(0x91); + + private byte controlCommand; + + OutputControl(int controlCommand) { + this.controlCommand = (byte) controlCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public byte getControlCommand() { + return controlCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public ObjectType getObjectType() { + return ObjectType.OUTPUT; + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/OutputState.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/OutputState.java new file mode 100644 index 00000000000..dba957412e8 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/OutputState.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.types; + +/** + * Available output states. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public enum OutputState implements StateType { + OUTPUT(0x17); + + private byte refreshCommand; + + OutputState(int refreshCommand) { + this.refreshCommand = (byte) refreshCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public byte getRefreshCommand() { + return refreshCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public ObjectType getObjectType() { + return ObjectType.OUTPUT; + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/PartitionControl.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/PartitionControl.java new file mode 100644 index 00000000000..8add644dd44 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/PartitionControl.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.types; + +/** + * Available zone control types. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public enum PartitionControl implements ControlType { + ARM_MODE_0(0x80), + ARM_MODE_1(0x81), + ARM_MODE_2(0x82), + ARM_MODE_3(0x83), + DISARM(0x84), + CLEAR_ALARM(0x85), + FORCE_ARM_MODE_0(0xa0), + FORCE_ARM_MODE_1(0xa1), + FORCE_ARM_MODE_2(0xa2), + FORCE_ARM_MODE_3(0xa3); + + private byte controlCommand; + + PartitionControl(int controlCommand) { + this.controlCommand = (byte) controlCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public byte getControlCommand() { + return controlCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public ObjectType getObjectType() { + return ObjectType.PARTITION; + } +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/PartitionState.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/PartitionState.java new file mode 100644 index 00000000000..bf79f8bcb79 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/PartitionState.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.types; + +/** + * Available partition states. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public enum PartitionState implements StateType { + ARMED(0x09), REALLY_ARMED(0x0a), ARMED_MODE_2(0x0b), ARMED_MODE_3(0x0c), FIRST_CODE_ENTERED(0x0d), ENTRY_TIME(0x0e), EXIT_TIME_GT_10( + 0x0f), EXIT_TIME_LT_10(0x10), TEMPORARY_BLOCKED(0x11), BLOCKED_FOR_GUARD(0x12), ALARM(0x13), FIRE_ALARM( + 0x14), ALARM_MEMORY(0x15), FIRE_ALARM_MEMORY(0x16), VIOLATED_ZONES(0x25), VERIFIED_ALARMS(0x27), ARMED_MODE_1( + 0x2a), WARNING_ALARMS(0x2b); + + private byte refreshCommand; + + PartitionState(int refreshCommand) { + this.refreshCommand = (byte) refreshCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public byte getRefreshCommand() { + return refreshCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public ObjectType getObjectType() { + return ObjectType.PARTITION; + } +} \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/StateType.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/StateType.java new file mode 100644 index 00000000000..ea85378a742 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/StateType.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.types; + +/** + * Base of all kinds of Integra state. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public interface StateType { + + /** + * Returns Satel command to get current state for this state type. + * @return command identifier + */ + byte getRefreshCommand(); + + /** + * Returns object type for this kind of state. + * @return Integra object type + */ + ObjectType getObjectType(); +} diff --git a/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/ZoneState.java b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/ZoneState.java new file mode 100644 index 00000000000..2f76fe9ea73 --- /dev/null +++ b/bundles/binding/org.openhab.binding.satel/src/main/java/org/openhab/binding/satel/internal/types/ZoneState.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2010-2014, openHAB.org and others. + * + * 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.satel.internal.types; + +/** + * Available zone states. + * + * @author Krzysztof Goworek + * @since 1.7.0 + */ +public enum ZoneState implements StateType { + VIOLATION(0x00), + TAMPER(0x01), + ALARM(0x02), + TAMPER_ALARM(0x03), + ALARM_MEMORY(0x04), + TAMPER_ALARM_MEMORY(0x05), + BYPASS(0x06), + NO_VIOLATION_TROUBLE(0x07), + LONG_VIOLATION_TROUBLE(0x08), + ISOLATE(0x26), + MASKED(0x28), + MASKED_MEMORY(0x29); + + private byte refreshCommand; + + ZoneState(int refreshCommand) { + this.refreshCommand = (byte) refreshCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public byte getRefreshCommand() { + return refreshCommand; + } + + /** + * {@inheritDoc} + */ + @Override + public ObjectType getObjectType() { + return ObjectType.ZONE; + } +} diff --git a/bundles/binding/org.openhab.binding.serial/.classpath b/bundles/binding/org.openhab.binding.serial/.classpath index 0f022a5084e..6566c1e3a03 100644 --- a/bundles/binding/org.openhab.binding.serial/.classpath +++ b/bundles/binding/org.openhab.binding.serial/.classpath @@ -3,6 +3,5 @@ - diff --git a/bundles/binding/org.openhab.binding.snmp/src/main/java/org/openhab/binding/snmp/SnmpBindingProvider.java b/bundles/binding/org.openhab.binding.snmp/src/main/java/org/openhab/binding/snmp/SnmpBindingProvider.java index ff572509104..d3f7b0a43b3 100644 --- a/bundles/binding/org.openhab.binding.snmp/src/main/java/org/openhab/binding/snmp/SnmpBindingProvider.java +++ b/bundles/binding/org.openhab.binding.snmp/src/main/java/org/openhab/binding/snmp/SnmpBindingProvider.java @@ -13,7 +13,6 @@ import org.openhab.core.binding.BindingProvider; import org.openhab.core.items.Item; import org.openhab.core.transform.TransformationException; -import org.openhab.core.transform.TransformationService; import org.openhab.core.types.Command; import org.snmp4j.smi.Address; import org.snmp4j.smi.Integer32; diff --git a/bundles/binding/org.openhab.binding.snmp/src/main/java/org/openhab/binding/snmp/internal/SnmpBinding.java b/bundles/binding/org.openhab.binding.snmp/src/main/java/org/openhab/binding/snmp/internal/SnmpBinding.java index 52516a6998a..8179967dbc5 100644 --- a/bundles/binding/org.openhab.binding.snmp/src/main/java/org/openhab/binding/snmp/internal/SnmpBinding.java +++ b/bundles/binding/org.openhab.binding.snmp/src/main/java/org/openhab/binding/snmp/internal/SnmpBinding.java @@ -89,7 +89,6 @@ public class SnmpBinding extends AbstractActiveBinding public void activate() { logger.debug("SNMP binding activated"); super.activate(); - setProperlyConfigured(true); } public void deactivate() { @@ -431,6 +430,7 @@ public void updated(Dictionary config) throws ConfigurationException if (mapping) { listen(); } + setProperlyConfigured(true); } private void sendPDU(CommunityTarget target, PDU pdu) { diff --git a/bundles/binding/org.openhab.binding.swegonventilation/.classpath b/bundles/binding/org.openhab.binding.swegonventilation/.classpath index 4033112b349..6d224cd3d0d 100644 --- a/bundles/binding/org.openhab.binding.swegonventilation/.classpath +++ b/bundles/binding/org.openhab.binding.swegonventilation/.classpath @@ -4,6 +4,5 @@ - diff --git a/bundles/binding/org.openhab.binding.tinkerforge/.classpath b/bundles/binding/org.openhab.binding.tinkerforge/.classpath index ac6c95a107a..5f71d9a6034 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/.classpath +++ b/bundles/binding/org.openhab.binding.tinkerforge/.classpath @@ -1,6 +1,6 @@ - + diff --git a/bundles/binding/org.openhab.binding.tinkerforge/META-INF/MANIFEST.MF b/bundles/binding/org.openhab.binding.tinkerforge/META-INF/MANIFEST.MF index 9839a74da28..a5e119bb028 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/META-INF/MANIFEST.MF +++ b/bundles/binding/org.openhab.binding.tinkerforge/META-INF/MANIFEST.MF @@ -24,12 +24,14 @@ Import-Package: org.apache.commons.lang, org.osgi.service.component, org.osgi.service.event, org.slf4j -Export-Package: org.openhab.binding.tinkerforge +Export-Package: org.openhab.binding.tinkerforge, + org.openhab.binding.tinkerforge.ecosystem, + org.openhab.binding.tinkerforge.internal.model Bundle-DocURL: http://www.openhab.org Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Service-Component: OSGI-INF/binding.xml, OSGI-INF/genericbindingprovider.xml Bundle-ClassPath: ., - lib/tinkerforge-2.1.1.jar + lib/tinkerforge-2.1.4.jar Bundle-ActivationPolicy: lazy Require-Bundle: org.eclipse.emf.ecore;bundle-version="2.8.0", org.eclipse.xtext.xbase.lib;bundle-version="2.3.0" diff --git a/bundles/binding/org.openhab.binding.tinkerforge/Readme.md b/bundles/binding/org.openhab.binding.tinkerforge/Readme.md index 005a73ad7d2..a752ca5d38b 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/Readme.md +++ b/bundles/binding/org.openhab.binding.tinkerforge/Readme.md @@ -1,288 +1,125 @@ -# Bugfixes - ## 1.4.0 - * Missing updates of Items if a Tinkerforge Device is referenced in several Items - ## 1.5.0 - * Reconnect support for IO16 Bricklet - * polled values now are only send once to the eventbus -# Incompatible Changes - ## 1.4.0 - * LCDBacklight is a sub device of LCD20x4 Bricklet (items file must be changed) - * LCD20x4Button posts an update not a command anymore (rules must be changed) - * IndustrialQuadRelay sub id numbering now starts from zero (items file must be changed) -# New Features - ## 1.4.0 - * new Devices - * Bricklet Industrial Quad Relay - * Bricklet Industrial Digital In 4 - * Bricklet IO-16 - * support for serveral Item types - * NumberItem - * SwitchItem - * ContactItem - * handle disconnected brickds - * on binding startup make retries every second - * when binding is running use the Tinkerforge autoreconnect feature - ## 1.5.0 - * new Devices -# Remote Switch Bricklet -* openhab.cfg (mandatory) -``` -tinkerforge:rs1.uid=jKw -tinkerforge:rs1.type=bricklet_remote_switch -tinkerforge:rs1.typeADevices=rslr1 rslr2 -tinkerforge:rs1.typeBDevices=kitchen -tinkerforge:rs1.typeCDevices=floor - -tinkerforge:rs_living_room.uid=jKw -tinkerforge:rs_living_room.subid=rslr1 -tinkerforge:rs_living_room.type=remote_switch_a -tinkerforge:rs_living_room.houseCode=31 -tinkerforge:rs_living_room.receiverCode=8 +# 1.7.0 +## New Devices + * Joystick Bricklet + * Linear Poti Bricklet + * Dual Button Bricklet -tinkerforge:rs_living_room2.uid=jKw -tinkerforge:rs_living_room2.subid=rslr2 -tinkerforge:rs_living_room2.type=remote_switch_a -tinkerforge:rs_living_room2.houseCode=31 -tinkerforge:rs_living_room2.receiverCode=4 +## New Features + * Tinkerforge Action Addon + * Brick DC fully supported + * Brick Servo fully supported -tinkerforge:rs_kitchen.uid=jKw -tinkerforge:rs_kitchen.subid=kitchen -tinkerforge:rs_kitchen.type=remote_switch_b -tinkerforge:rs_kitchen.address=344 -tinkerforge:rs_kitchen.unit=9 +## Other changes + * updated Tinkerforge API to 2.1.4 -tinkerforge:rs_floor.uid=jKw -tinkerforge:rs_floor.subid=floor -tinkerforge:rs_floor.type=remote_switch_c -tinkerforge:rs_floor.systemCode=A -tinkerforge:rs_floor.deviceCode=8 +## Brick DC +### Incompatible changes +* DriveMode now is one of "brake" or "coast" instead of "0" or "1" ``` -items file -``` -Switch r0 {tinkerforge="uid=jKw, subid=rslr1"} -Switch r1 {tinkerforge="uid=jKw, subid=rslr2"} -Switch rb {tinkerforge="uid=jKw, subid=kitchen"} -Switch rc {tinkerforge="uid=jKw, subid=floor"} -``` -* sitemap file -``` -Switch item=r0 -Switch item=r1 -Switch item=rb -Switch item=rc +tinkerforge:dc_garage.driveMode=brake ``` -# Motion Detection Bricklet -* items file -``` -Contact motion "motion [MAP(en.map):MOTION%s]" {tinkerforge="uid=m3W"} +* switchOnVelocity in openhab.cfg is no longer needed and has gone. +It is replaced by per item configuration: +With the benefit that you can have serveral switch items with different speeds. +~~tinkerforge:dc_garage.switchOnVelocity=10000~~ ``` -* sitemap file -``` -Text item=motion -``` -* en.map file -``` -MOTIONCLOSED=no motion -MOTIONOPEN=montion detected +Switch DCSWITCH "DC Switch" {tinkerforge="uid=62Zduj, speed=14000"} ``` -# Bricklet MultiTouch -* openhab.cfg -``` -tinkerforge:touch.uid=jUS -tinkerforge:touch.type=bricklet_multitouch -tinkerforge:touch.sensitivity=181 -tinkerforge:touch.recalibrate=true -tinkerforge:touche0.uid=jUS -tinkerforge:touche0.type=electrode -tinkerforge:touche0.subid=electrode1 -tinkerforge:touche0.disableElectrode=true +### Whats new? +Support for Dimmer, Rollershuter and Number items. Besides that the speed +can be set using a percent value. -tinkerforge:touche1.uid=jUS -tinkerforge:touche1.type=proximity -tinkerforge:touche1.subid=proximity -tinkerforge:touche1.disableElectrode=true -``` -* items file -``` -Contact electrode0 "electrode0 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode0"} -Contact electrode1 "electrode1 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode1"} -Contact electrode2 "electrode2 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode2"} -Contact electrode3 "electrode3 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode3"} -Contact electrode4 "electrode4 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode4"} -Contact electrode5 "electrode5 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode5"} -Contact electrode6 "electrode6 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode6"} -Contact electrode7 "electrode7 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode7"} -Contact electrode8 "electrode8 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode8"} -Contact electrode9 "electrode9 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode9"} -Contact electrode10 "electrode10 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode10"} -Contact electrode11 "electrode11 [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=electrode11"} -Contact proximity "proximity [MAP(en.map):%s]" {tinkerforge="uid=jUS, subid=proximity"} -``` -* sitemap file -``` -Text item=electrode0 -Text item=electrode1 -Text item=electrode2 -Text item=electrode3 -Text item=electrode4 -Text item=electrode5 -Text item=electrode6 -Text item=electrode7 -Text item=electrode8 -Text item=electrode9 -Text item=electrode10 -Text item=electrode11 -Text item=proximity -``` +The number items show the current velocity. The values are reported using the VelocityListener. +"callbackPeriod" and "threshold" for the listener can be configured in openhab.cfg. There is more +documentation about callback listeners at the official openHAB TinkerForgeBindig wiki page. -# Bricklet TemperatureIR -* openhab.cfg (optional) -``` -tinkerforge:objIR.uid=kr2 -tinkerforge:objIR.subid=object_temperature -tinkerforge:objIR.type=object_temperature -tinkerforge:objIR.emissivity=65535 -tinkerforge:objIR.threshold=0 +* callbackPeriod: milliseconds +* threshold: numeric value -tinkerforge:ambIR.uid=kr2 -tinkerforge:ambIR.subid=ambient_temperature -tinkerforge:ambIR.type=ambient_temperature -tinkerforge:ambIR.threshold=0 -``` -* items -``` -Number AmbientTemperature "AmbientTemperature [%.1f C]" { tinkerforge="uid=kr2, subid=ambient_temperature" } -Number ObjectTemperature "ObjectTemperature [%.1f C]" { tinkerforge="uid=kr2, subid=object_temperature" } -``` -* sitemap -``` -Text item=AmbientTemperature -Text item=ObjectTemperature - ``` +### New item configuration options +* speed: the target speed (Switch) +* max: the maximum speed (Dimmer, Rollershutter) +* min: the minimum speed (Dimmer, Rollershutter) +* step: the step value for increasing decreasing speed (Dimmer) +* leftspeed: the speed when the left rollershutter controller is pressed or command "DOWN" was send +* rightspeed: the speed when the right rollershutter controller is pressed or command "UP" was send +* acceleration: acceleration overrides value from openhab.cfg +* drivemode: drivemode overrides value from openhab.cfg -# Bricklet SoundIntensity -* openhab.cfg (optional) -``` -tinkerforge:sound.uid=iQE -tinkerforge:sound.type=bricklet_soundintensity -tinkerforge:sound.threshold=1 -tinkerforge:sound.callbackPeriod=5000 -``` -* items -``` -Number SoundIntensity "Sound [%.1f]" { tinkerforge="uid=iQE" } -``` -* sitemap -``` -Text item=SoundIntensity -``` +## Brick Servo +### Whats new? +Support for Dimmer, Rollershuter and Number items. Besides that the speed +can be set using a percent value. -# Bricklet Moisture -* openhab.cfg (optional) -``` -tinkerforge:moisture.uid=kve -tinkerforge:moisture.type=bricklet_moisture -tinkerforge:moisture.threshold=0 -tinkerforge:moisture.callbackPeriod=5000 -tinkerforge:moisture.movingAverage=90 -``` -* items -``` -Number Moisture "Moisture [%.1f]" { tinkerforge="uid=kve" } -``` -* sitemap -``` -Text item=Moisture -``` +Number items will show the current position. -# Bricklet DistanceUS -* openhab.cfg (optional) -``` -tinkerforge:distanceUS.uid=mXq -tinkerforge:distanceUS.type=bricklet_distanceUS -tinkerforge:distanceUS.threshold=0 -tinkerforge:distanceUS.callbackPeriod=100 -tinkerforge:distanceUS.movingAverage=100 -``` -* items -``` -Number DistanceUS "DistanceUS [%.1f]" { tinkerforge="uid=mXq" } -``` -* sitemap -``` -Text item=DistanceUS -``` +# New item configuration options +* velocity: the velocity used to reach the new position +* max: the maximum position (Dimmer, Rollershutter) +* min: the minimum position (Dimmer, Rollershutter) +* step: the step value for increasing decreasing position (Dimmer) +* leftposition: the target position to reach when the left rollershutter controller is pressed or command "DOWN" was send +* rightposition: the target position to reach when the right rollershutter controller is pressed or command "UP" was send +* acceleration: the acceleration -# Bricklet VoltageCurrent -* openhab.cfg (optional) +### TinkerForge Action +The new openHAB action TinkerForgeAction comes up with the action tfServoSetposition. +tfServoSetposition(uid, num, position, velocity, acceleration) can be used to control the servo. +#### Example +``` +tfServoSetposition("6Crt5W", "servo0", "-9000", "65535", "65535") ``` -tinkerforge:voltageCurrent.uid=dN5 -tinkerforge:voltageCurrent.type=bricklet_voltageCurrent -tinkerforge:voltageCurrent.averaging=3 -tinkerforge:voltageCurrent.voltageConversionTime=4 -tinkerforge:voltageCurrent.currentConversionTime=4 -tinkerforge:vc_voltage.uid=dN5 -tinkerforge:vc_voltage.subid=voltageCurrent_voltage -tinkerforge:vc_voltage.type=voltageCurrent_voltage -tinkerforge:vc_voltage.threshold=20 -tinkerforge:vc_voltage.callbackPeriod=100 +## Tinkerforge Action Addon +* tfServoSetposition as explained above +* tfClearLCD(uid) uid is the uid of the LCD display. A call of tfClearLCD will clear the LCD display. -tinkerforge:vc_current.uid=dN5 -tinkerforge:vc_current.subid=voltageCurrent_current -tinkerforge:vc_current.type=voltageCurrent_current -tinkerforge:vc_current.threshold=10 -tinkerforge:vc_current.callbackPeriod=100 -tinkerforge:vc_power.uid=dN5 -tinkerforge:vc_power.subid=voltageCurrent_power -tinkerforge:vc_power.type=voltageCurrent_power -tinkerforge:vc_power.threshold=10 -tinkerforge:vc_power.callbackPeriod=100 -``` -* items -``` -Number Voltage "Voltage [%d mV]" { tinkerforge="uid=dN5, subid=voltageCurrent_voltage" } -Number Current "Current [%d mA]" { tinkerforge="uid=dN5, subid=voltageCurrent_current" } -Number Power "Power [%d mW]" { tinkerforge="uid=dN5, subid=voltageCurrent_power" } -``` - -* sitemap -``` -Text item=Voltage -Text item=Current -Text item=Power -``` +# 1.5.0 +## Bugfixes + * Reconnect support for IO16 Bricklet + * polled values now are only send once to the eventbus -# Bricklet Tilt -* openhab.cfg: no entries needed -* items -``` -Contact tiltContact "tilt [MAP(en.map):%s]" { tinkerforge="uid=j7k" } -Number tiltSensor "tilt [MAP(en.map):%s]" { tinkerforge="uid=j7k" } -Switch tiltSwitch "tilt" { tinkerforge="uid=j7k" } -``` +## New Devices + * Remote Switch Bricklet + * Motion Detection Bricklet + * Bricklet MultiTouch + * Bricklet TemperatureIR + * Bricklet SoundIntensity + * Bricklet Moisture + * Bricklet DistanceUS + * Bricklet VoltageCurrent + * Bricklet Tilt + +## Other changes + * updated Tinkerforge API to 2.1.0 + * Threshold values now have the unit as the sensor value (incompatible change, you have to update your openhab.cfg) + * polling is only done for devices which don't support CallbackListeners / InterruptListeners + +# 1.4.0 +## Bugfixes + * Missing updates of Items if a Tinkerforge Device is referenced in several Items -* sitemap -``` -Text item=tiltContact -Text item=tiltSensor -Switch item=tiltSwitch -``` -* en.map (optional) -``` -0=closed -1=open -2=vibrating -``` +## Incompatible Changes + * LCDBacklight is a sub device of LCD20x4 Bricklet (items file must be changed) + * LCD20x4Button posts an update not a command anymore (rules must be changed) + * IndustrialQuadRelay sub id numbering now starts from zero (items file must be changed) -# other changes - ## 1.4.0 - * updated Tinkerforge API to 2.0.12 - ## 1.5.0 - * updated Tinkerforge API to 2.1.0 - * Threshold values now have the unit as the sensor value (incompatible change, you have to update your openhab.cfg) - * polling is only done for devices which don't support CallbackListeners / InterruptListeners \ No newline at end of file +## New Devices + * Bricklet Industrial Quad Relay + * Bricklet Industrial Digital In 4 + * Bricklet IO-16 + +## Other changes + * updated Tinkerforge API to 2.0.12 + * support for serveral Item types + * NumberItem + * SwitchItem + * ContactItem + * handle disconnected brickds + * on binding startup make retries every second + * when binding is running use the Tinkerforge autoreconnect feature + \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.tinkerforge/build.properties b/bundles/binding/org.openhab.binding.tinkerforge/build.properties index 9e025ec6fb8..6117aed7abe 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/build.properties +++ b/bundles/binding/org.openhab.binding.tinkerforge/build.properties @@ -5,7 +5,7 @@ bin.includes = .,\ META-INF/,\ plugin.properties,\ OSGI-INF/,\ - lib/tinkerforge-2.1.1.jar + lib/tinkerforge-2.1.4.jar jars.compile.order = . src.includes = .project,\ .classpath,\ @@ -19,4 +19,4 @@ src.includes = .project,\ pom.xml,\ src/,\ Readme.md,\ - lib/tinkerforge-2.1.1.jar + lib/ diff --git a/bundles/binding/org.openhab.binding.tinkerforge/lib/tinkerforge-2.1.1.jar b/bundles/binding/org.openhab.binding.tinkerforge/lib/tinkerforge-2.1.1.jar deleted file mode 100644 index ff2c95694c0..00000000000 Binary files a/bundles/binding/org.openhab.binding.tinkerforge/lib/tinkerforge-2.1.1.jar and /dev/null differ diff --git a/bundles/binding/org.openhab.binding.tinkerforge/lib/tinkerforge-2.1.4.jar b/bundles/binding/org.openhab.binding.tinkerforge/lib/tinkerforge-2.1.4.jar new file mode 100644 index 00000000000..3e05288d99e Binary files /dev/null and b/bundles/binding/org.openhab.binding.tinkerforge/lib/tinkerforge-2.1.4.jar differ diff --git a/bundles/binding/org.openhab.binding.tinkerforge/model/tinkerforge.xcore b/bundles/binding/org.openhab.binding.tinkerforge/model/tinkerforge.xcore index ce4335b2958..3925366f387 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/model/tinkerforge.xcore +++ b/bundles/binding/org.openhab.binding.tinkerforge/model/tinkerforge.xcore @@ -9,6 +9,7 @@ @GenModel(literalsInterface="true", loadInitialization="false") package org.openhab.binding.tinkerforge.internal.model + import com.tinkerforge.Device import com.tinkerforge.IPConnection import org.slf4j.Logger @@ -28,6 +29,8 @@ import org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue import org.openhab.binding.tinkerforge.internal.types.DecimalValue import org.openhab.binding.tinkerforge.internal.types.OnOffValue import org.openhab.binding.tinkerforge.internal.types.HighLowValue +import org.openhab.binding.tinkerforge.internal.types.PercentValue +import org.openhab.binding.tinkerforge.internal.types.DirectionValue import com.tinkerforge.BrickletIO16 import com.tinkerforge.BrickletRemoteSwitch import com.tinkerforge.BrickletMotionDetector @@ -43,7 +46,13 @@ import com.tinkerforge.BrickletIndustrialDigitalOut4 import com.tinkerforge.BrickletHallEffect import com.tinkerforge.BrickletSegmentDisplay4x7 import com.tinkerforge.BrickletLEDStrip +import com.tinkerforge.BrickletJoystick +import com.tinkerforge.BrickletLinearPoti +import com.tinkerforge.BrickletDualButton import org.openhab.core.library.types.HSBType +import org.openhab.core.library.types.UpDownType +import org.openhab.core.library.types.PercentType +import org.openhab.core.library.types.IncreaseDecreaseType import java.math.BigDecimal import org.openhab.binding.tinkerforge.internal.config.DeviceOptions @@ -87,8 +96,16 @@ type TinkerBrickletIO4 wraps BrickletIO4 type TinkerBrickletHallEffect wraps BrickletHallEffect type TinkerBrickletSegmentDisplay4x7 wraps BrickletSegmentDisplay4x7 type TinkerBrickletLEDStrip wraps BrickletLEDStrip +type BrickletJoystick wraps BrickletJoystick +type TinkerBrickletLinearPoti wraps BrickletLinearPoti +type TinkerBrickletDualButton wraps BrickletDualButton type HSBType wraps HSBType +type UpDownType wraps UpDownType +type PercentValue wraps PercentValue type DeviceOptions wraps DeviceOptions +type PercentType wraps PercentType +type IncreaseDecreaseType wraps IncreaseDecreaseType +type DirectionValue wraps DirectionValue type Enum wraps Enum class Ecosystem { @@ -156,11 +173,18 @@ interface MSubDeviceHolder> { interface MActor{ } +interface SwitchSensor { + op void fetchSwitchState() +} -interface MSwitchActor { +interface MSwitchActor extends SwitchSensor{ SwitchState switchState op void turnSwitch(SwitchState state) - op void fetchSwitchState() +} + +interface ProgrammableSwitchActor extends SwitchSensor{ + SwitchState switchState + op void turnSwitch(SwitchState state, DeviceOptions opts) } interface MOutSwitchActor extends MSwitchActor{ @@ -200,41 +224,128 @@ interface MTextActor{ interface MLCDSubDevice extends MSubDevice { } +interface DigitalActor { + DigitalValue digitalState + op void turnDigital(DigitalValue digitalState) + op void fetchDigitalValue() +} + +interface NumberActor { + op void setNumber(BigDecimal value) +} + +interface ColorActor { + op void setColor(HSBType color, DeviceOptions opts) +} + +interface MoveActor { + DirectionValue direction + op void move(UpDownType direction, DeviceOptions opts) + op void stop() + op void moveon(DeviceOptions opts) +} + +interface DimmableActor extends MTFConfigConsumer { + BigDecimal minValue + BigDecimal maxValue + op void dimm(IncreaseDecreaseType increaseDecrease, DeviceOptions opts) +} + +interface SetPointActor extends DimmableActor { + PercentValue percentValue + op void setValue(BigDecimal newValue, DeviceOptions opts) + op void setValue(PercentType newValue, DeviceOptions opts) +} + +class MBrickletDualButton extends MDevice, + MSubDeviceHolder{ + +} + +interface DualButtonDevice extends MSubDevice{ + +} + +class DualButtonLeftButton extends DualButtonDevice, MSensor { + +} + +class DualButtonRightButton extends DualButtonDevice, MSensor { + +} + +class DualButtonLeftLed extends DualButtonDevice, DigitalActor { + +} + +class DualButtonRightLed extends DualButtonDevice, DigitalActor { + +} + +class MBrickletLinearPoti extends MDevice, CallbackListener, + MTFConfigConsumer, MSensor { + readonly String deviceType = "bricklet_linear_poti" +} + +class MBrickletJoystick extends MDevice, MSubDeviceHolder, + CallbackListener, MTFConfigConsumer { + readonly String deviceType = "bricklet_joystick" + +} + +interface JoystickDevice extends MSubDevice{ + +} + +class JoystickXPosition extends JoystickDevice, MSensor { + readonly String deviceType = "joystick_xposition" +} + +class JoystickYPosition extends JoystickDevice, MSensor { + readonly String deviceType = "joystick_yposition" +} + +class JoystickButton extends JoystickDevice, MSensor { + readonly String deviceType = "joystick_button" +} + class MBrickServo extends MDevice, MSubDeviceHolder { readonly String deviceType = "brick_servo" op void init(){} //int outputVoltage = "5000" } -class MServo extends MInSwitchActor, MSubDevice, - MTFConfigConsumer{ +class MServo extends MSensor, ProgrammableSwitchActor, MSubDevice, + MoveActor, SetPointActor{ readonly String deviceType = "servo" - int velocity = "30000" - int acceleration = "30000" + int velocity = "65535" //max speed, set position immediately + int acceleration = "65535" // max acceleration, set position immediately + Short maxPosition = "9000" + Short minPosition = "-9000" int pulseWidthMin = "1000" int pulseWidthMax = "2000" int period = "19500" int outputVoltage = "5000" - short servoCurrentPosition - short servoDestinationPosition + short targetPosition op void init(){} + op boolean setPoint(Short position, int velocity, int acceleration) } -enum DCDriveMode { - Brake = 0 - Coast = 1 -} - -class MBrickDC extends MInSwitchActor, MDevice, - MTFConfigConsumer{ +class MBrickDC extends MSensor, ProgrammableSwitchActor, MDevice, + MoveActor, SetPointActor, + CallbackListener{ readonly String deviceType = "brick_dc" op void init(){} + BigDecimal threshold = "10" + Short maxVelocity = "32767" + Short minVelocity = "-32767" short velocity + short targetvelocity = "0" short currentVelocity int acceleration = "10000" int pwmFrequency = "15000" - DCDriveMode driveMode = "Break" - short switchOnVelocity = "10000" + DCDriveMode driveMode = "BRAKE" + op boolean setSpeed(Short velocity, int acceleration, String drivemode) } class MDualRelayBricklet extends MDevice, @@ -271,23 +382,10 @@ class DigitalActorDigitalOut4 extends DigitalActor, MSubDevice{ } -interface ColorActor { - op void setColor(HSBType color, DeviceOptions opts) -} class MBrickletLEDStrip extends ColorActor, MDevice{ @@ -400,11 +498,12 @@ class RemoteSwitchA extends RemoteSwitch, MTFConfigConsumer{ +class RemoteSwitchB extends MSensor, RemoteSwitch, DimmableActor{ readonly String deviceType = "remote_switch_b" Long address Short unit Short repeats + Short targetDimmvalue = "0" } class RemoteSwitchC extends RemoteSwitch, MTFConfigConsumer{ @@ -549,6 +648,7 @@ class MBrickletLCD20x4 extends MDevice, MTextActor, String positonSuffix = ">" boolean displayErrors = "true" readonly String errorPrefix = "openhab Error:" + op boolean clear() } class MLCD20x4Backlight extends MInSwitchActor, MLCDSubDevice{ @@ -619,12 +719,11 @@ class TFVoltageCurrentConfiguration extends TFConfig { Short currentConversionTime } -class TFBrickDCConfiguration extends TFConfig{ +class TFBrickDCConfiguration extends DimmableConfiguration, TFBaseConfiguration{ short velocity int acceleration int pwmFrequency - int driveMode - short switchOnVelocity + String driveMode } class TFIOActorConfiguration extends TFConfig{ @@ -640,7 +739,7 @@ class TFIOSensorConfiguration extends TFConfig{ boolean pullUpResistorEnabled } -class TFServoConfiguration extends TFConfig { +class TFServoConfiguration extends DimmableConfiguration { int velocity int acceleration int servoVoltage @@ -649,7 +748,7 @@ class TFServoConfiguration extends TFConfig { int period //TODO must be equal for all servos, it is a property of the BrickServo // but for now no config could be set for SubdeviceHolders - int outputVoltage + int outputVoltage } class BrickletRemoteSwitchConfiguration extends TFConfig { @@ -664,7 +763,7 @@ class RemoteSwitchAConfiguration extends TFConfig{ Short repeats } -class RemoteSwitchBConfiguration extends TFConfig{ +class RemoteSwitchBConfiguration extends DimmableConfiguration { Long address Short unit Short repeats @@ -686,6 +785,11 @@ class BrickletMultiTouchConfiguration extends TFConfig { Short sensitivity } +class DimmableConfiguration extends TFConfig { + BigDecimal minValue + BigDecimal maxValue +} + enum NoSubIds { } @@ -742,3 +846,28 @@ enum TemperatureIRSubIds { enum VoltageCurrentSubIds { VOLTAGECURRENT_VOLTAGE, VOLTAGECURRENT_CURRENT, VOLTAGECURRENT_POWER } + +enum ConfigOptsMove { + RIGHTSPEED, LEFTSPEED, ACCELERATION, DRIVEMODE, PWM +} + +enum ConfigOptsDimmable { + MAX, MIN, STEP +} + +enum ConfigOptsSetPoint { + MAX, MIN +} + +enum ConfigOptsSwitchSpeed { + SPEED +} + +enum DCDriveMode { + BRAKE, COAST +} + +enum ConfigOptsServo { + VELOCITY, ACCELERATION, PULSEWIDTHMIN, PULSEWIDTHMAX, + PERIOD, POSITION, LEFTPOSITION, RIGHTPOSITION +} diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/ecosystem/TinkerforgeContext.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/ecosystem/TinkerforgeContext.java new file mode 100644 index 00000000000..754e3d07402 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/ecosystem/TinkerforgeContext.java @@ -0,0 +1,27 @@ +package org.openhab.binding.tinkerforge.ecosystem; + +import org.openhab.binding.tinkerforge.internal.model.Ecosystem; + +public class TinkerforgeContext { + + private static TinkerforgeContext instance; + private Ecosystem ecosystem; + + private TinkerforgeContext() {} + + public static TinkerforgeContext getInstance() { + if (instance == null) { + instance = new TinkerforgeContext(); + } + return instance; + } + + public Ecosystem getEcosystem() { + return ecosystem; + } + + public void setEcosystem(Ecosystem ecosystem) { + this.ecosystem = ecosystem; + } + +} diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/TinkerforgeBinding.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/TinkerforgeBinding.java index 2d69b156705..ac496eb0cd0 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/TinkerforgeBinding.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/TinkerforgeBinding.java @@ -20,9 +20,11 @@ import org.eclipse.emf.ecore.util.EContentAdapter; import org.eclipse.emf.ecore.util.EcoreUtil; import org.openhab.binding.tinkerforge.TinkerforgeBindingProvider; +import org.openhab.binding.tinkerforge.ecosystem.TinkerforgeContext; import org.openhab.binding.tinkerforge.internal.config.ConfigurationHandler; import org.openhab.binding.tinkerforge.internal.model.ColorActor; import org.openhab.binding.tinkerforge.internal.model.DigitalActor; +import org.openhab.binding.tinkerforge.internal.model.DimmableActor; import org.openhab.binding.tinkerforge.internal.model.Ecosystem; import org.openhab.binding.tinkerforge.internal.model.GenericDevice; import org.openhab.binding.tinkerforge.internal.model.IODevice; @@ -38,27 +40,39 @@ import org.openhab.binding.tinkerforge.internal.model.MTextActor; import org.openhab.binding.tinkerforge.internal.model.ModelFactory; import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.model.MoveActor; import org.openhab.binding.tinkerforge.internal.model.NumberActor; import org.openhab.binding.tinkerforge.internal.model.OHConfig; import org.openhab.binding.tinkerforge.internal.model.OHTFDevice; +import org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor; +import org.openhab.binding.tinkerforge.internal.model.SetPointActor; +import org.openhab.binding.tinkerforge.internal.model.SwitchSensor; import org.openhab.binding.tinkerforge.internal.model.TFConfig; import org.openhab.binding.tinkerforge.internal.types.DecimalValue; +import org.openhab.binding.tinkerforge.internal.types.DirectionValue; import org.openhab.binding.tinkerforge.internal.types.HighLowValue; import org.openhab.binding.tinkerforge.internal.types.OnOffValue; +import org.openhab.binding.tinkerforge.internal.types.PercentValue; import org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue; import org.openhab.binding.tinkerforge.internal.types.UnDefValue; import org.openhab.core.binding.AbstractActiveBinding; import org.openhab.core.binding.BindingProvider; import org.openhab.core.items.Item; import org.openhab.core.library.items.ContactItem; +import org.openhab.core.library.items.DimmerItem; import org.openhab.core.library.items.NumberItem; +import org.openhab.core.library.items.RollershutterItem; import org.openhab.core.library.items.StringItem; import org.openhab.core.library.items.SwitchItem; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.HSBType; +import org.openhab.core.library.types.IncreaseDecreaseType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OpenClosedType; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.StopMoveType; import org.openhab.core.library.types.StringType; +import org.openhab.core.library.types.UpDownType; import org.openhab.core.types.Command; import org.openhab.core.types.State; import org.openhab.core.types.UnDefType; @@ -136,6 +150,7 @@ public class TinkerforgeBinding extends AbstractActiveBinding) device).setTfConfig(deviceTfConfig); - device.enable(); logger.debug("{} adding/enabling device {} with config: {}", LoggerConstants.TFINIT, logId, deviceTfConfig); + ((MTFConfigConsumer) device).setTfConfig(deviceTfConfig); + device.enable(); } } else if (device instanceof IODevice) { logger.debug("{} ignoring unconfigured IODevice: {}", LoggerConstants.TFINIT, logId); @@ -309,7 +326,7 @@ && checkDuplicateGenericDevice((GenericDevice) device, uid, subId)) { * . */ private void initializeTFDevices(Notification notification) { - logger.debug("{} notifier {}", LoggerConstants.TFINIT, notification.getNotifier()); + logger.trace("{} notifier {}", LoggerConstants.TFINIT, notification.getNotifier()); if (notification.getNotifier() instanceof MBrickd) { logger.debug("{} notifier is Brickd", LoggerConstants.TFINIT); int featureID = notification.getFeatureID(MBrickd.class); @@ -385,19 +402,38 @@ private void processTFDeviceValues(Notification notification) { if (featureID == ModelPackage.MSENSOR__SENSOR_VALUE) { processValue((MBaseDevice) sensor, notification); } - } else if (notification.getNotifier() instanceof MSwitchActor) { + } + if (notification.getNotifier() instanceof SetPointActor) { + SetPointActor actor = (SetPointActor) notification.getNotifier(); + int setpointFeatureID = notification.getFeatureID(SetPointActor.class); + if (setpointFeatureID == ModelPackage.SET_POINT_ACTOR__PERCENT_VALUE) { + processValue((MBaseDevice) actor, notification); + } + } + if (notification.getNotifier() instanceof MoveActor) { + MoveActor actor = (MoveActor) notification.getNotifier(); + int moveFeatureID = notification.getFeatureID(MoveActor.class); + if (moveFeatureID == ModelPackage.MOVE_ACTOR__DIRECTION) { + processValue((MBaseDevice) actor, notification); + } + } + if (notification.getNotifier() instanceof MSwitchActor) { MSwitchActor switchActor = (MSwitchActor) notification.getNotifier(); int featureID = notification.getFeatureID(MSwitchActor.class); if (featureID == ModelPackage.MSWITCH_ACTOR__SWITCH_STATE) { processValue((MBaseDevice) switchActor, notification); } - } else if (notification.getNotifier() instanceof DigitalActor) { + } + if (notification.getNotifier() instanceof DigitalActor) { DigitalActor actor = (DigitalActor) notification.getNotifier(); int featureID = notification.getFeatureID(DigitalActor.class); if (featureID == ModelPackage.DIGITAL_ACTOR__DIGITAL_STATE) { processValue((MBaseDevice) actor, notification); } - } else { + + } + // TODO hier muss noch was fuer die dimmer und rollershutter rein + else { logger.trace("{} ignored notifier {}", LoggerConstants.TFMODELUPDATE, notification.getNotifier()); } @@ -535,6 +571,10 @@ protected void execute() { */ protected void updateItemValues(TinkerforgeBindingProvider provider, String itemName, boolean only_poll_enabled) { + if ( tinkerforgeEcosystem == null){ + logger.warn("tinkerforge ecosystem not yet ready"); + return; + } String deviceUid = provider.getUid(itemName); Item item = provider.getItem(itemName); String deviceSubId = provider.getSubId(itemName); @@ -553,8 +593,8 @@ protected void updateItemValues(TinkerforgeBindingProvider provider, String item } else { if (mDevice instanceof MSensor) { ((MSensor) mDevice).fetchSensorValue(); - } else if (mDevice instanceof MInSwitchActor && item instanceof SwitchItem) { - ((MInSwitchActor) mDevice).fetchSwitchState(); + } else if (mDevice instanceof SwitchSensor && item instanceof SwitchItem) { + ((SwitchSensor) mDevice).fetchSwitchState(); } else if (mDevice instanceof DigitalActor) { ((DigitalActor) mDevice).fetchDigitalValue(); } @@ -570,6 +610,7 @@ public void bindingChanged(BindingProvider provider, String itemName) { private void postUpdate(String uid, String subId, TinkerforgeValue sensorValue) { // TODO undef handling + logger.trace("postUpdate for uid {} subid {}", uid, subId); Map providerMap = getBindingProviders(uid, subId); if (providerMap.size() == 0) { logger.debug("{} found no item for uid {}, subid {}", LoggerConstants.TFMODELUPDATE, uid, @@ -584,11 +625,15 @@ private void postUpdate(String uid, String subId, TinkerforgeValue sensorValue) if (itemType.isAssignableFrom(NumberItem.class) || itemType.isAssignableFrom(StringItem.class)) { value = DecimalType.valueOf(String.valueOf(sensorValue)); + logger.trace("found item to update for DecimalValue {}", itemName); } else if (itemType.isAssignableFrom(ContactItem.class)) { value = sensorValue.equals(DecimalValue.ZERO) ? OpenClosedType.CLOSED : OpenClosedType.OPEN; } else if (itemType.isAssignableFrom(SwitchItem.class)) { value = sensorValue.equals(DecimalValue.ZERO) ? OnOffType.OFF : OnOffType.ON; + } else { + logger.trace("no update for DecimalValue for item {}", itemName); + continue; } } else if (sensorValue instanceof HighLowValue) { if (itemType.isAssignableFrom(NumberItem.class) @@ -601,8 +646,7 @@ private void postUpdate(String uid, String subId, TinkerforgeValue sensorValue) } else if (itemType.isAssignableFrom(SwitchItem.class)) { value = sensorValue == HighLowValue.HIGH ? OnOffType.ON : OnOffType.OFF; } else { - logger.error("{} unsupported item type {} for item {}", LoggerConstants.TFMODELUPDATE, - provider.getItem(itemName), itemName); + continue; } } else if (sensorValue instanceof OnOffValue) { if (itemType.isAssignableFrom(NumberItem.class) @@ -614,8 +658,21 @@ private void postUpdate(String uid, String subId, TinkerforgeValue sensorValue) } else if (itemType.isAssignableFrom(SwitchItem.class)) { value = sensorValue == OnOffValue.ON ? OnOffType.ON : OnOffType.OFF; } else { - logger.error("{} unsupported item type {} for item {}", LoggerConstants.TFMODELUPDATE, - provider.getItem(itemName), itemName); + continue; + } + } else if (sensorValue instanceof PercentValue) { + if (itemType.isAssignableFrom(RollershutterItem.class) + || itemType.isAssignableFrom(DimmerItem.class)) { + value = new PercentType(((PercentValue) sensorValue).toBigDecimal()); + } else { + continue; + } + } else if (sensorValue instanceof DirectionValue) { + if (itemType.isAssignableFrom(RollershutterItem.class)) { + value = sensorValue == DirectionValue.RIGHT ? UpDownType.UP : UpDownType.DOWN; + logger.trace("found item to update for UpDownValue {}", itemName); + } else { + continue; } } else if (sensorValue == UnDefValue.UNDEF || sensorValue == null) { value = UnDefType.UNDEF; @@ -671,14 +728,17 @@ protected void internalReceiveCommand(String itemName, Command command) { if (mDevice != null && mDevice.getEnabledA().get()) { if (command instanceof OnOffType) { logger.trace("{} found onoff command", LoggerConstants.COMMAND); + OnOffType cmd = (OnOffType) command; if (mDevice instanceof MInSwitchActor) { - OnOffType cmd = (OnOffType) command; OnOffValue state = cmd == OnOffType.OFF ? OnOffValue.OFF : OnOffValue.ON; ((MSwitchActor) mDevice).turnSwitch(state); } else if (mDevice instanceof DigitalActor) { - OnOffType cmd = (OnOffType) command; HighLowValue state = cmd == OnOffType.OFF ? HighLowValue.LOW : HighLowValue.HIGH; ((DigitalActor) mDevice).turnDigital(state); + } else if (mDevice instanceof ProgrammableSwitchActor) { + OnOffValue state = cmd == OnOffType.OFF ? OnOffValue.OFF : OnOffValue.ON; + ((ProgrammableSwitchActor) mDevice).turnSwitch(state, + provider.getDeviceOptions(itemName)); } else { logger.error("{} received OnOff command for non-SwitchActor", LoggerConstants.COMMAND); @@ -688,6 +748,13 @@ protected void internalReceiveCommand(String itemName, Command command) { if (mDevice instanceof MTextActor) { ((MTextActor) mDevice).setText(command.toString()); } + } else if (command instanceof PercentType) { + if (mDevice instanceof SetPointActor) { + ((SetPointActor) mDevice).setValue(((PercentType) command), + provider.getDeviceOptions(itemName)); + } else { + logger.error("found no percenttype actor"); + } } else if (command instanceof DecimalType) { logger.debug("{} found number command", LoggerConstants.COMMAND); if (command instanceof HSBType) { @@ -699,9 +766,43 @@ protected void internalReceiveCommand(String itemName, Command command) { } else { if (mDevice instanceof NumberActor) { ((NumberActor) mDevice).setNumber(((DecimalType) command).toBigDecimal()); + } else if ( mDevice instanceof SetPointActor){ + ((SetPointActor) mDevice).setValue(((DecimalType) command).toBigDecimal(), + provider.getDeviceOptions(itemName)); + } + else { + logger.error("found no number actor"); } } - } else { + } else if (command instanceof UpDownType) { + UpDownType cmd = (UpDownType) command; + logger.debug("{} UpDownType command {}", itemName, cmd); + if (mDevice instanceof MoveActor) { + ((MoveActor) mDevice).move((UpDownType) command, + provider.getDeviceOptions(itemName)); + } + } + else if (command instanceof StopMoveType){ + StopMoveType cmd = (StopMoveType) command; + if (mDevice instanceof MoveActor) { + if ( cmd == StopMoveType.STOP){ + ((MoveActor) mDevice).stop(); + } else { + ((MoveActor) mDevice).moveon(provider.getDeviceOptions(itemName)); + } + } + logger.debug("{} StopMoveType command {}", itemName, cmd); + } + else if (command instanceof IncreaseDecreaseType){ + IncreaseDecreaseType cmd = (IncreaseDecreaseType) command; + if (mDevice instanceof DimmableActor) { + ((DimmableActor) mDevice).dimm((IncreaseDecreaseType) command, + provider.getDeviceOptions(itemName)); + } + logger.debug("{} IncreaseDecreaseType command {}", itemName, cmd); + } + + else { logger.error("{} got unknown command type: {}", LoggerConstants.COMMAND, command.toString()); } diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/config/ConfigurationHandler.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/config/ConfigurationHandler.java index 9caea3081a6..804a423b00a 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/config/ConfigurationHandler.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/config/ConfigurationHandler.java @@ -92,7 +92,7 @@ private enum TypeKey { bricklet_soundintensity, bricklet_moisture, bricklet_distanceUS, bricklet_voltageCurrent, voltageCurrent_voltage, voltageCurrent_current, voltageCurrent_power, bricklet_tilt, io4_actuator, io4sensor, bricklet_io4, - bricklet_halleffect + bricklet_halleffect, bricklet_joystick, bricklet_linear_poti } @@ -220,7 +220,9 @@ private void createOHTFDeviceConfig(Map deviceConfig) || deviceType.equals(TypeKey.voltageCurrent_voltage.name()) || deviceType.equals(TypeKey.voltageCurrent_current.name()) || deviceType.equals(TypeKey.voltageCurrent_power.name()) - || deviceType.equals(TypeKey.bricklet_halleffect)) { + || deviceType.equals(TypeKey.bricklet_joystick.name()) + || deviceType.equals(TypeKey.bricklet_halleffect.name()) + || deviceType.equals(TypeKey.bricklet_linear_poti.name())) { logger.debug("{} setting base config", LoggerConstants.CONFIG); TFBaseConfiguration tfBaseConfiguration = modelFactory.createTFBaseConfiguration(); if (deviceType.equals(TypeKey.bricklet_barometer)) { diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/config/DeviceOptions.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/config/DeviceOptions.java index 48c5d344406..92e46b6389c 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/config/DeviceOptions.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/config/DeviceOptions.java @@ -9,6 +9,7 @@ package org.openhab.binding.tinkerforge.internal.config; import java.util.HashMap; +import java.util.Map.Entry; /** * A Class for storing device options from the items configuration. The = options from @@ -61,4 +62,16 @@ public HashMap getDeviceOptions() { return deviceOptions; } + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + for (Entry opt : deviceOptions.entrySet()){ + buffer.append(opt.getKey()); + buffer.append(": "); + buffer.append(opt.getValue()); + buffer.append("\n"); + } + return buffer.toString(); + } + } diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsDimmable.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsDimmable.java new file mode 100644 index 00000000000..4de0190c238 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsDimmable.java @@ -0,0 +1,248 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.Enumerator; + +/** + * + * A representation of the literals of the enumeration 'Config Opts Dimmable', + * and utility methods for working with them. + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getConfigOptsDimmable() + * @model + * @generated + */ +public enum ConfigOptsDimmable implements Enumerator +{ + /** + * The 'MAX' literal object. + * + * + * @see #MAX_VALUE + * @generated + * @ordered + */ + MAX(0, "MAX", "MAX"), + + /** + * The 'MIN' literal object. + * + * + * @see #MIN_VALUE + * @generated + * @ordered + */ + MIN(0, "MIN", "MIN"), + + /** + * The 'STEP' literal object. + * + * + * @see #STEP_VALUE + * @generated + * @ordered + */ + STEP(0, "STEP", "STEP"); + + /** + * The 'MAX' literal value. + * + *

      + * If the meaning of 'MAX' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #MAX + * @model + * @generated + * @ordered + */ + public static final int MAX_VALUE = 0; + + /** + * The 'MIN' literal value. + * + *

      + * If the meaning of 'MIN' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #MIN + * @model + * @generated + * @ordered + */ + public static final int MIN_VALUE = 0; + + /** + * The 'STEP' literal value. + * + *

      + * If the meaning of 'STEP' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #STEP + * @model + * @generated + * @ordered + */ + public static final int STEP_VALUE = 0; + + /** + * An array of all the 'Config Opts Dimmable' enumerators. + * + * + * @generated + */ + private static final ConfigOptsDimmable[] VALUES_ARRAY = + new ConfigOptsDimmable[] + { + MAX, + MIN, + STEP, + }; + + /** + * A public read-only list of all the 'Config Opts Dimmable' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'Config Opts Dimmable' literal with the specified literal value. + * + * + * @generated + */ + public static ConfigOptsDimmable get(String literal) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + ConfigOptsDimmable result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Config Opts Dimmable' literal with the specified name. + * + * + * @generated + */ + public static ConfigOptsDimmable getByName(String name) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + ConfigOptsDimmable result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Config Opts Dimmable' literal with the specified integer value. + * + * + * @generated + */ + public static ConfigOptsDimmable get(int value) + { + switch (value) + { + case MAX_VALUE: return MAX; + } + return null; + } + + /** + * + * + * @generated + */ + private final int value; + + /** + * + * + * @generated + */ + private final String name; + + /** + * + * + * @generated + */ + private final String literal; + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private ConfigOptsDimmable(int value, String name, String literal) + { + this.value = value; + this.name = name; + this.literal = literal; + } + + /** + * + * + * @generated + */ + public int getValue() + { + return value; + } + + /** + * + * + * @generated + */ + public String getName() + { + return name; + } + + /** + * + * + * @generated + */ + public String getLiteral() + { + return literal; + } + + /** + * Returns the literal value of the enumerator, which is its string representation. + * + * + * @generated + */ + @Override + public String toString() + { + return literal; + } + +} //ConfigOptsDimmable diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsMove.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsMove.java new file mode 100644 index 00000000000..508b2608a4f --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsMove.java @@ -0,0 +1,294 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.Enumerator; + +/** + * + * A representation of the literals of the enumeration 'Config Opts Move', + * and utility methods for working with them. + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getConfigOptsMove() + * @model + * @generated + */ +public enum ConfigOptsMove implements Enumerator +{ + /** + * The 'RIGHTSPEED' literal object. + * + * + * @see #RIGHTSPEED_VALUE + * @generated + * @ordered + */ + RIGHTSPEED(0, "RIGHTSPEED", "RIGHTSPEED"), + + /** + * The 'LEFTSPEED' literal object. + * + * + * @see #LEFTSPEED_VALUE + * @generated + * @ordered + */ + LEFTSPEED(0, "LEFTSPEED", "LEFTSPEED"), /** + * The 'ACCELERATION' literal object. + * + * + * @see #ACCELERATION_VALUE + * @generated + * @ordered + */ + ACCELERATION(0, "ACCELERATION", "ACCELERATION"), /** + * The 'DRIVEMODE' literal object. + * + * + * @see #DRIVEMODE_VALUE + * @generated + * @ordered + */ + DRIVEMODE(0, "DRIVEMODE", "DRIVEMODE"), /** + * The 'PWM' literal object. + * + * + * @see #PWM_VALUE + * @generated + * @ordered + */ + PWM(0, "PWM", "PWM"); + + /** + * The 'RIGHTSPEED' literal value. + * + *

      + * If the meaning of 'RIGHTSPEED' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #RIGHTSPEED + * @model + * @generated + * @ordered + */ + public static final int RIGHTSPEED_VALUE = 0; + + /** + * The 'LEFTSPEED' literal value. + * + *

      + * If the meaning of 'LEFTSPEED' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #LEFTSPEED + * @model + * @generated + * @ordered + */ + public static final int LEFTSPEED_VALUE = 0; + + /** + * The 'ACCELERATION' literal value. + * + *

      + * If the meaning of 'ACCELERATION' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #ACCELERATION + * @model + * @generated + * @ordered + */ + public static final int ACCELERATION_VALUE = 0; + + /** + * The 'DRIVEMODE' literal value. + * + *

      + * If the meaning of 'DRIVEMODE' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #DRIVEMODE + * @model + * @generated + * @ordered + */ + public static final int DRIVEMODE_VALUE = 0; + + /** + * The 'PWM' literal value. + * + *

      + * If the meaning of 'PWM' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #PWM + * @model + * @generated + * @ordered + */ + public static final int PWM_VALUE = 0; + + /** + * An array of all the 'Config Opts Move' enumerators. + * + * + * @generated + */ + private static final ConfigOptsMove[] VALUES_ARRAY = + new ConfigOptsMove[] + { + RIGHTSPEED, + LEFTSPEED, + ACCELERATION, + DRIVEMODE, + PWM, + }; + + /** + * A public read-only list of all the 'Config Opts Move' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'Config Opts Move' literal with the specified literal value. + * + * + * @generated + */ + public static ConfigOptsMove get(String literal) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + ConfigOptsMove result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Config Opts Move' literal with the specified name. + * + * + * @generated + */ + public static ConfigOptsMove getByName(String name) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + ConfigOptsMove result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Config Opts Move' literal with the specified integer value. + * + * + * @generated + */ + public static ConfigOptsMove get(int value) + { + switch (value) + { + case RIGHTSPEED_VALUE: return RIGHTSPEED; + } + return null; + } + + /** + * + * + * @generated + */ + private final int value; + + /** + * + * + * @generated + */ + private final String name; + + /** + * + * + * @generated + */ + private final String literal; + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private ConfigOptsMove(int value, String name, String literal) + { + this.value = value; + this.name = name; + this.literal = literal; + } + + /** + * + * + * @generated + */ + public int getValue() + { + return value; + } + + /** + * + * + * @generated + */ + public String getName() + { + return name; + } + + /** + * + * + * @generated + */ + public String getLiteral() + { + return literal; + } + + /** + * Returns the literal value of the enumerator, which is its string representation. + * + * + * @generated + */ + @Override + public String toString() + { + return literal; + } + +} //ConfigOptsMove diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsServo.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsServo.java new file mode 100644 index 00000000000..c8b822b0ef6 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsServo.java @@ -0,0 +1,372 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.Enumerator; + +/** + * + * A representation of the literals of the enumeration 'Config Opts Servo', + * and utility methods for working with them. + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getConfigOptsServo() + * @model + * @generated + */ +public enum ConfigOptsServo implements Enumerator +{ + /** + * The 'VELOCITY' literal object. + * + * + * @see #VELOCITY_VALUE + * @generated + * @ordered + */ + VELOCITY(0, "VELOCITY", "VELOCITY"), + + /** + * The 'ACCELERATION' literal object. + * + * + * @see #ACCELERATION_VALUE + * @generated + * @ordered + */ + ACCELERATION(0, "ACCELERATION", "ACCELERATION"), + + /** + * The 'PULSEWIDTHMIN' literal object. + * + * + * @see #PULSEWIDTHMIN_VALUE + * @generated + * @ordered + */ + PULSEWIDTHMIN(0, "PULSEWIDTHMIN", "PULSEWIDTHMIN"), + + /** + * The 'PULSEWIDTHMAX' literal object. + * + * + * @see #PULSEWIDTHMAX_VALUE + * @generated + * @ordered + */ + PULSEWIDTHMAX(0, "PULSEWIDTHMAX", "PULSEWIDTHMAX"), + + /** + * The 'PERIOD' literal object. + * + * + * @see #PERIOD_VALUE + * @generated + * @ordered + */ + PERIOD(0, "PERIOD", "PERIOD"), /** + * The 'POSITION' literal object. + * + * + * @see #POSITION_VALUE + * @generated + * @ordered + */ + POSITION(0, "POSITION", "POSITION"), /** + * The 'LEFTPOSITION' literal object. + * + * + * @see #LEFTPOSITION_VALUE + * @generated + * @ordered + */ + LEFTPOSITION(0, "LEFTPOSITION", "LEFTPOSITION"), /** + * The 'RIGHTPOSITION' literal object. + * + * + * @see #RIGHTPOSITION_VALUE + * @generated + * @ordered + */ + RIGHTPOSITION(0, "RIGHTPOSITION", "RIGHTPOSITION"); + + /** + * The 'VELOCITY' literal value. + * + *

      + * If the meaning of 'VELOCITY' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #VELOCITY + * @model + * @generated + * @ordered + */ + public static final int VELOCITY_VALUE = 0; + + /** + * The 'ACCELERATION' literal value. + * + *

      + * If the meaning of 'ACCELERATION' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #ACCELERATION + * @model + * @generated + * @ordered + */ + public static final int ACCELERATION_VALUE = 0; + + /** + * The 'PULSEWIDTHMIN' literal value. + * + *

      + * If the meaning of 'PULSEWIDTHMIN' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #PULSEWIDTHMIN + * @model + * @generated + * @ordered + */ + public static final int PULSEWIDTHMIN_VALUE = 0; + + /** + * The 'PULSEWIDTHMAX' literal value. + * + *

      + * If the meaning of 'PULSEWIDTHMAX' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #PULSEWIDTHMAX + * @model + * @generated + * @ordered + */ + public static final int PULSEWIDTHMAX_VALUE = 0; + + /** + * The 'PERIOD' literal value. + * + *

      + * If the meaning of 'PERIOD' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #PERIOD + * @model + * @generated + * @ordered + */ + public static final int PERIOD_VALUE = 0; + + /** + * The 'POSITION' literal value. + * + *

      + * If the meaning of 'POSITION' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #POSITION + * @model + * @generated + * @ordered + */ + public static final int POSITION_VALUE = 0; + + /** + * The 'LEFTPOSITION' literal value. + * + *

      + * If the meaning of 'LEFTPOSITION' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #LEFTPOSITION + * @model + * @generated + * @ordered + */ + public static final int LEFTPOSITION_VALUE = 0; + + /** + * The 'RIGHTPOSITION' literal value. + * + *

      + * If the meaning of 'RIGHTPOSITION' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #RIGHTPOSITION + * @model + * @generated + * @ordered + */ + public static final int RIGHTPOSITION_VALUE = 0; + + /** + * An array of all the 'Config Opts Servo' enumerators. + * + * + * @generated + */ + private static final ConfigOptsServo[] VALUES_ARRAY = + new ConfigOptsServo[] + { + VELOCITY, + ACCELERATION, + PULSEWIDTHMIN, + PULSEWIDTHMAX, + PERIOD, + POSITION, + LEFTPOSITION, + RIGHTPOSITION, + }; + + /** + * A public read-only list of all the 'Config Opts Servo' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'Config Opts Servo' literal with the specified literal value. + * + * + * @generated + */ + public static ConfigOptsServo get(String literal) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + ConfigOptsServo result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Config Opts Servo' literal with the specified name. + * + * + * @generated + */ + public static ConfigOptsServo getByName(String name) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + ConfigOptsServo result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Config Opts Servo' literal with the specified integer value. + * + * + * @generated + */ + public static ConfigOptsServo get(int value) + { + switch (value) + { + case VELOCITY_VALUE: return VELOCITY; + } + return null; + } + + /** + * + * + * @generated + */ + private final int value; + + /** + * + * + * @generated + */ + private final String name; + + /** + * + * + * @generated + */ + private final String literal; + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private ConfigOptsServo(int value, String name, String literal) + { + this.value = value; + this.name = name; + this.literal = literal; + } + + /** + * + * + * @generated + */ + public int getValue() + { + return value; + } + + /** + * + * + * @generated + */ + public String getName() + { + return name; + } + + /** + * + * + * @generated + */ + public String getLiteral() + { + return literal; + } + + /** + * Returns the literal value of the enumerator, which is its string representation. + * + * + * @generated + */ + @Override + public String toString() + { + return literal; + } + +} //ConfigOptsServo diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsSetPoint.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsSetPoint.java new file mode 100644 index 00000000000..9ddb0d4c41b --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsSetPoint.java @@ -0,0 +1,222 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.Enumerator; + +/** + * + * A representation of the literals of the enumeration 'Config Opts Set Point', + * and utility methods for working with them. + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getConfigOptsSetPoint() + * @model + * @generated + */ +public enum ConfigOptsSetPoint implements Enumerator +{ + /** + * The 'MAX' literal object. + * + * + * @see #MAX_VALUE + * @generated + * @ordered + */ + MAX(0, "MAX", "MAX"), + + /** + * The 'MIN' literal object. + * + * + * @see #MIN_VALUE + * @generated + * @ordered + */ + MIN(0, "MIN", "MIN"); + + /** + * The 'MAX' literal value. + * + *

      + * If the meaning of 'MAX' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #MAX + * @model + * @generated + * @ordered + */ + public static final int MAX_VALUE = 0; + + /** + * The 'MIN' literal value. + * + *

      + * If the meaning of 'MIN' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #MIN + * @model + * @generated + * @ordered + */ + public static final int MIN_VALUE = 0; + + /** + * An array of all the 'Config Opts Set Point' enumerators. + * + * + * @generated + */ + private static final ConfigOptsSetPoint[] VALUES_ARRAY = + new ConfigOptsSetPoint[] + { + MAX, + MIN, + }; + + /** + * A public read-only list of all the 'Config Opts Set Point' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'Config Opts Set Point' literal with the specified literal value. + * + * + * @generated + */ + public static ConfigOptsSetPoint get(String literal) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + ConfigOptsSetPoint result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Config Opts Set Point' literal with the specified name. + * + * + * @generated + */ + public static ConfigOptsSetPoint getByName(String name) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + ConfigOptsSetPoint result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Config Opts Set Point' literal with the specified integer value. + * + * + * @generated + */ + public static ConfigOptsSetPoint get(int value) + { + switch (value) + { + case MAX_VALUE: return MAX; + } + return null; + } + + /** + * + * + * @generated + */ + private final int value; + + /** + * + * + * @generated + */ + private final String name; + + /** + * + * + * @generated + */ + private final String literal; + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private ConfigOptsSetPoint(int value, String name, String literal) + { + this.value = value; + this.name = name; + this.literal = literal; + } + + /** + * + * + * @generated + */ + public int getValue() + { + return value; + } + + /** + * + * + * @generated + */ + public String getName() + { + return name; + } + + /** + * + * + * @generated + */ + public String getLiteral() + { + return literal; + } + + /** + * Returns the literal value of the enumerator, which is its string representation. + * + * + * @generated + */ + @Override + public String toString() + { + return literal; + } + +} //ConfigOptsSetPoint diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsSwitchSpeed.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsSwitchSpeed.java new file mode 100644 index 00000000000..4f1c56397bd --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ConfigOptsSwitchSpeed.java @@ -0,0 +1,196 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.Enumerator; + +/** + * + * A representation of the literals of the enumeration 'Config Opts Switch Speed', + * and utility methods for working with them. + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getConfigOptsSwitchSpeed() + * @model + * @generated + */ +public enum ConfigOptsSwitchSpeed implements Enumerator +{ + /** + * The 'SPEED' literal object. + * + * + * @see #SPEED_VALUE + * @generated + * @ordered + */ + SPEED(0, "SPEED", "SPEED"); + + /** + * The 'SPEED' literal value. + * + *

      + * If the meaning of 'SPEED' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #SPEED + * @model + * @generated + * @ordered + */ + public static final int SPEED_VALUE = 0; + + /** + * An array of all the 'Config Opts Switch Speed' enumerators. + * + * + * @generated + */ + private static final ConfigOptsSwitchSpeed[] VALUES_ARRAY = + new ConfigOptsSwitchSpeed[] + { + SPEED, + }; + + /** + * A public read-only list of all the 'Config Opts Switch Speed' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'Config Opts Switch Speed' literal with the specified literal value. + * + * + * @generated + */ + public static ConfigOptsSwitchSpeed get(String literal) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + ConfigOptsSwitchSpeed result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Config Opts Switch Speed' literal with the specified name. + * + * + * @generated + */ + public static ConfigOptsSwitchSpeed getByName(String name) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + ConfigOptsSwitchSpeed result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Config Opts Switch Speed' literal with the specified integer value. + * + * + * @generated + */ + public static ConfigOptsSwitchSpeed get(int value) + { + switch (value) + { + case SPEED_VALUE: return SPEED; + } + return null; + } + + /** + * + * + * @generated + */ + private final int value; + + /** + * + * + * @generated + */ + private final String name; + + /** + * + * + * @generated + */ + private final String literal; + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private ConfigOptsSwitchSpeed(int value, String name, String literal) + { + this.value = value; + this.name = name; + this.literal = literal; + } + + /** + * + * + * @generated + */ + public int getValue() + { + return value; + } + + /** + * + * + * @generated + */ + public String getName() + { + return name; + } + + /** + * + * + * @generated + */ + public String getLiteral() + { + return literal; + } + + /** + * Returns the literal value of the enumerator, which is its string representation. + * + * + * @generated + */ + @Override + public String toString() + { + return literal; + } + +} //ConfigOptsSwitchSpeed diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DCDriveMode.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DCDriveMode.java index f10a2ea9108..59f26d7e876 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DCDriveMode.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DCDriveMode.java @@ -1,10 +1,4 @@ /** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.tinkerforge.internal.model; @@ -18,9 +12,6 @@ * * A representation of the literals of the enumeration 'DC Drive Mode', * and utility methods for working with them. - * - * @author Theo Weiss - * @since 1.3.0 * * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDCDriveMode() * @model @@ -29,54 +20,52 @@ public enum DCDriveMode implements Enumerator { /** - * The 'Brake' literal object. + * The 'BRAKE' literal object. * * * @see #BRAKE_VALUE * @generated * @ordered */ - BRAKE(0, "Brake", "Brake"), - - /** - * The 'Coast' literal object. + BRAKE(0, "BRAKE", "BRAKE"), /** + * The 'COAST' literal object. * * * @see #COAST_VALUE * @generated * @ordered */ - COAST(1, "Coast", "Coast"); + COAST(0, "COAST", "COAST"); /** - * The 'Brake' literal value. + * The 'BRAKE' literal value. * *

      - * If the meaning of 'Brake' literal object isn't clear, + * If the meaning of 'BRAKE' literal object isn't clear, * there really should be more of a description here... *

      * * @see #BRAKE - * @model name="Brake" + * @model * @generated * @ordered */ public static final int BRAKE_VALUE = 0; /** - * The 'Coast' literal value. + * The 'COAST' literal value. * *

      - * If the meaning of 'Coast' literal object isn't clear, + * If the meaning of 'COAST' literal object isn't clear, * there really should be more of a description here... *

      * * @see #COAST - * @model name="Coast" + * @model * @generated * @ordered */ - public static final int COAST_VALUE = 1; + public static final int COAST_VALUE = 0; /** * An array of all the 'DC Drive Mode' enumerators. @@ -148,7 +137,6 @@ public static DCDriveMode get(int value) switch (value) { case BRAKE_VALUE: return BRAKE; - case COAST_VALUE: return COAST; } return null; } diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DimmableActor.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DimmableActor.java new file mode 100644 index 00000000000..b62a5cfac25 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DimmableActor.java @@ -0,0 +1,89 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.math.BigDecimal; +import org.openhab.binding.tinkerforge.internal.config.DeviceOptions; +import org.openhab.core.library.types.IncreaseDecreaseType; +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'Dimmable Actor'. + * + * + *

      + * The following features are supported: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.DimmableActor#getMinValue Min Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.DimmableActor#getMaxValue Max Value}
      • + *
      + *

      + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDimmableActor() + * @model interface="true" abstract="true" + * @generated + */ +public interface DimmableActor extends MTFConfigConsumer +{ + /** + * Returns the value of the 'Min Value' attribute. + * + *

      + * If the meaning of the 'Min Value' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Min Value' attribute. + * @see #setMinValue(BigDecimal) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDimmableActor_MinValue() + * @model unique="false" + * @generated + */ + BigDecimal getMinValue(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.DimmableActor#getMinValue Min Value}' attribute. + * + * + * @param value the new value of the 'Min Value' attribute. + * @see #getMinValue() + * @generated + */ + void setMinValue(BigDecimal value); + + /** + * Returns the value of the 'Max Value' attribute. + * + *

      + * If the meaning of the 'Max Value' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Max Value' attribute. + * @see #setMaxValue(BigDecimal) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDimmableActor_MaxValue() + * @model unique="false" + * @generated + */ + BigDecimal getMaxValue(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.DimmableActor#getMaxValue Max Value}' attribute. + * + * + * @param value the new value of the 'Max Value' attribute. + * @see #getMaxValue() + * @generated + */ + void setMaxValue(BigDecimal value); + + /** + * + * + * @model increaseDecreaseDataType="org.openhab.binding.tinkerforge.internal.model.IncreaseDecreaseType" increaseDecreaseUnique="false" optsDataType="org.openhab.binding.tinkerforge.internal.model.DeviceOptions" optsUnique="false" + * @generated + */ + void dimm(IncreaseDecreaseType increaseDecrease, DeviceOptions opts); + +} // DimmableActor diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DimmableConfiguration.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DimmableConfiguration.java new file mode 100644 index 00000000000..77cca2d213c --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DimmableConfiguration.java @@ -0,0 +1,78 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.math.BigDecimal; + +/** + * + * A representation of the model object 'Dimmable Configuration'. + * + * + *

      + * The following features are supported: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration#getMinValue Min Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration#getMaxValue Max Value}
      • + *
      + *

      + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDimmableConfiguration() + * @model + * @generated + */ +public interface DimmableConfiguration extends TFConfig +{ + /** + * Returns the value of the 'Min Value' attribute. + * + *

      + * If the meaning of the 'Min Value' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Min Value' attribute. + * @see #setMinValue(BigDecimal) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDimmableConfiguration_MinValue() + * @model unique="false" + * @generated + */ + BigDecimal getMinValue(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration#getMinValue Min Value}' attribute. + * + * + * @param value the new value of the 'Min Value' attribute. + * @see #getMinValue() + * @generated + */ + void setMinValue(BigDecimal value); + + /** + * Returns the value of the 'Max Value' attribute. + * + *

      + * If the meaning of the 'Max Value' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Max Value' attribute. + * @see #setMaxValue(BigDecimal) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDimmableConfiguration_MaxValue() + * @model unique="false" + * @generated + */ + BigDecimal getMaxValue(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration#getMaxValue Max Value}' attribute. + * + * + * @param value the new value of the 'Max Value' attribute. + * @see #getMaxValue() + * @generated + */ + void setMaxValue(BigDecimal value); + +} // DimmableConfiguration diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/Direction.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/Direction.java new file mode 100644 index 00000000000..8d50e9ce153 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/Direction.java @@ -0,0 +1,248 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.Enumerator; + +/** + * + * A representation of the literals of the enumeration 'Direction', + * and utility methods for working with them. + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDirection() + * @model + * @generated + */ +public enum Direction implements Enumerator +{ + /** + * The 'UNDEF' literal object. + * + * + * @see #UNDEF_VALUE + * @generated + * @ordered + */ + UNDEF(0, "UNDEF", "UNDEF"), + + /** + * The 'LEFT' literal object. + * + * + * @see #LEFT_VALUE + * @generated + * @ordered + */ + LEFT(0, "LEFT", "LEFT"), + + /** + * The 'RIGHT' literal object. + * + * + * @see #RIGHT_VALUE + * @generated + * @ordered + */ + RIGHT(0, "RIGHT", "RIGHT"); + + /** + * The 'UNDEF' literal value. + * + *

      + * If the meaning of 'UNDEF' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #UNDEF + * @model + * @generated + * @ordered + */ + public static final int UNDEF_VALUE = 0; + + /** + * The 'LEFT' literal value. + * + *

      + * If the meaning of 'LEFT' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #LEFT + * @model + * @generated + * @ordered + */ + public static final int LEFT_VALUE = 0; + + /** + * The 'RIGHT' literal value. + * + *

      + * If the meaning of 'RIGHT' literal object isn't clear, + * there really should be more of a description here... + *

      + * + * @see #RIGHT + * @model + * @generated + * @ordered + */ + public static final int RIGHT_VALUE = 0; + + /** + * An array of all the 'Direction' enumerators. + * + * + * @generated + */ + private static final Direction[] VALUES_ARRAY = + new Direction[] + { + UNDEF, + LEFT, + RIGHT, + }; + + /** + * A public read-only list of all the 'Direction' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'Direction' literal with the specified literal value. + * + * + * @generated + */ + public static Direction get(String literal) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + Direction result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Direction' literal with the specified name. + * + * + * @generated + */ + public static Direction getByName(String name) + { + for (int i = 0; i < VALUES_ARRAY.length; ++i) + { + Direction result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) + { + return result; + } + } + return null; + } + + /** + * Returns the 'Direction' literal with the specified integer value. + * + * + * @generated + */ + public static Direction get(int value) + { + switch (value) + { + case UNDEF_VALUE: return UNDEF; + } + return null; + } + + /** + * + * + * @generated + */ + private final int value; + + /** + * + * + * @generated + */ + private final String name; + + /** + * + * + * @generated + */ + private final String literal; + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private Direction(int value, String name, String literal) + { + this.value = value; + this.name = name; + this.literal = literal; + } + + /** + * + * + * @generated + */ + public int getValue() + { + return value; + } + + /** + * + * + * @generated + */ + public String getName() + { + return name; + } + + /** + * + * + * @generated + */ + public String getLiteral() + { + return literal; + } + + /** + * Returns the literal value of the enumerator, which is its string representation. + * + * + * @generated + */ + @Override + public String toString() + { + return literal; + } + +} //Direction diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonDevice.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonDevice.java new file mode 100644 index 00000000000..3e84b78d514 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonDevice.java @@ -0,0 +1,18 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + + +/** + * + * A representation of the model object 'Dual Button Device'. + * + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDualButtonDevice() + * @model interface="true" abstract="true" + * @generated + */ +public interface DualButtonDevice extends MSubDevice +{ +} // DualButtonDevice diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonLeftButton.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonLeftButton.java new file mode 100644 index 00000000000..4c16db342f1 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonLeftButton.java @@ -0,0 +1,20 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import org.openhab.binding.tinkerforge.internal.types.HighLowValue; + + +/** + * + * A representation of the model object 'Dual Button Left Button'. + * + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDualButtonLeftButton() + * @model superTypes="org.openhab.binding.tinkerforge.internal.model.DualButtonDevice org.openhab.binding.tinkerforge.internal.model.MSensor" + * @generated + */ +public interface DualButtonLeftButton extends DualButtonDevice, MSensor +{ +} // DualButtonLeftButton diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonLeftLed.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonLeftLed.java new file mode 100644 index 00000000000..bce8c5061e3 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonLeftLed.java @@ -0,0 +1,18 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + + +/** + * + * A representation of the model object 'Dual Button Left Led'. + * + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDualButtonLeftLed() + * @model + * @generated + */ +public interface DualButtonLeftLed extends DualButtonDevice, DigitalActor +{ +} // DualButtonLeftLed diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonRightButton.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonRightButton.java new file mode 100644 index 00000000000..24b2ad8f217 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonRightButton.java @@ -0,0 +1,20 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import org.openhab.binding.tinkerforge.internal.types.HighLowValue; + + +/** + * + * A representation of the model object 'Dual Button Right Button'. + * + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDualButtonRightButton() + * @model superTypes="org.openhab.binding.tinkerforge.internal.model.DualButtonDevice org.openhab.binding.tinkerforge.internal.model.MSensor" + * @generated + */ +public interface DualButtonRightButton extends DualButtonDevice, MSensor +{ +} // DualButtonRightButton diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonRightLed.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonRightLed.java new file mode 100644 index 00000000000..ba3ffcc580a --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/DualButtonRightLed.java @@ -0,0 +1,18 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + + +/** + * + * A representation of the model object 'Dual Button Right Led'. + * + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getDualButtonRightLed() + * @model + * @generated + */ +public interface DualButtonRightLed extends DualButtonDevice, DigitalActor +{ +} // DualButtonRightLed diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickButton.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickButton.java new file mode 100644 index 00000000000..6d6ac9a8321 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickButton.java @@ -0,0 +1,41 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import org.openhab.binding.tinkerforge.internal.types.HighLowValue; + +/** + * + * A representation of the model object 'Joystick Button'. + * + * + *

      + * The following features are supported: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.JoystickButton#getDeviceType Device Type}
      • + *
      + *

      + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getJoystickButton() + * @model superTypes="org.openhab.binding.tinkerforge.internal.model.JoystickDevice org.openhab.binding.tinkerforge.internal.model.MSensor" + * @generated + */ +public interface JoystickButton extends JoystickDevice, MSensor +{ + + /** + * Returns the value of the 'Device Type' attribute. + * The default value is "joystick_button". + * + *

      + * If the meaning of the 'Device Type' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Device Type' attribute. + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getJoystickButton_DeviceType() + * @model default="joystick_button" unique="false" changeable="false" + * @generated + */ + String getDeviceType(); +} // JoystickButton diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickDevice.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickDevice.java new file mode 100644 index 00000000000..3efaf3de14f --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickDevice.java @@ -0,0 +1,18 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + + +/** + * + * A representation of the model object 'Joystick Device'. + * + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getJoystickDevice() + * @model interface="true" abstract="true" + * @generated + */ +public interface JoystickDevice extends MSubDevice +{ +} // JoystickDevice diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickXPosition.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickXPosition.java new file mode 100644 index 00000000000..4c9e46b7b36 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickXPosition.java @@ -0,0 +1,42 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.math.BigDecimal; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; + +/** + * + * A representation of the model object 'Joystick XPosition'. + * + * + *

      + * The following features are supported: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.JoystickXPosition#getDeviceType Device Type}
      • + *
      + *

      + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getJoystickXPosition() + * @model superTypes="org.openhab.binding.tinkerforge.internal.model.JoystickDevice org.openhab.binding.tinkerforge.internal.model.MSensor" + * @generated + */ +public interface JoystickXPosition extends JoystickDevice, MSensor +{ + + /** + * Returns the value of the 'Device Type' attribute. + * The default value is "joystick_xposition". + * + *

      + * If the meaning of the 'Device Type' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Device Type' attribute. + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getJoystickXPosition_DeviceType() + * @model default="joystick_xposition" unique="false" changeable="false" + * @generated + */ + String getDeviceType(); +} // JoystickXPosition diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickYPosition.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickYPosition.java new file mode 100644 index 00000000000..5f55cca303f --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/JoystickYPosition.java @@ -0,0 +1,42 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.math.BigDecimal; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; + +/** + * + * A representation of the model object 'Joystick YPosition'. + * + * + *

      + * The following features are supported: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.JoystickYPosition#getDeviceType Device Type}
      • + *
      + *

      + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getJoystickYPosition() + * @model superTypes="org.openhab.binding.tinkerforge.internal.model.JoystickDevice org.openhab.binding.tinkerforge.internal.model.MSensor" + * @generated + */ +public interface JoystickYPosition extends JoystickDevice, MSensor +{ + + /** + * Returns the value of the 'Device Type' attribute. + * The default value is "joystick_yposition". + * + *

      + * If the meaning of the 'Device Type' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Device Type' attribute. + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getJoystickYPosition_DeviceType() + * @model default="joystick_yposition" unique="false" changeable="false" + * @generated + */ + String getDeviceType(); +} // JoystickYPosition diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickDC.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickDC.java index 5915d78330e..b2a5a488e27 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickDC.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickDC.java @@ -9,6 +9,8 @@ package org.openhab.binding.tinkerforge.internal.model; import com.tinkerforge.BrickDC; +import java.math.BigDecimal; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; /** * @@ -22,21 +24,105 @@ * The following features are supported: *
        *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getDeviceType Device Type}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getThreshold Threshold}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getMaxVelocity Max Velocity}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getMinVelocity Min Velocity}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getVelocity Velocity}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getTargetvelocity Targetvelocity}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getCurrentVelocity Current Velocity}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getAcceleration Acceleration}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getPwmFrequency Pwm Frequency}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getDriveMode Drive Mode}
      • - *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getSwitchOnVelocity Switch On Velocity}
      • *
      *

      * * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickDC() - * @model superTypes="org.openhab.binding.tinkerforge.internal.model.MInSwitchActor org.openhab.binding.tinkerforge.internal.model.MDevice org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer" + * @model superTypes="org.openhab.binding.tinkerforge.internal.model.MSensor org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor org.openhab.binding.tinkerforge.internal.model.MDevice org.openhab.binding.tinkerforge.internal.model.MoveActor org.openhab.binding.tinkerforge.internal.model.SetPointActor org.openhab.binding.tinkerforge.internal.model.CallbackListener" * @generated */ -public interface MBrickDC extends MInSwitchActor, MDevice, MTFConfigConsumer +public interface MBrickDC extends MSensor, ProgrammableSwitchActor, MDevice, MoveActor, SetPointActor, CallbackListener { + /** + * Returns the value of the 'Threshold' attribute. + * The default value is "10". + * + *

      + * If the meaning of the 'Threshold' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Threshold' attribute. + * @see #setThreshold(BigDecimal) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickDC_Threshold() + * @model default="10" unique="false" + * @generated + */ + BigDecimal getThreshold(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getThreshold Threshold}' attribute. + * + * + * @param value the new value of the 'Threshold' attribute. + * @see #getThreshold() + * @generated + */ + void setThreshold(BigDecimal value); + + /** + * Returns the value of the 'Max Velocity' attribute. + * The default value is "32767". + * + *

      + * If the meaning of the 'Max Velocity' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Max Velocity' attribute. + * @see #setMaxVelocity(Short) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickDC_MaxVelocity() + * @model default="32767" unique="false" + * @generated + */ + Short getMaxVelocity(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getMaxVelocity Max Velocity}' attribute. + * + * + * @param value the new value of the 'Max Velocity' attribute. + * @see #getMaxVelocity() + * @generated + */ + void setMaxVelocity(Short value); + + /** + * Returns the value of the 'Min Velocity' attribute. + * The default value is "-32767". + * + *

      + * If the meaning of the 'Min Velocity' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Min Velocity' attribute. + * @see #setMinVelocity(Short) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickDC_MinVelocity() + * @model default="-32767" unique="false" + * @generated + */ + Short getMinVelocity(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getMinVelocity Min Velocity}' attribute. + * + * + * @param value the new value of the 'Min Velocity' attribute. + * @see #getMinVelocity() + * @generated + */ + void setMinVelocity(Short value); + /** * Returns the value of the 'Device Type' attribute. * The default value is "brick_dc". @@ -79,6 +165,33 @@ public interface MBrickDC extends MInSwitchActor, MDevice, MTFConfigCon */ void setVelocity(short value); + /** + * Returns the value of the 'Targetvelocity' attribute. + * The default value is "0". + * + *

      + * If the meaning of the 'Targetvelocity' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Targetvelocity' attribute. + * @see #setTargetvelocity(short) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickDC_Targetvelocity() + * @model default="0" unique="false" + * @generated + */ + short getTargetvelocity(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getTargetvelocity Targetvelocity}' attribute. + * + * + * @param value the new value of the 'Targetvelocity' attribute. + * @see #getTargetvelocity() + * @generated + */ + void setTargetvelocity(short value); + /** * Returns the value of the 'Current Velocity' attribute. * @@ -161,7 +274,7 @@ public interface MBrickDC extends MInSwitchActor, MDevice, MTFConfigCon /** * Returns the value of the 'Drive Mode' attribute. - * The default value is "Break". + * The default value is "BRAKE". * The literals are from the enumeration {@link org.openhab.binding.tinkerforge.internal.model.DCDriveMode}. * *

      @@ -173,7 +286,7 @@ public interface MBrickDC extends MInSwitchActor, MDevice, MTFConfigCon * @see org.openhab.binding.tinkerforge.internal.model.DCDriveMode * @see #setDriveMode(DCDriveMode) * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickDC_DriveMode() - * @model default="Break" unique="false" + * @model default="BRAKE" unique="false" * @generated */ DCDriveMode getDriveMode(); @@ -190,38 +303,19 @@ public interface MBrickDC extends MInSwitchActor, MDevice, MTFConfigCon void setDriveMode(DCDriveMode value); /** - * Returns the value of the 'Switch On Velocity' attribute. - * The default value is "10000". - * - *

      - * If the meaning of the 'Switch On Velocity' attribute isn't clear, - * there really should be more of a description here... - *

      - * - * @return the value of the 'Switch On Velocity' attribute. - * @see #setSwitchOnVelocity(short) - * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickDC_SwitchOnVelocity() - * @model default="10000" unique="false" - * @generated - */ - short getSwitchOnVelocity(); - - /** - * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getSwitchOnVelocity Switch On Velocity}' attribute. * * - * @param value the new value of the 'Switch On Velocity' attribute. - * @see #getSwitchOnVelocity() + * @model annotation="http://www.eclipse.org/emf/2002/GenModel body=''" * @generated */ - void setSwitchOnVelocity(short value); + void init(); /** * * - * @model annotation="http://www.eclipse.org/emf/2002/GenModel body=''" + * @model unique="false" velocityUnique="false" accelerationUnique="false" drivemodeUnique="false" * @generated */ - void init(); + boolean setSpeed(Short velocity, int acceleration, String drivemode); } // MBrickDC diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletDualButton.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletDualButton.java new file mode 100644 index 00000000000..12f11cf815e --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletDualButton.java @@ -0,0 +1,19 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import com.tinkerforge.BrickletDualButton; + +/** + * + * A representation of the model object 'MBricklet Dual Button'. + * + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickletDualButton() + * @model superTypes="org.openhab.binding.tinkerforge.internal.model.MDevice org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder" + * @generated + */ +public interface MBrickletDualButton extends MDevice, MSubDeviceHolder +{ +} // MBrickletDualButton diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletJoystick.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletJoystick.java new file mode 100644 index 00000000000..71a1ac32c00 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletJoystick.java @@ -0,0 +1,41 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import com.tinkerforge.BrickletJoystick; + +/** + * + * A representation of the model object 'MBricklet Joystick'. + * + * + *

      + * The following features are supported: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick#getDeviceType Device Type}
      • + *
      + *

      + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickletJoystick() + * @model superTypes="org.openhab.binding.tinkerforge.internal.model.MDevice org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder org.openhab.binding.tinkerforge.internal.model.CallbackListener org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer" + * @generated + */ +public interface MBrickletJoystick extends MDevice, MSubDeviceHolder, CallbackListener, MTFConfigConsumer +{ + + /** + * Returns the value of the 'Device Type' attribute. + * The default value is "bricklet_joystick". + * + *

      + * If the meaning of the 'Device Type' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Device Type' attribute. + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickletJoystick_DeviceType() + * @model default="bricklet_joystick" unique="false" changeable="false" + * @generated + */ + String getDeviceType(); +} // MBrickletJoystick diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletLCD20x4.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletLCD20x4.java index 9d3f190dfe5..3a2718c99e9 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletLCD20x4.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletLCD20x4.java @@ -156,4 +156,12 @@ public interface MBrickletLCD20x4 extends MDevice, MTextActor, */ void init(); + /** + * + * + * @model unique="false" + * @generated + */ + boolean clear(); + } // MBrickletLCD20x4 diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletLinearPoti.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletLinearPoti.java new file mode 100644 index 00000000000..5cf9f8aef57 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MBrickletLinearPoti.java @@ -0,0 +1,42 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import com.tinkerforge.BrickletLinearPoti; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; + +/** + * + * A representation of the model object 'MBricklet Linear Poti'. + * + * + *

      + * The following features are supported: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.MBrickletLinearPoti#getDeviceType Device Type}
      • + *
      + *

      + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickletLinearPoti() + * @model superTypes="org.openhab.binding.tinkerforge.internal.model.MDevice org.openhab.binding.tinkerforge.internal.model.CallbackListener org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer org.openhab.binding.tinkerforge.internal.model.MSensor" + * @generated + */ +public interface MBrickletLinearPoti extends MDevice, CallbackListener, MTFConfigConsumer, MSensor +{ + /** + * Returns the value of the 'Device Type' attribute. + * The default value is "bricklet_linear_poti". + * + *

      + * If the meaning of the 'Device Type' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Device Type' attribute. + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMBrickletLinearPoti_DeviceType() + * @model default="bricklet_linear_poti" unique="false" changeable="false" + * @generated + */ + String getDeviceType(); + +} // MBrickletLinearPoti diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MServo.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MServo.java index ad262b069a2..c3d8c2728df 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MServo.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MServo.java @@ -8,6 +8,8 @@ */ package org.openhab.binding.tinkerforge.internal.model; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; + /** @@ -24,20 +26,21 @@ *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getDeviceType Device Type}
    • *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getVelocity Velocity}
    • *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getAcceleration Acceleration}
    • + *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getMaxPosition Max Position}
    • + *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getMinPosition Min Position}
    • *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getPulseWidthMin Pulse Width Min}
    • *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getPulseWidthMax Pulse Width Max}
    • *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getPeriod Period}
    • *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getOutputVoltage Output Voltage}
    • - *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getServoCurrentPosition Servo Current Position}
    • - *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getServoDestinationPosition Servo Destination Position}
    • + *
    • {@link org.openhab.binding.tinkerforge.internal.model.MServo#getTargetPosition Target Position}
    • * *

      * * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMServo() - * @model + * @model superTypes="org.openhab.binding.tinkerforge.internal.model.MSensor org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor org.openhab.binding.tinkerforge.internal.model.MSubDevice org.openhab.binding.tinkerforge.internal.model.MoveActor org.openhab.binding.tinkerforge.internal.model.SetPointActor" * @generated */ -public interface MServo extends MInSwitchActor, MSubDevice, MTFConfigConsumer +public interface MServo extends MSensor, ProgrammableSwitchActor, MSubDevice, MoveActor, SetPointActor { /** * Returns the value of the 'Device Type' attribute. @@ -57,7 +60,7 @@ public interface MServo extends MInSwitchActor, MSubDevice, MTFConf /** * Returns the value of the 'Velocity' attribute. - * The default value is "30000". + * The default value is "65535". * *

      * If the meaning of the 'Velocity' attribute isn't clear, @@ -67,7 +70,7 @@ public interface MServo extends MInSwitchActor, MSubDevice, MTFConf * @return the value of the 'Velocity' attribute. * @see #setVelocity(int) * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMServo_Velocity() - * @model default="30000" unique="false" + * @model default="65535" unique="false" * @generated */ int getVelocity(); @@ -84,7 +87,7 @@ public interface MServo extends MInSwitchActor, MSubDevice, MTFConf /** * Returns the value of the 'Acceleration' attribute. - * The default value is "30000". + * The default value is "65535". * *

      * If the meaning of the 'Acceleration' attribute isn't clear, @@ -94,7 +97,7 @@ public interface MServo extends MInSwitchActor, MSubDevice, MTFConf * @return the value of the 'Acceleration' attribute. * @see #setAcceleration(int) * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMServo_Acceleration() - * @model default="30000" unique="false" + * @model default="65535" unique="false" * @generated */ int getAcceleration(); @@ -109,6 +112,60 @@ public interface MServo extends MInSwitchActor, MSubDevice, MTFConf */ void setAcceleration(int value); + /** + * Returns the value of the 'Max Position' attribute. + * The default value is "9000". + * + *

      + * If the meaning of the 'Max Position' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Max Position' attribute. + * @see #setMaxPosition(Short) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMServo_MaxPosition() + * @model default="9000" unique="false" + * @generated + */ + Short getMaxPosition(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getMaxPosition Max Position}' attribute. + * + * + * @param value the new value of the 'Max Position' attribute. + * @see #getMaxPosition() + * @generated + */ + void setMaxPosition(Short value); + + /** + * Returns the value of the 'Min Position' attribute. + * The default value is "-9000". + * + *

      + * If the meaning of the 'Min Position' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Min Position' attribute. + * @see #setMinPosition(Short) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMServo_MinPosition() + * @model default="-9000" unique="false" + * @generated + */ + Short getMinPosition(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getMinPosition Min Position}' attribute. + * + * + * @param value the new value of the 'Min Position' attribute. + * @see #getMinPosition() + * @generated + */ + void setMinPosition(Short value); + /** * Returns the value of the 'Pulse Width Min' attribute. * The default value is "1000". @@ -218,63 +275,45 @@ public interface MServo extends MInSwitchActor, MSubDevice, MTFConf void setOutputVoltage(int value); /** - * Returns the value of the 'Servo Current Position' attribute. + * Returns the value of the 'Target Position' attribute. * *

      - * If the meaning of the 'Servo Current Position' attribute isn't clear, + * If the meaning of the 'Target Position' attribute isn't clear, * there really should be more of a description here... *

      * - * @return the value of the 'Servo Current Position' attribute. - * @see #setServoCurrentPosition(short) - * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMServo_ServoCurrentPosition() + * @return the value of the 'Target Position' attribute. + * @see #setTargetPosition(short) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMServo_TargetPosition() * @model unique="false" * @generated */ - short getServoCurrentPosition(); - - /** - * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getServoCurrentPosition Servo Current Position}' attribute. - * - * - * @param value the new value of the 'Servo Current Position' attribute. - * @see #getServoCurrentPosition() - * @generated - */ - void setServoCurrentPosition(short value); + short getTargetPosition(); /** - * Returns the value of the 'Servo Destination Position' attribute. + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getTargetPosition Target Position}' attribute. * - *

      - * If the meaning of the 'Servo Destination Position' attribute isn't clear, - * there really should be more of a description here... - *

      * - * @return the value of the 'Servo Destination Position' attribute. - * @see #setServoDestinationPosition(short) - * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMServo_ServoDestinationPosition() - * @model unique="false" + * @param value the new value of the 'Target Position' attribute. + * @see #getTargetPosition() * @generated */ - short getServoDestinationPosition(); + void setTargetPosition(short value); /** - * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getServoDestinationPosition Servo Destination Position}' attribute. * * - * @param value the new value of the 'Servo Destination Position' attribute. - * @see #getServoDestinationPosition() + * @model annotation="http://www.eclipse.org/emf/2002/GenModel body=''" * @generated */ - void setServoDestinationPosition(short value); + void init(); /** * * - * @model annotation="http://www.eclipse.org/emf/2002/GenModel body=''" + * @model unique="false" positionUnique="false" velocityUnique="false" accelerationUnique="false" * @generated */ - void init(); + boolean setPoint(Short position, int velocity, int acceleration); } // MServo diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MSwitchActor.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MSwitchActor.java index aebe6a671da..99a22fc59d1 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MSwitchActor.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MSwitchActor.java @@ -31,7 +31,7 @@ * @model interface="true" abstract="true" * @generated */ -public interface MSwitchActor extends EObject +public interface MSwitchActor extends SwitchSensor { /** * Returns the value of the 'Switch State' attribute. @@ -67,12 +67,4 @@ public interface MSwitchActor extends EObject */ void turnSwitch(OnOffValue state); - /** - * - * - * @model - * @generated - */ - void fetchSwitchState(); - } // MSwitchActor diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ModelFactory.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ModelFactory.java index a8fa6136e80..3f09e77f2eb 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ModelFactory.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ModelFactory.java @@ -79,6 +79,96 @@ public interface ModelFactory extends EFactory */ MBrickd createMBrickd(); + /** + * Returns a new object of class 'MBricklet Dual Button'. + * + * + * @return a new object of class 'MBricklet Dual Button'. + * @generated + */ + MBrickletDualButton createMBrickletDualButton(); + + /** + * Returns a new object of class 'Dual Button Left Button'. + * + * + * @return a new object of class 'Dual Button Left Button'. + * @generated + */ + DualButtonLeftButton createDualButtonLeftButton(); + + /** + * Returns a new object of class 'Dual Button Right Button'. + * + * + * @return a new object of class 'Dual Button Right Button'. + * @generated + */ + DualButtonRightButton createDualButtonRightButton(); + + /** + * Returns a new object of class 'Dual Button Left Led'. + * + * + * @return a new object of class 'Dual Button Left Led'. + * @generated + */ + DualButtonLeftLed createDualButtonLeftLed(); + + /** + * Returns a new object of class 'Dual Button Right Led'. + * + * + * @return a new object of class 'Dual Button Right Led'. + * @generated + */ + DualButtonRightLed createDualButtonRightLed(); + + /** + * Returns a new object of class 'MBricklet Linear Poti'. + * + * + * @return a new object of class 'MBricklet Linear Poti'. + * @generated + */ + MBrickletLinearPoti createMBrickletLinearPoti(); + + /** + * Returns a new object of class 'MBricklet Joystick'. + * + * + * @return a new object of class 'MBricklet Joystick'. + * @generated + */ + MBrickletJoystick createMBrickletJoystick(); + + /** + * Returns a new object of class 'Joystick XPosition'. + * + * + * @return a new object of class 'Joystick XPosition'. + * @generated + */ + JoystickXPosition createJoystickXPosition(); + + /** + * Returns a new object of class 'Joystick YPosition'. + * + * + * @return a new object of class 'Joystick YPosition'. + * @generated + */ + JoystickYPosition createJoystickYPosition(); + + /** + * Returns a new object of class 'Joystick Button'. + * + * + * @return a new object of class 'Joystick Button'. + * @generated + */ + JoystickButton createJoystickButton(); + /** * Returns a new object of class 'MBrick Servo'. * @@ -439,6 +529,15 @@ public interface ModelFactory extends EFactory */ BrickletMultiTouchConfiguration createBrickletMultiTouchConfiguration(); + /** + * Returns a new object of class 'Dimmable Configuration'. + * + * + * @return a new object of class 'Dimmable Configuration'. + * @generated + */ + DimmableConfiguration createDimmableConfiguration(); + /** * Returns a new object of class 'MServo'. * diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ModelPackage.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ModelPackage.java index a0ae0b60591..a0caeda7121 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ModelPackage.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ModelPackage.java @@ -88,7 +88,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFConfig() * @generated */ - int TF_CONFIG = 75; + int TF_CONFIG = 92; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.OHTFDeviceImpl OHTF Device}' class. @@ -98,7 +98,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getOHTFDevice() * @generated */ - int OHTF_DEVICE = 76; + int OHTF_DEVICE = 93; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.OHConfigImpl OH Config}' class. @@ -108,7 +108,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getOHConfig() * @generated */ - int OH_CONFIG = 78; + int OH_CONFIG = 95; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.EcosystemImpl Ecosystem}' class. @@ -178,7 +178,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickServo() * @generated */ - int MBRICK_SERVO = 19; + int MBRICK_SERVO = 39; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl TF Brick DC Configuration}' class. @@ -188,7 +188,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFBrickDCConfiguration() * @generated */ - int TF_BRICK_DC_CONFIGURATION = 85; + int TF_BRICK_DC_CONFIGURATION = 102; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MDualRelayBrickletImpl MDual Relay Bricklet}' class. @@ -198,7 +198,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMDualRelayBricklet() * @generated */ - int MDUAL_RELAY_BRICKLET = 22; + int MDUAL_RELAY_BRICKLET = 42; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.MActor MActor}' class. @@ -218,7 +218,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMSwitchActor() * @generated */ - int MSWITCH_ACTOR = 8; + int MSWITCH_ACTOR = 9; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.MInSwitchActor MIn Switch Actor}' class. @@ -228,7 +228,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMInSwitchActor() * @generated */ - int MIN_SWITCH_ACTOR = 10; + int MIN_SWITCH_ACTOR = 12; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl MBrick DC}' class. @@ -238,7 +238,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickDC() * @generated */ - int MBRICK_DC = 21; + int MBRICK_DC = 41; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialQuadRelayBrickletImpl MIndustrial Quad Relay Bricklet}' class. @@ -248,7 +248,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMIndustrialQuadRelayBricklet() * @generated */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET = 23; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET = 43; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialQuadRelayImpl MIndustrial Quad Relay}' class. @@ -258,7 +258,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMIndustrialQuadRelay() * @generated */ - int MINDUSTRIAL_QUAD_RELAY = 24; + int MINDUSTRIAL_QUAD_RELAY = 44; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalIn4Impl MBricklet Industrial Digital In4}' class. @@ -268,7 +268,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletIndustrialDigitalIn4() * @generated */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4 = 25; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4 = 45; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.MOutSwitchActor MOut Switch Actor}' class. @@ -278,7 +278,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMOutSwitchActor() * @generated */ - int MOUT_SWITCH_ACTOR = 9; + int MOUT_SWITCH_ACTOR = 11; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.MSubDevice MSub Device}' class. @@ -288,7 +288,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMSubDevice() * @generated */ - int MSUB_DEVICE = 13; + int MSUB_DEVICE = 15; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialDigitalInImpl MIndustrial Digital In}' class. @@ -298,7 +298,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMIndustrialDigitalIn() * @generated */ - int MINDUSTRIAL_DIGITAL_IN = 26; + int MINDUSTRIAL_DIGITAL_IN = 46; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFIOActorConfigurationImpl TFIO Actor Configuration}' class. @@ -308,7 +308,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFIOActorConfiguration() * @generated */ - int TFIO_ACTOR_CONFIGURATION = 86; + int TFIO_ACTOR_CONFIGURATION = 103; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIO16Impl MBricklet IO16}' class. @@ -318,7 +318,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletIO16() * @generated */ - int MBRICKLET_IO16 = 35; + int MBRICKLET_IO16 = 52; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DigitalSensorImpl Digital Sensor}' class. @@ -328,7 +328,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalSensor() * @generated */ - int DIGITAL_SENSOR = 36; + int DIGITAL_SENSOR = 53; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.IODevice IO Device}' class. @@ -338,7 +338,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIODevice() * @generated */ - int IO_DEVICE = 12; + int IO_DEVICE = 14; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFInterruptListenerConfigurationImpl TF Interrupt Listener Configuration}' class. @@ -348,7 +348,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFInterruptListenerConfiguration() * @generated */ - int TF_INTERRUPT_LISTENER_CONFIGURATION = 87; + int TF_INTERRUPT_LISTENER_CONFIGURATION = 104; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFIOSensorConfigurationImpl TFIO Sensor Configuration}' class. @@ -358,7 +358,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFIOSensorConfiguration() * @generated */ - int TFIO_SENSOR_CONFIGURATION = 88; + int TFIO_SENSOR_CONFIGURATION = 105; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MDualRelayImpl MDual Relay}' class. @@ -368,7 +368,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMDualRelay() * @generated */ - int MDUAL_RELAY = 47; + int MDUAL_RELAY = 64; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFNullConfigurationImpl TF Null Configuration}' class. @@ -378,7 +378,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFNullConfiguration() * @generated */ - int TF_NULL_CONFIGURATION = 79; + int TF_NULL_CONFIGURATION = 96; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFServoConfigurationImpl TF Servo Configuration}' class. @@ -388,7 +388,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFServoConfiguration() * @generated */ - int TF_SERVO_CONFIGURATION = 89; + int TF_SERVO_CONFIGURATION = 106; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl MServo}' class. @@ -398,7 +398,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMServo() * @generated */ - int MSERVO = 20; + int MSERVO = 40; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.CallbackListener Callback Listener}' class. @@ -408,7 +408,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getCallbackListener() * @generated */ - int CALLBACK_LISTENER = 14; + int CALLBACK_LISTENER = 16; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.InterruptListener Interrupt Listener}' class. @@ -418,7 +418,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getInterruptListener() * @generated */ - int INTERRUPT_LISTENER = 15; + int INTERRUPT_LISTENER = 17; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.MSensor MSensor}' class. @@ -428,7 +428,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMSensor() * @generated */ - int MSENSOR = 16; + int MSENSOR = 18; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletHumidityImpl MBricklet Humidity}' class. @@ -438,7 +438,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletHumidity() * @generated */ - int MBRICKLET_HUMIDITY = 53; + int MBRICKLET_HUMIDITY = 70; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDistanceIRImpl MBricklet Distance IR}' class. @@ -448,7 +448,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletDistanceIR() * @generated */ - int MBRICKLET_DISTANCE_IR = 54; + int MBRICKLET_DISTANCE_IR = 71; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletTemperatureImpl MBricklet Temperature}' class. @@ -458,7 +458,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletTemperature() * @generated */ - int MBRICKLET_TEMPERATURE = 55; + int MBRICKLET_TEMPERATURE = 72; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFBaseConfigurationImpl TF Base Configuration}' class. @@ -468,7 +468,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFBaseConfiguration() * @generated */ - int TF_BASE_CONFIGURATION = 80; + int TF_BASE_CONFIGURATION = 97; /** * The feature id for the 'Logger' attribute. @@ -1029,6 +1029,43 @@ public interface ModelPackage extends EPackage */ int MACTOR_OPERATION_COUNT = 0; + /** + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.SwitchSensor Switch Sensor}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.SwitchSensor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getSwitchSensor() + * @generated + */ + int SWITCH_SENSOR = 8; + + /** + * The number of structural features of the 'Switch Sensor' class. + * + * + * @generated + * @ordered + */ + int SWITCH_SENSOR_FEATURE_COUNT = 0; + + /** + * The operation id for the 'Fetch Switch State' operation. + * + * + * @generated + * @ordered + */ + int SWITCH_SENSOR___FETCH_SWITCH_STATE = 0; + + /** + * The number of operations of the 'Switch Sensor' class. + * + * + * @generated + * @ordered + */ + int SWITCH_SENSOR_OPERATION_COUNT = 1; + /** * The feature id for the 'Switch State' attribute. * @@ -1036,7 +1073,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MSWITCH_ACTOR__SWITCH_STATE = 0; + int MSWITCH_ACTOR__SWITCH_STATE = SWITCH_SENSOR_FEATURE_COUNT + 0; /** * The number of structural features of the 'MSwitch Actor' class. @@ -1045,7 +1082,16 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MSWITCH_ACTOR_FEATURE_COUNT = 1; + int MSWITCH_ACTOR_FEATURE_COUNT = SWITCH_SENSOR_FEATURE_COUNT + 1; + + /** + * The operation id for the 'Fetch Switch State' operation. + * + * + * @generated + * @ordered + */ + int MSWITCH_ACTOR___FETCH_SWITCH_STATE = SWITCH_SENSOR___FETCH_SWITCH_STATE; /** * The operation id for the 'Turn Switch' operation. @@ -1054,7 +1100,44 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MSWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE = 0; + int MSWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE = SWITCH_SENSOR_OPERATION_COUNT + 0; + + /** + * The number of operations of the 'MSwitch Actor' class. + * + * + * @generated + * @ordered + */ + int MSWITCH_ACTOR_OPERATION_COUNT = SWITCH_SENSOR_OPERATION_COUNT + 1; + + /** + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor Programmable Switch Actor}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getProgrammableSwitchActor() + * @generated + */ + int PROGRAMMABLE_SWITCH_ACTOR = 10; + + /** + * The feature id for the 'Switch State' attribute. + * + * + * @generated + * @ordered + */ + int PROGRAMMABLE_SWITCH_ACTOR__SWITCH_STATE = SWITCH_SENSOR_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'Programmable Switch Actor' class. + * + * + * @generated + * @ordered + */ + int PROGRAMMABLE_SWITCH_ACTOR_FEATURE_COUNT = SWITCH_SENSOR_FEATURE_COUNT + 1; /** * The operation id for the 'Fetch Switch State' operation. @@ -1063,16 +1146,25 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MSWITCH_ACTOR___FETCH_SWITCH_STATE = 1; + int PROGRAMMABLE_SWITCH_ACTOR___FETCH_SWITCH_STATE = SWITCH_SENSOR___FETCH_SWITCH_STATE; /** - * The number of operations of the 'MSwitch Actor' class. + * The operation id for the 'Turn Switch' operation. + * + * + * @generated + * @ordered + */ + int PROGRAMMABLE_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE_DEVICEOPTIONS = SWITCH_SENSOR_OPERATION_COUNT + 0; + + /** + * The number of operations of the 'Programmable Switch Actor' class. * * * @generated * @ordered */ - int MSWITCH_ACTOR_OPERATION_COUNT = 2; + int PROGRAMMABLE_SWITCH_ACTOR_OPERATION_COUNT = SWITCH_SENSOR_OPERATION_COUNT + 1; /** * The feature id for the 'Switch State' attribute. @@ -1093,22 +1185,22 @@ public interface ModelPackage extends EPackage int MOUT_SWITCH_ACTOR_FEATURE_COUNT = MSWITCH_ACTOR_FEATURE_COUNT + 0; /** - * The operation id for the 'Turn Switch' operation. + * The operation id for the 'Fetch Switch State' operation. * * * @generated * @ordered */ - int MOUT_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE = MSWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; + int MOUT_SWITCH_ACTOR___FETCH_SWITCH_STATE = MSWITCH_ACTOR___FETCH_SWITCH_STATE; /** - * The operation id for the 'Fetch Switch State' operation. + * The operation id for the 'Turn Switch' operation. * * * @generated * @ordered */ - int MOUT_SWITCH_ACTOR___FETCH_SWITCH_STATE = MSWITCH_ACTOR___FETCH_SWITCH_STATE; + int MOUT_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE = MSWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; /** * The number of operations of the 'MOut Switch Actor' class. @@ -1138,22 +1230,22 @@ public interface ModelPackage extends EPackage int MIN_SWITCH_ACTOR_FEATURE_COUNT = MSWITCH_ACTOR_FEATURE_COUNT + 0; /** - * The operation id for the 'Turn Switch' operation. + * The operation id for the 'Fetch Switch State' operation. * * * @generated * @ordered */ - int MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE = MSWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; + int MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE = MSWITCH_ACTOR___FETCH_SWITCH_STATE; /** - * The operation id for the 'Fetch Switch State' operation. + * The operation id for the 'Turn Switch' operation. * * * @generated * @ordered */ - int MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE = MSWITCH_ACTOR___FETCH_SWITCH_STATE; + int MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE = MSWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; /** * The number of operations of the 'MIn Switch Actor' class. @@ -1172,7 +1264,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getGenericDevice() * @generated */ - int GENERIC_DEVICE = 11; + int GENERIC_DEVICE = 13; /** * The feature id for the 'Generic Device Id' attribute. @@ -1506,7 +1598,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletBarometer() * @generated */ - int MBRICKLET_BAROMETER = 66; + int MBRICKLET_BAROMETER = 83; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBarometerTemperatureImpl MBarometer Temperature}' class. @@ -1516,7 +1608,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBarometerTemperature() * @generated */ - int MBAROMETER_TEMPERATURE = 67; + int MBAROMETER_TEMPERATURE = 84; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletAmbientLightImpl MBricklet Ambient Light}' class. @@ -1526,7 +1618,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletAmbientLight() * @generated */ - int MBRICKLET_AMBIENT_LIGHT = 68; + int MBRICKLET_AMBIENT_LIGHT = 85; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLCD20x4Impl MBricklet LCD2 0x4}' class. @@ -1536,7 +1628,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletLCD20x4() * @generated */ - int MBRICKLET_LCD2_0X4 = 72; + int MBRICKLET_LCD2_0X4 = 89; /** * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.MTextActor MText Actor}' class. @@ -1546,7 +1638,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTextActor() * @generated */ - int MTEXT_ACTOR = 17; + int MTEXT_ACTOR = 19; /** * The feature id for the 'Text' attribute. @@ -1583,7 +1675,7 @@ public interface ModelPackage extends EPackage * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMLCDSubDevice() * @generated */ - int MLCD_SUB_DEVICE = 18; + int MLCD_SUB_DEVICE = 20; /** * The feature id for the 'Logger' attribute. @@ -1685,238 +1777,247 @@ public interface ModelPackage extends EPackage int MLCD_SUB_DEVICE_OPERATION_COUNT = MSUB_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Logger' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalOut4Impl MBricklet Industrial Digital Out4}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalOut4Impl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletIndustrialDigitalOut4() * @generated - * @ordered */ - int MBRICK_SERVO__LOGGER = MDEVICE__LOGGER; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4 = 47; /** - * The feature id for the 'Uid' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor Digital Actor}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActor() * @generated - * @ordered */ - int MBRICK_SERVO__UID = MDEVICE__UID; + int DIGITAL_ACTOR = 21; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Digital State' attribute. * * * @generated * @ordered */ - int MBRICK_SERVO__POLL = MDEVICE__POLL; + int DIGITAL_ACTOR__DIGITAL_STATE = 0; /** - * The feature id for the 'Enabled A' attribute. + * The number of structural features of the 'Digital Actor' class. * * * @generated * @ordered */ - int MBRICK_SERVO__ENABLED_A = MDEVICE__ENABLED_A; + int DIGITAL_ACTOR_FEATURE_COUNT = 1; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The operation id for the 'Turn Digital' operation. * * * @generated * @ordered */ - int MBRICK_SERVO__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int DIGITAL_ACTOR___TURN_DIGITAL__HIGHLOWVALUE = 0; /** - * The feature id for the 'Ip Connection' attribute. + * The operation id for the 'Fetch Digital Value' operation. * * * @generated * @ordered */ - int MBRICK_SERVO__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int DIGITAL_ACTOR___FETCH_DIGITAL_VALUE = 1; /** - * The feature id for the 'Connected Uid' attribute. + * The number of operations of the 'Digital Actor' class. * * * @generated * @ordered */ - int MBRICK_SERVO__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int DIGITAL_ACTOR_OPERATION_COUNT = 2; /** - * The feature id for the 'Position' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorDigitalOut4Impl Digital Actor Digital Out4}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorDigitalOut4Impl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActorDigitalOut4() * @generated - * @ordered */ - int MBRICK_SERVO__POSITION = MDEVICE__POSITION; + int DIGITAL_ACTOR_DIGITAL_OUT4 = 48; /** - * The feature id for the 'Device Identifier' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.NumberActor Number Actor}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.NumberActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getNumberActor() * @generated - * @ordered */ - int MBRICK_SERVO__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int NUMBER_ACTOR = 22; /** - * The feature id for the 'Name' attribute. + * The number of structural features of the 'Number Actor' class. * * * @generated * @ordered */ - int MBRICK_SERVO__NAME = MDEVICE__NAME; + int NUMBER_ACTOR_FEATURE_COUNT = 0; /** - * The feature id for the 'Brickd' container reference. + * The operation id for the 'Set Number' operation. * * * @generated * @ordered */ - int MBRICK_SERVO__BRICKD = MDEVICE__BRICKD; + int NUMBER_ACTOR___SET_NUMBER__BIGDECIMAL = 0; /** - * The feature id for the 'Msubdevices' containment reference list. + * The number of operations of the 'Number Actor' class. * * * @generated * @ordered */ - int MBRICK_SERVO__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; + int NUMBER_ACTOR_OPERATION_COUNT = 1; /** - * The feature id for the 'Device Type' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.ColorActor Color Actor}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.ColorActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getColorActor() * @generated - * @ordered */ - int MBRICK_SERVO__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 1; + int COLOR_ACTOR = 23; /** - * The number of structural features of the 'MBrick Servo' class. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLEDStripImpl MBricklet LED Strip}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLEDStripImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletLEDStrip() * @generated - * @ordered */ - int MBRICK_SERVO_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 2; + int MBRICKLET_LED_STRIP = 50; /** - * The operation id for the 'Enable' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletSegmentDisplay4x7Impl MBricklet Segment Display4x7}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletSegmentDisplay4x7Impl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletSegmentDisplay4x7() * @generated - * @ordered */ - int MBRICK_SERVO___ENABLE = MDEVICE___ENABLE; + int MBRICKLET_SEGMENT_DISPLAY4X7 = 49; /** - * The operation id for the 'Disable' operation. + * The number of structural features of the 'Color Actor' class. * * * @generated * @ordered */ - int MBRICK_SERVO___DISABLE = MDEVICE___DISABLE; + int COLOR_ACTOR_FEATURE_COUNT = 0; /** - * The operation id for the 'Init Sub Devices' operation. + * The operation id for the 'Set Color' operation. * * * @generated * @ordered */ - int MBRICK_SERVO___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; + int COLOR_ACTOR___SET_COLOR__HSBTYPE_DEVICEOPTIONS = 0; /** - * The operation id for the 'Init' operation. + * The number of operations of the 'Color Actor' class. * * * @generated * @ordered */ - int MBRICK_SERVO___INIT = MDEVICE_OPERATION_COUNT + 1; + int COLOR_ACTOR_OPERATION_COUNT = 1; /** - * The number of operations of the 'MBrick Servo' class. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.MoveActor Move Actor}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.MoveActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMoveActor() * @generated - * @ordered */ - int MBRICK_SERVO_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; + int MOVE_ACTOR = 24; /** - * The feature id for the 'Switch State' attribute. + * The feature id for the 'Direction' attribute. * * * @generated * @ordered */ - int MSERVO__SWITCH_STATE = MIN_SWITCH_ACTOR__SWITCH_STATE; + int MOVE_ACTOR__DIRECTION = 0; /** - * The feature id for the 'Logger' attribute. + * The number of structural features of the 'Move Actor' class. * * * @generated * @ordered */ - int MSERVO__LOGGER = MIN_SWITCH_ACTOR_FEATURE_COUNT + 0; + int MOVE_ACTOR_FEATURE_COUNT = 1; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Move' operation. * * * @generated * @ordered */ - int MSERVO__UID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 1; + int MOVE_ACTOR___MOVE__UPDOWNTYPE_DEVICEOPTIONS = 0; /** - * The feature id for the 'Poll' attribute. + * The operation id for the 'Stop' operation. * * * @generated * @ordered */ - int MSERVO__POLL = MIN_SWITCH_ACTOR_FEATURE_COUNT + 2; + int MOVE_ACTOR___STOP = 1; /** - * The feature id for the 'Enabled A' attribute. + * The operation id for the 'Moveon' operation. * * * @generated * @ordered */ - int MSERVO__ENABLED_A = MIN_SWITCH_ACTOR_FEATURE_COUNT + 3; + int MOVE_ACTOR___MOVEON__DEVICEOPTIONS = 2; /** - * The feature id for the 'Sub Id' attribute. + * The number of operations of the 'Move Actor' class. * * * @generated * @ordered */ - int MSERVO__SUB_ID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 4; + int MOVE_ACTOR_OPERATION_COUNT = 3; /** - * The feature id for the 'Mbrick' container reference. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.DimmableActor Dimmable Actor}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.DimmableActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDimmableActor() * @generated - * @ordered */ - int MSERVO__MBRICK = MIN_SWITCH_ACTOR_FEATURE_COUNT + 5; + int DIMMABLE_ACTOR = 25; /** * The feature id for the 'Tf Config' containment reference. @@ -1925,160 +2026,153 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MSERVO__TF_CONFIG = MIN_SWITCH_ACTOR_FEATURE_COUNT + 6; - - /** - * The feature id for the 'Device Type' attribute. - * - * - * @generated - * @ordered - */ - int MSERVO__DEVICE_TYPE = MIN_SWITCH_ACTOR_FEATURE_COUNT + 7; + int DIMMABLE_ACTOR__TF_CONFIG = MTF_CONFIG_CONSUMER__TF_CONFIG; /** - * The feature id for the 'Velocity' attribute. + * The feature id for the 'Min Value' attribute. * * * @generated * @ordered */ - int MSERVO__VELOCITY = MIN_SWITCH_ACTOR_FEATURE_COUNT + 8; + int DIMMABLE_ACTOR__MIN_VALUE = MTF_CONFIG_CONSUMER_FEATURE_COUNT + 0; /** - * The feature id for the 'Acceleration' attribute. + * The feature id for the 'Max Value' attribute. * * * @generated * @ordered */ - int MSERVO__ACCELERATION = MIN_SWITCH_ACTOR_FEATURE_COUNT + 9; + int DIMMABLE_ACTOR__MAX_VALUE = MTF_CONFIG_CONSUMER_FEATURE_COUNT + 1; /** - * The feature id for the 'Pulse Width Min' attribute. + * The number of structural features of the 'Dimmable Actor' class. * * * @generated * @ordered */ - int MSERVO__PULSE_WIDTH_MIN = MIN_SWITCH_ACTOR_FEATURE_COUNT + 10; + int DIMMABLE_ACTOR_FEATURE_COUNT = MTF_CONFIG_CONSUMER_FEATURE_COUNT + 2; /** - * The feature id for the 'Pulse Width Max' attribute. + * The operation id for the 'Dimm' operation. * * * @generated * @ordered */ - int MSERVO__PULSE_WIDTH_MAX = MIN_SWITCH_ACTOR_FEATURE_COUNT + 11; + int DIMMABLE_ACTOR___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS = MTF_CONFIG_CONSUMER_OPERATION_COUNT + 0; /** - * The feature id for the 'Period' attribute. + * The number of operations of the 'Dimmable Actor' class. * * * @generated * @ordered */ - int MSERVO__PERIOD = MIN_SWITCH_ACTOR_FEATURE_COUNT + 12; + int DIMMABLE_ACTOR_OPERATION_COUNT = MTF_CONFIG_CONSUMER_OPERATION_COUNT + 1; /** - * The feature id for the 'Output Voltage' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.SetPointActor Set Point Actor}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.SetPointActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getSetPointActor() * @generated - * @ordered */ - int MSERVO__OUTPUT_VOLTAGE = MIN_SWITCH_ACTOR_FEATURE_COUNT + 13; + int SET_POINT_ACTOR = 26; /** - * The feature id for the 'Servo Current Position' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MSERVO__SERVO_CURRENT_POSITION = MIN_SWITCH_ACTOR_FEATURE_COUNT + 14; + int SET_POINT_ACTOR__TF_CONFIG = DIMMABLE_ACTOR__TF_CONFIG; /** - * The feature id for the 'Servo Destination Position' attribute. + * The feature id for the 'Min Value' attribute. * * * @generated * @ordered */ - int MSERVO__SERVO_DESTINATION_POSITION = MIN_SWITCH_ACTOR_FEATURE_COUNT + 15; + int SET_POINT_ACTOR__MIN_VALUE = DIMMABLE_ACTOR__MIN_VALUE; /** - * The number of structural features of the 'MServo' class. + * The feature id for the 'Max Value' attribute. * * * @generated * @ordered */ - int MSERVO_FEATURE_COUNT = MIN_SWITCH_ACTOR_FEATURE_COUNT + 16; + int SET_POINT_ACTOR__MAX_VALUE = DIMMABLE_ACTOR__MAX_VALUE; /** - * The operation id for the 'Turn Switch' operation. + * The feature id for the 'Percent Value' attribute. * * * @generated * @ordered */ - int MSERVO___TURN_SWITCH__ONOFFVALUE = MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; + int SET_POINT_ACTOR__PERCENT_VALUE = DIMMABLE_ACTOR_FEATURE_COUNT + 0; /** - * The operation id for the 'Fetch Switch State' operation. + * The number of structural features of the 'Set Point Actor' class. * * * @generated * @ordered */ - int MSERVO___FETCH_SWITCH_STATE = MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE; + int SET_POINT_ACTOR_FEATURE_COUNT = DIMMABLE_ACTOR_FEATURE_COUNT + 1; /** - * The operation id for the 'Enable' operation. + * The operation id for the 'Dimm' operation. * * * @generated * @ordered */ - int MSERVO___ENABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 1; + int SET_POINT_ACTOR___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS = DIMMABLE_ACTOR___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS; /** - * The operation id for the 'Disable' operation. + * The operation id for the 'Set Value' operation. * * * @generated * @ordered */ - int MSERVO___DISABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 2; + int SET_POINT_ACTOR___SET_VALUE__BIGDECIMAL_DEVICEOPTIONS = DIMMABLE_ACTOR_OPERATION_COUNT + 0; /** - * The operation id for the 'Init' operation. + * The operation id for the 'Set Value' operation. * * * @generated * @ordered */ - int MSERVO___INIT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 3; + int SET_POINT_ACTOR___SET_VALUE__PERCENTTYPE_DEVICEOPTIONS = DIMMABLE_ACTOR_OPERATION_COUNT + 1; /** - * The number of operations of the 'MServo' class. + * The number of operations of the 'Set Point Actor' class. * * * @generated * @ordered */ - int MSERVO_OPERATION_COUNT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 4; + int SET_POINT_ACTOR_OPERATION_COUNT = DIMMABLE_ACTOR_OPERATION_COUNT + 2; /** - * The feature id for the 'Switch State' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl MBricklet Dual Button}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletDualButton() * @generated - * @ordered */ - int MBRICK_DC__SWITCH_STATE = MIN_SWITCH_ACTOR__SWITCH_STATE; + int MBRICKLET_DUAL_BUTTON = 27; /** * The feature id for the 'Logger' attribute. @@ -2087,7 +2181,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICK_DC__LOGGER = MIN_SWITCH_ACTOR_FEATURE_COUNT + 0; + int MBRICKLET_DUAL_BUTTON__LOGGER = MDEVICE__LOGGER; /** * The feature id for the 'Uid' attribute. @@ -2096,7 +2190,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICK_DC__UID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 1; + int MBRICKLET_DUAL_BUTTON__UID = MDEVICE__UID; /** * The feature id for the 'Poll' attribute. @@ -2105,7 +2199,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICK_DC__POLL = MIN_SWITCH_ACTOR_FEATURE_COUNT + 2; + int MBRICKLET_DUAL_BUTTON__POLL = MDEVICE__POLL; /** * The feature id for the 'Enabled A' attribute. @@ -2114,7 +2208,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICK_DC__ENABLED_A = MIN_SWITCH_ACTOR_FEATURE_COUNT + 3; + int MBRICKLET_DUAL_BUTTON__ENABLED_A = MDEVICE__ENABLED_A; /** * The feature id for the 'Tinkerforge Device' attribute. @@ -2123,7 +2217,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICK_DC__TINKERFORGE_DEVICE = MIN_SWITCH_ACTOR_FEATURE_COUNT + 4; + int MBRICKLET_DUAL_BUTTON__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** * The feature id for the 'Ip Connection' attribute. @@ -2132,7 +2226,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICK_DC__IP_CONNECTION = MIN_SWITCH_ACTOR_FEATURE_COUNT + 5; + int MBRICKLET_DUAL_BUTTON__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** * The feature id for the 'Connected Uid' attribute. @@ -2141,7 +2235,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICK_DC__CONNECTED_UID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 6; + int MBRICKLET_DUAL_BUTTON__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** * The feature id for the 'Position' attribute. @@ -2150,7 +2244,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICK_DC__POSITION = MIN_SWITCH_ACTOR_FEATURE_COUNT + 7; + int MBRICKLET_DUAL_BUTTON__POSITION = MDEVICE__POSITION; /** * The feature id for the 'Device Identifier' attribute. @@ -2159,7 +2253,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICK_DC__DEVICE_IDENTIFIER = MIN_SWITCH_ACTOR_FEATURE_COUNT + 8; + int MBRICKLET_DUAL_BUTTON__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** * The feature id for the 'Name' attribute. @@ -2168,7 +2262,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICK_DC__NAME = MIN_SWITCH_ACTOR_FEATURE_COUNT + 9; + int MBRICKLET_DUAL_BUTTON__NAME = MDEVICE__NAME; /** * The feature id for the 'Brickd' container reference. @@ -2177,313 +2271,316 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICK_DC__BRICKD = MIN_SWITCH_ACTOR_FEATURE_COUNT + 10; + int MBRICKLET_DUAL_BUTTON__BRICKD = MDEVICE__BRICKD; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Msubdevices' containment reference list. * * * @generated * @ordered */ - int MBRICK_DC__TF_CONFIG = MIN_SWITCH_ACTOR_FEATURE_COUNT + 11; + int MBRICKLET_DUAL_BUTTON__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Device Type' attribute. + * The number of structural features of the 'MBricklet Dual Button' class. * * * @generated * @ordered */ - int MBRICK_DC__DEVICE_TYPE = MIN_SWITCH_ACTOR_FEATURE_COUNT + 12; + int MBRICKLET_DUAL_BUTTON_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Velocity' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICK_DC__VELOCITY = MIN_SWITCH_ACTOR_FEATURE_COUNT + 13; + int MBRICKLET_DUAL_BUTTON___INIT = MDEVICE___INIT; /** - * The feature id for the 'Current Velocity' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICK_DC__CURRENT_VELOCITY = MIN_SWITCH_ACTOR_FEATURE_COUNT + 14; + int MBRICKLET_DUAL_BUTTON___ENABLE = MDEVICE___ENABLE; /** - * The feature id for the 'Acceleration' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICK_DC__ACCELERATION = MIN_SWITCH_ACTOR_FEATURE_COUNT + 15; + int MBRICKLET_DUAL_BUTTON___DISABLE = MDEVICE___DISABLE; /** - * The feature id for the 'Pwm Frequency' attribute. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int MBRICK_DC__PWM_FREQUENCY = MIN_SWITCH_ACTOR_FEATURE_COUNT + 16; + int MBRICKLET_DUAL_BUTTON___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Drive Mode' attribute. + * The number of operations of the 'MBricklet Dual Button' class. * * * @generated * @ordered */ - int MBRICK_DC__DRIVE_MODE = MIN_SWITCH_ACTOR_FEATURE_COUNT + 17; + int MBRICKLET_DUAL_BUTTON_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Switch On Velocity' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonDevice Dual Button Device}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonDevice + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualButtonDevice() * @generated - * @ordered */ - int MBRICK_DC__SWITCH_ON_VELOCITY = MIN_SWITCH_ACTOR_FEATURE_COUNT + 18; + int DUAL_BUTTON_DEVICE = 28; /** - * The number of structural features of the 'MBrick DC' class. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICK_DC_FEATURE_COUNT = MIN_SWITCH_ACTOR_FEATURE_COUNT + 19; + int DUAL_BUTTON_DEVICE__LOGGER = MSUB_DEVICE__LOGGER; /** - * The operation id for the 'Turn Switch' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICK_DC___TURN_SWITCH__ONOFFVALUE = MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; + int DUAL_BUTTON_DEVICE__UID = MSUB_DEVICE__UID; /** - * The operation id for the 'Fetch Switch State' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICK_DC___FETCH_SWITCH_STATE = MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE; + int DUAL_BUTTON_DEVICE__POLL = MSUB_DEVICE__POLL; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICK_DC___ENABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 1; + int DUAL_BUTTON_DEVICE__ENABLED_A = MSUB_DEVICE__ENABLED_A; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MBRICK_DC___DISABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 2; + int DUAL_BUTTON_DEVICE__SUB_ID = MSUB_DEVICE__SUB_ID; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICK_DC___INIT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 3; + int DUAL_BUTTON_DEVICE__MBRICK = MSUB_DEVICE__MBRICK; /** - * The number of operations of the 'MBrick DC' class. + * The number of structural features of the 'Dual Button Device' class. * * * @generated * @ordered */ - int MBRICK_DC_OPERATION_COUNT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 4; + int DUAL_BUTTON_DEVICE_FEATURE_COUNT = MSUB_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Logger' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__LOGGER = MDEVICE__LOGGER; + int DUAL_BUTTON_DEVICE___INIT = MSUB_DEVICE___INIT; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__UID = MDEVICE__UID; + int DUAL_BUTTON_DEVICE___ENABLE = MSUB_DEVICE___ENABLE; /** - * The feature id for the 'Poll' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__POLL = MDEVICE__POLL; + int DUAL_BUTTON_DEVICE___DISABLE = MSUB_DEVICE___DISABLE; /** - * The feature id for the 'Enabled A' attribute. + * The number of operations of the 'Dual Button Device' class. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__ENABLED_A = MDEVICE__ENABLED_A; + int DUAL_BUTTON_DEVICE_OPERATION_COUNT = MSUB_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftButtonImpl Dual Button Left Button}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftButtonImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualButtonLeftButton() * @generated - * @ordered */ - int MDUAL_RELAY_BRICKLET__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int DUAL_BUTTON_LEFT_BUTTON = 29; /** - * The feature id for the 'Ip Connection' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int DUAL_BUTTON_LEFT_BUTTON__LOGGER = DUAL_BUTTON_DEVICE__LOGGER; /** - * The feature id for the 'Connected Uid' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int DUAL_BUTTON_LEFT_BUTTON__UID = DUAL_BUTTON_DEVICE__UID; /** - * The feature id for the 'Position' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__POSITION = MDEVICE__POSITION; + int DUAL_BUTTON_LEFT_BUTTON__POLL = DUAL_BUTTON_DEVICE__POLL; /** - * The feature id for the 'Device Identifier' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int DUAL_BUTTON_LEFT_BUTTON__ENABLED_A = DUAL_BUTTON_DEVICE__ENABLED_A; /** - * The feature id for the 'Name' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__NAME = MDEVICE__NAME; + int DUAL_BUTTON_LEFT_BUTTON__SUB_ID = DUAL_BUTTON_DEVICE__SUB_ID; /** - * The feature id for the 'Brickd' container reference. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__BRICKD = MDEVICE__BRICKD; + int DUAL_BUTTON_LEFT_BUTTON__MBRICK = DUAL_BUTTON_DEVICE__MBRICK; /** - * The feature id for the 'Msubdevices' containment reference list. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; + int DUAL_BUTTON_LEFT_BUTTON__SENSOR_VALUE = DUAL_BUTTON_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Device Type' attribute. + * The number of structural features of the 'Dual Button Left Button' class. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 1; + int DUAL_BUTTON_LEFT_BUTTON_FEATURE_COUNT = DUAL_BUTTON_DEVICE_FEATURE_COUNT + 1; /** - * The number of structural features of the 'MDual Relay Bricklet' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 2; + int DUAL_BUTTON_LEFT_BUTTON___INIT = DUAL_BUTTON_DEVICE___INIT; /** - * The operation id for the 'Init' operation. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET___INIT = MDEVICE___INIT; + int DUAL_BUTTON_LEFT_BUTTON___ENABLE = DUAL_BUTTON_DEVICE___ENABLE; /** - * The operation id for the 'Enable' operation. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET___ENABLE = MDEVICE___ENABLE; + int DUAL_BUTTON_LEFT_BUTTON___DISABLE = DUAL_BUTTON_DEVICE___DISABLE; /** - * The operation id for the 'Disable' operation. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET___DISABLE = MDEVICE___DISABLE; + int DUAL_BUTTON_LEFT_BUTTON___FETCH_SENSOR_VALUE = DUAL_BUTTON_DEVICE_OPERATION_COUNT + 0; /** - * The operation id for the 'Init Sub Devices' operation. + * The number of operations of the 'Dual Button Left Button' class. * * * @generated * @ordered */ - int MDUAL_RELAY_BRICKLET___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; + int DUAL_BUTTON_LEFT_BUTTON_OPERATION_COUNT = DUAL_BUTTON_DEVICE_OPERATION_COUNT + 1; /** - * The number of operations of the 'MDual Relay Bricklet' class. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightButtonImpl Dual Button Right Button}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightButtonImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualButtonRightButton() * @generated - * @ordered */ - int MDUAL_RELAY_BRICKLET_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; + int DUAL_BUTTON_RIGHT_BUTTON = 30; /** * The feature id for the 'Logger' attribute. @@ -2492,7 +2589,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__LOGGER = MDEVICE__LOGGER; + int DUAL_BUTTON_RIGHT_BUTTON__LOGGER = DUAL_BUTTON_DEVICE__LOGGER; /** * The feature id for the 'Uid' attribute. @@ -2501,7 +2598,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__UID = MDEVICE__UID; + int DUAL_BUTTON_RIGHT_BUTTON__UID = DUAL_BUTTON_DEVICE__UID; /** * The feature id for the 'Poll' attribute. @@ -2510,7 +2607,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__POLL = MDEVICE__POLL; + int DUAL_BUTTON_RIGHT_BUTTON__POLL = DUAL_BUTTON_DEVICE__POLL; /** * The feature id for the 'Enabled A' attribute. @@ -2519,529 +2616,514 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__ENABLED_A = MDEVICE__ENABLED_A; - - /** - * The feature id for the 'Tinkerforge Device' attribute. - * - * - * @generated - * @ordered - */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; - - /** - * The feature id for the 'Ip Connection' attribute. - * - * - * @generated - * @ordered - */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int DUAL_BUTTON_RIGHT_BUTTON__ENABLED_A = DUAL_BUTTON_DEVICE__ENABLED_A; /** - * The feature id for the 'Connected Uid' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int DUAL_BUTTON_RIGHT_BUTTON__SUB_ID = DUAL_BUTTON_DEVICE__SUB_ID; /** - * The feature id for the 'Position' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__POSITION = MDEVICE__POSITION; + int DUAL_BUTTON_RIGHT_BUTTON__MBRICK = DUAL_BUTTON_DEVICE__MBRICK; /** - * The feature id for the 'Device Identifier' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int DUAL_BUTTON_RIGHT_BUTTON__SENSOR_VALUE = DUAL_BUTTON_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Name' attribute. + * The number of structural features of the 'Dual Button Right Button' class. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__NAME = MDEVICE__NAME; + int DUAL_BUTTON_RIGHT_BUTTON_FEATURE_COUNT = DUAL_BUTTON_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Brickd' container reference. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__BRICKD = MDEVICE__BRICKD; + int DUAL_BUTTON_RIGHT_BUTTON___INIT = DUAL_BUTTON_DEVICE___INIT; /** - * The feature id for the 'Msubdevices' containment reference list. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; + int DUAL_BUTTON_RIGHT_BUTTON___ENABLE = DUAL_BUTTON_DEVICE___ENABLE; /** - * The number of structural features of the 'MIndustrial Quad Relay Bricklet' class. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 1; + int DUAL_BUTTON_RIGHT_BUTTON___DISABLE = DUAL_BUTTON_DEVICE___DISABLE; /** - * The operation id for the 'Init' operation. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET___INIT = MDEVICE___INIT; + int DUAL_BUTTON_RIGHT_BUTTON___FETCH_SENSOR_VALUE = DUAL_BUTTON_DEVICE_OPERATION_COUNT + 0; /** - * The operation id for the 'Enable' operation. + * The number of operations of the 'Dual Button Right Button' class. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET___ENABLE = MDEVICE___ENABLE; + int DUAL_BUTTON_RIGHT_BUTTON_OPERATION_COUNT = DUAL_BUTTON_DEVICE_OPERATION_COUNT + 1; /** - * The operation id for the 'Disable' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftLedImpl Dual Button Left Led}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftLedImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualButtonLeftLed() * @generated - * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET___DISABLE = MDEVICE___DISABLE; + int DUAL_BUTTON_LEFT_LED = 31; /** - * The operation id for the 'Init Sub Devices' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; + int DUAL_BUTTON_LEFT_LED__LOGGER = DUAL_BUTTON_DEVICE__LOGGER; /** - * The number of operations of the 'MIndustrial Quad Relay Bricklet' class. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_BRICKLET_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; + int DUAL_BUTTON_LEFT_LED__UID = DUAL_BUTTON_DEVICE__UID; /** - * The feature id for the 'Switch State' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY__SWITCH_STATE = MIN_SWITCH_ACTOR__SWITCH_STATE; + int DUAL_BUTTON_LEFT_LED__POLL = DUAL_BUTTON_DEVICE__POLL; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY__LOGGER = MIN_SWITCH_ACTOR_FEATURE_COUNT + 0; + int DUAL_BUTTON_LEFT_LED__ENABLED_A = DUAL_BUTTON_DEVICE__ENABLED_A; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY__UID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 1; + int DUAL_BUTTON_LEFT_LED__SUB_ID = DUAL_BUTTON_DEVICE__SUB_ID; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY__POLL = MIN_SWITCH_ACTOR_FEATURE_COUNT + 2; + int DUAL_BUTTON_LEFT_LED__MBRICK = DUAL_BUTTON_DEVICE__MBRICK; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Digital State' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY__ENABLED_A = MIN_SWITCH_ACTOR_FEATURE_COUNT + 3; + int DUAL_BUTTON_LEFT_LED__DIGITAL_STATE = DUAL_BUTTON_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Sub Id' attribute. + * The number of structural features of the 'Dual Button Left Led' class. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY__SUB_ID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 4; + int DUAL_BUTTON_LEFT_LED_FEATURE_COUNT = DUAL_BUTTON_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Mbrick' container reference. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY__MBRICK = MIN_SWITCH_ACTOR_FEATURE_COUNT + 5; + int DUAL_BUTTON_LEFT_LED___INIT = DUAL_BUTTON_DEVICE___INIT; /** - * The feature id for the 'Device Type' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY__DEVICE_TYPE = MIN_SWITCH_ACTOR_FEATURE_COUNT + 6; + int DUAL_BUTTON_LEFT_LED___ENABLE = DUAL_BUTTON_DEVICE___ENABLE; /** - * The number of structural features of the 'MIndustrial Quad Relay' class. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_FEATURE_COUNT = MIN_SWITCH_ACTOR_FEATURE_COUNT + 7; + int DUAL_BUTTON_LEFT_LED___DISABLE = DUAL_BUTTON_DEVICE___DISABLE; /** - * The operation id for the 'Turn Switch' operation. + * The operation id for the 'Turn Digital' operation. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY___TURN_SWITCH__ONOFFVALUE = MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; + int DUAL_BUTTON_LEFT_LED___TURN_DIGITAL__HIGHLOWVALUE = DUAL_BUTTON_DEVICE_OPERATION_COUNT + 0; /** - * The operation id for the 'Fetch Switch State' operation. + * The operation id for the 'Fetch Digital Value' operation. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY___FETCH_SWITCH_STATE = MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE; + int DUAL_BUTTON_LEFT_LED___FETCH_DIGITAL_VALUE = DUAL_BUTTON_DEVICE_OPERATION_COUNT + 1; /** - * The operation id for the 'Init' operation. + * The number of operations of the 'Dual Button Left Led' class. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY___INIT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 0; + int DUAL_BUTTON_LEFT_LED_OPERATION_COUNT = DUAL_BUTTON_DEVICE_OPERATION_COUNT + 2; /** - * The operation id for the 'Enable' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightLedImpl Dual Button Right Led}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightLedImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualButtonRightLed() * @generated - * @ordered */ - int MINDUSTRIAL_QUAD_RELAY___ENABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 1; + int DUAL_BUTTON_RIGHT_LED = 32; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY___DISABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 2; + int DUAL_BUTTON_RIGHT_LED__LOGGER = DUAL_BUTTON_DEVICE__LOGGER; /** - * The number of operations of the 'MIndustrial Quad Relay' class. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_QUAD_RELAY_OPERATION_COUNT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 3; + int DUAL_BUTTON_RIGHT_LED__UID = DUAL_BUTTON_DEVICE__UID; /** - * The feature id for the 'Msubdevices' containment reference list. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__MSUBDEVICES = MSUB_DEVICE_HOLDER__MSUBDEVICES; + int DUAL_BUTTON_RIGHT_LED__POLL = DUAL_BUTTON_DEVICE__POLL; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__LOGGER = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 0; + int DUAL_BUTTON_RIGHT_LED__ENABLED_A = DUAL_BUTTON_DEVICE__ENABLED_A; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__UID = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 1; + int DUAL_BUTTON_RIGHT_LED__SUB_ID = DUAL_BUTTON_DEVICE__SUB_ID; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__POLL = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 2; + int DUAL_BUTTON_RIGHT_LED__MBRICK = DUAL_BUTTON_DEVICE__MBRICK; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Digital State' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__ENABLED_A = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 3; + int DUAL_BUTTON_RIGHT_LED__DIGITAL_STATE = DUAL_BUTTON_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The number of structural features of the 'Dual Button Right Led' class. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__TINKERFORGE_DEVICE = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 4; + int DUAL_BUTTON_RIGHT_LED_FEATURE_COUNT = DUAL_BUTTON_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Ip Connection' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__IP_CONNECTION = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 5; + int DUAL_BUTTON_RIGHT_LED___INIT = DUAL_BUTTON_DEVICE___INIT; /** - * The feature id for the 'Connected Uid' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__CONNECTED_UID = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 6; + int DUAL_BUTTON_RIGHT_LED___ENABLE = DUAL_BUTTON_DEVICE___ENABLE; /** - * The feature id for the 'Position' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__POSITION = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 7; + int DUAL_BUTTON_RIGHT_LED___DISABLE = DUAL_BUTTON_DEVICE___DISABLE; /** - * The feature id for the 'Device Identifier' attribute. + * The operation id for the 'Turn Digital' operation. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__DEVICE_IDENTIFIER = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 8; + int DUAL_BUTTON_RIGHT_LED___TURN_DIGITAL__HIGHLOWVALUE = DUAL_BUTTON_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Name' attribute. + * The operation id for the 'Fetch Digital Value' operation. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__NAME = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 9; + int DUAL_BUTTON_RIGHT_LED___FETCH_DIGITAL_VALUE = DUAL_BUTTON_DEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Brickd' container reference. + * The number of operations of the 'Dual Button Right Led' class. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__BRICKD = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 10; + int DUAL_BUTTON_RIGHT_LED_OPERATION_COUNT = DUAL_BUTTON_DEVICE_OPERATION_COUNT + 2; /** - * The feature id for the 'Debounce Period' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl MBricklet Linear Poti}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletLinearPoti() * @generated - * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__DEBOUNCE_PERIOD = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 11; + int MBRICKLET_LINEAR_POTI = 33; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__TF_CONFIG = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 12; + int MBRICKLET_LINEAR_POTI__LOGGER = MDEVICE__LOGGER; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__DEVICE_TYPE = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 13; + int MBRICKLET_LINEAR_POTI__UID = MDEVICE__UID; /** - * The number of structural features of the 'MBricklet Industrial Digital In4' class. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4_FEATURE_COUNT = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 14; + int MBRICKLET_LINEAR_POTI__POLL = MDEVICE__POLL; /** - * The operation id for the 'Init Sub Devices' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4___INIT_SUB_DEVICES = MSUB_DEVICE_HOLDER___INIT_SUB_DEVICES; + int MBRICKLET_LINEAR_POTI__ENABLED_A = MDEVICE__ENABLED_A; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4___INIT = MSUB_DEVICE_HOLDER_OPERATION_COUNT + 0; + int MBRICKLET_LINEAR_POTI__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4___ENABLE = MSUB_DEVICE_HOLDER_OPERATION_COUNT + 1; + int MBRICKLET_LINEAR_POTI__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4___DISABLE = MSUB_DEVICE_HOLDER_OPERATION_COUNT + 2; + int MBRICKLET_LINEAR_POTI__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The number of operations of the 'MBricklet Industrial Digital In4' class. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_IN4_OPERATION_COUNT = MSUB_DEVICE_HOLDER_OPERATION_COUNT + 3; + int MBRICKLET_LINEAR_POTI__POSITION = MDEVICE__POSITION; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN__LOGGER = MSUB_DEVICE__LOGGER; + int MBRICKLET_LINEAR_POTI__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN__UID = MSUB_DEVICE__UID; + int MBRICKLET_LINEAR_POTI__NAME = MDEVICE__NAME; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN__POLL = MSUB_DEVICE__POLL; + int MBRICKLET_LINEAR_POTI__BRICKD = MDEVICE__BRICKD; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN__ENABLED_A = MSUB_DEVICE__ENABLED_A; + int MBRICKLET_LINEAR_POTI__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN__SUB_ID = MSUB_DEVICE__SUB_ID; + int MBRICKLET_LINEAR_POTI__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN__MBRICK = MSUB_DEVICE__MBRICK; + int MBRICKLET_LINEAR_POTI__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN__SENSOR_VALUE = MSUB_DEVICE_FEATURE_COUNT + 0; + int MBRICKLET_LINEAR_POTI__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; /** - * The number of structural features of the 'MIndustrial Digital In' class. + * The number of structural features of the 'MBricklet Linear Poti' class. * * * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN_FEATURE_COUNT = MSUB_DEVICE_FEATURE_COUNT + 1; + int MBRICKLET_LINEAR_POTI_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 4; /** * The operation id for the 'Init' operation. @@ -3050,7 +3132,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN___INIT = MSUB_DEVICE___INIT; + int MBRICKLET_LINEAR_POTI___INIT = MDEVICE___INIT; /** * The operation id for the 'Enable' operation. @@ -3059,7 +3141,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN___ENABLE = MSUB_DEVICE___ENABLE; + int MBRICKLET_LINEAR_POTI___ENABLE = MDEVICE___ENABLE; /** * The operation id for the 'Disable' operation. @@ -3068,7 +3150,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN___DISABLE = MSUB_DEVICE___DISABLE; + int MBRICKLET_LINEAR_POTI___DISABLE = MDEVICE___DISABLE; /** * The operation id for the 'Fetch Sensor Value' operation. @@ -3077,26 +3159,26 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN___FETCH_SENSOR_VALUE = MSUB_DEVICE_OPERATION_COUNT + 0; + int MBRICKLET_LINEAR_POTI___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; /** - * The number of operations of the 'MIndustrial Digital In' class. + * The number of operations of the 'MBricklet Linear Poti' class. * * * @generated * @ordered */ - int MINDUSTRIAL_DIGITAL_IN_OPERATION_COUNT = MSUB_DEVICE_OPERATION_COUNT + 1; + int MBRICKLET_LINEAR_POTI_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalOut4Impl MBricklet Industrial Digital Out4}' class. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl MBricklet Joystick}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalOut4Impl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletIndustrialDigitalOut4() + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletJoystick() * @generated */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4 = 27; + int MBRICKLET_JOYSTICK = 34; /** * The feature id for the 'Logger' attribute. @@ -3105,7 +3187,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__LOGGER = MDEVICE__LOGGER; + int MBRICKLET_JOYSTICK__LOGGER = MDEVICE__LOGGER; /** * The feature id for the 'Uid' attribute. @@ -3114,7 +3196,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__UID = MDEVICE__UID; + int MBRICKLET_JOYSTICK__UID = MDEVICE__UID; /** * The feature id for the 'Poll' attribute. @@ -3123,7 +3205,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__POLL = MDEVICE__POLL; + int MBRICKLET_JOYSTICK__POLL = MDEVICE__POLL; /** * The feature id for the 'Enabled A' attribute. @@ -3132,7 +3214,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__ENABLED_A = MDEVICE__ENABLED_A; + int MBRICKLET_JOYSTICK__ENABLED_A = MDEVICE__ENABLED_A; /** * The feature id for the 'Tinkerforge Device' attribute. @@ -3141,7 +3223,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MBRICKLET_JOYSTICK__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** * The feature id for the 'Ip Connection' attribute. @@ -3150,7 +3232,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MBRICKLET_JOYSTICK__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** * The feature id for the 'Connected Uid' attribute. @@ -3159,7 +3241,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MBRICKLET_JOYSTICK__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** * The feature id for the 'Position' attribute. @@ -3168,7 +3250,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__POSITION = MDEVICE__POSITION; + int MBRICKLET_JOYSTICK__POSITION = MDEVICE__POSITION; /** * The feature id for the 'Device Identifier' attribute. @@ -3177,7 +3259,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICKLET_JOYSTICK__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** * The feature id for the 'Name' attribute. @@ -3186,7 +3268,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__NAME = MDEVICE__NAME; + int MBRICKLET_JOYSTICK__NAME = MDEVICE__NAME; /** * The feature id for the 'Brickd' container reference. @@ -3195,7 +3277,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_JOYSTICK__BRICKD = MDEVICE__BRICKD; /** * The feature id for the 'Msubdevices' containment reference list. @@ -3204,1628 +3286,1622 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_JOYSTICK__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** - * The number of structural features of the 'MBricklet Industrial Digital Out4' class. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 1; + int MBRICKLET_JOYSTICK__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 1; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4___INIT = MDEVICE___INIT; + int MBRICKLET_JOYSTICK__TF_CONFIG = MDEVICE_FEATURE_COUNT + 2; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4___ENABLE = MDEVICE___ENABLE; + int MBRICKLET_JOYSTICK__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; /** - * The operation id for the 'Disable' operation. + * The number of structural features of the 'MBricklet Joystick' class. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4___DISABLE = MDEVICE___DISABLE; + int MBRICKLET_JOYSTICK_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 4; /** - * The operation id for the 'Init Sub Devices' operation. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; + int MBRICKLET_JOYSTICK___INIT = MDEVICE___INIT; /** - * The number of operations of the 'MBricklet Industrial Digital Out4' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; + int MBRICKLET_JOYSTICK___ENABLE = MDEVICE___ENABLE; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor Digital Actor}' class. + * The operation id for the 'Disable' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActor() * @generated + * @ordered */ - int DIGITAL_ACTOR = 29; + int MBRICKLET_JOYSTICK___DISABLE = MDEVICE___DISABLE; /** - * The feature id for the 'Digital State' attribute. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR__DIGITAL_STATE = 0; + int MBRICKLET_JOYSTICK___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The number of structural features of the 'Digital Actor' class. + * The number of operations of the 'MBricklet Joystick' class. * * * @generated * @ordered */ - int DIGITAL_ACTOR_FEATURE_COUNT = 1; + int MBRICKLET_JOYSTICK_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The operation id for the 'Turn Digital' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.JoystickDevice Joystick Device}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.JoystickDevice + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getJoystickDevice() * @generated - * @ordered */ - int DIGITAL_ACTOR___TURN_DIGITAL__HIGHLOWVALUE = 0; + int JOYSTICK_DEVICE = 35; /** - * The operation id for the 'Fetch Digital Value' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR___FETCH_DIGITAL_VALUE = 1; + int JOYSTICK_DEVICE__LOGGER = MSUB_DEVICE__LOGGER; /** - * The number of operations of the 'Digital Actor' class. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_OPERATION_COUNT = 2; + int JOYSTICK_DEVICE__UID = MSUB_DEVICE__UID; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorDigitalOut4Impl Digital Actor Digital Out4}' class. + * The feature id for the 'Poll' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorDigitalOut4Impl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActorDigitalOut4() * @generated + * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4 = 28; + int JOYSTICK_DEVICE__POLL = MSUB_DEVICE__POLL; /** - * The feature id for the 'Digital State' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4__DIGITAL_STATE = DIGITAL_ACTOR__DIGITAL_STATE; + int JOYSTICK_DEVICE__ENABLED_A = MSUB_DEVICE__ENABLED_A; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4__LOGGER = DIGITAL_ACTOR_FEATURE_COUNT + 0; + int JOYSTICK_DEVICE__SUB_ID = MSUB_DEVICE__SUB_ID; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4__UID = DIGITAL_ACTOR_FEATURE_COUNT + 1; + int JOYSTICK_DEVICE__MBRICK = MSUB_DEVICE__MBRICK; /** - * The feature id for the 'Poll' attribute. + * The number of structural features of the 'Joystick Device' class. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4__POLL = DIGITAL_ACTOR_FEATURE_COUNT + 2; + int JOYSTICK_DEVICE_FEATURE_COUNT = MSUB_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Enabled A' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4__ENABLED_A = DIGITAL_ACTOR_FEATURE_COUNT + 3; + int JOYSTICK_DEVICE___INIT = MSUB_DEVICE___INIT; /** - * The feature id for the 'Sub Id' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4__SUB_ID = DIGITAL_ACTOR_FEATURE_COUNT + 4; + int JOYSTICK_DEVICE___ENABLE = MSUB_DEVICE___ENABLE; /** - * The feature id for the 'Mbrick' container reference. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4__MBRICK = DIGITAL_ACTOR_FEATURE_COUNT + 5; + int JOYSTICK_DEVICE___DISABLE = MSUB_DEVICE___DISABLE; /** - * The feature id for the 'Pin' attribute. + * The number of operations of the 'Joystick Device' class. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4__PIN = DIGITAL_ACTOR_FEATURE_COUNT + 6; + int JOYSTICK_DEVICE_OPERATION_COUNT = MSUB_DEVICE_OPERATION_COUNT + 0; /** - * The number of structural features of the 'Digital Actor Digital Out4' class. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl Joystick XPosition}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getJoystickXPosition() * @generated - * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4_FEATURE_COUNT = DIGITAL_ACTOR_FEATURE_COUNT + 7; + int JOYSTICK_XPOSITION = 36; /** - * The operation id for the 'Turn Digital' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4___TURN_DIGITAL__HIGHLOWVALUE = DIGITAL_ACTOR___TURN_DIGITAL__HIGHLOWVALUE; + int JOYSTICK_XPOSITION__LOGGER = JOYSTICK_DEVICE__LOGGER; /** - * The operation id for the 'Fetch Digital Value' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4___FETCH_DIGITAL_VALUE = DIGITAL_ACTOR___FETCH_DIGITAL_VALUE; + int JOYSTICK_XPOSITION__UID = JOYSTICK_DEVICE__UID; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4___INIT = DIGITAL_ACTOR_OPERATION_COUNT + 0; + int JOYSTICK_XPOSITION__POLL = JOYSTICK_DEVICE__POLL; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4___ENABLE = DIGITAL_ACTOR_OPERATION_COUNT + 1; + int JOYSTICK_XPOSITION__ENABLED_A = JOYSTICK_DEVICE__ENABLED_A; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4___DISABLE = DIGITAL_ACTOR_OPERATION_COUNT + 2; + int JOYSTICK_XPOSITION__SUB_ID = JOYSTICK_DEVICE__SUB_ID; /** - * The number of operations of the 'Digital Actor Digital Out4' class. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int DIGITAL_ACTOR_DIGITAL_OUT4_OPERATION_COUNT = DIGITAL_ACTOR_OPERATION_COUNT + 3; + int JOYSTICK_XPOSITION__MBRICK = JOYSTICK_DEVICE__MBRICK; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.NumberActor Number Actor}' class. + * The feature id for the 'Sensor Value' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.NumberActor - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getNumberActor() * @generated + * @ordered */ - int NUMBER_ACTOR = 30; + int JOYSTICK_XPOSITION__SENSOR_VALUE = JOYSTICK_DEVICE_FEATURE_COUNT + 0; /** - * The number of structural features of the 'Number Actor' class. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int NUMBER_ACTOR_FEATURE_COUNT = 0; + int JOYSTICK_XPOSITION__DEVICE_TYPE = JOYSTICK_DEVICE_FEATURE_COUNT + 1; /** - * The operation id for the 'Set Number' operation. + * The number of structural features of the 'Joystick XPosition' class. * * * @generated * @ordered */ - int NUMBER_ACTOR___SET_NUMBER__BIGDECIMAL = 0; + int JOYSTICK_XPOSITION_FEATURE_COUNT = JOYSTICK_DEVICE_FEATURE_COUNT + 2; /** - * The number of operations of the 'Number Actor' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int NUMBER_ACTOR_OPERATION_COUNT = 1; + int JOYSTICK_XPOSITION___INIT = JOYSTICK_DEVICE___INIT; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.ColorActor Color Actor}' class. + * The operation id for the 'Enable' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.ColorActor - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getColorActor() * @generated + * @ordered */ - int COLOR_ACTOR = 32; + int JOYSTICK_XPOSITION___ENABLE = JOYSTICK_DEVICE___ENABLE; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLEDStripImpl MBricklet LED Strip}' class. + * The operation id for the 'Disable' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLEDStripImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletLEDStrip() * @generated + * @ordered */ - int MBRICKLET_LED_STRIP = 33; + int JOYSTICK_XPOSITION___DISABLE = JOYSTICK_DEVICE___DISABLE; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletSegmentDisplay4x7Impl MBricklet Segment Display4x7}' class. + * The operation id for the 'Fetch Sensor Value' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletSegmentDisplay4x7Impl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletSegmentDisplay4x7() * @generated + * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7 = 31; + int JOYSTICK_XPOSITION___FETCH_SENSOR_VALUE = JOYSTICK_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Logger' attribute. + * The number of operations of the 'Joystick XPosition' class. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7__LOGGER = NUMBER_ACTOR_FEATURE_COUNT + 0; + int JOYSTICK_XPOSITION_OPERATION_COUNT = JOYSTICK_DEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Uid' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl Joystick YPosition}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getJoystickYPosition() * @generated - * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7__UID = NUMBER_ACTOR_FEATURE_COUNT + 1; + int JOYSTICK_YPOSITION = 37; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7__POLL = NUMBER_ACTOR_FEATURE_COUNT + 2; + int JOYSTICK_YPOSITION__LOGGER = JOYSTICK_DEVICE__LOGGER; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7__ENABLED_A = NUMBER_ACTOR_FEATURE_COUNT + 3; + int JOYSTICK_YPOSITION__UID = JOYSTICK_DEVICE__UID; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7__TINKERFORGE_DEVICE = NUMBER_ACTOR_FEATURE_COUNT + 4; + int JOYSTICK_YPOSITION__POLL = JOYSTICK_DEVICE__POLL; /** - * The feature id for the 'Ip Connection' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7__IP_CONNECTION = NUMBER_ACTOR_FEATURE_COUNT + 5; + int JOYSTICK_YPOSITION__ENABLED_A = JOYSTICK_DEVICE__ENABLED_A; /** - * The feature id for the 'Connected Uid' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7__CONNECTED_UID = NUMBER_ACTOR_FEATURE_COUNT + 6; + int JOYSTICK_YPOSITION__SUB_ID = JOYSTICK_DEVICE__SUB_ID; /** - * The feature id for the 'Position' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7__POSITION = NUMBER_ACTOR_FEATURE_COUNT + 7; + int JOYSTICK_YPOSITION__MBRICK = JOYSTICK_DEVICE__MBRICK; /** - * The feature id for the 'Device Identifier' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7__DEVICE_IDENTIFIER = NUMBER_ACTOR_FEATURE_COUNT + 8; + int JOYSTICK_YPOSITION__SENSOR_VALUE = JOYSTICK_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Name' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7__NAME = NUMBER_ACTOR_FEATURE_COUNT + 9; + int JOYSTICK_YPOSITION__DEVICE_TYPE = JOYSTICK_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Brickd' container reference. + * The number of structural features of the 'Joystick YPosition' class. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7__BRICKD = NUMBER_ACTOR_FEATURE_COUNT + 10; + int JOYSTICK_YPOSITION_FEATURE_COUNT = JOYSTICK_DEVICE_FEATURE_COUNT + 2; /** - * The number of structural features of the 'MBricklet Segment Display4x7' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7_FEATURE_COUNT = NUMBER_ACTOR_FEATURE_COUNT + 11; + int JOYSTICK_YPOSITION___INIT = JOYSTICK_DEVICE___INIT; /** - * The operation id for the 'Set Number' operation. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7___SET_NUMBER__BIGDECIMAL = NUMBER_ACTOR___SET_NUMBER__BIGDECIMAL; + int JOYSTICK_YPOSITION___ENABLE = JOYSTICK_DEVICE___ENABLE; /** - * The operation id for the 'Init' operation. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7___INIT = NUMBER_ACTOR_OPERATION_COUNT + 0; + int JOYSTICK_YPOSITION___DISABLE = JOYSTICK_DEVICE___DISABLE; /** - * The operation id for the 'Enable' operation. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7___ENABLE = NUMBER_ACTOR_OPERATION_COUNT + 1; + int JOYSTICK_YPOSITION___FETCH_SENSOR_VALUE = JOYSTICK_DEVICE_OPERATION_COUNT + 0; /** - * The operation id for the 'Disable' operation. + * The number of operations of the 'Joystick YPosition' class. * * * @generated * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7___DISABLE = NUMBER_ACTOR_OPERATION_COUNT + 2; + int JOYSTICK_YPOSITION_OPERATION_COUNT = JOYSTICK_DEVICE_OPERATION_COUNT + 1; /** - * The number of operations of the 'MBricklet Segment Display4x7' class. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl Joystick Button}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getJoystickButton() * @generated - * @ordered */ - int MBRICKLET_SEGMENT_DISPLAY4X7_OPERATION_COUNT = NUMBER_ACTOR_OPERATION_COUNT + 3; + int JOYSTICK_BUTTON = 38; /** - * The number of structural features of the 'Color Actor' class. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int COLOR_ACTOR_FEATURE_COUNT = 0; + int JOYSTICK_BUTTON__LOGGER = JOYSTICK_DEVICE__LOGGER; /** - * The operation id for the 'Set Color' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int COLOR_ACTOR___SET_COLOR__HSBTYPE_DEVICEOPTIONS = 0; + int JOYSTICK_BUTTON__UID = JOYSTICK_DEVICE__UID; /** - * The number of operations of the 'Color Actor' class. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int COLOR_ACTOR_OPERATION_COUNT = 1; + int JOYSTICK_BUTTON__POLL = JOYSTICK_DEVICE__POLL; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP__LOGGER = COLOR_ACTOR_FEATURE_COUNT + 0; + int JOYSTICK_BUTTON__ENABLED_A = JOYSTICK_DEVICE__ENABLED_A; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP__UID = COLOR_ACTOR_FEATURE_COUNT + 1; + int JOYSTICK_BUTTON__SUB_ID = JOYSTICK_DEVICE__SUB_ID; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP__POLL = COLOR_ACTOR_FEATURE_COUNT + 2; + int JOYSTICK_BUTTON__MBRICK = JOYSTICK_DEVICE__MBRICK; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP__ENABLED_A = COLOR_ACTOR_FEATURE_COUNT + 3; + int JOYSTICK_BUTTON__SENSOR_VALUE = JOYSTICK_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP__TINKERFORGE_DEVICE = COLOR_ACTOR_FEATURE_COUNT + 4; + int JOYSTICK_BUTTON__DEVICE_TYPE = JOYSTICK_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Ip Connection' attribute. + * The number of structural features of the 'Joystick Button' class. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP__IP_CONNECTION = COLOR_ACTOR_FEATURE_COUNT + 5; + int JOYSTICK_BUTTON_FEATURE_COUNT = JOYSTICK_DEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Connected Uid' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP__CONNECTED_UID = COLOR_ACTOR_FEATURE_COUNT + 6; + int JOYSTICK_BUTTON___INIT = JOYSTICK_DEVICE___INIT; /** - * The feature id for the 'Position' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP__POSITION = COLOR_ACTOR_FEATURE_COUNT + 7; + int JOYSTICK_BUTTON___ENABLE = JOYSTICK_DEVICE___ENABLE; /** - * The feature id for the 'Device Identifier' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP__DEVICE_IDENTIFIER = COLOR_ACTOR_FEATURE_COUNT + 8; + int JOYSTICK_BUTTON___DISABLE = JOYSTICK_DEVICE___DISABLE; /** - * The feature id for the 'Name' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP__NAME = COLOR_ACTOR_FEATURE_COUNT + 9; + int JOYSTICK_BUTTON___FETCH_SENSOR_VALUE = JOYSTICK_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Brickd' container reference. + * The number of operations of the 'Joystick Button' class. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP__BRICKD = COLOR_ACTOR_FEATURE_COUNT + 10; + int JOYSTICK_BUTTON_OPERATION_COUNT = JOYSTICK_DEVICE_OPERATION_COUNT + 1; /** - * The number of structural features of the 'MBricklet LED Strip' class. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP_FEATURE_COUNT = COLOR_ACTOR_FEATURE_COUNT + 11; + int MBRICK_SERVO__LOGGER = MDEVICE__LOGGER; /** - * The operation id for the 'Set Color' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP___SET_COLOR__HSBTYPE_DEVICEOPTIONS = COLOR_ACTOR___SET_COLOR__HSBTYPE_DEVICEOPTIONS; + int MBRICK_SERVO__UID = MDEVICE__UID; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP___INIT = COLOR_ACTOR_OPERATION_COUNT + 0; + int MBRICK_SERVO__POLL = MDEVICE__POLL; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP___ENABLE = COLOR_ACTOR_OPERATION_COUNT + 1; + int MBRICK_SERVO__ENABLED_A = MDEVICE__ENABLED_A; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP___DISABLE = COLOR_ACTOR_OPERATION_COUNT + 2; + int MBRICK_SERVO__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The number of operations of the 'MBricklet LED Strip' class. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int MBRICKLET_LED_STRIP_OPERATION_COUNT = COLOR_ACTOR_OPERATION_COUNT + 3; + int MBRICK_SERVO__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorIO16Impl Digital Actor IO16}' class. + * The feature id for the 'Connected Uid' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorIO16Impl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActorIO16() * @generated + * @ordered */ - int DIGITAL_ACTOR_IO16 = 34; + int MBRICK_SERVO__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The feature id for the 'Digital State' attribute. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__DIGITAL_STATE = DIGITAL_ACTOR__DIGITAL_STATE; + int MBRICK_SERVO__POSITION = MDEVICE__POSITION; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__LOGGER = DIGITAL_ACTOR_FEATURE_COUNT + 0; + int MBRICK_SERVO__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__UID = DIGITAL_ACTOR_FEATURE_COUNT + 1; + int MBRICK_SERVO__NAME = MDEVICE__NAME; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__POLL = DIGITAL_ACTOR_FEATURE_COUNT + 2; + int MBRICK_SERVO__BRICKD = MDEVICE__BRICKD; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Msubdevices' containment reference list. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__ENABLED_A = DIGITAL_ACTOR_FEATURE_COUNT + 3; + int MBRICK_SERVO__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__SUB_ID = DIGITAL_ACTOR_FEATURE_COUNT + 4; + int MBRICK_SERVO__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Mbrick' container reference. + * The number of structural features of the 'MBrick Servo' class. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__MBRICK = DIGITAL_ACTOR_FEATURE_COUNT + 5; + int MBRICK_SERVO_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Generic Device Id' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__GENERIC_DEVICE_ID = DIGITAL_ACTOR_FEATURE_COUNT + 6; + int MBRICK_SERVO___ENABLE = MDEVICE___ENABLE; /** - * The feature id for the 'Tf Config' containment reference. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__TF_CONFIG = DIGITAL_ACTOR_FEATURE_COUNT + 7; + int MBRICK_SERVO___DISABLE = MDEVICE___DISABLE; /** - * The feature id for the 'Device Type' attribute. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__DEVICE_TYPE = DIGITAL_ACTOR_FEATURE_COUNT + 8; + int MBRICK_SERVO___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Port' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__PORT = DIGITAL_ACTOR_FEATURE_COUNT + 9; + int MBRICK_SERVO___INIT = MDEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Pin' attribute. + * The number of operations of the 'MBrick Servo' class. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__PIN = DIGITAL_ACTOR_FEATURE_COUNT + 10; + int MBRICK_SERVO_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; /** - * The feature id for the 'Default State' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__DEFAULT_STATE = DIGITAL_ACTOR_FEATURE_COUNT + 11; + int MSERVO__SENSOR_VALUE = MSENSOR__SENSOR_VALUE; /** - * The feature id for the 'Keep On Reconnect' attribute. + * The feature id for the 'Switch State' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16__KEEP_ON_RECONNECT = DIGITAL_ACTOR_FEATURE_COUNT + 12; + int MSERVO__SWITCH_STATE = MSENSOR_FEATURE_COUNT + 0; /** - * The number of structural features of the 'Digital Actor IO16' class. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16_FEATURE_COUNT = DIGITAL_ACTOR_FEATURE_COUNT + 13; + int MSERVO__LOGGER = MSENSOR_FEATURE_COUNT + 1; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16___INIT = DIGITAL_ACTOR_OPERATION_COUNT + 0; + int MSERVO__UID = MSENSOR_FEATURE_COUNT + 2; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16___ENABLE = DIGITAL_ACTOR_OPERATION_COUNT + 1; + int MSERVO__POLL = MSENSOR_FEATURE_COUNT + 3; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16___DISABLE = DIGITAL_ACTOR_OPERATION_COUNT + 2; + int MSERVO__ENABLED_A = MSENSOR_FEATURE_COUNT + 4; /** - * The operation id for the 'Turn Digital' operation. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16___TURN_DIGITAL__HIGHLOWVALUE = DIGITAL_ACTOR_OPERATION_COUNT + 3; + int MSERVO__SUB_ID = MSENSOR_FEATURE_COUNT + 5; /** - * The operation id for the 'Fetch Digital Value' operation. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16___FETCH_DIGITAL_VALUE = DIGITAL_ACTOR_OPERATION_COUNT + 4; + int MSERVO__MBRICK = MSENSOR_FEATURE_COUNT + 6; /** - * The number of operations of the 'Digital Actor IO16' class. + * The feature id for the 'Direction' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO16_OPERATION_COUNT = DIGITAL_ACTOR_OPERATION_COUNT + 5; + int MSERVO__DIRECTION = MSENSOR_FEATURE_COUNT + 7; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_IO16__LOGGER = MDEVICE__LOGGER; + int MSERVO__TF_CONFIG = MSENSOR_FEATURE_COUNT + 8; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Min Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__UID = MDEVICE__UID; + int MSERVO__MIN_VALUE = MSENSOR_FEATURE_COUNT + 9; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Max Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__POLL = MDEVICE__POLL; + int MSERVO__MAX_VALUE = MSENSOR_FEATURE_COUNT + 10; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Percent Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__ENABLED_A = MDEVICE__ENABLED_A; + int MSERVO__PERCENT_VALUE = MSENSOR_FEATURE_COUNT + 11; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MSERVO__DEVICE_TYPE = MSENSOR_FEATURE_COUNT + 12; /** - * The feature id for the 'Ip Connection' attribute. + * The feature id for the 'Velocity' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MSERVO__VELOCITY = MSENSOR_FEATURE_COUNT + 13; /** - * The feature id for the 'Connected Uid' attribute. + * The feature id for the 'Acceleration' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MSERVO__ACCELERATION = MSENSOR_FEATURE_COUNT + 14; /** - * The feature id for the 'Position' attribute. + * The feature id for the 'Max Position' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__POSITION = MDEVICE__POSITION; + int MSERVO__MAX_POSITION = MSENSOR_FEATURE_COUNT + 15; /** - * The feature id for the 'Device Identifier' attribute. + * The feature id for the 'Min Position' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MSERVO__MIN_POSITION = MSENSOR_FEATURE_COUNT + 16; /** - * The feature id for the 'Name' attribute. + * The feature id for the 'Pulse Width Min' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__NAME = MDEVICE__NAME; + int MSERVO__PULSE_WIDTH_MIN = MSENSOR_FEATURE_COUNT + 17; /** - * The feature id for the 'Brickd' container reference. + * The feature id for the 'Pulse Width Max' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__BRICKD = MDEVICE__BRICKD; + int MSERVO__PULSE_WIDTH_MAX = MSENSOR_FEATURE_COUNT + 18; /** - * The feature id for the 'Msubdevices' containment reference list. + * The feature id for the 'Period' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; + int MSERVO__PERIOD = MSENSOR_FEATURE_COUNT + 19; /** - * The feature id for the 'Debounce Period' attribute. + * The feature id for the 'Output Voltage' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__DEBOUNCE_PERIOD = MDEVICE_FEATURE_COUNT + 1; + int MSERVO__OUTPUT_VOLTAGE = MSENSOR_FEATURE_COUNT + 20; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Target Position' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO16__TF_CONFIG = MDEVICE_FEATURE_COUNT + 2; + int MSERVO__TARGET_POSITION = MSENSOR_FEATURE_COUNT + 21; /** - * The feature id for the 'Device Type' attribute. + * The number of structural features of the 'MServo' class. * * * @generated * @ordered */ - int MBRICKLET_IO16__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; + int MSERVO_FEATURE_COUNT = MSENSOR_FEATURE_COUNT + 22; /** - * The number of structural features of the 'MBricklet IO16' class. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MBRICKLET_IO16_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 4; + int MSERVO___FETCH_SENSOR_VALUE = MSENSOR___FETCH_SENSOR_VALUE; /** - * The operation id for the 'Init' operation. + * The operation id for the 'Fetch Switch State' operation. * * * @generated * @ordered */ - int MBRICKLET_IO16___INIT = MDEVICE___INIT; + int MSERVO___FETCH_SWITCH_STATE = MSENSOR_OPERATION_COUNT + 0; /** - * The operation id for the 'Enable' operation. + * The operation id for the 'Turn Switch' operation. * * * @generated * @ordered */ - int MBRICKLET_IO16___ENABLE = MDEVICE___ENABLE; + int MSERVO___TURN_SWITCH__ONOFFVALUE_DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 1; /** - * The operation id for the 'Disable' operation. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_IO16___DISABLE = MDEVICE___DISABLE; + int MSERVO___ENABLE = MSENSOR_OPERATION_COUNT + 3; /** - * The operation id for the 'Init Sub Devices' operation. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_IO16___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; + int MSERVO___DISABLE = MSENSOR_OPERATION_COUNT + 4; /** - * The number of operations of the 'MBricklet IO16' class. + * The operation id for the 'Move' operation. * * * @generated * @ordered */ - int MBRICKLET_IO16_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; + int MSERVO___MOVE__UPDOWNTYPE_DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 5; /** - * The feature id for the 'Logger' attribute. + * The operation id for the 'Stop' operation. * * * @generated * @ordered */ - int DIGITAL_SENSOR__LOGGER = IO_DEVICE__LOGGER; + int MSERVO___STOP = MSENSOR_OPERATION_COUNT + 6; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Moveon' operation. * * * @generated * @ordered */ - int DIGITAL_SENSOR__UID = IO_DEVICE__UID; + int MSERVO___MOVEON__DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 7; /** - * The feature id for the 'Poll' attribute. + * The operation id for the 'Dimm' operation. * * * @generated * @ordered */ - int DIGITAL_SENSOR__POLL = IO_DEVICE__POLL; + int MSERVO___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 8; /** - * The feature id for the 'Enabled A' attribute. + * The operation id for the 'Set Value' operation. * * * @generated * @ordered */ - int DIGITAL_SENSOR__ENABLED_A = IO_DEVICE__ENABLED_A; + int MSERVO___SET_VALUE__BIGDECIMAL_DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 9; /** - * The feature id for the 'Sub Id' attribute. + * The operation id for the 'Set Value' operation. * * * @generated * @ordered */ - int DIGITAL_SENSOR__SUB_ID = IO_DEVICE__SUB_ID; + int MSERVO___SET_VALUE__PERCENTTYPE_DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 10; /** - * The feature id for the 'Mbrick' container reference. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int DIGITAL_SENSOR__MBRICK = IO_DEVICE__MBRICK; + int MSERVO___INIT = MSENSOR_OPERATION_COUNT + 11; /** - * The feature id for the 'Generic Device Id' attribute. + * The operation id for the 'Set Point' operation. * * * @generated * @ordered */ - int DIGITAL_SENSOR__GENERIC_DEVICE_ID = IO_DEVICE__GENERIC_DEVICE_ID; + int MSERVO___SET_POINT__SHORT_INT_INT = MSENSOR_OPERATION_COUNT + 12; /** - * The feature id for the 'Sensor Value' attribute. + * The number of operations of the 'MServo' class. * * * @generated * @ordered */ - int DIGITAL_SENSOR__SENSOR_VALUE = IO_DEVICE_FEATURE_COUNT + 0; + int MSERVO_OPERATION_COUNT = MSENSOR_OPERATION_COUNT + 13; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR__TF_CONFIG = IO_DEVICE_FEATURE_COUNT + 1; + int MBRICK_DC__SENSOR_VALUE = MSENSOR__SENSOR_VALUE; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Switch State' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR__DEVICE_TYPE = IO_DEVICE_FEATURE_COUNT + 2; + int MBRICK_DC__SWITCH_STATE = MSENSOR_FEATURE_COUNT + 0; /** - * The feature id for the 'Pull Up Resistor Enabled' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR__PULL_UP_RESISTOR_ENABLED = IO_DEVICE_FEATURE_COUNT + 3; + int MBRICK_DC__LOGGER = MSENSOR_FEATURE_COUNT + 1; /** - * The feature id for the 'Port' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR__PORT = IO_DEVICE_FEATURE_COUNT + 4; + int MBRICK_DC__UID = MSENSOR_FEATURE_COUNT + 2; /** - * The feature id for the 'Pin' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR__PIN = IO_DEVICE_FEATURE_COUNT + 5; + int MBRICK_DC__POLL = MSENSOR_FEATURE_COUNT + 3; /** - * The number of structural features of the 'Digital Sensor' class. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR_FEATURE_COUNT = IO_DEVICE_FEATURE_COUNT + 6; + int MBRICK_DC__ENABLED_A = MSENSOR_FEATURE_COUNT + 4; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR___INIT = IO_DEVICE___INIT; + int MBRICK_DC__TINKERFORGE_DEVICE = MSENSOR_FEATURE_COUNT + 5; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR___ENABLE = IO_DEVICE___ENABLE; + int MBRICK_DC__IP_CONNECTION = MSENSOR_FEATURE_COUNT + 6; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR___DISABLE = IO_DEVICE___DISABLE; + int MBRICK_DC__CONNECTED_UID = MSENSOR_FEATURE_COUNT + 7; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR___FETCH_SENSOR_VALUE = IO_DEVICE_OPERATION_COUNT + 0; + int MBRICK_DC__POSITION = MSENSOR_FEATURE_COUNT + 8; /** - * The number of operations of the 'Digital Sensor' class. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR_OPERATION_COUNT = IO_DEVICE_OPERATION_COUNT + 1; + int MBRICK_DC__DEVICE_IDENTIFIER = MSENSOR_FEATURE_COUNT + 9; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIO4Impl MBricklet IO4}' class. + * The feature id for the 'Name' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIO4Impl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletIO4() * @generated + * @ordered */ - int MBRICKLET_IO4 = 37; + int MBRICK_DC__NAME = MSENSOR_FEATURE_COUNT + 10; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int MBRICKLET_IO4__LOGGER = MDEVICE__LOGGER; + int MBRICK_DC__BRICKD = MSENSOR_FEATURE_COUNT + 11; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Direction' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__UID = MDEVICE__UID; + int MBRICK_DC__DIRECTION = MSENSOR_FEATURE_COUNT + 12; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_IO4__POLL = MDEVICE__POLL; + int MBRICK_DC__TF_CONFIG = MSENSOR_FEATURE_COUNT + 13; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Min Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__ENABLED_A = MDEVICE__ENABLED_A; + int MBRICK_DC__MIN_VALUE = MSENSOR_FEATURE_COUNT + 14; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The feature id for the 'Max Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MBRICK_DC__MAX_VALUE = MSENSOR_FEATURE_COUNT + 15; /** - * The feature id for the 'Ip Connection' attribute. + * The feature id for the 'Percent Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MBRICK_DC__PERCENT_VALUE = MSENSOR_FEATURE_COUNT + 16; /** - * The feature id for the 'Connected Uid' attribute. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MBRICK_DC__CALLBACK_PERIOD = MSENSOR_FEATURE_COUNT + 17; /** - * The feature id for the 'Position' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__POSITION = MDEVICE__POSITION; + int MBRICK_DC__DEVICE_TYPE = MSENSOR_FEATURE_COUNT + 18; /** - * The feature id for the 'Device Identifier' attribute. + * The feature id for the 'Threshold' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICK_DC__THRESHOLD = MSENSOR_FEATURE_COUNT + 19; /** - * The feature id for the 'Name' attribute. + * The feature id for the 'Max Velocity' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__NAME = MDEVICE__NAME; + int MBRICK_DC__MAX_VELOCITY = MSENSOR_FEATURE_COUNT + 20; /** - * The feature id for the 'Brickd' container reference. + * The feature id for the 'Min Velocity' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__BRICKD = MDEVICE__BRICKD; + int MBRICK_DC__MIN_VELOCITY = MSENSOR_FEATURE_COUNT + 21; /** - * The feature id for the 'Msubdevices' containment reference list. + * The feature id for the 'Velocity' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; + int MBRICK_DC__VELOCITY = MSENSOR_FEATURE_COUNT + 22; /** - * The feature id for the 'Debounce Period' attribute. + * The feature id for the 'Targetvelocity' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__DEBOUNCE_PERIOD = MDEVICE_FEATURE_COUNT + 1; + int MBRICK_DC__TARGETVELOCITY = MSENSOR_FEATURE_COUNT + 23; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Current Velocity' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__TF_CONFIG = MDEVICE_FEATURE_COUNT + 2; + int MBRICK_DC__CURRENT_VELOCITY = MSENSOR_FEATURE_COUNT + 24; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Acceleration' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; + int MBRICK_DC__ACCELERATION = MSENSOR_FEATURE_COUNT + 25; /** - * The number of structural features of the 'MBricklet IO4' class. + * The feature id for the 'Pwm Frequency' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 4; + int MBRICK_DC__PWM_FREQUENCY = MSENSOR_FEATURE_COUNT + 26; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Drive Mode' attribute. * * * @generated * @ordered */ - int MBRICKLET_IO4___INIT = MDEVICE___INIT; + int MBRICK_DC__DRIVE_MODE = MSENSOR_FEATURE_COUNT + 27; /** - * The operation id for the 'Enable' operation. + * The number of structural features of the 'MBrick DC' class. * * * @generated * @ordered */ - int MBRICKLET_IO4___ENABLE = MDEVICE___ENABLE; + int MBRICK_DC_FEATURE_COUNT = MSENSOR_FEATURE_COUNT + 28; /** - * The operation id for the 'Disable' operation. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MBRICKLET_IO4___DISABLE = MDEVICE___DISABLE; + int MBRICK_DC___FETCH_SENSOR_VALUE = MSENSOR___FETCH_SENSOR_VALUE; /** - * The operation id for the 'Init Sub Devices' operation. + * The operation id for the 'Fetch Switch State' operation. * * * @generated * @ordered */ - int MBRICKLET_IO4___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; + int MBRICK_DC___FETCH_SWITCH_STATE = MSENSOR_OPERATION_COUNT + 0; /** - * The number of operations of the 'MBricklet IO4' class. + * The operation id for the 'Turn Switch' operation. * * * @generated * @ordered */ - int MBRICKLET_IO4_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; + int MBRICK_DC___TURN_SWITCH__ONOFFVALUE_DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 1; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.IO4Device IO4 Device}' class. + * The operation id for the 'Enable' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.IO4Device - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIO4Device() * @generated + * @ordered */ - int IO4_DEVICE = 38; + int MBRICK_DC___ENABLE = MSENSOR_OPERATION_COUNT + 3; /** - * The feature id for the 'Logger' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int IO4_DEVICE__LOGGER = MSUB_DEVICE__LOGGER; + int MBRICK_DC___DISABLE = MSENSOR_OPERATION_COUNT + 4; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Move' operation. * * * @generated * @ordered */ - int IO4_DEVICE__UID = MSUB_DEVICE__UID; + int MBRICK_DC___MOVE__UPDOWNTYPE_DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 5; /** - * The feature id for the 'Poll' attribute. + * The operation id for the 'Stop' operation. * * * @generated * @ordered */ - int IO4_DEVICE__POLL = MSUB_DEVICE__POLL; + int MBRICK_DC___STOP = MSENSOR_OPERATION_COUNT + 6; /** - * The feature id for the 'Enabled A' attribute. + * The operation id for the 'Moveon' operation. * * * @generated * @ordered */ - int IO4_DEVICE__ENABLED_A = MSUB_DEVICE__ENABLED_A; + int MBRICK_DC___MOVEON__DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 7; /** - * The feature id for the 'Sub Id' attribute. + * The operation id for the 'Dimm' operation. * * * @generated * @ordered */ - int IO4_DEVICE__SUB_ID = MSUB_DEVICE__SUB_ID; + int MBRICK_DC___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 8; /** - * The feature id for the 'Mbrick' container reference. + * The operation id for the 'Set Value' operation. * * * @generated * @ordered */ - int IO4_DEVICE__MBRICK = MSUB_DEVICE__MBRICK; + int MBRICK_DC___SET_VALUE__BIGDECIMAL_DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 9; /** - * The feature id for the 'Generic Device Id' attribute. + * The operation id for the 'Set Value' operation. * * * @generated * @ordered */ - int IO4_DEVICE__GENERIC_DEVICE_ID = MSUB_DEVICE_FEATURE_COUNT + 0; + int MBRICK_DC___SET_VALUE__PERCENTTYPE_DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 10; /** - * The number of structural features of the 'IO4 Device' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int IO4_DEVICE_FEATURE_COUNT = MSUB_DEVICE_FEATURE_COUNT + 1; + int MBRICK_DC___INIT = MSENSOR_OPERATION_COUNT + 11; /** - * The operation id for the 'Init' operation. + * The operation id for the 'Set Speed' operation. * * * @generated * @ordered */ - int IO4_DEVICE___INIT = MSUB_DEVICE___INIT; + int MBRICK_DC___SET_SPEED__SHORT_INT_STRING = MSENSOR_OPERATION_COUNT + 12; /** - * The operation id for the 'Enable' operation. + * The number of operations of the 'MBrick DC' class. * * * @generated * @ordered */ - int IO4_DEVICE___ENABLE = MSUB_DEVICE___ENABLE; + int MBRICK_DC_OPERATION_COUNT = MSENSOR_OPERATION_COUNT + 13; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int IO4_DEVICE___DISABLE = MSUB_DEVICE___DISABLE; + int MDUAL_RELAY_BRICKLET__LOGGER = MDEVICE__LOGGER; /** - * The number of operations of the 'IO4 Device' class. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int IO4_DEVICE_OPERATION_COUNT = MSUB_DEVICE_OPERATION_COUNT + 0; + int MDUAL_RELAY_BRICKLET__UID = MDEVICE__UID; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DigitalSensorIO4Impl Digital Sensor IO4}' class. + * The feature id for the 'Poll' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.DigitalSensorIO4Impl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalSensorIO4() * @generated + * @ordered */ - int DIGITAL_SENSOR_IO4 = 39; + int MDUAL_RELAY_BRICKLET__POLL = MDEVICE__POLL; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__LOGGER = IO4_DEVICE__LOGGER; + int MDUAL_RELAY_BRICKLET__ENABLED_A = MDEVICE__ENABLED_A; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__UID = IO4_DEVICE__UID; + int MDUAL_RELAY_BRICKLET__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__POLL = IO4_DEVICE__POLL; + int MDUAL_RELAY_BRICKLET__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__ENABLED_A = IO4_DEVICE__ENABLED_A; + int MDUAL_RELAY_BRICKLET__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__SUB_ID = IO4_DEVICE__SUB_ID; + int MDUAL_RELAY_BRICKLET__POSITION = MDEVICE__POSITION; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__MBRICK = IO4_DEVICE__MBRICK; + int MDUAL_RELAY_BRICKLET__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The feature id for the 'Generic Device Id' attribute. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__GENERIC_DEVICE_ID = IO4_DEVICE__GENERIC_DEVICE_ID; + int MDUAL_RELAY_BRICKLET__NAME = MDEVICE__NAME; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__SENSOR_VALUE = IO4_DEVICE_FEATURE_COUNT + 0; + int MDUAL_RELAY_BRICKLET__BRICKD = MDEVICE__BRICKD; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Msubdevices' containment reference list. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__TF_CONFIG = IO4_DEVICE_FEATURE_COUNT + 1; + int MDUAL_RELAY_BRICKLET__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** * The feature id for the 'Device Type' attribute. @@ -4834,967 +4910,961 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__DEVICE_TYPE = IO4_DEVICE_FEATURE_COUNT + 2; + int MDUAL_RELAY_BRICKLET__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Pull Up Resistor Enabled' attribute. + * The number of structural features of the 'MDual Relay Bricklet' class. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__PULL_UP_RESISTOR_ENABLED = IO4_DEVICE_FEATURE_COUNT + 3; + int MDUAL_RELAY_BRICKLET_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Pin' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4__PIN = IO4_DEVICE_FEATURE_COUNT + 4; + int MDUAL_RELAY_BRICKLET___INIT = MDEVICE___INIT; /** - * The number of structural features of the 'Digital Sensor IO4' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4_FEATURE_COUNT = IO4_DEVICE_FEATURE_COUNT + 5; + int MDUAL_RELAY_BRICKLET___ENABLE = MDEVICE___ENABLE; /** - * The operation id for the 'Init' operation. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4___INIT = IO4_DEVICE___INIT; + int MDUAL_RELAY_BRICKLET___DISABLE = MDEVICE___DISABLE; /** - * The operation id for the 'Enable' operation. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4___ENABLE = IO4_DEVICE___ENABLE; + int MDUAL_RELAY_BRICKLET___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The operation id for the 'Disable' operation. + * The number of operations of the 'MDual Relay Bricklet' class. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4___DISABLE = IO4_DEVICE___DISABLE; + int MDUAL_RELAY_BRICKLET_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4___FETCH_SENSOR_VALUE = IO4_DEVICE_OPERATION_COUNT + 0; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__LOGGER = MDEVICE__LOGGER; /** - * The number of operations of the 'Digital Sensor IO4' class. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int DIGITAL_SENSOR_IO4_OPERATION_COUNT = IO4_DEVICE_OPERATION_COUNT + 1; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__UID = MDEVICE__UID; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorIO4Impl Digital Actor IO4}' class. + * The feature id for the 'Poll' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorIO4Impl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActorIO4() * @generated + * @ordered */ - int DIGITAL_ACTOR_IO4 = 40; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__POLL = MDEVICE__POLL; /** - * The feature id for the 'Digital State' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__DIGITAL_STATE = DIGITAL_ACTOR__DIGITAL_STATE; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__ENABLED_A = MDEVICE__ENABLED_A; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__LOGGER = DIGITAL_ACTOR_FEATURE_COUNT + 0; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__UID = DIGITAL_ACTOR_FEATURE_COUNT + 1; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__POLL = DIGITAL_ACTOR_FEATURE_COUNT + 2; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__ENABLED_A = DIGITAL_ACTOR_FEATURE_COUNT + 3; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__POSITION = MDEVICE__POSITION; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__SUB_ID = DIGITAL_ACTOR_FEATURE_COUNT + 4; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__MBRICK = DIGITAL_ACTOR_FEATURE_COUNT + 5; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__NAME = MDEVICE__NAME; /** - * The feature id for the 'Generic Device Id' attribute. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__GENERIC_DEVICE_ID = DIGITAL_ACTOR_FEATURE_COUNT + 6; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__BRICKD = MDEVICE__BRICKD; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Msubdevices' containment reference list. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__TF_CONFIG = DIGITAL_ACTOR_FEATURE_COUNT + 7; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Device Type' attribute. + * The number of structural features of the 'MIndustrial Quad Relay Bricklet' class. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__DEVICE_TYPE = DIGITAL_ACTOR_FEATURE_COUNT + 8; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Pin' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__PIN = DIGITAL_ACTOR_FEATURE_COUNT + 9; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET___INIT = MDEVICE___INIT; /** - * The feature id for the 'Default State' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__DEFAULT_STATE = DIGITAL_ACTOR_FEATURE_COUNT + 10; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET___ENABLE = MDEVICE___ENABLE; /** - * The feature id for the 'Keep On Reconnect' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4__KEEP_ON_RECONNECT = DIGITAL_ACTOR_FEATURE_COUNT + 11; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET___DISABLE = MDEVICE___DISABLE; /** - * The number of structural features of the 'Digital Actor IO4' class. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4_FEATURE_COUNT = DIGITAL_ACTOR_FEATURE_COUNT + 12; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The operation id for the 'Init' operation. + * The number of operations of the 'MIndustrial Quad Relay Bricklet' class. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4___INIT = DIGITAL_ACTOR_OPERATION_COUNT + 0; + int MINDUSTRIAL_QUAD_RELAY_BRICKLET_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Switch State' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4___ENABLE = DIGITAL_ACTOR_OPERATION_COUNT + 1; + int MINDUSTRIAL_QUAD_RELAY__SWITCH_STATE = MIN_SWITCH_ACTOR__SWITCH_STATE; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4___DISABLE = DIGITAL_ACTOR_OPERATION_COUNT + 2; + int MINDUSTRIAL_QUAD_RELAY__LOGGER = MIN_SWITCH_ACTOR_FEATURE_COUNT + 0; /** - * The operation id for the 'Turn Digital' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4___TURN_DIGITAL__HIGHLOWVALUE = DIGITAL_ACTOR_OPERATION_COUNT + 3; + int MINDUSTRIAL_QUAD_RELAY__UID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 1; /** - * The operation id for the 'Fetch Digital Value' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4___FETCH_DIGITAL_VALUE = DIGITAL_ACTOR_OPERATION_COUNT + 4; + int MINDUSTRIAL_QUAD_RELAY__POLL = MIN_SWITCH_ACTOR_FEATURE_COUNT + 2; /** - * The number of operations of the 'Digital Actor IO4' class. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int DIGITAL_ACTOR_IO4_OPERATION_COUNT = DIGITAL_ACTOR_OPERATION_COUNT + 5; + int MINDUSTRIAL_QUAD_RELAY__ENABLED_A = MIN_SWITCH_ACTOR_FEATURE_COUNT + 3; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMultiTouchImpl MBricklet Multi Touch}' class. + * The feature id for the 'Sub Id' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMultiTouchImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletMultiTouch() * @generated + * @ordered */ - int MBRICKLET_MULTI_TOUCH = 41; + int MINDUSTRIAL_QUAD_RELAY__SUB_ID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 4; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__LOGGER = MDEVICE__LOGGER; + int MINDUSTRIAL_QUAD_RELAY__MBRICK = MIN_SWITCH_ACTOR_FEATURE_COUNT + 5; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__UID = MDEVICE__UID; + int MINDUSTRIAL_QUAD_RELAY__DEVICE_TYPE = MIN_SWITCH_ACTOR_FEATURE_COUNT + 6; /** - * The feature id for the 'Poll' attribute. + * The number of structural features of the 'MIndustrial Quad Relay' class. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__POLL = MDEVICE__POLL; + int MINDUSTRIAL_QUAD_RELAY_FEATURE_COUNT = MIN_SWITCH_ACTOR_FEATURE_COUNT + 7; /** - * The feature id for the 'Enabled A' attribute. + * The operation id for the 'Fetch Switch State' operation. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__ENABLED_A = MDEVICE__ENABLED_A; + int MINDUSTRIAL_QUAD_RELAY___FETCH_SWITCH_STATE = MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The operation id for the 'Turn Switch' operation. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MINDUSTRIAL_QUAD_RELAY___TURN_SWITCH__ONOFFVALUE = MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; /** - * The feature id for the 'Ip Connection' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MINDUSTRIAL_QUAD_RELAY___INIT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 0; /** - * The feature id for the 'Connected Uid' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MINDUSTRIAL_QUAD_RELAY___ENABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 1; /** - * The feature id for the 'Position' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__POSITION = MDEVICE__POSITION; + int MINDUSTRIAL_QUAD_RELAY___DISABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 2; /** - * The feature id for the 'Device Identifier' attribute. + * The number of operations of the 'MIndustrial Quad Relay' class. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MINDUSTRIAL_QUAD_RELAY_OPERATION_COUNT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 3; /** - * The feature id for the 'Name' attribute. + * The feature id for the 'Msubdevices' containment reference list. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__NAME = MDEVICE__NAME; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__MSUBDEVICES = MSUB_DEVICE_HOLDER__MSUBDEVICES; /** - * The feature id for the 'Brickd' container reference. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__LOGGER = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 0; /** - * The feature id for the 'Msubdevices' containment reference list. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__UID = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 1; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__POLL = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 2; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 2; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__ENABLED_A = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 3; /** - * The feature id for the 'Recalibrate' attribute. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__RECALIBRATE = MDEVICE_FEATURE_COUNT + 3; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__TINKERFORGE_DEVICE = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 4; /** - * The feature id for the 'Sensitivity' attribute. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH__SENSITIVITY = MDEVICE_FEATURE_COUNT + 4; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__IP_CONNECTION = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 5; /** - * The number of structural features of the 'MBricklet Multi Touch' class. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 5; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__CONNECTED_UID = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 6; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH___INIT = MDEVICE___INIT; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__POSITION = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 7; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH___ENABLE = MDEVICE___ENABLE; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__DEVICE_IDENTIFIER = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 8; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH___DISABLE = MDEVICE___DISABLE; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__NAME = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 9; /** - * The operation id for the 'Init Sub Devices' operation. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__BRICKD = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 10; /** - * The number of operations of the 'MBricklet Multi Touch' class. + * The feature id for the 'Debounce Period' attribute. * * * @generated * @ordered */ - int MBRICKLET_MULTI_TOUCH_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__DEBOUNCE_PERIOD = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 11; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MultiTouchDeviceImpl Multi Touch Device}' class. + * The feature id for the 'Tf Config' containment reference. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MultiTouchDeviceImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMultiTouchDevice() * @generated + * @ordered */ - int MULTI_TOUCH_DEVICE = 42; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__TF_CONFIG = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 12; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE__LOGGER = MSUB_DEVICE__LOGGER; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4__DEVICE_TYPE = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 13; /** - * The feature id for the 'Uid' attribute. + * The number of structural features of the 'MBricklet Industrial Digital In4' class. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE__UID = MSUB_DEVICE__UID; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4_FEATURE_COUNT = MSUB_DEVICE_HOLDER_FEATURE_COUNT + 14; /** - * The feature id for the 'Poll' attribute. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE__POLL = MSUB_DEVICE__POLL; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4___INIT_SUB_DEVICES = MSUB_DEVICE_HOLDER___INIT_SUB_DEVICES; /** - * The feature id for the 'Enabled A' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE__ENABLED_A = MSUB_DEVICE__ENABLED_A; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4___INIT = MSUB_DEVICE_HOLDER_OPERATION_COUNT + 0; /** - * The feature id for the 'Sub Id' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE__SUB_ID = MSUB_DEVICE__SUB_ID; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4___ENABLE = MSUB_DEVICE_HOLDER_OPERATION_COUNT + 1; /** - * The feature id for the 'Mbrick' container reference. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE__MBRICK = MSUB_DEVICE__MBRICK; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4___DISABLE = MSUB_DEVICE_HOLDER_OPERATION_COUNT + 2; /** - * The feature id for the 'Sensor Value' attribute. + * The number of operations of the 'MBricklet Industrial Digital In4' class. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE__SENSOR_VALUE = MSUB_DEVICE_FEATURE_COUNT + 0; + int MBRICKLET_INDUSTRIAL_DIGITAL_IN4_OPERATION_COUNT = MSUB_DEVICE_HOLDER_OPERATION_COUNT + 3; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE__TF_CONFIG = MSUB_DEVICE_FEATURE_COUNT + 1; + int MINDUSTRIAL_DIGITAL_IN__LOGGER = MSUB_DEVICE__LOGGER; /** - * The feature id for the 'Pin' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE__PIN = MSUB_DEVICE_FEATURE_COUNT + 2; + int MINDUSTRIAL_DIGITAL_IN__UID = MSUB_DEVICE__UID; /** - * The feature id for the 'Disable Electrode' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE__DISABLE_ELECTRODE = MSUB_DEVICE_FEATURE_COUNT + 3; + int MINDUSTRIAL_DIGITAL_IN__POLL = MSUB_DEVICE__POLL; /** - * The number of structural features of the 'Multi Touch Device' class. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE_FEATURE_COUNT = MSUB_DEVICE_FEATURE_COUNT + 4; + int MINDUSTRIAL_DIGITAL_IN__ENABLED_A = MSUB_DEVICE__ENABLED_A; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE___INIT = MSUB_DEVICE___INIT; + int MINDUSTRIAL_DIGITAL_IN__SUB_ID = MSUB_DEVICE__SUB_ID; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE___ENABLE = MSUB_DEVICE___ENABLE; + int MINDUSTRIAL_DIGITAL_IN__MBRICK = MSUB_DEVICE__MBRICK; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE___DISABLE = MSUB_DEVICE___DISABLE; + int MINDUSTRIAL_DIGITAL_IN__SENSOR_VALUE = MSUB_DEVICE_FEATURE_COUNT + 0; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The number of structural features of the 'MIndustrial Digital In' class. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE___FETCH_SENSOR_VALUE = MSUB_DEVICE_OPERATION_COUNT + 0; + int MINDUSTRIAL_DIGITAL_IN_FEATURE_COUNT = MSUB_DEVICE_FEATURE_COUNT + 1; /** - * The number of operations of the 'Multi Touch Device' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE_OPERATION_COUNT = MSUB_DEVICE_OPERATION_COUNT + 1; + int MINDUSTRIAL_DIGITAL_IN___INIT = MSUB_DEVICE___INIT; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.ElectrodeImpl Electrode}' class. + * The operation id for the 'Enable' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.ElectrodeImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getElectrode() * @generated + * @ordered */ - int ELECTRODE = 43; + int MINDUSTRIAL_DIGITAL_IN___ENABLE = MSUB_DEVICE___ENABLE; /** - * The feature id for the 'Logger' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int ELECTRODE__LOGGER = MULTI_TOUCH_DEVICE__LOGGER; + int MINDUSTRIAL_DIGITAL_IN___DISABLE = MSUB_DEVICE___DISABLE; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int ELECTRODE__UID = MULTI_TOUCH_DEVICE__UID; + int MINDUSTRIAL_DIGITAL_IN___FETCH_SENSOR_VALUE = MSUB_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Poll' attribute. + * The number of operations of the 'MIndustrial Digital In' class. * * * @generated * @ordered */ - int ELECTRODE__POLL = MULTI_TOUCH_DEVICE__POLL; + int MINDUSTRIAL_DIGITAL_IN_OPERATION_COUNT = MSUB_DEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int ELECTRODE__ENABLED_A = MULTI_TOUCH_DEVICE__ENABLED_A; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__LOGGER = MDEVICE__LOGGER; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int ELECTRODE__SUB_ID = MULTI_TOUCH_DEVICE__SUB_ID; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__UID = MDEVICE__UID; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int ELECTRODE__MBRICK = MULTI_TOUCH_DEVICE__MBRICK; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__POLL = MDEVICE__POLL; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int ELECTRODE__SENSOR_VALUE = MULTI_TOUCH_DEVICE__SENSOR_VALUE; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__ENABLED_A = MDEVICE__ENABLED_A; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int ELECTRODE__TF_CONFIG = MULTI_TOUCH_DEVICE__TF_CONFIG; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The feature id for the 'Pin' attribute. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int ELECTRODE__PIN = MULTI_TOUCH_DEVICE__PIN; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The feature id for the 'Disable Electrode' attribute. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int ELECTRODE__DISABLE_ELECTRODE = MULTI_TOUCH_DEVICE__DISABLE_ELECTRODE; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int ELECTRODE__DEVICE_TYPE = MULTI_TOUCH_DEVICE_FEATURE_COUNT + 0; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__POSITION = MDEVICE__POSITION; /** - * The number of structural features of the 'Electrode' class. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int ELECTRODE_FEATURE_COUNT = MULTI_TOUCH_DEVICE_FEATURE_COUNT + 1; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int ELECTRODE___INIT = MULTI_TOUCH_DEVICE___INIT; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__NAME = MDEVICE__NAME; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int ELECTRODE___ENABLE = MULTI_TOUCH_DEVICE___ENABLE; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__BRICKD = MDEVICE__BRICKD; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Msubdevices' containment reference list. * * * @generated * @ordered */ - int ELECTRODE___DISABLE = MULTI_TOUCH_DEVICE___DISABLE; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The number of structural features of the 'MBricklet Industrial Digital Out4' class. * * * @generated * @ordered */ - int ELECTRODE___FETCH_SENSOR_VALUE = MULTI_TOUCH_DEVICE___FETCH_SENSOR_VALUE; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 1; /** - * The number of operations of the 'Electrode' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int ELECTRODE_OPERATION_COUNT = MULTI_TOUCH_DEVICE_OPERATION_COUNT + 0; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4___INIT = MDEVICE___INIT; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.ProximityImpl Proximity}' class. + * The operation id for the 'Enable' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.ProximityImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getProximity() * @generated + * @ordered */ - int PROXIMITY = 44; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4___ENABLE = MDEVICE___ENABLE; /** - * The feature id for the 'Logger' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int PROXIMITY__LOGGER = MULTI_TOUCH_DEVICE__LOGGER; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4___DISABLE = MDEVICE___DISABLE; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int PROXIMITY__UID = MULTI_TOUCH_DEVICE__UID; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Poll' attribute. + * The number of operations of the 'MBricklet Industrial Digital Out4' class. * * * @generated * @ordered */ - int PROXIMITY__POLL = MULTI_TOUCH_DEVICE__POLL; + int MBRICKLET_INDUSTRIAL_DIGITAL_OUT4_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Digital State' attribute. * * * @generated * @ordered */ - int PROXIMITY__ENABLED_A = MULTI_TOUCH_DEVICE__ENABLED_A; + int DIGITAL_ACTOR_DIGITAL_OUT4__DIGITAL_STATE = DIGITAL_ACTOR__DIGITAL_STATE; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int PROXIMITY__SUB_ID = MULTI_TOUCH_DEVICE__SUB_ID; + int DIGITAL_ACTOR_DIGITAL_OUT4__LOGGER = DIGITAL_ACTOR_FEATURE_COUNT + 0; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int PROXIMITY__MBRICK = MULTI_TOUCH_DEVICE__MBRICK; + int DIGITAL_ACTOR_DIGITAL_OUT4__UID = DIGITAL_ACTOR_FEATURE_COUNT + 1; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int PROXIMITY__SENSOR_VALUE = MULTI_TOUCH_DEVICE__SENSOR_VALUE; + int DIGITAL_ACTOR_DIGITAL_OUT4__POLL = DIGITAL_ACTOR_FEATURE_COUNT + 2; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int PROXIMITY__TF_CONFIG = MULTI_TOUCH_DEVICE__TF_CONFIG; + int DIGITAL_ACTOR_DIGITAL_OUT4__ENABLED_A = DIGITAL_ACTOR_FEATURE_COUNT + 3; /** - * The feature id for the 'Pin' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int PROXIMITY__PIN = MULTI_TOUCH_DEVICE__PIN; + int DIGITAL_ACTOR_DIGITAL_OUT4__SUB_ID = DIGITAL_ACTOR_FEATURE_COUNT + 4; /** - * The feature id for the 'Disable Electrode' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int PROXIMITY__DISABLE_ELECTRODE = MULTI_TOUCH_DEVICE__DISABLE_ELECTRODE; + int DIGITAL_ACTOR_DIGITAL_OUT4__MBRICK = DIGITAL_ACTOR_FEATURE_COUNT + 5; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Pin' attribute. * * * @generated * @ordered */ - int PROXIMITY__DEVICE_TYPE = MULTI_TOUCH_DEVICE_FEATURE_COUNT + 0; + int DIGITAL_ACTOR_DIGITAL_OUT4__PIN = DIGITAL_ACTOR_FEATURE_COUNT + 6; /** - * The number of structural features of the 'Proximity' class. + * The number of structural features of the 'Digital Actor Digital Out4' class. * * * @generated * @ordered */ - int PROXIMITY_FEATURE_COUNT = MULTI_TOUCH_DEVICE_FEATURE_COUNT + 1; + int DIGITAL_ACTOR_DIGITAL_OUT4_FEATURE_COUNT = DIGITAL_ACTOR_FEATURE_COUNT + 7; /** - * The operation id for the 'Init' operation. + * The operation id for the 'Turn Digital' operation. * * * @generated * @ordered */ - int PROXIMITY___INIT = MULTI_TOUCH_DEVICE___INIT; + int DIGITAL_ACTOR_DIGITAL_OUT4___TURN_DIGITAL__HIGHLOWVALUE = DIGITAL_ACTOR___TURN_DIGITAL__HIGHLOWVALUE; /** - * The operation id for the 'Enable' operation. + * The operation id for the 'Fetch Digital Value' operation. * * * @generated * @ordered */ - int PROXIMITY___ENABLE = MULTI_TOUCH_DEVICE___ENABLE; + int DIGITAL_ACTOR_DIGITAL_OUT4___FETCH_DIGITAL_VALUE = DIGITAL_ACTOR___FETCH_DIGITAL_VALUE; /** - * The operation id for the 'Disable' operation. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int PROXIMITY___DISABLE = MULTI_TOUCH_DEVICE___DISABLE; + int DIGITAL_ACTOR_DIGITAL_OUT4___INIT = DIGITAL_ACTOR_OPERATION_COUNT + 0; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int PROXIMITY___FETCH_SENSOR_VALUE = MULTI_TOUCH_DEVICE___FETCH_SENSOR_VALUE; + int DIGITAL_ACTOR_DIGITAL_OUT4___ENABLE = DIGITAL_ACTOR_OPERATION_COUNT + 1; /** - * The number of operations of the 'Proximity' class. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int PROXIMITY_OPERATION_COUNT = MULTI_TOUCH_DEVICE_OPERATION_COUNT + 0; + int DIGITAL_ACTOR_DIGITAL_OUT4___DISABLE = DIGITAL_ACTOR_OPERATION_COUNT + 2; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMotionDetectorImpl MBricklet Motion Detector}' class. + * The number of operations of the 'Digital Actor Digital Out4' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMotionDetectorImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletMotionDetector() * @generated + * @ordered */ - int MBRICKLET_MOTION_DETECTOR = 45; + int DIGITAL_ACTOR_DIGITAL_OUT4_OPERATION_COUNT = DIGITAL_ACTOR_OPERATION_COUNT + 3; /** * The feature id for the 'Logger' attribute. @@ -5803,7 +5873,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__LOGGER = MDEVICE__LOGGER; + int MBRICKLET_SEGMENT_DISPLAY4X7__LOGGER = NUMBER_ACTOR_FEATURE_COUNT + 0; /** * The feature id for the 'Uid' attribute. @@ -5812,7 +5882,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__UID = MDEVICE__UID; + int MBRICKLET_SEGMENT_DISPLAY4X7__UID = NUMBER_ACTOR_FEATURE_COUNT + 1; /** * The feature id for the 'Poll' attribute. @@ -5821,7 +5891,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__POLL = MDEVICE__POLL; + int MBRICKLET_SEGMENT_DISPLAY4X7__POLL = NUMBER_ACTOR_FEATURE_COUNT + 2; /** * The feature id for the 'Enabled A' attribute. @@ -5830,7 +5900,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__ENABLED_A = MDEVICE__ENABLED_A; + int MBRICKLET_SEGMENT_DISPLAY4X7__ENABLED_A = NUMBER_ACTOR_FEATURE_COUNT + 3; /** * The feature id for the 'Tinkerforge Device' attribute. @@ -5839,7 +5909,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MBRICKLET_SEGMENT_DISPLAY4X7__TINKERFORGE_DEVICE = NUMBER_ACTOR_FEATURE_COUNT + 4; /** * The feature id for the 'Ip Connection' attribute. @@ -5848,7 +5918,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MBRICKLET_SEGMENT_DISPLAY4X7__IP_CONNECTION = NUMBER_ACTOR_FEATURE_COUNT + 5; /** * The feature id for the 'Connected Uid' attribute. @@ -5857,7 +5927,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MBRICKLET_SEGMENT_DISPLAY4X7__CONNECTED_UID = NUMBER_ACTOR_FEATURE_COUNT + 6; /** * The feature id for the 'Position' attribute. @@ -5866,7 +5936,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__POSITION = MDEVICE__POSITION; + int MBRICKLET_SEGMENT_DISPLAY4X7__POSITION = NUMBER_ACTOR_FEATURE_COUNT + 7; /** * The feature id for the 'Device Identifier' attribute. @@ -5875,7 +5945,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICKLET_SEGMENT_DISPLAY4X7__DEVICE_IDENTIFIER = NUMBER_ACTOR_FEATURE_COUNT + 8; /** * The feature id for the 'Name' attribute. @@ -5884,7 +5954,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__NAME = MDEVICE__NAME; + int MBRICKLET_SEGMENT_DISPLAY4X7__NAME = NUMBER_ACTOR_FEATURE_COUNT + 9; /** * The feature id for the 'Brickd' container reference. @@ -5893,34 +5963,34 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_SEGMENT_DISPLAY4X7__BRICKD = NUMBER_ACTOR_FEATURE_COUNT + 10; /** - * The feature id for the 'Sensor Value' attribute. + * The number of structural features of the 'MBricklet Segment Display4x7' class. * * * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_SEGMENT_DISPLAY4X7_FEATURE_COUNT = NUMBER_ACTOR_FEATURE_COUNT + 11; /** - * The feature id for the 'Device Type' attribute. + * The operation id for the 'Set Number' operation. * * * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 1; + int MBRICKLET_SEGMENT_DISPLAY4X7___SET_NUMBER__BIGDECIMAL = NUMBER_ACTOR___SET_NUMBER__BIGDECIMAL; /** - * The number of structural features of the 'MBricklet Motion Detector' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 2; + int MBRICKLET_SEGMENT_DISPLAY4X7___INIT = NUMBER_ACTOR_OPERATION_COUNT + 0; /** * The operation id for the 'Enable' operation. @@ -5929,7 +5999,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR___ENABLE = MDEVICE___ENABLE; + int MBRICKLET_SEGMENT_DISPLAY4X7___ENABLE = NUMBER_ACTOR_OPERATION_COUNT + 1; /** * The operation id for the 'Disable' operation. @@ -5938,378 +6008,368 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR___DISABLE = MDEVICE___DISABLE; + int MBRICKLET_SEGMENT_DISPLAY4X7___DISABLE = NUMBER_ACTOR_OPERATION_COUNT + 2; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The number of operations of the 'MBricklet Segment Display4x7' class. * * * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; + int MBRICKLET_SEGMENT_DISPLAY4X7_OPERATION_COUNT = NUMBER_ACTOR_OPERATION_COUNT + 3; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR___INIT = MDEVICE_OPERATION_COUNT + 1; + int MBRICKLET_LED_STRIP__LOGGER = COLOR_ACTOR_FEATURE_COUNT + 0; /** - * The number of operations of the 'MBricklet Motion Detector' class. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOTION_DETECTOR_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; + int MBRICKLET_LED_STRIP__UID = COLOR_ACTOR_FEATURE_COUNT + 1; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletHallEffectImpl MBricklet Hall Effect}' class. - * - * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletHallEffectImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletHallEffect() - * @generated - */ - int MBRICKLET_HALL_EFFECT = 46; - - /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__LOGGER = MDEVICE__LOGGER; + int MBRICKLET_LED_STRIP__POLL = COLOR_ACTOR_FEATURE_COUNT + 2; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__UID = MDEVICE__UID; + int MBRICKLET_LED_STRIP__ENABLED_A = COLOR_ACTOR_FEATURE_COUNT + 3; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__POLL = MDEVICE__POLL; + int MBRICKLET_LED_STRIP__TINKERFORGE_DEVICE = COLOR_ACTOR_FEATURE_COUNT + 4; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__ENABLED_A = MDEVICE__ENABLED_A; + int MBRICKLET_LED_STRIP__IP_CONNECTION = COLOR_ACTOR_FEATURE_COUNT + 5; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MBRICKLET_LED_STRIP__CONNECTED_UID = COLOR_ACTOR_FEATURE_COUNT + 6; /** - * The feature id for the 'Ip Connection' attribute. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MBRICKLET_LED_STRIP__POSITION = COLOR_ACTOR_FEATURE_COUNT + 7; /** - * The feature id for the 'Connected Uid' attribute. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MBRICKLET_LED_STRIP__DEVICE_IDENTIFIER = COLOR_ACTOR_FEATURE_COUNT + 8; /** - * The feature id for the 'Position' attribute. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__POSITION = MDEVICE__POSITION; + int MBRICKLET_LED_STRIP__NAME = COLOR_ACTOR_FEATURE_COUNT + 9; /** - * The feature id for the 'Device Identifier' attribute. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICKLET_LED_STRIP__BRICKD = COLOR_ACTOR_FEATURE_COUNT + 10; /** - * The feature id for the 'Name' attribute. + * The number of structural features of the 'MBricklet LED Strip' class. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__NAME = MDEVICE__NAME; + int MBRICKLET_LED_STRIP_FEATURE_COUNT = COLOR_ACTOR_FEATURE_COUNT + 11; /** - * The feature id for the 'Brickd' container reference. + * The operation id for the 'Set Color' operation. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_LED_STRIP___SET_COLOR__HSBTYPE_DEVICEOPTIONS = COLOR_ACTOR___SET_COLOR__HSBTYPE_DEVICEOPTIONS; /** - * The feature id for the 'Sensor Value' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_LED_STRIP___INIT = COLOR_ACTOR_OPERATION_COUNT + 0; /** - * The feature id for the 'Callback Period' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 1; + int MBRICKLET_LED_STRIP___ENABLE = COLOR_ACTOR_OPERATION_COUNT + 1; /** - * The feature id for the 'Tf Config' containment reference. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__TF_CONFIG = MDEVICE_FEATURE_COUNT + 2; + int MBRICKLET_LED_STRIP___DISABLE = COLOR_ACTOR_OPERATION_COUNT + 2; /** - * The feature id for the 'Device Type' attribute. + * The number of operations of the 'MBricklet LED Strip' class. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; + int MBRICKLET_LED_STRIP_OPERATION_COUNT = COLOR_ACTOR_OPERATION_COUNT + 3; /** - * The number of structural features of the 'MBricklet Hall Effect' class. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorIO16Impl Digital Actor IO16}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorIO16Impl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActorIO16() * @generated - * @ordered */ - int MBRICKLET_HALL_EFFECT_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 4; + int DIGITAL_ACTOR_IO16 = 51; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Digital State' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT___ENABLE = MDEVICE___ENABLE; + int DIGITAL_ACTOR_IO16__DIGITAL_STATE = DIGITAL_ACTOR__DIGITAL_STATE; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT___DISABLE = MDEVICE___DISABLE; + int DIGITAL_ACTOR_IO16__LOGGER = DIGITAL_ACTOR_FEATURE_COUNT + 0; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; + int DIGITAL_ACTOR_IO16__UID = DIGITAL_ACTOR_FEATURE_COUNT + 1; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT___INIT = MDEVICE_OPERATION_COUNT + 1; + int DIGITAL_ACTOR_IO16__POLL = DIGITAL_ACTOR_FEATURE_COUNT + 2; /** - * The number of operations of the 'MBricklet Hall Effect' class. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_HALL_EFFECT_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; + int DIGITAL_ACTOR_IO16__ENABLED_A = DIGITAL_ACTOR_FEATURE_COUNT + 3; /** - * The feature id for the 'Switch State' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY__SWITCH_STATE = MIN_SWITCH_ACTOR__SWITCH_STATE; + int DIGITAL_ACTOR_IO16__SUB_ID = DIGITAL_ACTOR_FEATURE_COUNT + 4; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MDUAL_RELAY__LOGGER = MIN_SWITCH_ACTOR_FEATURE_COUNT + 0; + int DIGITAL_ACTOR_IO16__MBRICK = DIGITAL_ACTOR_FEATURE_COUNT + 5; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Generic Device Id' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY__UID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 1; + int DIGITAL_ACTOR_IO16__GENERIC_DEVICE_ID = DIGITAL_ACTOR_FEATURE_COUNT + 6; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MDUAL_RELAY__POLL = MIN_SWITCH_ACTOR_FEATURE_COUNT + 2; + int DIGITAL_ACTOR_IO16__TF_CONFIG = DIGITAL_ACTOR_FEATURE_COUNT + 7; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY__ENABLED_A = MIN_SWITCH_ACTOR_FEATURE_COUNT + 3; + int DIGITAL_ACTOR_IO16__DEVICE_TYPE = DIGITAL_ACTOR_FEATURE_COUNT + 8; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Port' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY__SUB_ID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 4; + int DIGITAL_ACTOR_IO16__PORT = DIGITAL_ACTOR_FEATURE_COUNT + 9; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Pin' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY__MBRICK = MIN_SWITCH_ACTOR_FEATURE_COUNT + 5; + int DIGITAL_ACTOR_IO16__PIN = DIGITAL_ACTOR_FEATURE_COUNT + 10; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Default State' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY__DEVICE_TYPE = MIN_SWITCH_ACTOR_FEATURE_COUNT + 6; + int DIGITAL_ACTOR_IO16__DEFAULT_STATE = DIGITAL_ACTOR_FEATURE_COUNT + 11; /** - * The number of structural features of the 'MDual Relay' class. + * The feature id for the 'Keep On Reconnect' attribute. * * * @generated * @ordered */ - int MDUAL_RELAY_FEATURE_COUNT = MIN_SWITCH_ACTOR_FEATURE_COUNT + 7; + int DIGITAL_ACTOR_IO16__KEEP_ON_RECONNECT = DIGITAL_ACTOR_FEATURE_COUNT + 12; /** - * The operation id for the 'Turn Switch' operation. + * The number of structural features of the 'Digital Actor IO16' class. * * * @generated * @ordered */ - int MDUAL_RELAY___TURN_SWITCH__ONOFFVALUE = MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; + int DIGITAL_ACTOR_IO16_FEATURE_COUNT = DIGITAL_ACTOR_FEATURE_COUNT + 13; /** - * The operation id for the 'Fetch Switch State' operation. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MDUAL_RELAY___FETCH_SWITCH_STATE = MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE; + int DIGITAL_ACTOR_IO16___INIT = DIGITAL_ACTOR_OPERATION_COUNT + 0; /** - * The operation id for the 'Init' operation. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MDUAL_RELAY___INIT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 0; + int DIGITAL_ACTOR_IO16___ENABLE = DIGITAL_ACTOR_OPERATION_COUNT + 1; /** - * The operation id for the 'Enable' operation. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MDUAL_RELAY___ENABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 1; + int DIGITAL_ACTOR_IO16___DISABLE = DIGITAL_ACTOR_OPERATION_COUNT + 2; /** - * The operation id for the 'Disable' operation. + * The operation id for the 'Turn Digital' operation. * * * @generated * @ordered */ - int MDUAL_RELAY___DISABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 2; + int DIGITAL_ACTOR_IO16___TURN_DIGITAL__HIGHLOWVALUE = DIGITAL_ACTOR_OPERATION_COUNT + 3; /** - * The number of operations of the 'MDual Relay' class. + * The operation id for the 'Fetch Digital Value' operation. * * * @generated * @ordered */ - int MDUAL_RELAY_OPERATION_COUNT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 3; + int DIGITAL_ACTOR_IO16___FETCH_DIGITAL_VALUE = DIGITAL_ACTOR_OPERATION_COUNT + 4; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletRemoteSwitchImpl MBricklet Remote Switch}' class. + * The number of operations of the 'Digital Actor IO16' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletRemoteSwitchImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletRemoteSwitch() * @generated + * @ordered */ - int MBRICKLET_REMOTE_SWITCH = 48; + int DIGITAL_ACTOR_IO16_OPERATION_COUNT = DIGITAL_ACTOR_OPERATION_COUNT + 5; /** * The feature id for the 'Logger' attribute. @@ -6318,7 +6378,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__LOGGER = MDEVICE__LOGGER; + int MBRICKLET_IO16__LOGGER = MDEVICE__LOGGER; /** * The feature id for the 'Uid' attribute. @@ -6327,7 +6387,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__UID = MDEVICE__UID; + int MBRICKLET_IO16__UID = MDEVICE__UID; /** * The feature id for the 'Poll' attribute. @@ -6336,7 +6396,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__POLL = MDEVICE__POLL; + int MBRICKLET_IO16__POLL = MDEVICE__POLL; /** * The feature id for the 'Enabled A' attribute. @@ -6345,7 +6405,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__ENABLED_A = MDEVICE__ENABLED_A; + int MBRICKLET_IO16__ENABLED_A = MDEVICE__ENABLED_A; /** * The feature id for the 'Tinkerforge Device' attribute. @@ -6354,7 +6414,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MBRICKLET_IO16__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** * The feature id for the 'Ip Connection' attribute. @@ -6363,7 +6423,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MBRICKLET_IO16__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** * The feature id for the 'Connected Uid' attribute. @@ -6372,7 +6432,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MBRICKLET_IO16__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** * The feature id for the 'Position' attribute. @@ -6381,7 +6441,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__POSITION = MDEVICE__POSITION; + int MBRICKLET_IO16__POSITION = MDEVICE__POSITION; /** * The feature id for the 'Device Identifier' attribute. @@ -6390,7 +6450,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICKLET_IO16__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** * The feature id for the 'Name' attribute. @@ -6399,7 +6459,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__NAME = MDEVICE__NAME; + int MBRICKLET_IO16__NAME = MDEVICE__NAME; /** * The feature id for the 'Brickd' container reference. @@ -6408,7 +6468,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_IO16__BRICKD = MDEVICE__BRICKD; /** * The feature id for the 'Msubdevices' containment reference list. @@ -6417,215 +6477,214 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_IO16__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Debounce Period' attribute. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; + int MBRICKLET_IO16__DEBOUNCE_PERIOD = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 2; + int MBRICKLET_IO16__TF_CONFIG = MDEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Type ADevices' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__TYPE_ADEVICES = MDEVICE_FEATURE_COUNT + 3; + int MBRICKLET_IO16__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; /** - * The feature id for the 'Type BDevices' attribute. + * The number of structural features of the 'MBricklet IO16' class. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__TYPE_BDEVICES = MDEVICE_FEATURE_COUNT + 4; + int MBRICKLET_IO16_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 4; /** - * The feature id for the 'Type CDevices' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH__TYPE_CDEVICES = MDEVICE_FEATURE_COUNT + 5; + int MBRICKLET_IO16___INIT = MDEVICE___INIT; /** - * The number of structural features of the 'MBricklet Remote Switch' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 6; + int MBRICKLET_IO16___ENABLE = MDEVICE___ENABLE; /** - * The operation id for the 'Init' operation. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH___INIT = MDEVICE___INIT; + int MBRICKLET_IO16___DISABLE = MDEVICE___DISABLE; /** - * The operation id for the 'Enable' operation. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH___ENABLE = MDEVICE___ENABLE; + int MBRICKLET_IO16___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The operation id for the 'Disable' operation. + * The number of operations of the 'MBricklet IO16' class. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH___DISABLE = MDEVICE___DISABLE; + int MBRICKLET_IO16_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The operation id for the 'Init Sub Devices' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; + int DIGITAL_SENSOR__LOGGER = IO_DEVICE__LOGGER; /** - * The operation id for the 'Add Sub Device' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH___ADD_SUB_DEVICE__STRING_STRING = MDEVICE_OPERATION_COUNT + 1; + int DIGITAL_SENSOR__UID = IO_DEVICE__UID; /** - * The number of operations of the 'MBricklet Remote Switch' class. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_REMOTE_SWITCH_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; + int DIGITAL_SENSOR__POLL = IO_DEVICE__POLL; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitch Remote Switch}' class. + * The feature id for the 'Enabled A' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitch - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitch() * @generated + * @ordered */ - int REMOTE_SWITCH = 49; + int DIGITAL_SENSOR__ENABLED_A = IO_DEVICE__ENABLED_A; /** - * The feature id for the 'Switch State' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH__SWITCH_STATE = MIN_SWITCH_ACTOR__SWITCH_STATE; + int DIGITAL_SENSOR__SUB_ID = IO_DEVICE__SUB_ID; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int REMOTE_SWITCH__LOGGER = MIN_SWITCH_ACTOR_FEATURE_COUNT + 0; + int DIGITAL_SENSOR__MBRICK = IO_DEVICE__MBRICK; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Generic Device Id' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH__UID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 1; + int DIGITAL_SENSOR__GENERIC_DEVICE_ID = IO_DEVICE__GENERIC_DEVICE_ID; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH__POLL = MIN_SWITCH_ACTOR_FEATURE_COUNT + 2; + int DIGITAL_SENSOR__SENSOR_VALUE = IO_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int REMOTE_SWITCH__ENABLED_A = MIN_SWITCH_ACTOR_FEATURE_COUNT + 3; + int DIGITAL_SENSOR__TF_CONFIG = IO_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH__SUB_ID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 4; + int DIGITAL_SENSOR__DEVICE_TYPE = IO_DEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Pull Up Resistor Enabled' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH__MBRICK = MIN_SWITCH_ACTOR_FEATURE_COUNT + 5; + int DIGITAL_SENSOR__PULL_UP_RESISTOR_ENABLED = IO_DEVICE_FEATURE_COUNT + 3; /** - * The number of structural features of the 'Remote Switch' class. + * The feature id for the 'Port' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_FEATURE_COUNT = MIN_SWITCH_ACTOR_FEATURE_COUNT + 6; + int DIGITAL_SENSOR__PORT = IO_DEVICE_FEATURE_COUNT + 4; /** - * The operation id for the 'Turn Switch' operation. + * The feature id for the 'Pin' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH___TURN_SWITCH__ONOFFVALUE = MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; + int DIGITAL_SENSOR__PIN = IO_DEVICE_FEATURE_COUNT + 5; /** - * The operation id for the 'Fetch Switch State' operation. + * The number of structural features of the 'Digital Sensor' class. * * * @generated * @ordered */ - int REMOTE_SWITCH___FETCH_SWITCH_STATE = MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE; + int DIGITAL_SENSOR_FEATURE_COUNT = IO_DEVICE_FEATURE_COUNT + 6; /** * The operation id for the 'Init' operation. @@ -6634,7 +6693,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH___INIT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 0; + int DIGITAL_SENSOR___INIT = IO_DEVICE___INIT; /** * The operation id for the 'Enable' operation. @@ -6643,7 +6702,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH___ENABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 1; + int DIGITAL_SENSOR___ENABLE = IO_DEVICE___ENABLE; /** * The operation id for the 'Disable' operation. @@ -6652,35 +6711,35 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH___DISABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 2; + int DIGITAL_SENSOR___DISABLE = IO_DEVICE___DISABLE; /** - * The number of operations of the 'Remote Switch' class. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_OPERATION_COUNT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 3; + int DIGITAL_SENSOR___FETCH_SENSOR_VALUE = IO_DEVICE_OPERATION_COUNT + 0; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchAImpl Remote Switch A}' class. + * The number of operations of the 'Digital Sensor' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchAImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchA() * @generated + * @ordered */ - int REMOTE_SWITCH_A = 50; + int DIGITAL_SENSOR_OPERATION_COUNT = IO_DEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Switch State' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIO4Impl MBricklet IO4}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIO4Impl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletIO4() * @generated - * @ordered */ - int REMOTE_SWITCH_A__SWITCH_STATE = REMOTE_SWITCH__SWITCH_STATE; + int MBRICKLET_IO4 = 54; /** * The feature id for the 'Logger' attribute. @@ -6689,7 +6748,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_A__LOGGER = REMOTE_SWITCH__LOGGER; + int MBRICKLET_IO4__LOGGER = MDEVICE__LOGGER; /** * The feature id for the 'Uid' attribute. @@ -6698,7 +6757,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_A__UID = REMOTE_SWITCH__UID; + int MBRICKLET_IO4__UID = MDEVICE__UID; /** * The feature id for the 'Poll' attribute. @@ -6707,7 +6766,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_A__POLL = REMOTE_SWITCH__POLL; + int MBRICKLET_IO4__POLL = MDEVICE__POLL; /** * The feature id for the 'Enabled A' attribute. @@ -6716,97 +6775,115 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_A__ENABLED_A = REMOTE_SWITCH__ENABLED_A; + int MBRICKLET_IO4__ENABLED_A = MDEVICE__ENABLED_A; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_A__SUB_ID = REMOTE_SWITCH__SUB_ID; + int MBRICKLET_IO4__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_A__MBRICK = REMOTE_SWITCH__MBRICK; + int MBRICKLET_IO4__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_A__TF_CONFIG = REMOTE_SWITCH_FEATURE_COUNT + 0; + int MBRICKLET_IO4__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_A__DEVICE_TYPE = REMOTE_SWITCH_FEATURE_COUNT + 1; + int MBRICKLET_IO4__POSITION = MDEVICE__POSITION; /** - * The feature id for the 'House Code' attribute. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_A__HOUSE_CODE = REMOTE_SWITCH_FEATURE_COUNT + 2; + int MBRICKLET_IO4__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The feature id for the 'Receiver Code' attribute. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_A__RECEIVER_CODE = REMOTE_SWITCH_FEATURE_COUNT + 3; + int MBRICKLET_IO4__NAME = MDEVICE__NAME; /** - * The feature id for the 'Repeats' attribute. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int REMOTE_SWITCH_A__REPEATS = REMOTE_SWITCH_FEATURE_COUNT + 4; + int MBRICKLET_IO4__BRICKD = MDEVICE__BRICKD; /** - * The number of structural features of the 'Remote Switch A' class. + * The feature id for the 'Msubdevices' containment reference list. * * * @generated * @ordered */ - int REMOTE_SWITCH_A_FEATURE_COUNT = REMOTE_SWITCH_FEATURE_COUNT + 5; + int MBRICKLET_IO4__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** - * The operation id for the 'Turn Switch' operation. + * The feature id for the 'Debounce Period' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_A___TURN_SWITCH__ONOFFVALUE = REMOTE_SWITCH___TURN_SWITCH__ONOFFVALUE; + int MBRICKLET_IO4__DEBOUNCE_PERIOD = MDEVICE_FEATURE_COUNT + 1; /** - * The operation id for the 'Fetch Switch State' operation. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int REMOTE_SWITCH_A___FETCH_SWITCH_STATE = REMOTE_SWITCH___FETCH_SWITCH_STATE; + int MBRICKLET_IO4__TF_CONFIG = MDEVICE_FEATURE_COUNT + 2; + + /** + * The feature id for the 'Device Type' attribute. + * + * + * @generated + * @ordered + */ + int MBRICKLET_IO4__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; + + /** + * The number of structural features of the 'MBricklet IO4' class. + * + * + * @generated + * @ordered + */ + int MBRICKLET_IO4_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 4; /** * The operation id for the 'Init' operation. @@ -6815,7 +6892,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_A___INIT = REMOTE_SWITCH___INIT; + int MBRICKLET_IO4___INIT = MDEVICE___INIT; /** * The operation id for the 'Enable' operation. @@ -6824,7 +6901,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_A___ENABLE = REMOTE_SWITCH___ENABLE; + int MBRICKLET_IO4___ENABLE = MDEVICE___ENABLE; /** * The operation id for the 'Disable' operation. @@ -6833,35 +6910,35 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_A___DISABLE = REMOTE_SWITCH___DISABLE; + int MBRICKLET_IO4___DISABLE = MDEVICE___DISABLE; /** - * The number of operations of the 'Remote Switch A' class. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_A_OPERATION_COUNT = REMOTE_SWITCH_OPERATION_COUNT + 0; + int MBRICKLET_IO4___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl Remote Switch B}' class. + * The number of operations of the 'MBricklet IO4' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchB() * @generated + * @ordered */ - int REMOTE_SWITCH_B = 51; + int MBRICKLET_IO4_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Switch State' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.IO4Device IO4 Device}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.IO4Device + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIO4Device() * @generated - * @ordered */ - int REMOTE_SWITCH_B__SWITCH_STATE = REMOTE_SWITCH__SWITCH_STATE; + int IO4_DEVICE = 55; /** * The feature id for the 'Logger' attribute. @@ -6870,7 +6947,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_B__LOGGER = REMOTE_SWITCH__LOGGER; + int IO4_DEVICE__LOGGER = MSUB_DEVICE__LOGGER; /** * The feature id for the 'Uid' attribute. @@ -6879,7 +6956,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_B__UID = REMOTE_SWITCH__UID; + int IO4_DEVICE__UID = MSUB_DEVICE__UID; /** * The feature id for the 'Poll' attribute. @@ -6888,7 +6965,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_B__POLL = REMOTE_SWITCH__POLL; + int IO4_DEVICE__POLL = MSUB_DEVICE__POLL; /** * The feature id for the 'Enabled A' attribute. @@ -6897,7 +6974,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_B__ENABLED_A = REMOTE_SWITCH__ENABLED_A; + int IO4_DEVICE__ENABLED_A = MSUB_DEVICE__ENABLED_A; /** * The feature id for the 'Sub Id' attribute. @@ -6906,7 +6983,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_B__SUB_ID = REMOTE_SWITCH__SUB_ID; + int IO4_DEVICE__SUB_ID = MSUB_DEVICE__SUB_ID; /** * The feature id for the 'Mbrick' container reference. @@ -6915,1398 +6992,1401 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int REMOTE_SWITCH_B__MBRICK = REMOTE_SWITCH__MBRICK; + int IO4_DEVICE__MBRICK = MSUB_DEVICE__MBRICK; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Generic Device Id' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_B__TF_CONFIG = REMOTE_SWITCH_FEATURE_COUNT + 0; + int IO4_DEVICE__GENERIC_DEVICE_ID = MSUB_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Device Type' attribute. + * The number of structural features of the 'IO4 Device' class. * * * @generated * @ordered */ - int REMOTE_SWITCH_B__DEVICE_TYPE = REMOTE_SWITCH_FEATURE_COUNT + 1; + int IO4_DEVICE_FEATURE_COUNT = MSUB_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Address' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_B__ADDRESS = REMOTE_SWITCH_FEATURE_COUNT + 2; + int IO4_DEVICE___INIT = MSUB_DEVICE___INIT; /** - * The feature id for the 'Unit' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_B__UNIT = REMOTE_SWITCH_FEATURE_COUNT + 3; + int IO4_DEVICE___ENABLE = MSUB_DEVICE___ENABLE; /** - * The feature id for the 'Repeats' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_B__REPEATS = REMOTE_SWITCH_FEATURE_COUNT + 4; + int IO4_DEVICE___DISABLE = MSUB_DEVICE___DISABLE; /** - * The number of structural features of the 'Remote Switch B' class. + * The number of operations of the 'IO4 Device' class. * * * @generated * @ordered */ - int REMOTE_SWITCH_B_FEATURE_COUNT = REMOTE_SWITCH_FEATURE_COUNT + 5; + int IO4_DEVICE_OPERATION_COUNT = MSUB_DEVICE_OPERATION_COUNT + 0; /** - * The operation id for the 'Turn Switch' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DigitalSensorIO4Impl Digital Sensor IO4}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.DigitalSensorIO4Impl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalSensorIO4() * @generated - * @ordered */ - int REMOTE_SWITCH_B___TURN_SWITCH__ONOFFVALUE = REMOTE_SWITCH___TURN_SWITCH__ONOFFVALUE; + int DIGITAL_SENSOR_IO4 = 56; /** - * The operation id for the 'Fetch Switch State' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_B___FETCH_SWITCH_STATE = REMOTE_SWITCH___FETCH_SWITCH_STATE; + int DIGITAL_SENSOR_IO4__LOGGER = IO4_DEVICE__LOGGER; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_B___INIT = REMOTE_SWITCH___INIT; + int DIGITAL_SENSOR_IO4__UID = IO4_DEVICE__UID; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_B___ENABLE = REMOTE_SWITCH___ENABLE; + int DIGITAL_SENSOR_IO4__POLL = IO4_DEVICE__POLL; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_B___DISABLE = REMOTE_SWITCH___DISABLE; + int DIGITAL_SENSOR_IO4__ENABLED_A = IO4_DEVICE__ENABLED_A; /** - * The number of operations of the 'Remote Switch B' class. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_B_OPERATION_COUNT = REMOTE_SWITCH_OPERATION_COUNT + 0; + int DIGITAL_SENSOR_IO4__SUB_ID = IO4_DEVICE__SUB_ID; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchCImpl Remote Switch C}' class. + * The feature id for the 'Mbrick' container reference. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchCImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchC() * @generated + * @ordered */ - int REMOTE_SWITCH_C = 52; + int DIGITAL_SENSOR_IO4__MBRICK = IO4_DEVICE__MBRICK; /** - * The feature id for the 'Switch State' attribute. + * The feature id for the 'Generic Device Id' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__SWITCH_STATE = REMOTE_SWITCH__SWITCH_STATE; + int DIGITAL_SENSOR_IO4__GENERIC_DEVICE_ID = IO4_DEVICE__GENERIC_DEVICE_ID; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__LOGGER = REMOTE_SWITCH__LOGGER; + int DIGITAL_SENSOR_IO4__SENSOR_VALUE = IO4_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__UID = REMOTE_SWITCH__UID; + int DIGITAL_SENSOR_IO4__TF_CONFIG = IO4_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__POLL = REMOTE_SWITCH__POLL; + int DIGITAL_SENSOR_IO4__DEVICE_TYPE = IO4_DEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Pull Up Resistor Enabled' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__ENABLED_A = REMOTE_SWITCH__ENABLED_A; + int DIGITAL_SENSOR_IO4__PULL_UP_RESISTOR_ENABLED = IO4_DEVICE_FEATURE_COUNT + 3; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Pin' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__SUB_ID = REMOTE_SWITCH__SUB_ID; + int DIGITAL_SENSOR_IO4__PIN = IO4_DEVICE_FEATURE_COUNT + 4; /** - * The feature id for the 'Mbrick' container reference. + * The number of structural features of the 'Digital Sensor IO4' class. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__MBRICK = REMOTE_SWITCH__MBRICK; + int DIGITAL_SENSOR_IO4_FEATURE_COUNT = IO4_DEVICE_FEATURE_COUNT + 5; /** - * The feature id for the 'Tf Config' containment reference. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__TF_CONFIG = REMOTE_SWITCH_FEATURE_COUNT + 0; + int DIGITAL_SENSOR_IO4___INIT = IO4_DEVICE___INIT; /** - * The feature id for the 'Device Type' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__DEVICE_TYPE = REMOTE_SWITCH_FEATURE_COUNT + 1; + int DIGITAL_SENSOR_IO4___ENABLE = IO4_DEVICE___ENABLE; /** - * The feature id for the 'System Code' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__SYSTEM_CODE = REMOTE_SWITCH_FEATURE_COUNT + 2; + int DIGITAL_SENSOR_IO4___DISABLE = IO4_DEVICE___DISABLE; /** - * The feature id for the 'Device Code' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__DEVICE_CODE = REMOTE_SWITCH_FEATURE_COUNT + 3; + int DIGITAL_SENSOR_IO4___FETCH_SENSOR_VALUE = IO4_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Repeats' attribute. + * The number of operations of the 'Digital Sensor IO4' class. * * * @generated * @ordered */ - int REMOTE_SWITCH_C__REPEATS = REMOTE_SWITCH_FEATURE_COUNT + 4; + int DIGITAL_SENSOR_IO4_OPERATION_COUNT = IO4_DEVICE_OPERATION_COUNT + 1; /** - * The number of structural features of the 'Remote Switch C' class. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorIO4Impl Digital Actor IO4}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorIO4Impl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActorIO4() * @generated - * @ordered */ - int REMOTE_SWITCH_C_FEATURE_COUNT = REMOTE_SWITCH_FEATURE_COUNT + 5; + int DIGITAL_ACTOR_IO4 = 57; /** - * The operation id for the 'Turn Switch' operation. + * The feature id for the 'Digital State' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_C___TURN_SWITCH__ONOFFVALUE = REMOTE_SWITCH___TURN_SWITCH__ONOFFVALUE; + int DIGITAL_ACTOR_IO4__DIGITAL_STATE = DIGITAL_ACTOR__DIGITAL_STATE; /** - * The operation id for the 'Fetch Switch State' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_C___FETCH_SWITCH_STATE = REMOTE_SWITCH___FETCH_SWITCH_STATE; + int DIGITAL_ACTOR_IO4__LOGGER = DIGITAL_ACTOR_FEATURE_COUNT + 0; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_C___INIT = REMOTE_SWITCH___INIT; + int DIGITAL_ACTOR_IO4__UID = DIGITAL_ACTOR_FEATURE_COUNT + 1; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_C___ENABLE = REMOTE_SWITCH___ENABLE; + int DIGITAL_ACTOR_IO4__POLL = DIGITAL_ACTOR_FEATURE_COUNT + 2; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_C___DISABLE = REMOTE_SWITCH___DISABLE; + int DIGITAL_ACTOR_IO4__ENABLED_A = DIGITAL_ACTOR_FEATURE_COUNT + 3; /** - * The number of operations of the 'Remote Switch C' class. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_C_OPERATION_COUNT = REMOTE_SWITCH_OPERATION_COUNT + 0; + int DIGITAL_ACTOR_IO4__SUB_ID = DIGITAL_ACTOR_FEATURE_COUNT + 4; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__SENSOR_VALUE = MSENSOR__SENSOR_VALUE; + int DIGITAL_ACTOR_IO4__MBRICK = DIGITAL_ACTOR_FEATURE_COUNT + 5; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Generic Device Id' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__LOGGER = MSENSOR_FEATURE_COUNT + 0; + int DIGITAL_ACTOR_IO4__GENERIC_DEVICE_ID = DIGITAL_ACTOR_FEATURE_COUNT + 6; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__UID = MSENSOR_FEATURE_COUNT + 1; + int DIGITAL_ACTOR_IO4__TF_CONFIG = DIGITAL_ACTOR_FEATURE_COUNT + 7; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__POLL = MSENSOR_FEATURE_COUNT + 2; + int DIGITAL_ACTOR_IO4__DEVICE_TYPE = DIGITAL_ACTOR_FEATURE_COUNT + 8; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Pin' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__ENABLED_A = MSENSOR_FEATURE_COUNT + 3; + int DIGITAL_ACTOR_IO4__PIN = DIGITAL_ACTOR_FEATURE_COUNT + 9; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The feature id for the 'Default State' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__TINKERFORGE_DEVICE = MSENSOR_FEATURE_COUNT + 4; + int DIGITAL_ACTOR_IO4__DEFAULT_STATE = DIGITAL_ACTOR_FEATURE_COUNT + 10; /** - * The feature id for the 'Ip Connection' attribute. + * The feature id for the 'Keep On Reconnect' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__IP_CONNECTION = MSENSOR_FEATURE_COUNT + 5; + int DIGITAL_ACTOR_IO4__KEEP_ON_RECONNECT = DIGITAL_ACTOR_FEATURE_COUNT + 11; /** - * The feature id for the 'Connected Uid' attribute. + * The number of structural features of the 'Digital Actor IO4' class. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__CONNECTED_UID = MSENSOR_FEATURE_COUNT + 6; + int DIGITAL_ACTOR_IO4_FEATURE_COUNT = DIGITAL_ACTOR_FEATURE_COUNT + 12; /** - * The feature id for the 'Position' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__POSITION = MSENSOR_FEATURE_COUNT + 7; + int DIGITAL_ACTOR_IO4___INIT = DIGITAL_ACTOR_OPERATION_COUNT + 0; /** - * The feature id for the 'Device Identifier' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__DEVICE_IDENTIFIER = MSENSOR_FEATURE_COUNT + 8; + int DIGITAL_ACTOR_IO4___ENABLE = DIGITAL_ACTOR_OPERATION_COUNT + 1; /** - * The feature id for the 'Name' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__NAME = MSENSOR_FEATURE_COUNT + 9; + int DIGITAL_ACTOR_IO4___DISABLE = DIGITAL_ACTOR_OPERATION_COUNT + 2; /** - * The feature id for the 'Brickd' container reference. + * The operation id for the 'Turn Digital' operation. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__BRICKD = MSENSOR_FEATURE_COUNT + 10; + int DIGITAL_ACTOR_IO4___TURN_DIGITAL__HIGHLOWVALUE = DIGITAL_ACTOR_OPERATION_COUNT + 3; /** - * The feature id for the 'Tf Config' containment reference. + * The operation id for the 'Fetch Digital Value' operation. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__TF_CONFIG = MSENSOR_FEATURE_COUNT + 11; + int DIGITAL_ACTOR_IO4___FETCH_DIGITAL_VALUE = DIGITAL_ACTOR_OPERATION_COUNT + 4; /** - * The feature id for the 'Callback Period' attribute. + * The number of operations of the 'Digital Actor IO4' class. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__CALLBACK_PERIOD = MSENSOR_FEATURE_COUNT + 12; + int DIGITAL_ACTOR_IO4_OPERATION_COUNT = DIGITAL_ACTOR_OPERATION_COUNT + 5; /** - * The feature id for the 'Device Type' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMultiTouchImpl MBricklet Multi Touch}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMultiTouchImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletMultiTouch() * @generated - * @ordered */ - int MBRICKLET_HUMIDITY__DEVICE_TYPE = MSENSOR_FEATURE_COUNT + 13; + int MBRICKLET_MULTI_TOUCH = 58; /** - * The feature id for the 'Threshold' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY__THRESHOLD = MSENSOR_FEATURE_COUNT + 14; + int MBRICKLET_MULTI_TOUCH__LOGGER = MDEVICE__LOGGER; /** - * The number of structural features of the 'MBricklet Humidity' class. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY_FEATURE_COUNT = MSENSOR_FEATURE_COUNT + 15; + int MBRICKLET_MULTI_TOUCH__UID = MDEVICE__UID; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY___FETCH_SENSOR_VALUE = MSENSOR___FETCH_SENSOR_VALUE; + int MBRICKLET_MULTI_TOUCH__POLL = MDEVICE__POLL; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY___ENABLE = MSENSOR_OPERATION_COUNT + 1; + int MBRICKLET_MULTI_TOUCH__ENABLED_A = MDEVICE__ENABLED_A; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY___DISABLE = MSENSOR_OPERATION_COUNT + 2; + int MBRICKLET_MULTI_TOUCH__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY___INIT = MSENSOR_OPERATION_COUNT + 3; + int MBRICKLET_MULTI_TOUCH__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The number of operations of the 'MBricklet Humidity' class. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_HUMIDITY_OPERATION_COUNT = MSENSOR_OPERATION_COUNT + 4; + int MBRICKLET_MULTI_TOUCH__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__LOGGER = MDEVICE__LOGGER; + int MBRICKLET_MULTI_TOUCH__POSITION = MDEVICE__POSITION; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__UID = MDEVICE__UID; + int MBRICKLET_MULTI_TOUCH__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__POLL = MDEVICE__POLL; + int MBRICKLET_MULTI_TOUCH__NAME = MDEVICE__NAME; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__ENABLED_A = MDEVICE__ENABLED_A; + int MBRICKLET_MULTI_TOUCH__BRICKD = MDEVICE__BRICKD; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The feature id for the 'Msubdevices' containment reference list. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MBRICKLET_MULTI_TOUCH__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Ip Connection' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MBRICKLET_MULTI_TOUCH__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Connected Uid' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MBRICKLET_MULTI_TOUCH__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Position' attribute. + * The feature id for the 'Recalibrate' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__POSITION = MDEVICE__POSITION; + int MBRICKLET_MULTI_TOUCH__RECALIBRATE = MDEVICE_FEATURE_COUNT + 3; /** - * The feature id for the 'Device Identifier' attribute. + * The feature id for the 'Sensitivity' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICKLET_MULTI_TOUCH__SENSITIVITY = MDEVICE_FEATURE_COUNT + 4; /** - * The feature id for the 'Name' attribute. + * The number of structural features of the 'MBricklet Multi Touch' class. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__NAME = MDEVICE__NAME; + int MBRICKLET_MULTI_TOUCH_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 5; /** - * The feature id for the 'Brickd' container reference. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_MULTI_TOUCH___INIT = MDEVICE___INIT; /** - * The feature id for the 'Sensor Value' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_MULTI_TOUCH___ENABLE = MDEVICE___ENABLE; /** - * The feature id for the 'Tf Config' containment reference. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; + int MBRICKLET_MULTI_TOUCH___DISABLE = MDEVICE___DISABLE; /** - * The feature id for the 'Callback Period' attribute. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; + int MBRICKLET_MULTI_TOUCH___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Device Type' attribute. + * The number of operations of the 'MBricklet Multi Touch' class. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; + int MBRICKLET_MULTI_TOUCH_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Threshold' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MultiTouchDeviceImpl Multi Touch Device}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MultiTouchDeviceImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMultiTouchDevice() * @generated - * @ordered */ - int MBRICKLET_DISTANCE_IR__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; + int MULTI_TOUCH_DEVICE = 59; /** - * The number of structural features of the 'MBricklet Distance IR' class. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 5; + int MULTI_TOUCH_DEVICE__LOGGER = MSUB_DEVICE__LOGGER; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR___ENABLE = MDEVICE___ENABLE; + int MULTI_TOUCH_DEVICE__UID = MSUB_DEVICE__UID; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR___DISABLE = MDEVICE___DISABLE; + int MULTI_TOUCH_DEVICE__POLL = MSUB_DEVICE__POLL; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; + int MULTI_TOUCH_DEVICE__ENABLED_A = MSUB_DEVICE__ENABLED_A; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR___INIT = MDEVICE_OPERATION_COUNT + 1; + int MULTI_TOUCH_DEVICE__SUB_ID = MSUB_DEVICE__SUB_ID; /** - * The number of operations of the 'MBricklet Distance IR' class. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_IR_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; + int MULTI_TOUCH_DEVICE__MBRICK = MSUB_DEVICE__MBRICK; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__LOGGER = MDEVICE__LOGGER; + int MULTI_TOUCH_DEVICE__SENSOR_VALUE = MSUB_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__UID = MDEVICE__UID; + int MULTI_TOUCH_DEVICE__TF_CONFIG = MSUB_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Pin' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__POLL = MDEVICE__POLL; + int MULTI_TOUCH_DEVICE__PIN = MSUB_DEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Disable Electrode' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__ENABLED_A = MDEVICE__ENABLED_A; + int MULTI_TOUCH_DEVICE__DISABLE_ELECTRODE = MSUB_DEVICE_FEATURE_COUNT + 3; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The number of structural features of the 'Multi Touch Device' class. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MULTI_TOUCH_DEVICE_FEATURE_COUNT = MSUB_DEVICE_FEATURE_COUNT + 4; /** - * The feature id for the 'Ip Connection' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MULTI_TOUCH_DEVICE___INIT = MSUB_DEVICE___INIT; /** - * The feature id for the 'Connected Uid' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MULTI_TOUCH_DEVICE___ENABLE = MSUB_DEVICE___ENABLE; /** - * The feature id for the 'Position' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__POSITION = MDEVICE__POSITION; + int MULTI_TOUCH_DEVICE___DISABLE = MSUB_DEVICE___DISABLE; /** - * The feature id for the 'Device Identifier' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MULTI_TOUCH_DEVICE___FETCH_SENSOR_VALUE = MSUB_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Name' attribute. + * The number of operations of the 'Multi Touch Device' class. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__NAME = MDEVICE__NAME; + int MULTI_TOUCH_DEVICE_OPERATION_COUNT = MSUB_DEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Brickd' container reference. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.ElectrodeImpl Electrode}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.ElectrodeImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getElectrode() * @generated - * @ordered */ - int MBRICKLET_TEMPERATURE__BRICKD = MDEVICE__BRICKD; + int ELECTRODE = 60; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; + int ELECTRODE__LOGGER = MULTI_TOUCH_DEVICE__LOGGER; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; + int ELECTRODE__UID = MULTI_TOUCH_DEVICE__UID; /** - * The feature id for the 'Callback Period' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; + int ELECTRODE__POLL = MULTI_TOUCH_DEVICE__POLL; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; + int ELECTRODE__ENABLED_A = MULTI_TOUCH_DEVICE__ENABLED_A; /** - * The feature id for the 'Threshold' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; + int ELECTRODE__SUB_ID = MULTI_TOUCH_DEVICE__SUB_ID; /** - * The number of structural features of the 'MBricklet Temperature' class. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 5; + int ELECTRODE__MBRICK = MULTI_TOUCH_DEVICE__MBRICK; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE___ENABLE = MDEVICE___ENABLE; + int ELECTRODE__SENSOR_VALUE = MULTI_TOUCH_DEVICE__SENSOR_VALUE; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE___DISABLE = MDEVICE___DISABLE; + int ELECTRODE__TF_CONFIG = MULTI_TOUCH_DEVICE__TF_CONFIG; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Pin' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; + int ELECTRODE__PIN = MULTI_TOUCH_DEVICE__PIN; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Disable Electrode' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE___INIT = MDEVICE_OPERATION_COUNT + 1; + int ELECTRODE__DISABLE_ELECTRODE = MULTI_TOUCH_DEVICE__DISABLE_ELECTRODE; /** - * The number of operations of the 'MBricklet Temperature' class. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; + int ELECTRODE__DEVICE_TYPE = MULTI_TOUCH_DEVICE_FEATURE_COUNT + 0; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletTemperatureIRImpl MBricklet Temperature IR}' class. + * The number of structural features of the 'Electrode' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletTemperatureIRImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletTemperatureIR() * @generated + * @ordered */ - int MBRICKLET_TEMPERATURE_IR = 56; + int ELECTRODE_FEATURE_COUNT = MULTI_TOUCH_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Logger' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__LOGGER = MDEVICE__LOGGER; + int ELECTRODE___INIT = MULTI_TOUCH_DEVICE___INIT; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__UID = MDEVICE__UID; + int ELECTRODE___ENABLE = MULTI_TOUCH_DEVICE___ENABLE; /** - * The feature id for the 'Poll' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__POLL = MDEVICE__POLL; + int ELECTRODE___DISABLE = MULTI_TOUCH_DEVICE___DISABLE; /** - * The feature id for the 'Enabled A' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__ENABLED_A = MDEVICE__ENABLED_A; + int ELECTRODE___FETCH_SENSOR_VALUE = MULTI_TOUCH_DEVICE___FETCH_SENSOR_VALUE; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The number of operations of the 'Electrode' class. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int ELECTRODE_OPERATION_COUNT = MULTI_TOUCH_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Ip Connection' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.ProximityImpl Proximity}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.ProximityImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getProximity() * @generated - * @ordered */ - int MBRICKLET_TEMPERATURE_IR__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int PROXIMITY = 61; /** - * The feature id for the 'Connected Uid' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int PROXIMITY__LOGGER = MULTI_TOUCH_DEVICE__LOGGER; /** - * The feature id for the 'Position' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__POSITION = MDEVICE__POSITION; + int PROXIMITY__UID = MULTI_TOUCH_DEVICE__UID; /** - * The feature id for the 'Device Identifier' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int PROXIMITY__POLL = MULTI_TOUCH_DEVICE__POLL; /** - * The feature id for the 'Name' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__NAME = MDEVICE__NAME; + int PROXIMITY__ENABLED_A = MULTI_TOUCH_DEVICE__ENABLED_A; /** - * The feature id for the 'Brickd' container reference. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__BRICKD = MDEVICE__BRICKD; + int PROXIMITY__SUB_ID = MULTI_TOUCH_DEVICE__SUB_ID; /** - * The feature id for the 'Msubdevices' containment reference list. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; + int PROXIMITY__MBRICK = MULTI_TOUCH_DEVICE__MBRICK; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 1; + int PROXIMITY__SENSOR_VALUE = MULTI_TOUCH_DEVICE__SENSOR_VALUE; /** - * The number of structural features of the 'MBricklet Temperature IR' class. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 2; + int PROXIMITY__TF_CONFIG = MULTI_TOUCH_DEVICE__TF_CONFIG; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Pin' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR___INIT = MDEVICE___INIT; + int PROXIMITY__PIN = MULTI_TOUCH_DEVICE__PIN; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Disable Electrode' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR___ENABLE = MDEVICE___ENABLE; + int PROXIMITY__DISABLE_ELECTRODE = MULTI_TOUCH_DEVICE__DISABLE_ELECTRODE; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR___DISABLE = MDEVICE___DISABLE; + int PROXIMITY__DEVICE_TYPE = MULTI_TOUCH_DEVICE_FEATURE_COUNT + 0; /** - * The operation id for the 'Init Sub Devices' operation. + * The number of structural features of the 'Proximity' class. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; + int PROXIMITY_FEATURE_COUNT = MULTI_TOUCH_DEVICE_FEATURE_COUNT + 1; /** - * The number of operations of the 'MBricklet Temperature IR' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_TEMPERATURE_IR_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; + int PROXIMITY___INIT = MULTI_TOUCH_DEVICE___INIT; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice MTemperature IR Device}' class. + * The operation id for the 'Enable' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTemperatureIRDevice() * @generated + * @ordered */ - int MTEMPERATURE_IR_DEVICE = 57; + int PROXIMITY___ENABLE = MULTI_TOUCH_DEVICE___ENABLE; /** - * The feature id for the 'Sensor Value' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE__SENSOR_VALUE = MSENSOR__SENSOR_VALUE; + int PROXIMITY___DISABLE = MULTI_TOUCH_DEVICE___DISABLE; /** - * The feature id for the 'Logger' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE__LOGGER = MSENSOR_FEATURE_COUNT + 0; + int PROXIMITY___FETCH_SENSOR_VALUE = MULTI_TOUCH_DEVICE___FETCH_SENSOR_VALUE; /** - * The feature id for the 'Uid' attribute. + * The number of operations of the 'Proximity' class. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE__UID = MSENSOR_FEATURE_COUNT + 1; + int PROXIMITY_OPERATION_COUNT = MULTI_TOUCH_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Poll' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMotionDetectorImpl MBricklet Motion Detector}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMotionDetectorImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletMotionDetector() * @generated - * @ordered */ - int MTEMPERATURE_IR_DEVICE__POLL = MSENSOR_FEATURE_COUNT + 2; + int MBRICKLET_MOTION_DETECTOR = 62; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE__ENABLED_A = MSENSOR_FEATURE_COUNT + 3; + int MBRICKLET_MOTION_DETECTOR__LOGGER = MDEVICE__LOGGER; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE__SUB_ID = MSENSOR_FEATURE_COUNT + 4; + int MBRICKLET_MOTION_DETECTOR__UID = MDEVICE__UID; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE__MBRICK = MSENSOR_FEATURE_COUNT + 5; + int MBRICKLET_MOTION_DETECTOR__POLL = MDEVICE__POLL; /** - * The feature id for the 'Callback Period' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE__CALLBACK_PERIOD = MSENSOR_FEATURE_COUNT + 6; + int MBRICKLET_MOTION_DETECTOR__ENABLED_A = MDEVICE__ENABLED_A; /** - * The feature id for the 'Threshold' attribute. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE__THRESHOLD = MSENSOR_FEATURE_COUNT + 7; + int MBRICKLET_MOTION_DETECTOR__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The number of structural features of the 'MTemperature IR Device' class. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE_FEATURE_COUNT = MSENSOR_FEATURE_COUNT + 8; + int MBRICKLET_MOTION_DETECTOR__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE___FETCH_SENSOR_VALUE = MSENSOR___FETCH_SENSOR_VALUE; + int MBRICKLET_MOTION_DETECTOR__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE___INIT = MSENSOR_OPERATION_COUNT + 0; + int MBRICKLET_MOTION_DETECTOR__POSITION = MDEVICE__POSITION; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE___ENABLE = MSENSOR_OPERATION_COUNT + 1; + int MBRICKLET_MOTION_DETECTOR__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE___DISABLE = MSENSOR_OPERATION_COUNT + 2; + int MBRICKLET_MOTION_DETECTOR__NAME = MDEVICE__NAME; /** - * The number of operations of the 'MTemperature IR Device' class. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int MTEMPERATURE_IR_DEVICE_OPERATION_COUNT = MSENSOR_OPERATION_COUNT + 3; + int MBRICKLET_MOTION_DETECTOR__BRICKD = MDEVICE__BRICKD; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.ObjectTemperatureImpl Object Temperature}' class. + * The feature id for the 'Sensor Value' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.ObjectTemperatureImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getObjectTemperature() * @generated + * @ordered */ - int OBJECT_TEMPERATURE = 58; + int MBRICKLET_MOTION_DETECTOR__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE__SENSOR_VALUE = MTEMPERATURE_IR_DEVICE__SENSOR_VALUE; + int MBRICKLET_MOTION_DETECTOR__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Logger' attribute. + * The number of structural features of the 'MBricklet Motion Detector' class. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE__LOGGER = MTEMPERATURE_IR_DEVICE__LOGGER; + int MBRICKLET_MOTION_DETECTOR_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE__UID = MTEMPERATURE_IR_DEVICE__UID; + int MBRICKLET_MOTION_DETECTOR___ENABLE = MDEVICE___ENABLE; /** - * The feature id for the 'Poll' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE__POLL = MTEMPERATURE_IR_DEVICE__POLL; + int MBRICKLET_MOTION_DETECTOR___DISABLE = MDEVICE___DISABLE; /** - * The feature id for the 'Enabled A' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE__ENABLED_A = MTEMPERATURE_IR_DEVICE__ENABLED_A; + int MBRICKLET_MOTION_DETECTOR___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Sub Id' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE__SUB_ID = MTEMPERATURE_IR_DEVICE__SUB_ID; + int MBRICKLET_MOTION_DETECTOR___INIT = MDEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Mbrick' container reference. + * The number of operations of the 'MBricklet Motion Detector' class. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE__MBRICK = MTEMPERATURE_IR_DEVICE__MBRICK; + int MBRICKLET_MOTION_DETECTOR_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; /** - * The feature id for the 'Callback Period' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletHallEffectImpl MBricklet Hall Effect}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletHallEffectImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletHallEffect() * @generated - * @ordered */ - int OBJECT_TEMPERATURE__CALLBACK_PERIOD = MTEMPERATURE_IR_DEVICE__CALLBACK_PERIOD; + int MBRICKLET_HALL_EFFECT = 63; /** - * The feature id for the 'Threshold' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE__THRESHOLD = MTEMPERATURE_IR_DEVICE__THRESHOLD; + int MBRICKLET_HALL_EFFECT__LOGGER = MDEVICE__LOGGER; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE__TF_CONFIG = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 0; + int MBRICKLET_HALL_EFFECT__UID = MDEVICE__UID; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE__DEVICE_TYPE = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 1; + int MBRICKLET_HALL_EFFECT__POLL = MDEVICE__POLL; /** - * The feature id for the 'Emissivity' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE__EMISSIVITY = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 2; + int MBRICKLET_HALL_EFFECT__ENABLED_A = MDEVICE__ENABLED_A; /** - * The number of structural features of the 'Object Temperature' class. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE_FEATURE_COUNT = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 3; + int MBRICKLET_HALL_EFFECT__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE___FETCH_SENSOR_VALUE = MTEMPERATURE_IR_DEVICE___FETCH_SENSOR_VALUE; + int MBRICKLET_HALL_EFFECT__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE___INIT = MTEMPERATURE_IR_DEVICE___INIT; + int MBRICKLET_HALL_EFFECT__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE___ENABLE = MTEMPERATURE_IR_DEVICE___ENABLE; + int MBRICKLET_HALL_EFFECT__POSITION = MDEVICE__POSITION; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE___DISABLE = MTEMPERATURE_IR_DEVICE___DISABLE; + int MBRICKLET_HALL_EFFECT__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The number of operations of the 'Object Temperature' class. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int OBJECT_TEMPERATURE_OPERATION_COUNT = MTEMPERATURE_IR_DEVICE_OPERATION_COUNT + 0; + int MBRICKLET_HALL_EFFECT__NAME = MDEVICE__NAME; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.AmbientTemperatureImpl Ambient Temperature}' class. + * The feature id for the 'Brickd' container reference. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.AmbientTemperatureImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getAmbientTemperature() * @generated + * @ordered */ - int AMBIENT_TEMPERATURE = 59; + int MBRICKLET_HALL_EFFECT__BRICKD = MDEVICE__BRICKD; /** * The feature id for the 'Sensor Value' attribute. @@ -8315,1147 +8395,1146 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int AMBIENT_TEMPERATURE__SENSOR_VALUE = MTEMPERATURE_IR_DEVICE__SENSOR_VALUE; + int MBRICKLET_HALL_EFFECT__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE__LOGGER = MTEMPERATURE_IR_DEVICE__LOGGER; + int MBRICKLET_HALL_EFFECT__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE__UID = MTEMPERATURE_IR_DEVICE__UID; + int MBRICKLET_HALL_EFFECT__TF_CONFIG = MDEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE__POLL = MTEMPERATURE_IR_DEVICE__POLL; + int MBRICKLET_HALL_EFFECT__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; /** - * The feature id for the 'Enabled A' attribute. + * The number of structural features of the 'MBricklet Hall Effect' class. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE__ENABLED_A = MTEMPERATURE_IR_DEVICE__ENABLED_A; + int MBRICKLET_HALL_EFFECT_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 4; /** - * The feature id for the 'Sub Id' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE__SUB_ID = MTEMPERATURE_IR_DEVICE__SUB_ID; + int MBRICKLET_HALL_EFFECT___ENABLE = MDEVICE___ENABLE; /** - * The feature id for the 'Mbrick' container reference. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE__MBRICK = MTEMPERATURE_IR_DEVICE__MBRICK; + int MBRICKLET_HALL_EFFECT___DISABLE = MDEVICE___DISABLE; /** - * The feature id for the 'Callback Period' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE__CALLBACK_PERIOD = MTEMPERATURE_IR_DEVICE__CALLBACK_PERIOD; + int MBRICKLET_HALL_EFFECT___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Threshold' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE__THRESHOLD = MTEMPERATURE_IR_DEVICE__THRESHOLD; + int MBRICKLET_HALL_EFFECT___INIT = MDEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Tf Config' containment reference. + * The number of operations of the 'MBricklet Hall Effect' class. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE__TF_CONFIG = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 0; + int MBRICKLET_HALL_EFFECT_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Switch State' attribute. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE__DEVICE_TYPE = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 1; + int MDUAL_RELAY__SWITCH_STATE = MIN_SWITCH_ACTOR__SWITCH_STATE; /** - * The number of structural features of the 'Ambient Temperature' class. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE_FEATURE_COUNT = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 2; + int MDUAL_RELAY__LOGGER = MIN_SWITCH_ACTOR_FEATURE_COUNT + 0; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE___FETCH_SENSOR_VALUE = MTEMPERATURE_IR_DEVICE___FETCH_SENSOR_VALUE; + int MDUAL_RELAY__UID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 1; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE___INIT = MTEMPERATURE_IR_DEVICE___INIT; + int MDUAL_RELAY__POLL = MIN_SWITCH_ACTOR_FEATURE_COUNT + 2; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE___ENABLE = MTEMPERATURE_IR_DEVICE___ENABLE; + int MDUAL_RELAY__ENABLED_A = MIN_SWITCH_ACTOR_FEATURE_COUNT + 3; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE___DISABLE = MTEMPERATURE_IR_DEVICE___DISABLE; + int MDUAL_RELAY__SUB_ID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 4; /** - * The number of operations of the 'Ambient Temperature' class. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int AMBIENT_TEMPERATURE_OPERATION_COUNT = MTEMPERATURE_IR_DEVICE_OPERATION_COUNT + 0; + int MDUAL_RELAY__MBRICK = MIN_SWITCH_ACTOR_FEATURE_COUNT + 5; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletTiltImpl MBricklet Tilt}' class. + * The feature id for the 'Device Type' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletTiltImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletTilt() * @generated + * @ordered */ - int MBRICKLET_TILT = 60; + int MDUAL_RELAY__DEVICE_TYPE = MIN_SWITCH_ACTOR_FEATURE_COUNT + 6; /** - * The feature id for the 'Logger' attribute. + * The number of structural features of the 'MDual Relay' class. * * * @generated * @ordered */ - int MBRICKLET_TILT__LOGGER = MDEVICE__LOGGER; + int MDUAL_RELAY_FEATURE_COUNT = MIN_SWITCH_ACTOR_FEATURE_COUNT + 7; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Fetch Switch State' operation. * * * @generated * @ordered */ - int MBRICKLET_TILT__UID = MDEVICE__UID; + int MDUAL_RELAY___FETCH_SWITCH_STATE = MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE; /** - * The feature id for the 'Poll' attribute. + * The operation id for the 'Turn Switch' operation. * * * @generated * @ordered */ - int MBRICKLET_TILT__POLL = MDEVICE__POLL; + int MDUAL_RELAY___TURN_SWITCH__ONOFFVALUE = MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; /** - * The feature id for the 'Enabled A' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_TILT__ENABLED_A = MDEVICE__ENABLED_A; + int MDUAL_RELAY___INIT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 0; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_TILT__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MDUAL_RELAY___ENABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 1; /** - * The feature id for the 'Ip Connection' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_TILT__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MDUAL_RELAY___DISABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 2; /** - * The feature id for the 'Connected Uid' attribute. + * The number of operations of the 'MDual Relay' class. * * * @generated * @ordered */ - int MBRICKLET_TILT__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MDUAL_RELAY_OPERATION_COUNT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 3; /** - * The feature id for the 'Position' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletRemoteSwitchImpl MBricklet Remote Switch}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletRemoteSwitchImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletRemoteSwitch() * @generated - * @ordered */ - int MBRICKLET_TILT__POSITION = MDEVICE__POSITION; + int MBRICKLET_REMOTE_SWITCH = 65; /** - * The feature id for the 'Device Identifier' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_TILT__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICKLET_REMOTE_SWITCH__LOGGER = MDEVICE__LOGGER; /** - * The feature id for the 'Name' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_TILT__NAME = MDEVICE__NAME; + int MBRICKLET_REMOTE_SWITCH__UID = MDEVICE__UID; /** - * The feature id for the 'Brickd' container reference. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_TILT__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_REMOTE_SWITCH__POLL = MDEVICE__POLL; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_TILT__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_REMOTE_SWITCH__ENABLED_A = MDEVICE__ENABLED_A; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int MBRICKLET_TILT__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 1; + int MBRICKLET_REMOTE_SWITCH__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The number of structural features of the 'MBricklet Tilt' class. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int MBRICKLET_TILT_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 2; + int MBRICKLET_REMOTE_SWITCH__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_TILT___INIT = MDEVICE___INIT; + int MBRICKLET_REMOTE_SWITCH__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int MBRICKLET_TILT___ENABLE = MDEVICE___ENABLE; + int MBRICKLET_REMOTE_SWITCH__POSITION = MDEVICE__POSITION; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int MBRICKLET_TILT___DISABLE = MDEVICE___DISABLE; + int MBRICKLET_REMOTE_SWITCH__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int MBRICKLET_TILT___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; + int MBRICKLET_REMOTE_SWITCH__NAME = MDEVICE__NAME; /** - * The number of operations of the 'MBricklet Tilt' class. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int MBRICKLET_TILT_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; + int MBRICKLET_REMOTE_SWITCH__BRICKD = MDEVICE__BRICKD; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletVoltageCurrentImpl MBricklet Voltage Current}' class. + * The feature id for the 'Msubdevices' containment reference list. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletVoltageCurrentImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletVoltageCurrent() * @generated + * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT = 61; + int MBRICKLET_REMOTE_SWITCH__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__LOGGER = MDEVICE__LOGGER; + int MBRICKLET_REMOTE_SWITCH__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__UID = MDEVICE__UID; + int MBRICKLET_REMOTE_SWITCH__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Type ADevices' attribute. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__POLL = MDEVICE__POLL; + int MBRICKLET_REMOTE_SWITCH__TYPE_ADEVICES = MDEVICE_FEATURE_COUNT + 3; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Type BDevices' attribute. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__ENABLED_A = MDEVICE__ENABLED_A; + int MBRICKLET_REMOTE_SWITCH__TYPE_BDEVICES = MDEVICE_FEATURE_COUNT + 4; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The feature id for the 'Type CDevices' attribute. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MBRICKLET_REMOTE_SWITCH__TYPE_CDEVICES = MDEVICE_FEATURE_COUNT + 5; /** - * The feature id for the 'Ip Connection' attribute. + * The number of structural features of the 'MBricklet Remote Switch' class. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MBRICKLET_REMOTE_SWITCH_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 6; /** - * The feature id for the 'Connected Uid' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MBRICKLET_REMOTE_SWITCH___INIT = MDEVICE___INIT; /** - * The feature id for the 'Position' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__POSITION = MDEVICE__POSITION; + int MBRICKLET_REMOTE_SWITCH___ENABLE = MDEVICE___ENABLE; /** - * The feature id for the 'Device Identifier' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICKLET_REMOTE_SWITCH___DISABLE = MDEVICE___DISABLE; /** - * The feature id for the 'Name' attribute. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__NAME = MDEVICE__NAME; + int MBRICKLET_REMOTE_SWITCH___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Brickd' container reference. + * The operation id for the 'Add Sub Device' operation. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_REMOTE_SWITCH___ADD_SUB_DEVICE__STRING_STRING = MDEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Msubdevices' containment reference list. + * The number of operations of the 'MBricklet Remote Switch' class. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_REMOTE_SWITCH_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; /** - * The feature id for the 'Tf Config' containment reference. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitch Remote Switch}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitch + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitch() * @generated - * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; + int REMOTE_SWITCH = 66; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Switch State' attribute. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 2; + int REMOTE_SWITCH__SWITCH_STATE = MIN_SWITCH_ACTOR__SWITCH_STATE; /** - * The feature id for the 'Averaging' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__AVERAGING = MDEVICE_FEATURE_COUNT + 3; + int REMOTE_SWITCH__LOGGER = MIN_SWITCH_ACTOR_FEATURE_COUNT + 0; /** - * The feature id for the 'Voltage Conversion Time' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__VOLTAGE_CONVERSION_TIME = MDEVICE_FEATURE_COUNT + 4; + int REMOTE_SWITCH__UID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 1; /** - * The feature id for the 'Current Conversion Time' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT__CURRENT_CONVERSION_TIME = MDEVICE_FEATURE_COUNT + 5; + int REMOTE_SWITCH__POLL = MIN_SWITCH_ACTOR_FEATURE_COUNT + 2; /** - * The number of structural features of the 'MBricklet Voltage Current' class. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 6; + int REMOTE_SWITCH__ENABLED_A = MIN_SWITCH_ACTOR_FEATURE_COUNT + 3; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT___INIT = MDEVICE___INIT; + int REMOTE_SWITCH__SUB_ID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 4; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT___ENABLE = MDEVICE___ENABLE; + int REMOTE_SWITCH__MBRICK = MIN_SWITCH_ACTOR_FEATURE_COUNT + 5; /** - * The operation id for the 'Disable' operation. + * The number of structural features of the 'Remote Switch' class. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT___DISABLE = MDEVICE___DISABLE; + int REMOTE_SWITCH_FEATURE_COUNT = MIN_SWITCH_ACTOR_FEATURE_COUNT + 6; /** - * The operation id for the 'Init Sub Devices' operation. + * The operation id for the 'Fetch Switch State' operation. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; + int REMOTE_SWITCH___FETCH_SWITCH_STATE = MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE; /** - * The number of operations of the 'MBricklet Voltage Current' class. + * The operation id for the 'Turn Switch' operation. * * * @generated * @ordered */ - int MBRICKLET_VOLTAGE_CURRENT_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; + int REMOTE_SWITCH___TURN_SWITCH__ONOFFVALUE = MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.VoltageCurrentDevice Voltage Current Device}' class. + * The operation id for the 'Init' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.VoltageCurrentDevice - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getVoltageCurrentDevice() * @generated + * @ordered */ - int VOLTAGE_CURRENT_DEVICE = 62; + int REMOTE_SWITCH___INIT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 0; /** - * The feature id for the 'Sensor Value' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE__SENSOR_VALUE = MSENSOR__SENSOR_VALUE; + int REMOTE_SWITCH___ENABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 1; /** - * The feature id for the 'Logger' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE__LOGGER = MSENSOR_FEATURE_COUNT + 0; + int REMOTE_SWITCH___DISABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 2; /** - * The feature id for the 'Uid' attribute. + * The number of operations of the 'Remote Switch' class. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE__UID = MSENSOR_FEATURE_COUNT + 1; + int REMOTE_SWITCH_OPERATION_COUNT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 3; /** - * The feature id for the 'Poll' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchAImpl Remote Switch A}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchAImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchA() * @generated - * @ordered */ - int VOLTAGE_CURRENT_DEVICE__POLL = MSENSOR_FEATURE_COUNT + 2; + int REMOTE_SWITCH_A = 67; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Switch State' attribute. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE__ENABLED_A = MSENSOR_FEATURE_COUNT + 3; + int REMOTE_SWITCH_A__SWITCH_STATE = REMOTE_SWITCH__SWITCH_STATE; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE__SUB_ID = MSENSOR_FEATURE_COUNT + 4; + int REMOTE_SWITCH_A__LOGGER = REMOTE_SWITCH__LOGGER; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE__MBRICK = MSENSOR_FEATURE_COUNT + 5; + int REMOTE_SWITCH_A__UID = REMOTE_SWITCH__UID; /** - * The feature id for the 'Callback Period' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE__CALLBACK_PERIOD = MSENSOR_FEATURE_COUNT + 6; + int REMOTE_SWITCH_A__POLL = REMOTE_SWITCH__POLL; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE__TF_CONFIG = MSENSOR_FEATURE_COUNT + 7; + int REMOTE_SWITCH_A__ENABLED_A = REMOTE_SWITCH__ENABLED_A; /** - * The number of structural features of the 'Voltage Current Device' class. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT = MSENSOR_FEATURE_COUNT + 8; + int REMOTE_SWITCH_A__SUB_ID = REMOTE_SWITCH__SUB_ID; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE___FETCH_SENSOR_VALUE = MSENSOR___FETCH_SENSOR_VALUE; + int REMOTE_SWITCH_A__MBRICK = REMOTE_SWITCH__MBRICK; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE___INIT = MSENSOR_OPERATION_COUNT + 0; + int REMOTE_SWITCH_A__TF_CONFIG = REMOTE_SWITCH_FEATURE_COUNT + 0; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE___ENABLE = MSENSOR_OPERATION_COUNT + 1; + int REMOTE_SWITCH_A__DEVICE_TYPE = REMOTE_SWITCH_FEATURE_COUNT + 1; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'House Code' attribute. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE___DISABLE = MSENSOR_OPERATION_COUNT + 2; + int REMOTE_SWITCH_A__HOUSE_CODE = REMOTE_SWITCH_FEATURE_COUNT + 2; /** - * The number of operations of the 'Voltage Current Device' class. + * The feature id for the 'Receiver Code' attribute. * * * @generated * @ordered */ - int VOLTAGE_CURRENT_DEVICE_OPERATION_COUNT = MSENSOR_OPERATION_COUNT + 3; + int REMOTE_SWITCH_A__RECEIVER_CODE = REMOTE_SWITCH_FEATURE_COUNT + 3; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.VCDeviceVoltageImpl VC Device Voltage}' class. + * The feature id for the 'Repeats' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.VCDeviceVoltageImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getVCDeviceVoltage() * @generated + * @ordered */ - int VC_DEVICE_VOLTAGE = 63; + int REMOTE_SWITCH_A__REPEATS = REMOTE_SWITCH_FEATURE_COUNT + 4; /** - * The feature id for the 'Sensor Value' attribute. + * The number of structural features of the 'Remote Switch A' class. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE__SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE__SENSOR_VALUE; + int REMOTE_SWITCH_A_FEATURE_COUNT = REMOTE_SWITCH_FEATURE_COUNT + 5; /** - * The feature id for the 'Logger' attribute. + * The operation id for the 'Fetch Switch State' operation. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE__LOGGER = VOLTAGE_CURRENT_DEVICE__LOGGER; + int REMOTE_SWITCH_A___FETCH_SWITCH_STATE = REMOTE_SWITCH___FETCH_SWITCH_STATE; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Turn Switch' operation. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE__UID = VOLTAGE_CURRENT_DEVICE__UID; + int REMOTE_SWITCH_A___TURN_SWITCH__ONOFFVALUE = REMOTE_SWITCH___TURN_SWITCH__ONOFFVALUE; /** - * The feature id for the 'Poll' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE__POLL = VOLTAGE_CURRENT_DEVICE__POLL; + int REMOTE_SWITCH_A___INIT = REMOTE_SWITCH___INIT; /** - * The feature id for the 'Enabled A' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE__ENABLED_A = VOLTAGE_CURRENT_DEVICE__ENABLED_A; + int REMOTE_SWITCH_A___ENABLE = REMOTE_SWITCH___ENABLE; /** - * The feature id for the 'Sub Id' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE__SUB_ID = VOLTAGE_CURRENT_DEVICE__SUB_ID; + int REMOTE_SWITCH_A___DISABLE = REMOTE_SWITCH___DISABLE; /** - * The feature id for the 'Mbrick' container reference. + * The number of operations of the 'Remote Switch A' class. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE__MBRICK = VOLTAGE_CURRENT_DEVICE__MBRICK; + int REMOTE_SWITCH_A_OPERATION_COUNT = REMOTE_SWITCH_OPERATION_COUNT + 0; /** - * The feature id for the 'Callback Period' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl Remote Switch B}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchB() * @generated - * @ordered */ - int VC_DEVICE_VOLTAGE__CALLBACK_PERIOD = VOLTAGE_CURRENT_DEVICE__CALLBACK_PERIOD; + int REMOTE_SWITCH_B = 68; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE__TF_CONFIG = VOLTAGE_CURRENT_DEVICE__TF_CONFIG; + int REMOTE_SWITCH_B__SENSOR_VALUE = MSENSOR__SENSOR_VALUE; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Switch State' attribute. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE__DEVICE_TYPE = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 0; + int REMOTE_SWITCH_B__SWITCH_STATE = MSENSOR_FEATURE_COUNT + 0; /** - * The feature id for the 'Threshold' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE__THRESHOLD = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 1; + int REMOTE_SWITCH_B__LOGGER = MSENSOR_FEATURE_COUNT + 1; /** - * The number of structural features of the 'VC Device Voltage' class. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE_FEATURE_COUNT = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 2; + int REMOTE_SWITCH_B__UID = MSENSOR_FEATURE_COUNT + 2; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE___FETCH_SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE___FETCH_SENSOR_VALUE; + int REMOTE_SWITCH_B__POLL = MSENSOR_FEATURE_COUNT + 3; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE___INIT = VOLTAGE_CURRENT_DEVICE___INIT; + int REMOTE_SWITCH_B__ENABLED_A = MSENSOR_FEATURE_COUNT + 4; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE___ENABLE = VOLTAGE_CURRENT_DEVICE___ENABLE; + int REMOTE_SWITCH_B__SUB_ID = MSENSOR_FEATURE_COUNT + 5; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE___DISABLE = VOLTAGE_CURRENT_DEVICE___DISABLE; + int REMOTE_SWITCH_B__MBRICK = MSENSOR_FEATURE_COUNT + 6; /** - * The number of operations of the 'VC Device Voltage' class. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int VC_DEVICE_VOLTAGE_OPERATION_COUNT = VOLTAGE_CURRENT_DEVICE_OPERATION_COUNT + 0; + int REMOTE_SWITCH_B__TF_CONFIG = MSENSOR_FEATURE_COUNT + 7; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.VCDeviceCurrentImpl VC Device Current}' class. + * The feature id for the 'Min Value' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.VCDeviceCurrentImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getVCDeviceCurrent() * @generated + * @ordered */ - int VC_DEVICE_CURRENT = 64; + int REMOTE_SWITCH_B__MIN_VALUE = MSENSOR_FEATURE_COUNT + 8; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Max Value' attribute. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT__SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE__SENSOR_VALUE; + int REMOTE_SWITCH_B__MAX_VALUE = MSENSOR_FEATURE_COUNT + 9; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT__LOGGER = VOLTAGE_CURRENT_DEVICE__LOGGER; + int REMOTE_SWITCH_B__DEVICE_TYPE = MSENSOR_FEATURE_COUNT + 10; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Address' attribute. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT__UID = VOLTAGE_CURRENT_DEVICE__UID; + int REMOTE_SWITCH_B__ADDRESS = MSENSOR_FEATURE_COUNT + 11; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Unit' attribute. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT__POLL = VOLTAGE_CURRENT_DEVICE__POLL; + int REMOTE_SWITCH_B__UNIT = MSENSOR_FEATURE_COUNT + 12; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Repeats' attribute. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT__ENABLED_A = VOLTAGE_CURRENT_DEVICE__ENABLED_A; + int REMOTE_SWITCH_B__REPEATS = MSENSOR_FEATURE_COUNT + 13; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Target Dimmvalue' attribute. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT__SUB_ID = VOLTAGE_CURRENT_DEVICE__SUB_ID; + int REMOTE_SWITCH_B__TARGET_DIMMVALUE = MSENSOR_FEATURE_COUNT + 14; /** - * The feature id for the 'Mbrick' container reference. + * The number of structural features of the 'Remote Switch B' class. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT__MBRICK = VOLTAGE_CURRENT_DEVICE__MBRICK; + int REMOTE_SWITCH_B_FEATURE_COUNT = MSENSOR_FEATURE_COUNT + 15; /** - * The feature id for the 'Callback Period' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT__CALLBACK_PERIOD = VOLTAGE_CURRENT_DEVICE__CALLBACK_PERIOD; + int REMOTE_SWITCH_B___FETCH_SENSOR_VALUE = MSENSOR___FETCH_SENSOR_VALUE; /** - * The feature id for the 'Tf Config' containment reference. + * The operation id for the 'Fetch Switch State' operation. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT__TF_CONFIG = VOLTAGE_CURRENT_DEVICE__TF_CONFIG; + int REMOTE_SWITCH_B___FETCH_SWITCH_STATE = MSENSOR_OPERATION_COUNT + 0; /** - * The feature id for the 'Device Type' attribute. + * The operation id for the 'Turn Switch' operation. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT__DEVICE_TYPE = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 0; + int REMOTE_SWITCH_B___TURN_SWITCH__ONOFFVALUE = MSENSOR_OPERATION_COUNT + 1; /** - * The feature id for the 'Threshold' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT__THRESHOLD = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 1; + int REMOTE_SWITCH_B___INIT = MSENSOR_OPERATION_COUNT + 2; /** - * The number of structural features of the 'VC Device Current' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT_FEATURE_COUNT = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 2; + int REMOTE_SWITCH_B___ENABLE = MSENSOR_OPERATION_COUNT + 3; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT___FETCH_SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE___FETCH_SENSOR_VALUE; + int REMOTE_SWITCH_B___DISABLE = MSENSOR_OPERATION_COUNT + 4; /** - * The operation id for the 'Init' operation. + * The operation id for the 'Dimm' operation. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT___INIT = VOLTAGE_CURRENT_DEVICE___INIT; + int REMOTE_SWITCH_B___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS = MSENSOR_OPERATION_COUNT + 5; /** - * The operation id for the 'Enable' operation. + * The number of operations of the 'Remote Switch B' class. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT___ENABLE = VOLTAGE_CURRENT_DEVICE___ENABLE; + int REMOTE_SWITCH_B_OPERATION_COUNT = MSENSOR_OPERATION_COUNT + 6; /** - * The operation id for the 'Disable' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchCImpl Remote Switch C}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchCImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchC() * @generated - * @ordered */ - int VC_DEVICE_CURRENT___DISABLE = VOLTAGE_CURRENT_DEVICE___DISABLE; + int REMOTE_SWITCH_C = 69; /** - * The number of operations of the 'VC Device Current' class. + * The feature id for the 'Switch State' attribute. * * * @generated * @ordered */ - int VC_DEVICE_CURRENT_OPERATION_COUNT = VOLTAGE_CURRENT_DEVICE_OPERATION_COUNT + 0; + int REMOTE_SWITCH_C__SWITCH_STATE = REMOTE_SWITCH__SWITCH_STATE; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.VCDevicePowerImpl VC Device Power}' class. + * The feature id for the 'Logger' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.VCDevicePowerImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getVCDevicePower() * @generated + * @ordered */ - int VC_DEVICE_POWER = 65; + int REMOTE_SWITCH_C__LOGGER = REMOTE_SWITCH__LOGGER; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int VC_DEVICE_POWER__SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE__SENSOR_VALUE; + int REMOTE_SWITCH_C__UID = REMOTE_SWITCH__UID; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int VC_DEVICE_POWER__LOGGER = VOLTAGE_CURRENT_DEVICE__LOGGER; + int REMOTE_SWITCH_C__POLL = REMOTE_SWITCH__POLL; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int VC_DEVICE_POWER__UID = VOLTAGE_CURRENT_DEVICE__UID; + int REMOTE_SWITCH_C__ENABLED_A = REMOTE_SWITCH__ENABLED_A; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int VC_DEVICE_POWER__POLL = VOLTAGE_CURRENT_DEVICE__POLL; + int REMOTE_SWITCH_C__SUB_ID = REMOTE_SWITCH__SUB_ID; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int VC_DEVICE_POWER__ENABLED_A = VOLTAGE_CURRENT_DEVICE__ENABLED_A; + int REMOTE_SWITCH_C__MBRICK = REMOTE_SWITCH__MBRICK; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int VC_DEVICE_POWER__SUB_ID = VOLTAGE_CURRENT_DEVICE__SUB_ID; + int REMOTE_SWITCH_C__TF_CONFIG = REMOTE_SWITCH_FEATURE_COUNT + 0; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int VC_DEVICE_POWER__MBRICK = VOLTAGE_CURRENT_DEVICE__MBRICK; + int REMOTE_SWITCH_C__DEVICE_TYPE = REMOTE_SWITCH_FEATURE_COUNT + 1; /** - * The feature id for the 'Callback Period' attribute. + * The feature id for the 'System Code' attribute. * * * @generated * @ordered */ - int VC_DEVICE_POWER__CALLBACK_PERIOD = VOLTAGE_CURRENT_DEVICE__CALLBACK_PERIOD; + int REMOTE_SWITCH_C__SYSTEM_CODE = REMOTE_SWITCH_FEATURE_COUNT + 2; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Device Code' attribute. * * * @generated * @ordered */ - int VC_DEVICE_POWER__TF_CONFIG = VOLTAGE_CURRENT_DEVICE__TF_CONFIG; + int REMOTE_SWITCH_C__DEVICE_CODE = REMOTE_SWITCH_FEATURE_COUNT + 3; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Repeats' attribute. * * * @generated * @ordered */ - int VC_DEVICE_POWER__DEVICE_TYPE = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 0; + int REMOTE_SWITCH_C__REPEATS = REMOTE_SWITCH_FEATURE_COUNT + 4; /** - * The feature id for the 'Threshold' attribute. + * The number of structural features of the 'Remote Switch C' class. * * * @generated * @ordered */ - int VC_DEVICE_POWER__THRESHOLD = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 1; + int REMOTE_SWITCH_C_FEATURE_COUNT = REMOTE_SWITCH_FEATURE_COUNT + 5; /** - * The number of structural features of the 'VC Device Power' class. + * The operation id for the 'Fetch Switch State' operation. * * * @generated * @ordered */ - int VC_DEVICE_POWER_FEATURE_COUNT = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 2; + int REMOTE_SWITCH_C___FETCH_SWITCH_STATE = REMOTE_SWITCH___FETCH_SWITCH_STATE; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The operation id for the 'Turn Switch' operation. * * * @generated * @ordered */ - int VC_DEVICE_POWER___FETCH_SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE___FETCH_SENSOR_VALUE; + int REMOTE_SWITCH_C___TURN_SWITCH__ONOFFVALUE = REMOTE_SWITCH___TURN_SWITCH__ONOFFVALUE; /** * The operation id for the 'Init' operation. @@ -9464,7 +9543,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int VC_DEVICE_POWER___INIT = VOLTAGE_CURRENT_DEVICE___INIT; + int REMOTE_SWITCH_C___INIT = REMOTE_SWITCH___INIT; /** * The operation id for the 'Enable' operation. @@ -9473,7 +9552,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int VC_DEVICE_POWER___ENABLE = VOLTAGE_CURRENT_DEVICE___ENABLE; + int REMOTE_SWITCH_C___ENABLE = REMOTE_SWITCH___ENABLE; /** * The operation id for the 'Disable' operation. @@ -9482,34 +9561,43 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int VC_DEVICE_POWER___DISABLE = VOLTAGE_CURRENT_DEVICE___DISABLE; + int REMOTE_SWITCH_C___DISABLE = REMOTE_SWITCH___DISABLE; /** - * The number of operations of the 'VC Device Power' class. + * The number of operations of the 'Remote Switch C' class. * * * @generated * @ordered */ - int VC_DEVICE_POWER_OPERATION_COUNT = VOLTAGE_CURRENT_DEVICE_OPERATION_COUNT + 0; + int REMOTE_SWITCH_C_OPERATION_COUNT = REMOTE_SWITCH_OPERATION_COUNT + 0; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER__LOGGER = MDEVICE__LOGGER; + int MBRICKLET_HUMIDITY__SENSOR_VALUE = MSENSOR__SENSOR_VALUE; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER__UID = MDEVICE__UID; + int MBRICKLET_HUMIDITY__LOGGER = MSENSOR_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Uid' attribute. + * + * + * @generated + * @ordered + */ + int MBRICKLET_HUMIDITY__UID = MSENSOR_FEATURE_COUNT + 1; /** * The feature id for the 'Poll' attribute. @@ -9518,7 +9606,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_BAROMETER__POLL = MDEVICE__POLL; + int MBRICKLET_HUMIDITY__POLL = MSENSOR_FEATURE_COUNT + 2; /** * The feature id for the 'Enabled A' attribute. @@ -9527,7 +9615,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_BAROMETER__ENABLED_A = MDEVICE__ENABLED_A; + int MBRICKLET_HUMIDITY__ENABLED_A = MSENSOR_FEATURE_COUNT + 3; /** * The feature id for the 'Tinkerforge Device' attribute. @@ -9536,7 +9624,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_BAROMETER__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MBRICKLET_HUMIDITY__TINKERFORGE_DEVICE = MSENSOR_FEATURE_COUNT + 4; /** * The feature id for the 'Ip Connection' attribute. @@ -9545,7 +9633,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_BAROMETER__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MBRICKLET_HUMIDITY__IP_CONNECTION = MSENSOR_FEATURE_COUNT + 5; /** * The feature id for the 'Connected Uid' attribute. @@ -9554,7 +9642,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_BAROMETER__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MBRICKLET_HUMIDITY__CONNECTED_UID = MSENSOR_FEATURE_COUNT + 6; /** * The feature id for the 'Position' attribute. @@ -9563,7 +9651,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_BAROMETER__POSITION = MDEVICE__POSITION; + int MBRICKLET_HUMIDITY__POSITION = MSENSOR_FEATURE_COUNT + 7; /** * The feature id for the 'Device Identifier' attribute. @@ -9572,7 +9660,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_BAROMETER__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICKLET_HUMIDITY__DEVICE_IDENTIFIER = MSENSOR_FEATURE_COUNT + 8; /** * The feature id for the 'Name' attribute. @@ -9581,7 +9669,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_BAROMETER__NAME = MDEVICE__NAME; + int MBRICKLET_HUMIDITY__NAME = MSENSOR_FEATURE_COUNT + 9; /** * The feature id for the 'Brickd' container reference. @@ -9590,187 +9678,223 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_BAROMETER__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_HUMIDITY__BRICKD = MSENSOR_FEATURE_COUNT + 10; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_HUMIDITY__TF_CONFIG = MSENSOR_FEATURE_COUNT + 11; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; + int MBRICKLET_HUMIDITY__CALLBACK_PERIOD = MSENSOR_FEATURE_COUNT + 12; /** - * The feature id for the 'Msubdevices' containment reference list. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 2; + int MBRICKLET_HUMIDITY__DEVICE_TYPE = MSENSOR_FEATURE_COUNT + 13; /** - * The feature id for the 'Callback Period' attribute. + * The feature id for the 'Threshold' attribute. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 3; + int MBRICKLET_HUMIDITY__THRESHOLD = MSENSOR_FEATURE_COUNT + 14; /** - * The feature id for the 'Device Type' attribute. + * The number of structural features of the 'MBricklet Humidity' class. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 4; + int MBRICKLET_HUMIDITY_FEATURE_COUNT = MSENSOR_FEATURE_COUNT + 15; /** - * The feature id for the 'Threshold' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER__THRESHOLD = MDEVICE_FEATURE_COUNT + 5; + int MBRICKLET_HUMIDITY___FETCH_SENSOR_VALUE = MSENSOR___FETCH_SENSOR_VALUE; /** - * The number of structural features of the 'MBricklet Barometer' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 6; + int MBRICKLET_HUMIDITY___ENABLE = MSENSOR_OPERATION_COUNT + 1; /** - * The operation id for the 'Enable' operation. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER___ENABLE = MDEVICE___ENABLE; + int MBRICKLET_HUMIDITY___DISABLE = MSENSOR_OPERATION_COUNT + 2; /** - * The operation id for the 'Disable' operation. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER___DISABLE = MDEVICE___DISABLE; + int MBRICKLET_HUMIDITY___INIT = MSENSOR_OPERATION_COUNT + 3; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The number of operations of the 'MBricklet Humidity' class. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; + int MBRICKLET_HUMIDITY_OPERATION_COUNT = MSENSOR_OPERATION_COUNT + 4; /** - * The operation id for the 'Init Sub Devices' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 1; + int MBRICKLET_DISTANCE_IR__LOGGER = MDEVICE__LOGGER; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER___INIT = MDEVICE_OPERATION_COUNT + 2; + int MBRICKLET_DISTANCE_IR__UID = MDEVICE__UID; /** - * The number of operations of the 'MBricklet Barometer' class. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_BAROMETER_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 3; + int MBRICKLET_DISTANCE_IR__POLL = MDEVICE__POLL; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBAROMETER_TEMPERATURE__SENSOR_VALUE = MSENSOR__SENSOR_VALUE; + int MBRICKLET_DISTANCE_IR__ENABLED_A = MDEVICE__ENABLED_A; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int MBAROMETER_TEMPERATURE__LOGGER = MSENSOR_FEATURE_COUNT + 0; + int MBRICKLET_DISTANCE_IR__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int MBAROMETER_TEMPERATURE__UID = MSENSOR_FEATURE_COUNT + 1; + int MBRICKLET_DISTANCE_IR__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int MBAROMETER_TEMPERATURE__POLL = MSENSOR_FEATURE_COUNT + 2; + int MBRICKLET_DISTANCE_IR__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int MBAROMETER_TEMPERATURE__ENABLED_A = MSENSOR_FEATURE_COUNT + 3; + int MBRICKLET_DISTANCE_IR__POSITION = MDEVICE__POSITION; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int MBAROMETER_TEMPERATURE__SUB_ID = MSENSOR_FEATURE_COUNT + 4; + int MBRICKLET_DISTANCE_IR__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int MBAROMETER_TEMPERATURE__MBRICK = MSENSOR_FEATURE_COUNT + 5; + int MBRICKLET_DISTANCE_IR__NAME = MDEVICE__NAME; + + /** + * The feature id for the 'Brickd' container reference. + * + * + * @generated + * @ordered + */ + int MBRICKLET_DISTANCE_IR__BRICKD = MDEVICE__BRICKD; + + /** + * The feature id for the 'Sensor Value' attribute. + * + * + * @generated + * @ordered + */ + int MBRICKLET_DISTANCE_IR__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Tf Config' containment reference. + * + * + * @generated + * @ordered + */ + int MBRICKLET_DISTANCE_IR__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; + + /** + * The feature id for the 'Callback Period' attribute. + * + * + * @generated + * @ordered + */ + int MBRICKLET_DISTANCE_IR__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; /** * The feature id for the 'Device Type' attribute. @@ -9779,25 +9903,25 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBAROMETER_TEMPERATURE__DEVICE_TYPE = MSENSOR_FEATURE_COUNT + 6; + int MBRICKLET_DISTANCE_IR__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; /** - * The number of structural features of the 'MBarometer Temperature' class. + * The feature id for the 'Threshold' attribute. * * * @generated * @ordered */ - int MBAROMETER_TEMPERATURE_FEATURE_COUNT = MSENSOR_FEATURE_COUNT + 7; + int MBRICKLET_DISTANCE_IR__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The number of structural features of the 'MBricklet Distance IR' class. * * * @generated * @ordered */ - int MBAROMETER_TEMPERATURE___FETCH_SENSOR_VALUE = MSENSOR___FETCH_SENSOR_VALUE; + int MBRICKLET_DISTANCE_IR_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 5; /** * The operation id for the 'Enable' operation. @@ -9806,7 +9930,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBAROMETER_TEMPERATURE___ENABLE = MSENSOR_OPERATION_COUNT + 1; + int MBRICKLET_DISTANCE_IR___ENABLE = MDEVICE___ENABLE; /** * The operation id for the 'Disable' operation. @@ -9815,7 +9939,16 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBAROMETER_TEMPERATURE___DISABLE = MSENSOR_OPERATION_COUNT + 2; + int MBRICKLET_DISTANCE_IR___DISABLE = MDEVICE___DISABLE; + + /** + * The operation id for the 'Fetch Sensor Value' operation. + * + * + * @generated + * @ordered + */ + int MBRICKLET_DISTANCE_IR___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; /** * The operation id for the 'Init' operation. @@ -9824,16 +9957,16 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBAROMETER_TEMPERATURE___INIT = MSENSOR_OPERATION_COUNT + 3; + int MBRICKLET_DISTANCE_IR___INIT = MDEVICE_OPERATION_COUNT + 1; /** - * The number of operations of the 'MBarometer Temperature' class. + * The number of operations of the 'MBricklet Distance IR' class. * * * @generated * @ordered */ - int MBAROMETER_TEMPERATURE_OPERATION_COUNT = MSENSOR_OPERATION_COUNT + 4; + int MBRICKLET_DISTANCE_IR_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; /** * The feature id for the 'Logger' attribute. @@ -9842,7 +9975,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__LOGGER = MDEVICE__LOGGER; + int MBRICKLET_TEMPERATURE__LOGGER = MDEVICE__LOGGER; /** * The feature id for the 'Uid' attribute. @@ -9851,7 +9984,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__UID = MDEVICE__UID; + int MBRICKLET_TEMPERATURE__UID = MDEVICE__UID; /** * The feature id for the 'Poll' attribute. @@ -9860,7 +9993,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__POLL = MDEVICE__POLL; + int MBRICKLET_TEMPERATURE__POLL = MDEVICE__POLL; /** * The feature id for the 'Enabled A' attribute. @@ -9869,7 +10002,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__ENABLED_A = MDEVICE__ENABLED_A; + int MBRICKLET_TEMPERATURE__ENABLED_A = MDEVICE__ENABLED_A; /** * The feature id for the 'Tinkerforge Device' attribute. @@ -9878,7 +10011,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MBRICKLET_TEMPERATURE__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** * The feature id for the 'Ip Connection' attribute. @@ -9887,7 +10020,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MBRICKLET_TEMPERATURE__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** * The feature id for the 'Connected Uid' attribute. @@ -9896,7 +10029,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MBRICKLET_TEMPERATURE__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** * The feature id for the 'Position' attribute. @@ -9905,7 +10038,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__POSITION = MDEVICE__POSITION; + int MBRICKLET_TEMPERATURE__POSITION = MDEVICE__POSITION; /** * The feature id for the 'Device Identifier' attribute. @@ -9914,7 +10047,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICKLET_TEMPERATURE__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** * The feature id for the 'Name' attribute. @@ -9923,7 +10056,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__NAME = MDEVICE__NAME; + int MBRICKLET_TEMPERATURE__NAME = MDEVICE__NAME; /** * The feature id for the 'Brickd' container reference. @@ -9932,7 +10065,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_TEMPERATURE__BRICKD = MDEVICE__BRICKD; /** * The feature id for the 'Sensor Value' attribute. @@ -9941,7 +10074,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_TEMPERATURE__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; /** * The feature id for the 'Tf Config' containment reference. @@ -9950,7 +10083,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; + int MBRICKLET_TEMPERATURE__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; /** * The feature id for the 'Callback Period' attribute. @@ -9959,7 +10092,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; + int MBRICKLET_TEMPERATURE__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; /** * The feature id for the 'Device Type' attribute. @@ -9968,7 +10101,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; + int MBRICKLET_TEMPERATURE__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; /** * The feature id for the 'Threshold' attribute. @@ -9977,16 +10110,16 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; + int MBRICKLET_TEMPERATURE__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; /** - * The number of structural features of the 'MBricklet Ambient Light' class. + * The number of structural features of the 'MBricklet Temperature' class. * * * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 5; + int MBRICKLET_TEMPERATURE_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 5; /** * The operation id for the 'Enable' operation. @@ -9995,7 +10128,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT___ENABLE = MDEVICE___ENABLE; + int MBRICKLET_TEMPERATURE___ENABLE = MDEVICE___ENABLE; /** * The operation id for the 'Disable' operation. @@ -10004,7 +10137,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT___DISABLE = MDEVICE___DISABLE; + int MBRICKLET_TEMPERATURE___DISABLE = MDEVICE___DISABLE; /** * The operation id for the 'Fetch Sensor Value' operation. @@ -10013,7 +10146,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; + int MBRICKLET_TEMPERATURE___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; /** * The operation id for the 'Init' operation. @@ -10022,26 +10155,26 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT___INIT = MDEVICE_OPERATION_COUNT + 1; + int MBRICKLET_TEMPERATURE___INIT = MDEVICE_OPERATION_COUNT + 1; /** - * The number of operations of the 'MBricklet Ambient Light' class. + * The number of operations of the 'MBricklet Temperature' class. * * * @generated * @ordered */ - int MBRICKLET_AMBIENT_LIGHT_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; + int MBRICKLET_TEMPERATURE_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletSoundIntensityImpl MBricklet Sound Intensity}' class. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletTemperatureIRImpl MBricklet Temperature IR}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletSoundIntensityImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletSoundIntensity() + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletTemperatureIRImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletTemperatureIR() * @generated */ - int MBRICKLET_SOUND_INTENSITY = 69; + int MBRICKLET_TEMPERATURE_IR = 73; /** * The feature id for the 'Logger' attribute. @@ -10050,7 +10183,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__LOGGER = MDEVICE__LOGGER; + int MBRICKLET_TEMPERATURE_IR__LOGGER = MDEVICE__LOGGER; /** * The feature id for the 'Uid' attribute. @@ -10059,7 +10192,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__UID = MDEVICE__UID; + int MBRICKLET_TEMPERATURE_IR__UID = MDEVICE__UID; /** * The feature id for the 'Poll' attribute. @@ -10068,7 +10201,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__POLL = MDEVICE__POLL; + int MBRICKLET_TEMPERATURE_IR__POLL = MDEVICE__POLL; /** * The feature id for the 'Enabled A' attribute. @@ -10077,7 +10210,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__ENABLED_A = MDEVICE__ENABLED_A; + int MBRICKLET_TEMPERATURE_IR__ENABLED_A = MDEVICE__ENABLED_A; /** * The feature id for the 'Tinkerforge Device' attribute. @@ -10086,7 +10219,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MBRICKLET_TEMPERATURE_IR__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** * The feature id for the 'Ip Connection' attribute. @@ -10095,7 +10228,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MBRICKLET_TEMPERATURE_IR__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** * The feature id for the 'Connected Uid' attribute. @@ -10104,7 +10237,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MBRICKLET_TEMPERATURE_IR__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** * The feature id for the 'Position' attribute. @@ -10113,7 +10246,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__POSITION = MDEVICE__POSITION; + int MBRICKLET_TEMPERATURE_IR__POSITION = MDEVICE__POSITION; /** * The feature id for the 'Device Identifier' attribute. @@ -10122,7 +10255,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICKLET_TEMPERATURE_IR__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** * The feature id for the 'Name' attribute. @@ -10131,7 +10264,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__NAME = MDEVICE__NAME; + int MBRICKLET_TEMPERATURE_IR__NAME = MDEVICE__NAME; /** * The feature id for the 'Brickd' container reference. @@ -10140,513 +10273,514 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_TEMPERATURE_IR__BRICKD = MDEVICE__BRICKD; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Msubdevices' containment reference list. * * * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_TEMPERATURE_IR__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; + int MBRICKLET_TEMPERATURE_IR__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Callback Period' attribute. + * The number of structural features of the 'MBricklet Temperature IR' class. * * * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; + int MBRICKLET_TEMPERATURE_IR_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Device Type' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; + int MBRICKLET_TEMPERATURE_IR___INIT = MDEVICE___INIT; /** - * The feature id for the 'Threshold' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; + int MBRICKLET_TEMPERATURE_IR___ENABLE = MDEVICE___ENABLE; /** - * The number of structural features of the 'MBricklet Sound Intensity' class. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 5; + int MBRICKLET_TEMPERATURE_IR___DISABLE = MDEVICE___DISABLE; /** - * The operation id for the 'Enable' operation. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY___ENABLE = MDEVICE___ENABLE; + int MBRICKLET_TEMPERATURE_IR___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The operation id for the 'Disable' operation. + * The number of operations of the 'MBricklet Temperature IR' class. * * * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY___DISABLE = MDEVICE___DISABLE; + int MBRICKLET_TEMPERATURE_IR_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice MTemperature IR Device}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTemperatureIRDevice() * @generated - * @ordered */ - int MBRICKLET_SOUND_INTENSITY___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; + int MTEMPERATURE_IR_DEVICE = 74; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY___INIT = MDEVICE_OPERATION_COUNT + 1; + int MTEMPERATURE_IR_DEVICE__SENSOR_VALUE = MSENSOR__SENSOR_VALUE; /** - * The number of operations of the 'MBricklet Sound Intensity' class. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_SOUND_INTENSITY_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; + int MTEMPERATURE_IR_DEVICE__LOGGER = MSENSOR_FEATURE_COUNT + 0; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMoistureImpl MBricklet Moisture}' class. + * The feature id for the 'Uid' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMoistureImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletMoisture() * @generated + * @ordered */ - int MBRICKLET_MOISTURE = 70; + int MTEMPERATURE_IR_DEVICE__UID = MSENSOR_FEATURE_COUNT + 1; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__LOGGER = MDEVICE__LOGGER; + int MTEMPERATURE_IR_DEVICE__POLL = MSENSOR_FEATURE_COUNT + 2; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__UID = MDEVICE__UID; + int MTEMPERATURE_IR_DEVICE__ENABLED_A = MSENSOR_FEATURE_COUNT + 3; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__POLL = MDEVICE__POLL; + int MTEMPERATURE_IR_DEVICE__SUB_ID = MSENSOR_FEATURE_COUNT + 4; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__ENABLED_A = MDEVICE__ENABLED_A; + int MTEMPERATURE_IR_DEVICE__MBRICK = MSENSOR_FEATURE_COUNT + 5; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MTEMPERATURE_IR_DEVICE__CALLBACK_PERIOD = MSENSOR_FEATURE_COUNT + 6; /** - * The feature id for the 'Ip Connection' attribute. + * The feature id for the 'Threshold' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MTEMPERATURE_IR_DEVICE__THRESHOLD = MSENSOR_FEATURE_COUNT + 7; /** - * The feature id for the 'Connected Uid' attribute. + * The number of structural features of the 'MTemperature IR Device' class. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MTEMPERATURE_IR_DEVICE_FEATURE_COUNT = MSENSOR_FEATURE_COUNT + 8; /** - * The feature id for the 'Position' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__POSITION = MDEVICE__POSITION; + int MTEMPERATURE_IR_DEVICE___FETCH_SENSOR_VALUE = MSENSOR___FETCH_SENSOR_VALUE; /** - * The feature id for the 'Device Identifier' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MTEMPERATURE_IR_DEVICE___INIT = MSENSOR_OPERATION_COUNT + 0; /** - * The feature id for the 'Name' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__NAME = MDEVICE__NAME; + int MTEMPERATURE_IR_DEVICE___ENABLE = MSENSOR_OPERATION_COUNT + 1; /** - * The feature id for the 'Brickd' container reference. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__BRICKD = MDEVICE__BRICKD; + int MTEMPERATURE_IR_DEVICE___DISABLE = MSENSOR_OPERATION_COUNT + 2; /** - * The feature id for the 'Sensor Value' attribute. + * The number of operations of the 'MTemperature IR Device' class. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; + int MTEMPERATURE_IR_DEVICE_OPERATION_COUNT = MSENSOR_OPERATION_COUNT + 3; /** - * The feature id for the 'Tf Config' containment reference. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.ObjectTemperatureImpl Object Temperature}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.ObjectTemperatureImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getObjectTemperature() * @generated - * @ordered */ - int MBRICKLET_MOISTURE__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; + int OBJECT_TEMPERATURE = 75; /** - * The feature id for the 'Callback Period' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; + int OBJECT_TEMPERATURE__SENSOR_VALUE = MTEMPERATURE_IR_DEVICE__SENSOR_VALUE; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; + int OBJECT_TEMPERATURE__LOGGER = MTEMPERATURE_IR_DEVICE__LOGGER; /** - * The feature id for the 'Threshold' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; + int OBJECT_TEMPERATURE__UID = MTEMPERATURE_IR_DEVICE__UID; /** - * The feature id for the 'Moving Average' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE__MOVING_AVERAGE = MDEVICE_FEATURE_COUNT + 5; + int OBJECT_TEMPERATURE__POLL = MTEMPERATURE_IR_DEVICE__POLL; /** - * The number of structural features of the 'MBricklet Moisture' class. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 6; + int OBJECT_TEMPERATURE__ENABLED_A = MTEMPERATURE_IR_DEVICE__ENABLED_A; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE___ENABLE = MDEVICE___ENABLE; + int OBJECT_TEMPERATURE__SUB_ID = MTEMPERATURE_IR_DEVICE__SUB_ID; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE___DISABLE = MDEVICE___DISABLE; + int OBJECT_TEMPERATURE__MBRICK = MTEMPERATURE_IR_DEVICE__MBRICK; /** - * The operation id for the 'Fetch Sensor Value' operation. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; + int OBJECT_TEMPERATURE__CALLBACK_PERIOD = MTEMPERATURE_IR_DEVICE__CALLBACK_PERIOD; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Threshold' attribute. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE___INIT = MDEVICE_OPERATION_COUNT + 1; + int OBJECT_TEMPERATURE__THRESHOLD = MTEMPERATURE_IR_DEVICE__THRESHOLD; /** - * The number of operations of the 'MBricklet Moisture' class. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_MOISTURE_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; + int OBJECT_TEMPERATURE__TF_CONFIG = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 0; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDistanceUSImpl MBricklet Distance US}' class. + * The feature id for the 'Device Type' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDistanceUSImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletDistanceUS() * @generated + * @ordered */ - int MBRICKLET_DISTANCE_US = 71; + int OBJECT_TEMPERATURE__DEVICE_TYPE = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Emissivity' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__LOGGER = MDEVICE__LOGGER; + int OBJECT_TEMPERATURE__EMISSIVITY = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Uid' attribute. + * The number of structural features of the 'Object Temperature' class. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__UID = MDEVICE__UID; + int OBJECT_TEMPERATURE_FEATURE_COUNT = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 3; /** - * The feature id for the 'Poll' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__POLL = MDEVICE__POLL; + int OBJECT_TEMPERATURE___FETCH_SENSOR_VALUE = MTEMPERATURE_IR_DEVICE___FETCH_SENSOR_VALUE; /** - * The feature id for the 'Enabled A' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__ENABLED_A = MDEVICE__ENABLED_A; + int OBJECT_TEMPERATURE___INIT = MTEMPERATURE_IR_DEVICE___INIT; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int OBJECT_TEMPERATURE___ENABLE = MTEMPERATURE_IR_DEVICE___ENABLE; /** - * The feature id for the 'Ip Connection' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int OBJECT_TEMPERATURE___DISABLE = MTEMPERATURE_IR_DEVICE___DISABLE; /** - * The feature id for the 'Connected Uid' attribute. + * The number of operations of the 'Object Temperature' class. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int OBJECT_TEMPERATURE_OPERATION_COUNT = MTEMPERATURE_IR_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Position' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.AmbientTemperatureImpl Ambient Temperature}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.AmbientTemperatureImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getAmbientTemperature() * @generated - * @ordered */ - int MBRICKLET_DISTANCE_US__POSITION = MDEVICE__POSITION; + int AMBIENT_TEMPERATURE = 76; /** - * The feature id for the 'Device Identifier' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int AMBIENT_TEMPERATURE__SENSOR_VALUE = MTEMPERATURE_IR_DEVICE__SENSOR_VALUE; /** - * The feature id for the 'Name' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__NAME = MDEVICE__NAME; + int AMBIENT_TEMPERATURE__LOGGER = MTEMPERATURE_IR_DEVICE__LOGGER; /** - * The feature id for the 'Brickd' container reference. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__BRICKD = MDEVICE__BRICKD; + int AMBIENT_TEMPERATURE__UID = MTEMPERATURE_IR_DEVICE__UID; /** - * The feature id for the 'Sensor Value' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; + int AMBIENT_TEMPERATURE__POLL = MTEMPERATURE_IR_DEVICE__POLL; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; + int AMBIENT_TEMPERATURE__ENABLED_A = MTEMPERATURE_IR_DEVICE__ENABLED_A; /** - * The feature id for the 'Callback Period' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; + int AMBIENT_TEMPERATURE__SUB_ID = MTEMPERATURE_IR_DEVICE__SUB_ID; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; + int AMBIENT_TEMPERATURE__MBRICK = MTEMPERATURE_IR_DEVICE__MBRICK; /** - * The feature id for the 'Threshold' attribute. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; + int AMBIENT_TEMPERATURE__CALLBACK_PERIOD = MTEMPERATURE_IR_DEVICE__CALLBACK_PERIOD; /** - * The feature id for the 'Moving Average' attribute. + * The feature id for the 'Threshold' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US__MOVING_AVERAGE = MDEVICE_FEATURE_COUNT + 5; + int AMBIENT_TEMPERATURE__THRESHOLD = MTEMPERATURE_IR_DEVICE__THRESHOLD; /** - * The number of structural features of the 'MBricklet Distance US' class. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 6; + int AMBIENT_TEMPERATURE__TF_CONFIG = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 0; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US___ENABLE = MDEVICE___ENABLE; + int AMBIENT_TEMPERATURE__DEVICE_TYPE = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 1; /** - * The operation id for the 'Disable' operation. + * The number of structural features of the 'Ambient Temperature' class. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US___DISABLE = MDEVICE___DISABLE; + int AMBIENT_TEMPERATURE_FEATURE_COUNT = MTEMPERATURE_IR_DEVICE_FEATURE_COUNT + 2; /** * The operation id for the 'Fetch Sensor Value' operation. @@ -10655,7 +10789,7 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_DISTANCE_US___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; + int AMBIENT_TEMPERATURE___FETCH_SENSOR_VALUE = MTEMPERATURE_IR_DEVICE___FETCH_SENSOR_VALUE; /** * The operation id for the 'Init' operation. @@ -10664,839 +10798,840 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int MBRICKLET_DISTANCE_US___INIT = MDEVICE_OPERATION_COUNT + 1; + int AMBIENT_TEMPERATURE___INIT = MTEMPERATURE_IR_DEVICE___INIT; /** - * The number of operations of the 'MBricklet Distance US' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_DISTANCE_US_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; + int AMBIENT_TEMPERATURE___ENABLE = MTEMPERATURE_IR_DEVICE___ENABLE; /** - * The feature id for the 'Logger' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__LOGGER = MDEVICE__LOGGER; + int AMBIENT_TEMPERATURE___DISABLE = MTEMPERATURE_IR_DEVICE___DISABLE; /** - * The feature id for the 'Uid' attribute. + * The number of operations of the 'Ambient Temperature' class. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__UID = MDEVICE__UID; + int AMBIENT_TEMPERATURE_OPERATION_COUNT = MTEMPERATURE_IR_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Poll' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletTiltImpl MBricklet Tilt}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletTiltImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletTilt() * @generated - * @ordered */ - int MBRICKLET_LCD2_0X4__POLL = MDEVICE__POLL; + int MBRICKLET_TILT = 77; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__ENABLED_A = MDEVICE__ENABLED_A; + int MBRICKLET_TILT__LOGGER = MDEVICE__LOGGER; /** - * The feature id for the 'Tinkerforge Device' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; + int MBRICKLET_TILT__UID = MDEVICE__UID; /** - * The feature id for the 'Ip Connection' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__IP_CONNECTION = MDEVICE__IP_CONNECTION; + int MBRICKLET_TILT__POLL = MDEVICE__POLL; /** - * The feature id for the 'Connected Uid' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__CONNECTED_UID = MDEVICE__CONNECTED_UID; + int MBRICKLET_TILT__ENABLED_A = MDEVICE__ENABLED_A; /** - * The feature id for the 'Position' attribute. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__POSITION = MDEVICE__POSITION; + int MBRICKLET_TILT__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The feature id for the 'Device Identifier' attribute. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; + int MBRICKLET_TILT__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The feature id for the 'Name' attribute. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__NAME = MDEVICE__NAME; + int MBRICKLET_TILT__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The feature id for the 'Brickd' container reference. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__BRICKD = MDEVICE__BRICKD; + int MBRICKLET_TILT__POSITION = MDEVICE__POSITION; /** - * The feature id for the 'Text' attribute. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__TEXT = MDEVICE_FEATURE_COUNT + 0; + int MBRICKLET_TILT__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The feature id for the 'Msubdevices' containment reference list. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 1; + int MBRICKLET_TILT__NAME = MDEVICE__NAME; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 2; + int MBRICKLET_TILT__BRICKD = MDEVICE__BRICKD; /** - * The feature id for the 'Position Prefix' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__POSITION_PREFIX = MDEVICE_FEATURE_COUNT + 3; + int MBRICKLET_TILT__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Positon Suffix' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__POSITON_SUFFIX = MDEVICE_FEATURE_COUNT + 4; + int MBRICKLET_TILT__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Display Errors' attribute. + * The number of structural features of the 'MBricklet Tilt' class. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__DISPLAY_ERRORS = MDEVICE_FEATURE_COUNT + 5; + int MBRICKLET_TILT_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Error Prefix' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4__ERROR_PREFIX = MDEVICE_FEATURE_COUNT + 6; + int MBRICKLET_TILT___INIT = MDEVICE___INIT; /** - * The number of structural features of the 'MBricklet LCD2 0x4' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 7; + int MBRICKLET_TILT___ENABLE = MDEVICE___ENABLE; /** - * The operation id for the 'Enable' operation. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4___ENABLE = MDEVICE___ENABLE; + int MBRICKLET_TILT___DISABLE = MDEVICE___DISABLE; /** - * The operation id for the 'Disable' operation. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4___DISABLE = MDEVICE___DISABLE; + int MBRICKLET_TILT___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; /** - * The operation id for the 'Init Sub Devices' operation. + * The number of operations of the 'MBricklet Tilt' class. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; + int MBRICKLET_TILT_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The operation id for the 'Init' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletVoltageCurrentImpl MBricklet Voltage Current}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletVoltageCurrentImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletVoltageCurrent() * @generated - * @ordered */ - int MBRICKLET_LCD2_0X4___INIT = MDEVICE_OPERATION_COUNT + 1; + int MBRICKLET_VOLTAGE_CURRENT = 78; /** - * The number of operations of the 'MBricklet LCD2 0x4' class. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MBRICKLET_LCD2_0X4_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; + int MBRICKLET_VOLTAGE_CURRENT__LOGGER = MDEVICE__LOGGER; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MLCD20x4BacklightImpl MLCD2 0x4 Backlight}' class. + * The feature id for the 'Uid' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MLCD20x4BacklightImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMLCD20x4Backlight() * @generated + * @ordered */ - int MLCD2_0X4_BACKLIGHT = 73; + int MBRICKLET_VOLTAGE_CURRENT__UID = MDEVICE__UID; /** - * The feature id for the 'Switch State' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT__SWITCH_STATE = MIN_SWITCH_ACTOR__SWITCH_STATE; + int MBRICKLET_VOLTAGE_CURRENT__POLL = MDEVICE__POLL; /** - * The feature id for the 'Logger' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT__LOGGER = MIN_SWITCH_ACTOR_FEATURE_COUNT + 0; + int MBRICKLET_VOLTAGE_CURRENT__ENABLED_A = MDEVICE__ENABLED_A; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT__UID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 1; + int MBRICKLET_VOLTAGE_CURRENT__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The feature id for the 'Poll' attribute. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT__POLL = MIN_SWITCH_ACTOR_FEATURE_COUNT + 2; + int MBRICKLET_VOLTAGE_CURRENT__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The feature id for the 'Enabled A' attribute. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT__ENABLED_A = MIN_SWITCH_ACTOR_FEATURE_COUNT + 3; + int MBRICKLET_VOLTAGE_CURRENT__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The feature id for the 'Sub Id' attribute. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT__SUB_ID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 4; + int MBRICKLET_VOLTAGE_CURRENT__POSITION = MDEVICE__POSITION; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT__MBRICK = MIN_SWITCH_ACTOR_FEATURE_COUNT + 5; + int MBRICKLET_VOLTAGE_CURRENT__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT__DEVICE_TYPE = MIN_SWITCH_ACTOR_FEATURE_COUNT + 6; + int MBRICKLET_VOLTAGE_CURRENT__NAME = MDEVICE__NAME; /** - * The number of structural features of the 'MLCD2 0x4 Backlight' class. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT_FEATURE_COUNT = MIN_SWITCH_ACTOR_FEATURE_COUNT + 7; + int MBRICKLET_VOLTAGE_CURRENT__BRICKD = MDEVICE__BRICKD; /** - * The operation id for the 'Turn Switch' operation. + * The feature id for the 'Msubdevices' containment reference list. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT___TURN_SWITCH__ONOFFVALUE = MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; + int MBRICKLET_VOLTAGE_CURRENT__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 0; /** - * The operation id for the 'Fetch Switch State' operation. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT___FETCH_SWITCH_STATE = MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE; + int MBRICKLET_VOLTAGE_CURRENT__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT___INIT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 0; + int MBRICKLET_VOLTAGE_CURRENT__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 2; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Averaging' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT___ENABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 1; + int MBRICKLET_VOLTAGE_CURRENT__AVERAGING = MDEVICE_FEATURE_COUNT + 3; /** - * The operation id for the 'Disable' operation. + * The feature id for the 'Voltage Conversion Time' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT___DISABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 2; + int MBRICKLET_VOLTAGE_CURRENT__VOLTAGE_CONVERSION_TIME = MDEVICE_FEATURE_COUNT + 4; /** - * The number of operations of the 'MLCD2 0x4 Backlight' class. + * The feature id for the 'Current Conversion Time' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BACKLIGHT_OPERATION_COUNT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 3; + int MBRICKLET_VOLTAGE_CURRENT__CURRENT_CONVERSION_TIME = MDEVICE_FEATURE_COUNT + 5; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MLCD20x4ButtonImpl MLCD2 0x4 Button}' class. + * The number of structural features of the 'MBricklet Voltage Current' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MLCD20x4ButtonImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMLCD20x4Button() * @generated + * @ordered */ - int MLCD2_0X4_BUTTON = 74; + int MBRICKLET_VOLTAGE_CURRENT_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 6; /** - * The feature id for the 'Switch State' attribute. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON__SWITCH_STATE = MOUT_SWITCH_ACTOR__SWITCH_STATE; + int MBRICKLET_VOLTAGE_CURRENT___INIT = MDEVICE___INIT; /** - * The feature id for the 'Logger' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON__LOGGER = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 0; + int MBRICKLET_VOLTAGE_CURRENT___ENABLE = MDEVICE___ENABLE; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON__UID = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 1; + int MBRICKLET_VOLTAGE_CURRENT___DISABLE = MDEVICE___DISABLE; /** - * The feature id for the 'Poll' attribute. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON__POLL = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 2; + int MBRICKLET_VOLTAGE_CURRENT___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Enabled A' attribute. + * The number of operations of the 'MBricklet Voltage Current' class. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON__ENABLED_A = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 3; + int MBRICKLET_VOLTAGE_CURRENT_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 1; /** - * The feature id for the 'Sub Id' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.VoltageCurrentDevice Voltage Current Device}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.VoltageCurrentDevice + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getVoltageCurrentDevice() * @generated - * @ordered */ - int MLCD2_0X4_BUTTON__SUB_ID = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 4; + int VOLTAGE_CURRENT_DEVICE = 79; /** - * The feature id for the 'Mbrick' container reference. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON__MBRICK = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 5; + int VOLTAGE_CURRENT_DEVICE__SENSOR_VALUE = MSENSOR__SENSOR_VALUE; /** - * The feature id for the 'Callback Period' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON__CALLBACK_PERIOD = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 6; + int VOLTAGE_CURRENT_DEVICE__LOGGER = MSENSOR_FEATURE_COUNT + 0; /** - * The feature id for the 'Device Type' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON__DEVICE_TYPE = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 7; + int VOLTAGE_CURRENT_DEVICE__UID = MSENSOR_FEATURE_COUNT + 1; /** - * The feature id for the 'Button Num' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON__BUTTON_NUM = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 8; + int VOLTAGE_CURRENT_DEVICE__POLL = MSENSOR_FEATURE_COUNT + 2; /** - * The number of structural features of the 'MLCD2 0x4 Button' class. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON_FEATURE_COUNT = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 9; + int VOLTAGE_CURRENT_DEVICE__ENABLED_A = MSENSOR_FEATURE_COUNT + 3; /** - * The operation id for the 'Turn Switch' operation. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON___TURN_SWITCH__ONOFFVALUE = MOUT_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; + int VOLTAGE_CURRENT_DEVICE__SUB_ID = MSENSOR_FEATURE_COUNT + 4; /** - * The operation id for the 'Fetch Switch State' operation. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON___FETCH_SWITCH_STATE = MOUT_SWITCH_ACTOR___FETCH_SWITCH_STATE; + int VOLTAGE_CURRENT_DEVICE__MBRICK = MSENSOR_FEATURE_COUNT + 5; /** - * The operation id for the 'Init' operation. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON___INIT = MOUT_SWITCH_ACTOR_OPERATION_COUNT + 0; + int VOLTAGE_CURRENT_DEVICE__CALLBACK_PERIOD = MSENSOR_FEATURE_COUNT + 6; /** - * The operation id for the 'Enable' operation. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON___ENABLE = MOUT_SWITCH_ACTOR_OPERATION_COUNT + 1; + int VOLTAGE_CURRENT_DEVICE__TF_CONFIG = MSENSOR_FEATURE_COUNT + 7; /** - * The operation id for the 'Disable' operation. + * The number of structural features of the 'Voltage Current Device' class. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON___DISABLE = MOUT_SWITCH_ACTOR_OPERATION_COUNT + 2; + int VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT = MSENSOR_FEATURE_COUNT + 8; /** - * The number of operations of the 'MLCD2 0x4 Button' class. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int MLCD2_0X4_BUTTON_OPERATION_COUNT = MOUT_SWITCH_ACTOR_OPERATION_COUNT + 3; + int VOLTAGE_CURRENT_DEVICE___FETCH_SENSOR_VALUE = MSENSOR___FETCH_SENSOR_VALUE; /** - * The number of structural features of the 'TF Config' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int TF_CONFIG_FEATURE_COUNT = 0; + int VOLTAGE_CURRENT_DEVICE___INIT = MSENSOR_OPERATION_COUNT + 0; /** - * The number of operations of the 'TF Config' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int TF_CONFIG_OPERATION_COUNT = 0; + int VOLTAGE_CURRENT_DEVICE___ENABLE = MSENSOR_OPERATION_COUNT + 1; /** - * The feature id for the 'Uid' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int OHTF_DEVICE__UID = 0; + int VOLTAGE_CURRENT_DEVICE___DISABLE = MSENSOR_OPERATION_COUNT + 2; /** - * The feature id for the 'Subid' attribute. + * The number of operations of the 'Voltage Current Device' class. * * * @generated * @ordered */ - int OHTF_DEVICE__SUBID = 1; + int VOLTAGE_CURRENT_DEVICE_OPERATION_COUNT = MSENSOR_OPERATION_COUNT + 3; /** - * The feature id for the 'Ohid' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.VCDeviceVoltageImpl VC Device Voltage}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.VCDeviceVoltageImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getVCDeviceVoltage() * @generated - * @ordered */ - int OHTF_DEVICE__OHID = 2; + int VC_DEVICE_VOLTAGE = 80; /** - * The feature id for the 'Sub Device Ids' attribute list. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int OHTF_DEVICE__SUB_DEVICE_IDS = 3; + int VC_DEVICE_VOLTAGE__SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE__SENSOR_VALUE; /** - * The feature id for the 'Tf Config' containment reference. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int OHTF_DEVICE__TF_CONFIG = 4; + int VC_DEVICE_VOLTAGE__LOGGER = VOLTAGE_CURRENT_DEVICE__LOGGER; /** - * The feature id for the 'Oh Config' container reference. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int OHTF_DEVICE__OH_CONFIG = 5; + int VC_DEVICE_VOLTAGE__UID = VOLTAGE_CURRENT_DEVICE__UID; /** - * The number of structural features of the 'OHTF Device' class. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int OHTF_DEVICE_FEATURE_COUNT = 6; + int VC_DEVICE_VOLTAGE__POLL = VOLTAGE_CURRENT_DEVICE__POLL; /** - * The operation id for the 'Is Valid Sub Id' operation. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int OHTF_DEVICE___IS_VALID_SUB_ID__STRING = 0; + int VC_DEVICE_VOLTAGE__ENABLED_A = VOLTAGE_CURRENT_DEVICE__ENABLED_A; /** - * The number of operations of the 'OHTF Device' class. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int OHTF_DEVICE_OPERATION_COUNT = 1; + int VC_DEVICE_VOLTAGE__SUB_ID = VOLTAGE_CURRENT_DEVICE__SUB_ID; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.OHTFSubDeviceAdminDeviceImpl OHTF Sub Device Admin Device}' class. + * The feature id for the 'Mbrick' container reference. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.OHTFSubDeviceAdminDeviceImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getOHTFSubDeviceAdminDevice() * @generated + * @ordered */ - int OHTF_SUB_DEVICE_ADMIN_DEVICE = 77; + int VC_DEVICE_VOLTAGE__MBRICK = VOLTAGE_CURRENT_DEVICE__MBRICK; /** - * The feature id for the 'Uid' attribute. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int OHTF_SUB_DEVICE_ADMIN_DEVICE__UID = OHTF_DEVICE__UID; + int VC_DEVICE_VOLTAGE__CALLBACK_PERIOD = VOLTAGE_CURRENT_DEVICE__CALLBACK_PERIOD; /** - * The feature id for the 'Subid' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int OHTF_SUB_DEVICE_ADMIN_DEVICE__SUBID = OHTF_DEVICE__SUBID; + int VC_DEVICE_VOLTAGE__TF_CONFIG = VOLTAGE_CURRENT_DEVICE__TF_CONFIG; /** - * The feature id for the 'Ohid' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int OHTF_SUB_DEVICE_ADMIN_DEVICE__OHID = OHTF_DEVICE__OHID; + int VC_DEVICE_VOLTAGE__DEVICE_TYPE = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Sub Device Ids' attribute list. + * The feature id for the 'Threshold' attribute. * * * @generated * @ordered */ - int OHTF_SUB_DEVICE_ADMIN_DEVICE__SUB_DEVICE_IDS = OHTF_DEVICE__SUB_DEVICE_IDS; + int VC_DEVICE_VOLTAGE__THRESHOLD = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Tf Config' containment reference. + * The number of structural features of the 'VC Device Voltage' class. * * * @generated * @ordered */ - int OHTF_SUB_DEVICE_ADMIN_DEVICE__TF_CONFIG = OHTF_DEVICE__TF_CONFIG; + int VC_DEVICE_VOLTAGE_FEATURE_COUNT = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Oh Config' container reference. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int OHTF_SUB_DEVICE_ADMIN_DEVICE__OH_CONFIG = OHTF_DEVICE__OH_CONFIG; + int VC_DEVICE_VOLTAGE___FETCH_SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE___FETCH_SENSOR_VALUE; /** - * The number of structural features of the 'OHTF Sub Device Admin Device' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int OHTF_SUB_DEVICE_ADMIN_DEVICE_FEATURE_COUNT = OHTF_DEVICE_FEATURE_COUNT + 0; + int VC_DEVICE_VOLTAGE___INIT = VOLTAGE_CURRENT_DEVICE___INIT; /** - * The operation id for the 'Is Valid Sub Id' operation. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int OHTF_SUB_DEVICE_ADMIN_DEVICE___IS_VALID_SUB_ID__STRING = OHTF_DEVICE_OPERATION_COUNT + 0; + int VC_DEVICE_VOLTAGE___ENABLE = VOLTAGE_CURRENT_DEVICE___ENABLE; /** - * The number of operations of the 'OHTF Sub Device Admin Device' class. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int OHTF_SUB_DEVICE_ADMIN_DEVICE_OPERATION_COUNT = OHTF_DEVICE_OPERATION_COUNT + 1; + int VC_DEVICE_VOLTAGE___DISABLE = VOLTAGE_CURRENT_DEVICE___DISABLE; /** - * The feature id for the 'Oh Tf Devices' containment reference list. + * The number of operations of the 'VC Device Voltage' class. * * * @generated * @ordered */ - int OH_CONFIG__OH_TF_DEVICES = 0; + int VC_DEVICE_VOLTAGE_OPERATION_COUNT = VOLTAGE_CURRENT_DEVICE_OPERATION_COUNT + 0; /** - * The number of structural features of the 'OH Config' class. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.VCDeviceCurrentImpl VC Device Current}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.VCDeviceCurrentImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getVCDeviceCurrent() * @generated - * @ordered */ - int OH_CONFIG_FEATURE_COUNT = 1; + int VC_DEVICE_CURRENT = 81; /** - * The operation id for the 'Get Config By TF Id' operation. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int OH_CONFIG___GET_CONFIG_BY_TF_ID__STRING_STRING = 0; + int VC_DEVICE_CURRENT__SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE__SENSOR_VALUE; /** - * The operation id for the 'Get Config By OH Id' operation. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int OH_CONFIG___GET_CONFIG_BY_OH_ID__STRING = 1; + int VC_DEVICE_CURRENT__LOGGER = VOLTAGE_CURRENT_DEVICE__LOGGER; /** - * The number of operations of the 'OH Config' class. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int OH_CONFIG_OPERATION_COUNT = 2; + int VC_DEVICE_CURRENT__UID = VOLTAGE_CURRENT_DEVICE__UID; /** - * The number of structural features of the 'TF Null Configuration' class. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int TF_NULL_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 0; + int VC_DEVICE_CURRENT__POLL = VOLTAGE_CURRENT_DEVICE__POLL; /** - * The number of operations of the 'TF Null Configuration' class. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int TF_NULL_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int VC_DEVICE_CURRENT__ENABLED_A = VOLTAGE_CURRENT_DEVICE__ENABLED_A; /** - * The feature id for the 'Threshold' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int TF_BASE_CONFIGURATION__THRESHOLD = TF_CONFIG_FEATURE_COUNT + 0; + int VC_DEVICE_CURRENT__SUB_ID = VOLTAGE_CURRENT_DEVICE__SUB_ID; /** - * The feature id for the 'Callback Period' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int TF_BASE_CONFIGURATION__CALLBACK_PERIOD = TF_CONFIG_FEATURE_COUNT + 1; + int VC_DEVICE_CURRENT__MBRICK = VOLTAGE_CURRENT_DEVICE__MBRICK; /** - * The number of structural features of the 'TF Base Configuration' class. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int TF_BASE_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 2; + int VC_DEVICE_CURRENT__CALLBACK_PERIOD = VOLTAGE_CURRENT_DEVICE__CALLBACK_PERIOD; /** - * The number of operations of the 'TF Base Configuration' class. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int TF_BASE_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int VC_DEVICE_CURRENT__TF_CONFIG = VOLTAGE_CURRENT_DEVICE__TF_CONFIG; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFObjectTemperatureConfigurationImpl TF Object Temperature Configuration}' class. + * The feature id for the 'Device Type' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.TFObjectTemperatureConfigurationImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFObjectTemperatureConfiguration() * @generated + * @ordered */ - int TF_OBJECT_TEMPERATURE_CONFIGURATION = 81; + int VC_DEVICE_CURRENT__DEVICE_TYPE = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 0; /** * The feature id for the 'Threshold' attribute. @@ -11505,5694 +11640,9041 @@ public interface ModelPackage extends EPackage * @generated * @ordered */ - int TF_OBJECT_TEMPERATURE_CONFIGURATION__THRESHOLD = TF_BASE_CONFIGURATION__THRESHOLD; + int VC_DEVICE_CURRENT__THRESHOLD = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Callback Period' attribute. + * The number of structural features of the 'VC Device Current' class. * * * @generated * @ordered */ - int TF_OBJECT_TEMPERATURE_CONFIGURATION__CALLBACK_PERIOD = TF_BASE_CONFIGURATION__CALLBACK_PERIOD; + int VC_DEVICE_CURRENT_FEATURE_COUNT = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Emissivity' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int TF_OBJECT_TEMPERATURE_CONFIGURATION__EMISSIVITY = TF_BASE_CONFIGURATION_FEATURE_COUNT + 0; + int VC_DEVICE_CURRENT___FETCH_SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE___FETCH_SENSOR_VALUE; /** - * The number of structural features of the 'TF Object Temperature Configuration' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int TF_OBJECT_TEMPERATURE_CONFIGURATION_FEATURE_COUNT = TF_BASE_CONFIGURATION_FEATURE_COUNT + 1; + int VC_DEVICE_CURRENT___INIT = VOLTAGE_CURRENT_DEVICE___INIT; /** - * The number of operations of the 'TF Object Temperature Configuration' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int TF_OBJECT_TEMPERATURE_CONFIGURATION_OPERATION_COUNT = TF_BASE_CONFIGURATION_OPERATION_COUNT + 0; + int VC_DEVICE_CURRENT___ENABLE = VOLTAGE_CURRENT_DEVICE___ENABLE; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFMoistureBrickletConfigurationImpl TF Moisture Bricklet Configuration}' class. + * The operation id for the 'Disable' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.TFMoistureBrickletConfigurationImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFMoistureBrickletConfiguration() * @generated + * @ordered */ - int TF_MOISTURE_BRICKLET_CONFIGURATION = 82; + int VC_DEVICE_CURRENT___DISABLE = VOLTAGE_CURRENT_DEVICE___DISABLE; /** - * The feature id for the 'Threshold' attribute. + * The number of operations of the 'VC Device Current' class. * * * @generated * @ordered */ - int TF_MOISTURE_BRICKLET_CONFIGURATION__THRESHOLD = TF_BASE_CONFIGURATION__THRESHOLD; + int VC_DEVICE_CURRENT_OPERATION_COUNT = VOLTAGE_CURRENT_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Callback Period' attribute. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.VCDevicePowerImpl VC Device Power}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.VCDevicePowerImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getVCDevicePower() * @generated - * @ordered */ - int TF_MOISTURE_BRICKLET_CONFIGURATION__CALLBACK_PERIOD = TF_BASE_CONFIGURATION__CALLBACK_PERIOD; + int VC_DEVICE_POWER = 82; /** - * The feature id for the 'Moving Average' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int TF_MOISTURE_BRICKLET_CONFIGURATION__MOVING_AVERAGE = TF_BASE_CONFIGURATION_FEATURE_COUNT + 0; + int VC_DEVICE_POWER__SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE__SENSOR_VALUE; /** - * The number of structural features of the 'TF Moisture Bricklet Configuration' class. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int TF_MOISTURE_BRICKLET_CONFIGURATION_FEATURE_COUNT = TF_BASE_CONFIGURATION_FEATURE_COUNT + 1; + int VC_DEVICE_POWER__LOGGER = VOLTAGE_CURRENT_DEVICE__LOGGER; /** - * The number of operations of the 'TF Moisture Bricklet Configuration' class. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int TF_MOISTURE_BRICKLET_CONFIGURATION_OPERATION_COUNT = TF_BASE_CONFIGURATION_OPERATION_COUNT + 0; + int VC_DEVICE_POWER__UID = VOLTAGE_CURRENT_DEVICE__UID; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFDistanceUSBrickletConfigurationImpl TF Distance US Bricklet Configuration}' class. + * The feature id for the 'Poll' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.TFDistanceUSBrickletConfigurationImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFDistanceUSBrickletConfiguration() * @generated + * @ordered */ - int TF_DISTANCE_US_BRICKLET_CONFIGURATION = 83; + int VC_DEVICE_POWER__POLL = VOLTAGE_CURRENT_DEVICE__POLL; /** - * The feature id for the 'Threshold' attribute. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int TF_DISTANCE_US_BRICKLET_CONFIGURATION__THRESHOLD = TF_BASE_CONFIGURATION__THRESHOLD; + int VC_DEVICE_POWER__ENABLED_A = VOLTAGE_CURRENT_DEVICE__ENABLED_A; /** - * The feature id for the 'Callback Period' attribute. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int TF_DISTANCE_US_BRICKLET_CONFIGURATION__CALLBACK_PERIOD = TF_BASE_CONFIGURATION__CALLBACK_PERIOD; + int VC_DEVICE_POWER__SUB_ID = VOLTAGE_CURRENT_DEVICE__SUB_ID; /** - * The feature id for the 'Moving Average' attribute. + * The feature id for the 'Mbrick' container reference. * * * @generated * @ordered */ - int TF_DISTANCE_US_BRICKLET_CONFIGURATION__MOVING_AVERAGE = TF_BASE_CONFIGURATION_FEATURE_COUNT + 0; + int VC_DEVICE_POWER__MBRICK = VOLTAGE_CURRENT_DEVICE__MBRICK; /** - * The number of structural features of the 'TF Distance US Bricklet Configuration' class. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int TF_DISTANCE_US_BRICKLET_CONFIGURATION_FEATURE_COUNT = TF_BASE_CONFIGURATION_FEATURE_COUNT + 1; + int VC_DEVICE_POWER__CALLBACK_PERIOD = VOLTAGE_CURRENT_DEVICE__CALLBACK_PERIOD; /** - * The number of operations of the 'TF Distance US Bricklet Configuration' class. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int TF_DISTANCE_US_BRICKLET_CONFIGURATION_OPERATION_COUNT = TF_BASE_CONFIGURATION_OPERATION_COUNT + 0; + int VC_DEVICE_POWER__TF_CONFIG = VOLTAGE_CURRENT_DEVICE__TF_CONFIG; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFVoltageCurrentConfigurationImpl TF Voltage Current Configuration}' class. + * The feature id for the 'Device Type' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.TFVoltageCurrentConfigurationImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFVoltageCurrentConfiguration() * @generated + * @ordered */ - int TF_VOLTAGE_CURRENT_CONFIGURATION = 84; + int VC_DEVICE_POWER__DEVICE_TYPE = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Averaging' attribute. + * The feature id for the 'Threshold' attribute. * * * @generated * @ordered */ - int TF_VOLTAGE_CURRENT_CONFIGURATION__AVERAGING = TF_CONFIG_FEATURE_COUNT + 0; + int VC_DEVICE_POWER__THRESHOLD = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 1; /** - * The feature id for the 'Voltage Conversion Time' attribute. + * The number of structural features of the 'VC Device Power' class. * * * @generated * @ordered */ - int TF_VOLTAGE_CURRENT_CONFIGURATION__VOLTAGE_CONVERSION_TIME = TF_CONFIG_FEATURE_COUNT + 1; + int VC_DEVICE_POWER_FEATURE_COUNT = VOLTAGE_CURRENT_DEVICE_FEATURE_COUNT + 2; /** - * The feature id for the 'Current Conversion Time' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int TF_VOLTAGE_CURRENT_CONFIGURATION__CURRENT_CONVERSION_TIME = TF_CONFIG_FEATURE_COUNT + 2; + int VC_DEVICE_POWER___FETCH_SENSOR_VALUE = VOLTAGE_CURRENT_DEVICE___FETCH_SENSOR_VALUE; /** - * The number of structural features of the 'TF Voltage Current Configuration' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int TF_VOLTAGE_CURRENT_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 3; + int VC_DEVICE_POWER___INIT = VOLTAGE_CURRENT_DEVICE___INIT; /** - * The number of operations of the 'TF Voltage Current Configuration' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int TF_VOLTAGE_CURRENT_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int VC_DEVICE_POWER___ENABLE = VOLTAGE_CURRENT_DEVICE___ENABLE; /** - * The feature id for the 'Velocity' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int TF_BRICK_DC_CONFIGURATION__VELOCITY = TF_CONFIG_FEATURE_COUNT + 0; + int VC_DEVICE_POWER___DISABLE = VOLTAGE_CURRENT_DEVICE___DISABLE; /** - * The feature id for the 'Acceleration' attribute. + * The number of operations of the 'VC Device Power' class. * * * @generated * @ordered */ - int TF_BRICK_DC_CONFIGURATION__ACCELERATION = TF_CONFIG_FEATURE_COUNT + 1; + int VC_DEVICE_POWER_OPERATION_COUNT = VOLTAGE_CURRENT_DEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Pwm Frequency' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int TF_BRICK_DC_CONFIGURATION__PWM_FREQUENCY = TF_CONFIG_FEATURE_COUNT + 2; + int MBRICKLET_BAROMETER__LOGGER = MDEVICE__LOGGER; /** - * The feature id for the 'Drive Mode' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int TF_BRICK_DC_CONFIGURATION__DRIVE_MODE = TF_CONFIG_FEATURE_COUNT + 3; + int MBRICKLET_BAROMETER__UID = MDEVICE__UID; /** - * The feature id for the 'Switch On Velocity' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int TF_BRICK_DC_CONFIGURATION__SWITCH_ON_VELOCITY = TF_CONFIG_FEATURE_COUNT + 4; + int MBRICKLET_BAROMETER__POLL = MDEVICE__POLL; /** - * The number of structural features of the 'TF Brick DC Configuration' class. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int TF_BRICK_DC_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 5; + int MBRICKLET_BAROMETER__ENABLED_A = MDEVICE__ENABLED_A; /** - * The number of operations of the 'TF Brick DC Configuration' class. + * The feature id for the 'Tinkerforge Device' attribute. * * * @generated * @ordered */ - int TF_BRICK_DC_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int MBRICKLET_BAROMETER__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The feature id for the 'Default State' attribute. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int TFIO_ACTOR_CONFIGURATION__DEFAULT_STATE = TF_CONFIG_FEATURE_COUNT + 0; + int MBRICKLET_BAROMETER__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The feature id for the 'Keep On Reconnect' attribute. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int TFIO_ACTOR_CONFIGURATION__KEEP_ON_RECONNECT = TF_CONFIG_FEATURE_COUNT + 1; + int MBRICKLET_BAROMETER__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The number of structural features of the 'TFIO Actor Configuration' class. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int TFIO_ACTOR_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 2; + int MBRICKLET_BAROMETER__POSITION = MDEVICE__POSITION; /** - * The number of operations of the 'TFIO Actor Configuration' class. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int TFIO_ACTOR_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int MBRICKLET_BAROMETER__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The feature id for the 'Debounce Period' attribute. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int TF_INTERRUPT_LISTENER_CONFIGURATION__DEBOUNCE_PERIOD = TF_CONFIG_FEATURE_COUNT + 0; + int MBRICKLET_BAROMETER__NAME = MDEVICE__NAME; /** - * The number of structural features of the 'TF Interrupt Listener Configuration' class. + * The feature id for the 'Brickd' container reference. * * * @generated * @ordered */ - int TF_INTERRUPT_LISTENER_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 1; + int MBRICKLET_BAROMETER__BRICKD = MDEVICE__BRICKD; /** - * The number of operations of the 'TF Interrupt Listener Configuration' class. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int TF_INTERRUPT_LISTENER_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int MBRICKLET_BAROMETER__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; /** - * The feature id for the 'Pull Up Resistor Enabled' attribute. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int TFIO_SENSOR_CONFIGURATION__PULL_UP_RESISTOR_ENABLED = TF_CONFIG_FEATURE_COUNT + 0; + int MBRICKLET_BAROMETER__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; /** - * The number of structural features of the 'TFIO Sensor Configuration' class. + * The feature id for the 'Msubdevices' containment reference list. * * * @generated * @ordered */ - int TFIO_SENSOR_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 1; + int MBRICKLET_BAROMETER__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 2; /** - * The number of operations of the 'TFIO Sensor Configuration' class. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int TFIO_SENSOR_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int MBRICKLET_BAROMETER__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 3; /** - * The feature id for the 'Velocity' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int TF_SERVO_CONFIGURATION__VELOCITY = TF_CONFIG_FEATURE_COUNT + 0; + int MBRICKLET_BAROMETER__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 4; /** - * The feature id for the 'Acceleration' attribute. + * The feature id for the 'Threshold' attribute. * * * @generated * @ordered */ - int TF_SERVO_CONFIGURATION__ACCELERATION = TF_CONFIG_FEATURE_COUNT + 1; + int MBRICKLET_BAROMETER__THRESHOLD = MDEVICE_FEATURE_COUNT + 5; /** - * The feature id for the 'Servo Voltage' attribute. + * The number of structural features of the 'MBricklet Barometer' class. * * * @generated * @ordered */ - int TF_SERVO_CONFIGURATION__SERVO_VOLTAGE = TF_CONFIG_FEATURE_COUNT + 2; + int MBRICKLET_BAROMETER_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 6; /** - * The feature id for the 'Pulse Width Min' attribute. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int TF_SERVO_CONFIGURATION__PULSE_WIDTH_MIN = TF_CONFIG_FEATURE_COUNT + 3; + int MBRICKLET_BAROMETER___ENABLE = MDEVICE___ENABLE; /** - * The feature id for the 'Pulse Width Max' attribute. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int TF_SERVO_CONFIGURATION__PULSE_WIDTH_MAX = TF_CONFIG_FEATURE_COUNT + 4; + int MBRICKLET_BAROMETER___DISABLE = MDEVICE___DISABLE; /** - * The feature id for the 'Period' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int TF_SERVO_CONFIGURATION__PERIOD = TF_CONFIG_FEATURE_COUNT + 5; + int MBRICKLET_BAROMETER___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; /** - * The feature id for the 'Output Voltage' attribute. + * The operation id for the 'Init Sub Devices' operation. * * * @generated * @ordered */ - int TF_SERVO_CONFIGURATION__OUTPUT_VOLTAGE = TF_CONFIG_FEATURE_COUNT + 6; + int MBRICKLET_BAROMETER___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 1; /** - * The number of structural features of the 'TF Servo Configuration' class. + * The operation id for the 'Init' operation. * * * @generated * @ordered */ - int TF_SERVO_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 7; + int MBRICKLET_BAROMETER___INIT = MDEVICE_OPERATION_COUNT + 2; /** - * The number of operations of the 'TF Servo Configuration' class. + * The number of operations of the 'MBricklet Barometer' class. * * * @generated * @ordered */ - int TF_SERVO_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int MBRICKLET_BAROMETER_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 3; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.BrickletRemoteSwitchConfigurationImpl Bricklet Remote Switch Configuration}' class. + * The feature id for the 'Sensor Value' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.BrickletRemoteSwitchConfigurationImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getBrickletRemoteSwitchConfiguration() * @generated + * @ordered */ - int BRICKLET_REMOTE_SWITCH_CONFIGURATION = 90; + int MBAROMETER_TEMPERATURE__SENSOR_VALUE = MSENSOR__SENSOR_VALUE; /** - * The feature id for the 'Type ADevices' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int BRICKLET_REMOTE_SWITCH_CONFIGURATION__TYPE_ADEVICES = TF_CONFIG_FEATURE_COUNT + 0; + int MBAROMETER_TEMPERATURE__LOGGER = MSENSOR_FEATURE_COUNT + 0; /** - * The feature id for the 'Type BDevices' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int BRICKLET_REMOTE_SWITCH_CONFIGURATION__TYPE_BDEVICES = TF_CONFIG_FEATURE_COUNT + 1; + int MBAROMETER_TEMPERATURE__UID = MSENSOR_FEATURE_COUNT + 1; /** - * The feature id for the 'Type CDevices' attribute. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int BRICKLET_REMOTE_SWITCH_CONFIGURATION__TYPE_CDEVICES = TF_CONFIG_FEATURE_COUNT + 2; + int MBAROMETER_TEMPERATURE__POLL = MSENSOR_FEATURE_COUNT + 2; /** - * The number of structural features of the 'Bricklet Remote Switch Configuration' class. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int BRICKLET_REMOTE_SWITCH_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 3; + int MBAROMETER_TEMPERATURE__ENABLED_A = MSENSOR_FEATURE_COUNT + 3; /** - * The number of operations of the 'Bricklet Remote Switch Configuration' class. + * The feature id for the 'Sub Id' attribute. * * * @generated * @ordered */ - int BRICKLET_REMOTE_SWITCH_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int MBAROMETER_TEMPERATURE__SUB_ID = MSENSOR_FEATURE_COUNT + 4; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchAConfigurationImpl Remote Switch AConfiguration}' class. + * The feature id for the 'Mbrick' container reference. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchAConfigurationImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchAConfiguration() * @generated + * @ordered */ - int REMOTE_SWITCH_ACONFIGURATION = 91; + int MBAROMETER_TEMPERATURE__MBRICK = MSENSOR_FEATURE_COUNT + 5; /** - * The feature id for the 'House Code' attribute. + * The feature id for the 'Device Type' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_ACONFIGURATION__HOUSE_CODE = TF_CONFIG_FEATURE_COUNT + 0; + int MBAROMETER_TEMPERATURE__DEVICE_TYPE = MSENSOR_FEATURE_COUNT + 6; /** - * The feature id for the 'Receiver Code' attribute. + * The number of structural features of the 'MBarometer Temperature' class. * * * @generated * @ordered */ - int REMOTE_SWITCH_ACONFIGURATION__RECEIVER_CODE = TF_CONFIG_FEATURE_COUNT + 1; + int MBAROMETER_TEMPERATURE_FEATURE_COUNT = MSENSOR_FEATURE_COUNT + 7; /** - * The feature id for the 'Repeats' attribute. + * The operation id for the 'Fetch Sensor Value' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_ACONFIGURATION__REPEATS = TF_CONFIG_FEATURE_COUNT + 2; + int MBAROMETER_TEMPERATURE___FETCH_SENSOR_VALUE = MSENSOR___FETCH_SENSOR_VALUE; /** - * The number of structural features of the 'Remote Switch AConfiguration' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_ACONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 3; + int MBAROMETER_TEMPERATURE___ENABLE = MSENSOR_OPERATION_COUNT + 1; /** - * The number of operations of the 'Remote Switch AConfiguration' class. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int REMOTE_SWITCH_ACONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int MBAROMETER_TEMPERATURE___DISABLE = MSENSOR_OPERATION_COUNT + 2; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBConfigurationImpl Remote Switch BConfiguration}' class. + * The operation id for the 'Init' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBConfigurationImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchBConfiguration() * @generated + * @ordered */ - int REMOTE_SWITCH_BCONFIGURATION = 92; + int MBAROMETER_TEMPERATURE___INIT = MSENSOR_OPERATION_COUNT + 3; /** - * The feature id for the 'Address' attribute. + * The number of operations of the 'MBarometer Temperature' class. * * * @generated * @ordered */ - int REMOTE_SWITCH_BCONFIGURATION__ADDRESS = TF_CONFIG_FEATURE_COUNT + 0; + int MBAROMETER_TEMPERATURE_OPERATION_COUNT = MSENSOR_OPERATION_COUNT + 4; /** - * The feature id for the 'Unit' attribute. + * The feature id for the 'Logger' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_BCONFIGURATION__UNIT = TF_CONFIG_FEATURE_COUNT + 1; + int MBRICKLET_AMBIENT_LIGHT__LOGGER = MDEVICE__LOGGER; /** - * The feature id for the 'Repeats' attribute. + * The feature id for the 'Uid' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_BCONFIGURATION__REPEATS = TF_CONFIG_FEATURE_COUNT + 2; + int MBRICKLET_AMBIENT_LIGHT__UID = MDEVICE__UID; /** - * The number of structural features of the 'Remote Switch BConfiguration' class. + * The feature id for the 'Poll' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_BCONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 3; + int MBRICKLET_AMBIENT_LIGHT__POLL = MDEVICE__POLL; /** - * The number of operations of the 'Remote Switch BConfiguration' class. + * The feature id for the 'Enabled A' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_BCONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int MBRICKLET_AMBIENT_LIGHT__ENABLED_A = MDEVICE__ENABLED_A; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchCConfigurationImpl Remote Switch CConfiguration}' class. + * The feature id for the 'Tinkerforge Device' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchCConfigurationImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchCConfiguration() * @generated + * @ordered */ - int REMOTE_SWITCH_CCONFIGURATION = 93; + int MBRICKLET_AMBIENT_LIGHT__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The feature id for the 'System Code' attribute. + * The feature id for the 'Ip Connection' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_CCONFIGURATION__SYSTEM_CODE = TF_CONFIG_FEATURE_COUNT + 0; + int MBRICKLET_AMBIENT_LIGHT__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The feature id for the 'Device Code' attribute. + * The feature id for the 'Connected Uid' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_CCONFIGURATION__DEVICE_CODE = TF_CONFIG_FEATURE_COUNT + 1; + int MBRICKLET_AMBIENT_LIGHT__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The feature id for the 'Repeats' attribute. + * The feature id for the 'Position' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_CCONFIGURATION__REPEATS = TF_CONFIG_FEATURE_COUNT + 2; + int MBRICKLET_AMBIENT_LIGHT__POSITION = MDEVICE__POSITION; /** - * The number of structural features of the 'Remote Switch CConfiguration' class. + * The feature id for the 'Device Identifier' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_CCONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 3; + int MBRICKLET_AMBIENT_LIGHT__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The number of operations of the 'Remote Switch CConfiguration' class. + * The feature id for the 'Name' attribute. * * * @generated * @ordered */ - int REMOTE_SWITCH_CCONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int MBRICKLET_AMBIENT_LIGHT__NAME = MDEVICE__NAME; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MultiTouchDeviceConfigurationImpl Multi Touch Device Configuration}' class. + * The feature id for the 'Brickd' container reference. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MultiTouchDeviceConfigurationImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMultiTouchDeviceConfiguration() * @generated + * @ordered */ - int MULTI_TOUCH_DEVICE_CONFIGURATION = 94; + int MBRICKLET_AMBIENT_LIGHT__BRICKD = MDEVICE__BRICKD; /** - * The feature id for the 'Disable Electrode' attribute. + * The feature id for the 'Sensor Value' attribute. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE_CONFIGURATION__DISABLE_ELECTRODE = TF_CONFIG_FEATURE_COUNT + 0; + int MBRICKLET_AMBIENT_LIGHT__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; /** - * The number of structural features of the 'Multi Touch Device Configuration' class. + * The feature id for the 'Tf Config' containment reference. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 1; + int MBRICKLET_AMBIENT_LIGHT__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; /** - * The number of operations of the 'Multi Touch Device Configuration' class. + * The feature id for the 'Callback Period' attribute. * * * @generated * @ordered */ - int MULTI_TOUCH_DEVICE_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int MBRICKLET_AMBIENT_LIGHT__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.BrickletMultiTouchConfigurationImpl Bricklet Multi Touch Configuration}' class. + * The feature id for the 'Device Type' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.BrickletMultiTouchConfigurationImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getBrickletMultiTouchConfiguration() * @generated + * @ordered */ - int BRICKLET_MULTI_TOUCH_CONFIGURATION = 95; + int MBRICKLET_AMBIENT_LIGHT__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; /** - * The feature id for the 'Recalibrate' attribute. + * The feature id for the 'Threshold' attribute. * * * @generated * @ordered */ - int BRICKLET_MULTI_TOUCH_CONFIGURATION__RECALIBRATE = TF_CONFIG_FEATURE_COUNT + 0; + int MBRICKLET_AMBIENT_LIGHT__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; /** - * The feature id for the 'Sensitivity' attribute. + * The number of structural features of the 'MBricklet Ambient Light' class. * * * @generated * @ordered */ - int BRICKLET_MULTI_TOUCH_CONFIGURATION__SENSITIVITY = TF_CONFIG_FEATURE_COUNT + 1; + int MBRICKLET_AMBIENT_LIGHT_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 5; /** - * The number of structural features of the 'Bricklet Multi Touch Configuration' class. + * The operation id for the 'Enable' operation. * * * @generated * @ordered */ - int BRICKLET_MULTI_TOUCH_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 2; + int MBRICKLET_AMBIENT_LIGHT___ENABLE = MDEVICE___ENABLE; /** - * The number of operations of the 'Bricklet Multi Touch Configuration' class. + * The operation id for the 'Disable' operation. * * * @generated * @ordered */ - int BRICKLET_MULTI_TOUCH_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; + int MBRICKLET_AMBIENT_LIGHT___DISABLE = MDEVICE___DISABLE; /** - * The meta object id for the 'Switch State' data type. + * The operation id for the 'Fetch Sensor Value' operation. * * - * @see org.openhab.binding.tinkerforge.internal.types.OnOffValue - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getSwitchState() * @generated + * @ordered */ - int SWITCH_STATE = 120; + int MBRICKLET_AMBIENT_LIGHT___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; /** - * The meta object id for the 'Digital Value' data type. + * The operation id for the 'Init' operation. * * - * @see org.openhab.binding.tinkerforge.internal.types.HighLowValue - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalValue() * @generated + * @ordered */ - int DIGITAL_VALUE = 121; + int MBRICKLET_AMBIENT_LIGHT___INIT = MDEVICE_OPERATION_COUNT + 1; /** - * The meta object id for the 'Tinker Bricklet IO16' data type. + * The number of operations of the 'MBricklet Ambient Light' class. * * - * @see com.tinkerforge.BrickletIO16 - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletIO16() * @generated + * @ordered */ - int TINKER_BRICKLET_IO16 = 122; + int MBRICKLET_AMBIENT_LIGHT_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.DCDriveMode DC Drive Mode}' enum. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletSoundIntensityImpl MBricklet Sound Intensity}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.DCDriveMode - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDCDriveMode() + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletSoundIntensityImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletSoundIntensity() * @generated */ - int DC_DRIVE_MODE = 96; + int MBRICKLET_SOUND_INTENSITY = 86; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.NoSubIds No Sub Ids}' enum. + * The feature id for the 'Logger' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.NoSubIds - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getNoSubIds() * @generated + * @ordered */ - int NO_SUB_IDS = 97; + int MBRICKLET_SOUND_INTENSITY__LOGGER = MDEVICE__LOGGER; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.IndustrialDigitalInSubIDs Industrial Digital In Sub IDs}' enum. + * The feature id for the 'Uid' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.IndustrialDigitalInSubIDs - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIndustrialDigitalInSubIDs() * @generated + * @ordered */ - int INDUSTRIAL_DIGITAL_IN_SUB_IDS = 98; + int MBRICKLET_SOUND_INTENSITY__UID = MDEVICE__UID; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.IndustrialQuadRelayIDs Industrial Quad Relay IDs}' enum. + * The feature id for the 'Poll' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.IndustrialQuadRelayIDs - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIndustrialQuadRelayIDs() * @generated + * @ordered */ - int INDUSTRIAL_QUAD_RELAY_IDS = 99; + int MBRICKLET_SOUND_INTENSITY__POLL = MDEVICE__POLL; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.ServoSubIDs Servo Sub IDs}' enum. + * The feature id for the 'Enabled A' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.ServoSubIDs - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getServoSubIDs() * @generated + * @ordered */ - int SERVO_SUB_IDS = 100; + int MBRICKLET_SOUND_INTENSITY__ENABLED_A = MDEVICE__ENABLED_A; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.BarometerSubIDs Barometer Sub IDs}' enum. + * The feature id for the 'Tinkerforge Device' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.BarometerSubIDs - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getBarometerSubIDs() * @generated + * @ordered */ - int BAROMETER_SUB_IDS = 101; + int MBRICKLET_SOUND_INTENSITY__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.IO16SubIds IO16 Sub Ids}' enum. + * The feature id for the 'Ip Connection' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.IO16SubIds - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIO16SubIds() * @generated + * @ordered */ - int IO16_SUB_IDS = 102; + int MBRICKLET_SOUND_INTENSITY__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.IO4SubIds IO4 Sub Ids}' enum. + * The feature id for the 'Connected Uid' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.IO4SubIds - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIO4SubIds() * @generated + * @ordered */ - int IO4_SUB_IDS = 103; + int MBRICKLET_SOUND_INTENSITY__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.DualRelaySubIds Dual Relay Sub Ids}' enum. + * The feature id for the 'Position' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.DualRelaySubIds - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualRelaySubIds() * @generated + * @ordered */ - int DUAL_RELAY_SUB_IDS = 104; + int MBRICKLET_SOUND_INTENSITY__POSITION = MDEVICE__POSITION; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.LCDButtonSubIds LCD Button Sub Ids}' enum. + * The feature id for the 'Device Identifier' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.LCDButtonSubIds - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getLCDButtonSubIds() * @generated + * @ordered */ - int LCD_BUTTON_SUB_IDS = 105; + int MBRICKLET_SOUND_INTENSITY__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.LCDBacklightSubIds LCD Backlight Sub Ids}' enum. + * The feature id for the 'Name' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.LCDBacklightSubIds - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getLCDBacklightSubIds() * @generated + * @ordered */ - int LCD_BACKLIGHT_SUB_IDS = 106; + int MBRICKLET_SOUND_INTENSITY__NAME = MDEVICE__NAME; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchSubIds Multi Touch Sub Ids}' enum. + * The feature id for the 'Brickd' container reference. * * - * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchSubIds - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMultiTouchSubIds() * @generated + * @ordered */ - int MULTI_TOUCH_SUB_IDS = 107; + int MBRICKLET_SOUND_INTENSITY__BRICKD = MDEVICE__BRICKD; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.TemperatureIRSubIds Temperature IR Sub Ids}' enum. + * The feature id for the 'Sensor Value' attribute. * * - * @see org.openhab.binding.tinkerforge.internal.model.TemperatureIRSubIds - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTemperatureIRSubIds() * @generated + * @ordered */ - int TEMPERATURE_IR_SUB_IDS = 108; + int MBRICKLET_SOUND_INTENSITY__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; /** - * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.VoltageCurrentSubIds Voltage Current Sub Ids}' enum. + * The feature id for the 'Tf Config' containment reference. * * - * @see org.openhab.binding.tinkerforge.internal.model.VoltageCurrentSubIds - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getVoltageCurrentSubIds() * @generated + * @ordered */ - int VOLTAGE_CURRENT_SUB_IDS = 109; + int MBRICKLET_SOUND_INTENSITY__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; /** - * The meta object id for the 'MIP Connection' data type. + * The feature id for the 'Callback Period' attribute. * * - * @see com.tinkerforge.IPConnection - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMIPConnection() * @generated + * @ordered */ - int MIP_CONNECTION = 110; + int MBRICKLET_SOUND_INTENSITY__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; /** - * The meta object id for the 'MTinker Device' data type. + * The feature id for the 'Device Type' attribute. * * - * @see com.tinkerforge.Device - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerDevice() * @generated + * @ordered */ - int MTINKER_DEVICE = 111; + int MBRICKLET_SOUND_INTENSITY__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; /** - * The meta object id for the 'MLogger' data type. + * The feature id for the 'Threshold' attribute. * * - * @see org.slf4j.Logger - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMLogger() * @generated + * @ordered */ - int MLOGGER = 112; - + int MBRICKLET_SOUND_INTENSITY__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; /** - * The meta object id for the 'MAtomic Boolean' data type. + * The number of structural features of the 'MBricklet Sound Intensity' class. * * - * @see java.util.concurrent.atomic.AtomicBoolean - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMAtomicBoolean() * @generated + * @ordered */ - int MATOMIC_BOOLEAN = 113; + int MBRICKLET_SOUND_INTENSITY_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 5; /** - * The meta object id for the 'MTinkerforge Device' data type. + * The operation id for the 'Enable' operation. * * - * @see com.tinkerforge.Device - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerforgeDevice() * @generated + * @ordered */ - int MTINKERFORGE_DEVICE = 114; + int MBRICKLET_SOUND_INTENSITY___ENABLE = MDEVICE___ENABLE; /** - * The meta object id for the 'MTinker Brick DC' data type. + * The operation id for the 'Disable' operation. * * - * @see com.tinkerforge.BrickDC - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickDC() * @generated + * @ordered */ - int MTINKER_BRICK_DC = 115; + int MBRICKLET_SOUND_INTENSITY___DISABLE = MDEVICE___DISABLE; /** - * The meta object id for the 'MTinker Brick Servo' data type. + * The operation id for the 'Fetch Sensor Value' operation. * * - * @see com.tinkerforge.BrickServo - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickServo() * @generated + * @ordered */ - int MTINKER_BRICK_SERVO = 123; - + int MBRICKLET_SOUND_INTENSITY___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; /** - * The meta object id for the 'MTinkerforge Value' data type. + * The operation id for the 'Init' operation. * * - * @see org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerforgeValue() * @generated + * @ordered */ - int MTINKERFORGE_VALUE = 124; + int MBRICKLET_SOUND_INTENSITY___INIT = MDEVICE_OPERATION_COUNT + 1; /** - * The meta object id for the 'MDecimal Value' data type. + * The number of operations of the 'MBricklet Sound Intensity' class. * * - * @see org.openhab.binding.tinkerforge.internal.types.DecimalValue - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMDecimalValue() * @generated + * @ordered */ - int MDECIMAL_VALUE = 125; + int MBRICKLET_SOUND_INTENSITY_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; /** - * The meta object id for the 'MTinker Bricklet Humidity' data type. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMoistureImpl MBricklet Moisture}' class. * * - * @see com.tinkerforge.BrickletHumidity - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletHumidity() + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletMoistureImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletMoisture() * @generated */ - int MTINKER_BRICKLET_HUMIDITY = 126; + int MBRICKLET_MOISTURE = 87; /** - * The meta object id for the 'MTinker Bricklet Distance IR' data type. + * The feature id for the 'Logger' attribute. * * - * @see com.tinkerforge.BrickletDistanceIR - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletDistanceIR() * @generated + * @ordered */ - int MTINKER_BRICKLET_DISTANCE_IR = 127; + int MBRICKLET_MOISTURE__LOGGER = MDEVICE__LOGGER; /** - * The meta object id for the 'MTinker Bricklet Temperature' data type. + * The feature id for the 'Uid' attribute. * * - * @see com.tinkerforge.BrickletTemperature - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletTemperature() * @generated + * @ordered */ - int MTINKER_BRICKLET_TEMPERATURE = 128; + int MBRICKLET_MOISTURE__UID = MDEVICE__UID; /** - * The meta object id for the 'MTinker Bricklet Barometer' data type. + * The feature id for the 'Poll' attribute. * * - * @see com.tinkerforge.BrickletBarometer - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletBarometer() * @generated + * @ordered */ - int MTINKER_BRICKLET_BAROMETER = 129; + int MBRICKLET_MOISTURE__POLL = MDEVICE__POLL; /** - * The meta object id for the 'MTinker Bricklet Ambient Light' data type. + * The feature id for the 'Enabled A' attribute. * * - * @see com.tinkerforge.BrickletAmbientLight - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletAmbientLight() * @generated + * @ordered */ - int MTINKER_BRICKLET_AMBIENT_LIGHT = 130; + int MBRICKLET_MOISTURE__ENABLED_A = MDEVICE__ENABLED_A; /** - * The meta object id for the 'MTinker Bricklet LCD2 0x4' data type. + * The feature id for the 'Tinkerforge Device' attribute. * * - * @see com.tinkerforge.BrickletLCD20x4 - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletLCD20x4() * @generated + * @ordered */ - int MTINKER_BRICKLET_LCD2_0X4 = 131; + int MBRICKLET_MOISTURE__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * The meta object id for the 'Tinker Bricklet Remote Switch' data type. + * The feature id for the 'Ip Connection' attribute. * * - * @see com.tinkerforge.BrickletRemoteSwitch - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletRemoteSwitch() * @generated + * @ordered */ - int TINKER_BRICKLET_REMOTE_SWITCH = 132; + int MBRICKLET_MOISTURE__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * The meta object id for the 'Tinker Bricklet Motion Detector' data type. + * The feature id for the 'Connected Uid' attribute. * * - * @see com.tinkerforge.BrickletMotionDetector - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletMotionDetector() * @generated + * @ordered */ - int TINKER_BRICKLET_MOTION_DETECTOR = 133; + int MBRICKLET_MOISTURE__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * The meta object id for the 'Tinker Bricklet Multi Touch' data type. + * The feature id for the 'Position' attribute. * * - * @see com.tinkerforge.BrickletMultiTouch - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletMultiTouch() * @generated + * @ordered */ - int TINKER_BRICKLET_MULTI_TOUCH = 134; + int MBRICKLET_MOISTURE__POSITION = MDEVICE__POSITION; /** - * The meta object id for the 'Tinker Bricklet Temperature IR' data type. + * The feature id for the 'Device Identifier' attribute. * * - * @see com.tinkerforge.BrickletTemperatureIR - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletTemperatureIR() * @generated + * @ordered */ - int TINKER_BRICKLET_TEMPERATURE_IR = 135; + int MBRICKLET_MOISTURE__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * The meta object id for the 'Tinker Bricklet Sound Intensity' data type. + * The feature id for the 'Name' attribute. * * - * @see com.tinkerforge.BrickletSoundIntensity - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletSoundIntensity() * @generated + * @ordered */ - int TINKER_BRICKLET_SOUND_INTENSITY = 136; + int MBRICKLET_MOISTURE__NAME = MDEVICE__NAME; /** - * The meta object id for the 'Tinker Bricklet Moisture' data type. + * The feature id for the 'Brickd' container reference. * * - * @see com.tinkerforge.BrickletMoisture - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletMoisture() * @generated + * @ordered */ - int TINKER_BRICKLET_MOISTURE = 137; + int MBRICKLET_MOISTURE__BRICKD = MDEVICE__BRICKD; /** - * The meta object id for the 'Tinker Bricklet Distance US' data type. + * The feature id for the 'Sensor Value' attribute. * * - * @see com.tinkerforge.BrickletDistanceUS - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletDistanceUS() * @generated + * @ordered */ - int TINKER_BRICKLET_DISTANCE_US = 138; + int MBRICKLET_MOISTURE__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; /** - * The meta object id for the 'Tinker Bricklet Voltage Current' data type. + * The feature id for the 'Tf Config' containment reference. * * - * @see com.tinkerforge.BrickletVoltageCurrent - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletVoltageCurrent() * @generated + * @ordered */ - int TINKER_BRICKLET_VOLTAGE_CURRENT = 139; + int MBRICKLET_MOISTURE__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; /** - * The meta object id for the 'Tinker Bricklet Tilt' data type. + * The feature id for the 'Callback Period' attribute. * * - * @see com.tinkerforge.BrickletTilt - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletTilt() * @generated + * @ordered */ - int TINKER_BRICKLET_TILT = 140; + int MBRICKLET_MOISTURE__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; /** - * The meta object id for the 'Tinker Bricklet IO4' data type. + * The feature id for the 'Device Type' attribute. * * - * @see com.tinkerforge.BrickletIO4 - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletIO4() * @generated + * @ordered */ - int TINKER_BRICKLET_IO4 = 141; + int MBRICKLET_MOISTURE__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; /** - * The meta object id for the 'Tinker Bricklet Hall Effect' data type. + * The feature id for the 'Threshold' attribute. * * - * @see com.tinkerforge.BrickletHallEffect - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletHallEffect() * @generated + * @ordered */ - int TINKER_BRICKLET_HALL_EFFECT = 142; + int MBRICKLET_MOISTURE__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; /** - * The meta object id for the 'Tinker Bricklet Segment Display4x7' data type. + * The feature id for the 'Moving Average' attribute. * * - * @see com.tinkerforge.BrickletSegmentDisplay4x7 - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletSegmentDisplay4x7() * @generated + * @ordered */ - int TINKER_BRICKLET_SEGMENT_DISPLAY4X7 = 143; + int MBRICKLET_MOISTURE__MOVING_AVERAGE = MDEVICE_FEATURE_COUNT + 5; /** - * The meta object id for the 'Tinker Bricklet LED Strip' data type. + * The number of structural features of the 'MBricklet Moisture' class. * * - * @see com.tinkerforge.BrickletLEDStrip - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletLEDStrip() * @generated + * @ordered */ - int TINKER_BRICKLET_LED_STRIP = 144; + int MBRICKLET_MOISTURE_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 6; /** - * The meta object id for the 'HSB Type' data type. + * The operation id for the 'Enable' operation. * * - * @see org.openhab.core.library.types.HSBType - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getHSBType() * @generated + * @ordered */ - int HSB_TYPE = 145; + int MBRICKLET_MOISTURE___ENABLE = MDEVICE___ENABLE; /** - * The meta object id for the 'Device Options' data type. + * The operation id for the 'Disable' operation. * * - * @see org.openhab.binding.tinkerforge.internal.config.DeviceOptions - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDeviceOptions() * @generated + * @ordered */ - int DEVICE_OPTIONS = 146; + int MBRICKLET_MOISTURE___DISABLE = MDEVICE___DISABLE; /** - * The meta object id for the 'Enum' data type. + * The operation id for the 'Fetch Sensor Value' operation. * * - * @see java.lang.Enum - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getEnum() * @generated + * @ordered */ - int ENUM = 147; + int MBRICKLET_MOISTURE___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFConfig TF Config}'. + * The operation id for the 'Init' operation. * * - * @return the meta object for class 'TF Config'. - * @see org.openhab.binding.tinkerforge.internal.model.TFConfig * @generated + * @ordered */ - EClass getTFConfig(); + int MBRICKLET_MOISTURE___INIT = MDEVICE_OPERATION_COUNT + 1; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice OHTF Device}'. + * The number of operations of the 'MBricklet Moisture' class. * * - * @return the meta object for class 'OHTF Device'. - * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice * @generated + * @ordered */ - EClass getOHTFDevice(); + int MBRICKLET_MOISTURE_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getUid Uid}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDistanceUSImpl MBricklet Distance US}' class. * * - * @return the meta object for the attribute 'Uid'. - * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getUid() - * @see #getOHTFDevice() + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDistanceUSImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletDistanceUS() * @generated */ - EAttribute getOHTFDevice_Uid(); + int MBRICKLET_DISTANCE_US = 88; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getSubid Subid}'. + * The feature id for the 'Logger' attribute. * * - * @return the meta object for the attribute 'Subid'. - * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getSubid() - * @see #getOHTFDevice() * @generated + * @ordered */ - EAttribute getOHTFDevice_Subid(); + int MBRICKLET_DISTANCE_US__LOGGER = MDEVICE__LOGGER; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getOhid Ohid}'. + * The feature id for the 'Uid' attribute. * * - * @return the meta object for the attribute 'Ohid'. - * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getOhid() - * @see #getOHTFDevice() * @generated + * @ordered */ - EAttribute getOHTFDevice_Ohid(); + int MBRICKLET_DISTANCE_US__UID = MDEVICE__UID; /** - * Returns the meta object for the attribute list '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getSubDeviceIds Sub Device Ids}'. + * The feature id for the 'Poll' attribute. * * - * @return the meta object for the attribute list 'Sub Device Ids'. - * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getSubDeviceIds() - * @see #getOHTFDevice() * @generated + * @ordered */ - EAttribute getOHTFDevice_SubDeviceIds(); + int MBRICKLET_DISTANCE_US__POLL = MDEVICE__POLL; /** - * Returns the meta object for the containment reference '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getTfConfig Tf Config}'. + * The feature id for the 'Enabled A' attribute. * * - * @return the meta object for the containment reference 'Tf Config'. - * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getTfConfig() - * @see #getOHTFDevice() * @generated + * @ordered */ - EReference getOHTFDevice_TfConfig(); + int MBRICKLET_DISTANCE_US__ENABLED_A = MDEVICE__ENABLED_A; /** - * Returns the meta object for the container reference '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getOhConfig Oh Config}'. + * The feature id for the 'Tinkerforge Device' attribute. * * - * @return the meta object for the container reference 'Oh Config'. - * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getOhConfig() - * @see #getOHTFDevice() * @generated + * @ordered */ - EReference getOHTFDevice_OhConfig(); + int MBRICKLET_DISTANCE_US__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#isValidSubId(java.lang.String) Is Valid Sub Id}' operation. + * The feature id for the 'Ip Connection' attribute. * * - * @return the meta object for the 'Is Valid Sub Id' operation. - * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#isValidSubId(java.lang.String) * @generated + * @ordered */ - EOperation getOHTFDevice__IsValidSubId__String(); + int MBRICKLET_DISTANCE_US__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.OHTFSubDeviceAdminDevice OHTF Sub Device Admin Device}'. + * The feature id for the 'Connected Uid' attribute. * * - * @return the meta object for class 'OHTF Sub Device Admin Device'. - * @see org.openhab.binding.tinkerforge.internal.model.OHTFSubDeviceAdminDevice * @generated + * @ordered */ - EClass getOHTFSubDeviceAdminDevice(); + int MBRICKLET_DISTANCE_US__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.OHTFSubDeviceAdminDevice#isValidSubId(java.lang.String) Is Valid Sub Id}' operation. + * The feature id for the 'Position' attribute. * * - * @return the meta object for the 'Is Valid Sub Id' operation. - * @see org.openhab.binding.tinkerforge.internal.model.OHTFSubDeviceAdminDevice#isValidSubId(java.lang.String) * @generated + * @ordered */ - EOperation getOHTFSubDeviceAdminDevice__IsValidSubId__String(); + int MBRICKLET_DISTANCE_US__POSITION = MDEVICE__POSITION; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.OHConfig OH Config}'. + * The feature id for the 'Device Identifier' attribute. * * - * @return the meta object for class 'OH Config'. - * @see org.openhab.binding.tinkerforge.internal.model.OHConfig * @generated + * @ordered */ - EClass getOHConfig(); + int MBRICKLET_DISTANCE_US__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * Returns the meta object for the containment reference list '{@link org.openhab.binding.tinkerforge.internal.model.OHConfig#getOhTfDevices Oh Tf Devices}'. + * The feature id for the 'Name' attribute. * * - * @return the meta object for the containment reference list 'Oh Tf Devices'. - * @see org.openhab.binding.tinkerforge.internal.model.OHConfig#getOhTfDevices() - * @see #getOHConfig() * @generated + * @ordered */ - EReference getOHConfig_OhTfDevices(); + int MBRICKLET_DISTANCE_US__NAME = MDEVICE__NAME; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.OHConfig#getConfigByTFId(java.lang.String, java.lang.String) Get Config By TF Id}' operation. + * The feature id for the 'Brickd' container reference. * * - * @return the meta object for the 'Get Config By TF Id' operation. - * @see org.openhab.binding.tinkerforge.internal.model.OHConfig#getConfigByTFId(java.lang.String, java.lang.String) * @generated + * @ordered */ - EOperation getOHConfig__GetConfigByTFId__String_String(); + int MBRICKLET_DISTANCE_US__BRICKD = MDEVICE__BRICKD; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.OHConfig#getConfigByOHId(java.lang.String) Get Config By OH Id}' operation. + * The feature id for the 'Sensor Value' attribute. * * - * @return the meta object for the 'Get Config By OH Id' operation. - * @see org.openhab.binding.tinkerforge.internal.model.OHConfig#getConfigByOHId(java.lang.String) * @generated + * @ordered */ - EOperation getOHConfig__GetConfigByOHId__String(); + int MBRICKLET_DISTANCE_US__SENSOR_VALUE = MDEVICE_FEATURE_COUNT + 0; /** - * The meta object id for the 'MTinker Bricklet Dual Relay' data type. + * The feature id for the 'Tf Config' containment reference. * * - * @see com.tinkerforge.BrickletDualRelay - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletDualRelay() * @generated + * @ordered */ - int MTINKER_BRICKLET_DUAL_RELAY = 116; - + int MBRICKLET_DISTANCE_US__TF_CONFIG = MDEVICE_FEATURE_COUNT + 1; /** - * The meta object id for the 'MTinker Bricklet Industrial Quad Relay' data type. + * The feature id for the 'Callback Period' attribute. * * - * @see com.tinkerforge.BrickletIndustrialQuadRelay - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletIndustrialQuadRelay() * @generated + * @ordered */ - int MTINKER_BRICKLET_INDUSTRIAL_QUAD_RELAY = 117; + int MBRICKLET_DISTANCE_US__CALLBACK_PERIOD = MDEVICE_FEATURE_COUNT + 2; /** - * The meta object id for the 'MTinker Bricklet Industrial Digital In4' data type. + * The feature id for the 'Device Type' attribute. * * - * @see com.tinkerforge.BrickletIndustrialDigitalIn4 - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletIndustrialDigitalIn4() * @generated + * @ordered */ - int MTINKER_BRICKLET_INDUSTRIAL_DIGITAL_IN4 = 118; + int MBRICKLET_DISTANCE_US__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 3; /** - * The meta object id for the 'MTinker Bricklet Industrial Digital Out4' data type. + * The feature id for the 'Threshold' attribute. * * - * @see com.tinkerforge.BrickletIndustrialDigitalOut4 - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletIndustrialDigitalOut4() * @generated + * @ordered */ - int MTINKER_BRICKLET_INDUSTRIAL_DIGITAL_OUT4 = 119; + int MBRICKLET_DISTANCE_US__THRESHOLD = MDEVICE_FEATURE_COUNT + 4; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem Ecosystem}'. + * The feature id for the 'Moving Average' attribute. * * - * @return the meta object for class 'Ecosystem'. - * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem * @generated + * @ordered */ - EClass getEcosystem(); + int MBRICKLET_DISTANCE_US__MOVING_AVERAGE = MDEVICE_FEATURE_COUNT + 5; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#getLogger Logger}'. + * The number of structural features of the 'MBricklet Distance US' class. * * - * @return the meta object for the attribute 'Logger'. - * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#getLogger() - * @see #getEcosystem() * @generated + * @ordered */ - EAttribute getEcosystem_Logger(); + int MBRICKLET_DISTANCE_US_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 6; /** - * Returns the meta object for the containment reference list '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#getMbrickds Mbrickds}'. + * The operation id for the 'Enable' operation. * * - * @return the meta object for the containment reference list 'Mbrickds'. - * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#getMbrickds() - * @see #getEcosystem() * @generated + * @ordered */ - EReference getEcosystem_Mbrickds(); + int MBRICKLET_DISTANCE_US___ENABLE = MDEVICE___ENABLE; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#getBrickd(java.lang.String, int) Get Brickd}' operation. + * The operation id for the 'Disable' operation. * * - * @return the meta object for the 'Get Brickd' operation. - * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#getBrickd(java.lang.String, int) * @generated + * @ordered */ - EOperation getEcosystem__GetBrickd__String_int(); + int MBRICKLET_DISTANCE_US___DISABLE = MDEVICE___DISABLE; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#getDevice(java.lang.String, java.lang.String) Get Device}' operation. + * The operation id for the 'Fetch Sensor Value' operation. * * - * @return the meta object for the 'Get Device' operation. - * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#getDevice(java.lang.String, java.lang.String) * @generated + * @ordered */ - EOperation getEcosystem__GetDevice__String_String(); + int MBRICKLET_DISTANCE_US___FETCH_SENSOR_VALUE = MDEVICE_OPERATION_COUNT + 0; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#getDevices4GenericId(java.lang.String, java.lang.String) Get Devices4 Generic Id}' operation. + * The operation id for the 'Init' operation. * * - * @return the meta object for the 'Get Devices4 Generic Id' operation. - * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#getDevices4GenericId(java.lang.String, java.lang.String) * @generated + * @ordered */ - EOperation getEcosystem__GetDevices4GenericId__String_String(); + int MBRICKLET_DISTANCE_US___INIT = MDEVICE_OPERATION_COUNT + 1; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#disconnect() Disconnect}' operation. + * The number of operations of the 'MBricklet Distance US' class. * * - * @return the meta object for the 'Disconnect' operation. - * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#disconnect() * @generated + * @ordered */ - EOperation getEcosystem__Disconnect(); + int MBRICKLET_DISTANCE_US_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 2; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd MBrickd}'. + * The feature id for the 'Logger' attribute. * * - * @return the meta object for class 'MBrickd'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd * @generated + * @ordered */ - EClass getMBrickd(); + int MBRICKLET_LCD2_0X4__LOGGER = MDEVICE__LOGGER; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getLogger Logger}'. + * The feature id for the 'Uid' attribute. * * - * @return the meta object for the attribute 'Logger'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getLogger() - * @see #getMBrickd() * @generated + * @ordered */ - EAttribute getMBrickd_Logger(); + int MBRICKLET_LCD2_0X4__UID = MDEVICE__UID; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getIpConnection Ip Connection}'. + * The feature id for the 'Poll' attribute. * * - * @return the meta object for the attribute 'Ip Connection'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getIpConnection() - * @see #getMBrickd() * @generated + * @ordered */ - EAttribute getMBrickd_IpConnection(); + int MBRICKLET_LCD2_0X4__POLL = MDEVICE__POLL; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getHost Host}'. + * The feature id for the 'Enabled A' attribute. * * - * @return the meta object for the attribute 'Host'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getHost() - * @see #getMBrickd() * @generated + * @ordered */ - EAttribute getMBrickd_Host(); + int MBRICKLET_LCD2_0X4__ENABLED_A = MDEVICE__ENABLED_A; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getPort Port}'. + * The feature id for the 'Tinkerforge Device' attribute. * * - * @return the meta object for the attribute 'Port'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getPort() - * @see #getMBrickd() * @generated + * @ordered */ - EAttribute getMBrickd_Port(); + int MBRICKLET_LCD2_0X4__TINKERFORGE_DEVICE = MDEVICE__TINKERFORGE_DEVICE; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#isIsConnected Is Connected}'. + * The feature id for the 'Ip Connection' attribute. * * - * @return the meta object for the attribute 'Is Connected'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#isIsConnected() - * @see #getMBrickd() * @generated + * @ordered */ - EAttribute getMBrickd_IsConnected(); + int MBRICKLET_LCD2_0X4__IP_CONNECTION = MDEVICE__IP_CONNECTION; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#isAutoReconnect Auto Reconnect}'. + * The feature id for the 'Connected Uid' attribute. * * - * @return the meta object for the attribute 'Auto Reconnect'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#isAutoReconnect() - * @see #getMBrickd() * @generated + * @ordered */ - EAttribute getMBrickd_AutoReconnect(); + int MBRICKLET_LCD2_0X4__CONNECTED_UID = MDEVICE__CONNECTED_UID; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#isReconnected Reconnected}'. + * The feature id for the 'Position' attribute. * * - * @return the meta object for the attribute 'Reconnected'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#isReconnected() - * @see #getMBrickd() * @generated + * @ordered */ - EAttribute getMBrickd_Reconnected(); + int MBRICKLET_LCD2_0X4__POSITION = MDEVICE__POSITION; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getTimeout Timeout}'. + * The feature id for the 'Device Identifier' attribute. * * - * @return the meta object for the attribute 'Timeout'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getTimeout() - * @see #getMBrickd() * @generated + * @ordered */ - EAttribute getMBrickd_Timeout(); + int MBRICKLET_LCD2_0X4__DEVICE_IDENTIFIER = MDEVICE__DEVICE_IDENTIFIER; /** - * Returns the meta object for the containment reference list '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getMdevices Mdevices}'. + * The feature id for the 'Name' attribute. * * - * @return the meta object for the containment reference list 'Mdevices'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getMdevices() - * @see #getMBrickd() * @generated + * @ordered */ - EReference getMBrickd_Mdevices(); + int MBRICKLET_LCD2_0X4__NAME = MDEVICE__NAME; /** - * Returns the meta object for the container reference '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getEcosystem Ecosystem}'. + * The feature id for the 'Brickd' container reference. * * - * @return the meta object for the container reference 'Ecosystem'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getEcosystem() - * @see #getMBrickd() * @generated + * @ordered */ - EReference getMBrickd_Ecosystem(); + int MBRICKLET_LCD2_0X4__BRICKD = MDEVICE__BRICKD; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#connect() Connect}' operation. + * The feature id for the 'Text' attribute. * * - * @return the meta object for the 'Connect' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#connect() * @generated + * @ordered */ - EOperation getMBrickd__Connect(); + int MBRICKLET_LCD2_0X4__TEXT = MDEVICE_FEATURE_COUNT + 0; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#disconnect() Disconnect}' operation. + * The feature id for the 'Msubdevices' containment reference list. * * - * @return the meta object for the 'Disconnect' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#disconnect() * @generated + * @ordered */ - EOperation getMBrickd__Disconnect(); + int MBRICKLET_LCD2_0X4__MSUBDEVICES = MDEVICE_FEATURE_COUNT + 1; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#init() Init}' operation. + * The feature id for the 'Device Type' attribute. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#init() * @generated + * @ordered */ - EOperation getMBrickd__Init(); + int MBRICKLET_LCD2_0X4__DEVICE_TYPE = MDEVICE_FEATURE_COUNT + 2; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getDevice(java.lang.String) Get Device}' operation. + * The feature id for the 'Position Prefix' attribute. * * - * @return the meta object for the 'Get Device' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getDevice(java.lang.String) * @generated + * @ordered */ - EOperation getMBrickd__GetDevice__String(); + int MBRICKLET_LCD2_0X4__POSITION_PREFIX = MDEVICE_FEATURE_COUNT + 3; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin Sub Device Admin}'. + * The feature id for the 'Positon Suffix' attribute. * * - * @return the meta object for class 'Sub Device Admin'. - * @see org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin * @generated + * @ordered */ - EClass getSubDeviceAdmin(); + int MBRICKLET_LCD2_0X4__POSITON_SUFFIX = MDEVICE_FEATURE_COUNT + 4; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin#addSubDevice(java.lang.String, java.lang.String) Add Sub Device}' operation. + * The feature id for the 'Display Errors' attribute. * * - * @return the meta object for the 'Add Sub Device' operation. - * @see org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin#addSubDevice(java.lang.String, java.lang.String) * @generated + * @ordered */ - EOperation getSubDeviceAdmin__AddSubDevice__String_String(); + int MBRICKLET_LCD2_0X4__DISPLAY_ERRORS = MDEVICE_FEATURE_COUNT + 5; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer MTF Config Consumer}'. + * The feature id for the 'Error Prefix' attribute. * * - * @return the meta object for class 'MTF Config Consumer'. - * @see org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer * @generated + * @ordered */ - EClass getMTFConfigConsumer(); + int MBRICKLET_LCD2_0X4__ERROR_PREFIX = MDEVICE_FEATURE_COUNT + 6; /** - * Returns the meta object for the containment reference '{@link org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer#getTfConfig Tf Config}'. + * The number of structural features of the 'MBricklet LCD2 0x4' class. * * - * @return the meta object for the containment reference 'Tf Config'. - * @see org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer#getTfConfig() - * @see #getMTFConfigConsumer() * @generated + * @ordered */ - EReference getMTFConfigConsumer_TfConfig(); + int MBRICKLET_LCD2_0X4_FEATURE_COUNT = MDEVICE_FEATURE_COUNT + 7; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice MBase Device}'. + * The operation id for the 'Enable' operation. * * - * @return the meta object for class 'MBase Device'. - * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice * @generated + * @ordered */ - EClass getMBaseDevice(); + int MBRICKLET_LCD2_0X4___ENABLE = MDEVICE___ENABLE; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getLogger Logger}'. + * The operation id for the 'Disable' operation. * * - * @return the meta object for the attribute 'Logger'. - * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getLogger() - * @see #getMBaseDevice() * @generated + * @ordered */ - EAttribute getMBaseDevice_Logger(); + int MBRICKLET_LCD2_0X4___DISABLE = MDEVICE___DISABLE; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getUid Uid}'. + * The operation id for the 'Init Sub Devices' operation. * * - * @return the meta object for the attribute 'Uid'. - * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getUid() - * @see #getMBaseDevice() * @generated + * @ordered */ - EAttribute getMBaseDevice_Uid(); + int MBRICKLET_LCD2_0X4___INIT_SUB_DEVICES = MDEVICE_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#isPoll Poll}'. + * The operation id for the 'Init' operation. * * - * @return the meta object for the attribute 'Poll'. - * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#isPoll() - * @see #getMBaseDevice() * @generated + * @ordered */ - EAttribute getMBaseDevice_Poll(); + int MBRICKLET_LCD2_0X4___INIT = MDEVICE_OPERATION_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getEnabledA Enabled A}'. + * The operation id for the 'Clear' operation. * * - * @return the meta object for the attribute 'Enabled A'. - * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getEnabledA() - * @see #getMBaseDevice() * @generated + * @ordered */ - EAttribute getMBaseDevice_EnabledA(); + int MBRICKLET_LCD2_0X4___CLEAR = MDEVICE_OPERATION_COUNT + 2; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#init() Init}' operation. + * The number of operations of the 'MBricklet LCD2 0x4' class. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#init() * @generated + * @ordered */ - EOperation getMBaseDevice__Init(); + int MBRICKLET_LCD2_0X4_OPERATION_COUNT = MDEVICE_OPERATION_COUNT + 3; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#enable() Enable}' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MLCD20x4BacklightImpl MLCD2 0x4 Backlight}' class. * * - * @return the meta object for the 'Enable' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#enable() + * @see org.openhab.binding.tinkerforge.internal.model.impl.MLCD20x4BacklightImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMLCD20x4Backlight() * @generated */ - EOperation getMBaseDevice__Enable(); + int MLCD2_0X4_BACKLIGHT = 90; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#disable() Disable}' operation. + * The feature id for the 'Switch State' attribute. * * - * @return the meta object for the 'Disable' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#disable() * @generated + * @ordered */ - EOperation getMBaseDevice__Disable(); + int MLCD2_0X4_BACKLIGHT__SWITCH_STATE = MIN_SWITCH_ACTOR__SWITCH_STATE; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MDevice MDevice}'. + * The feature id for the 'Logger' attribute. * * - * @return the meta object for class 'MDevice'. - * @see org.openhab.binding.tinkerforge.internal.model.MDevice * @generated + * @ordered */ - EClass getMDevice(); + int MLCD2_0X4_BACKLIGHT__LOGGER = MIN_SWITCH_ACTOR_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getTinkerforgeDevice Tinkerforge Device}'. + * The feature id for the 'Uid' attribute. * * - * @return the meta object for the attribute 'Tinkerforge Device'. - * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getTinkerforgeDevice() - * @see #getMDevice() * @generated + * @ordered */ - EAttribute getMDevice_TinkerforgeDevice(); + int MLCD2_0X4_BACKLIGHT__UID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getIpConnection Ip Connection}'. + * The feature id for the 'Poll' attribute. * * - * @return the meta object for the attribute 'Ip Connection'. - * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getIpConnection() - * @see #getMDevice() * @generated + * @ordered */ - EAttribute getMDevice_IpConnection(); + int MLCD2_0X4_BACKLIGHT__POLL = MIN_SWITCH_ACTOR_FEATURE_COUNT + 2; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getConnectedUid Connected Uid}'. + * The feature id for the 'Enabled A' attribute. * * - * @return the meta object for the attribute 'Connected Uid'. - * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getConnectedUid() - * @see #getMDevice() * @generated + * @ordered */ - EAttribute getMDevice_ConnectedUid(); + int MLCD2_0X4_BACKLIGHT__ENABLED_A = MIN_SWITCH_ACTOR_FEATURE_COUNT + 3; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getPosition Position}'. + * The feature id for the 'Sub Id' attribute. * * - * @return the meta object for the attribute 'Position'. - * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getPosition() - * @see #getMDevice() * @generated + * @ordered */ - EAttribute getMDevice_Position(); + int MLCD2_0X4_BACKLIGHT__SUB_ID = MIN_SWITCH_ACTOR_FEATURE_COUNT + 4; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getDeviceIdentifier Device Identifier}'. + * The feature id for the 'Mbrick' container reference. * * - * @return the meta object for the attribute 'Device Identifier'. - * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getDeviceIdentifier() - * @see #getMDevice() * @generated + * @ordered */ - EAttribute getMDevice_DeviceIdentifier(); + int MLCD2_0X4_BACKLIGHT__MBRICK = MIN_SWITCH_ACTOR_FEATURE_COUNT + 5; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getName Name}'. + * The feature id for the 'Device Type' attribute. * * - * @return the meta object for the attribute 'Name'. - * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getName() - * @see #getMDevice() * @generated + * @ordered */ - EAttribute getMDevice_Name(); + int MLCD2_0X4_BACKLIGHT__DEVICE_TYPE = MIN_SWITCH_ACTOR_FEATURE_COUNT + 6; /** - * Returns the meta object for the container reference '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getBrickd Brickd}'. + * The number of structural features of the 'MLCD2 0x4 Backlight' class. * * - * @return the meta object for the container reference 'Brickd'. - * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getBrickd() - * @see #getMDevice() * @generated + * @ordered */ - EReference getMDevice_Brickd(); + int MLCD2_0X4_BACKLIGHT_FEATURE_COUNT = MIN_SWITCH_ACTOR_FEATURE_COUNT + 7; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder MSub Device Holder}'. + * The operation id for the 'Fetch Switch State' operation. * * - * @return the meta object for class 'MSub Device Holder'. - * @see org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder * @generated + * @ordered */ - EClass getMSubDeviceHolder(); + int MLCD2_0X4_BACKLIGHT___FETCH_SWITCH_STATE = MIN_SWITCH_ACTOR___FETCH_SWITCH_STATE; /** - * Returns the meta object for the containment reference list '{@link org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder#getMsubdevices Msubdevices}'. + * The operation id for the 'Turn Switch' operation. * * - * @return the meta object for the containment reference list 'Msubdevices'. - * @see org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder#getMsubdevices() - * @see #getMSubDeviceHolder() * @generated + * @ordered */ - EReference getMSubDeviceHolder_Msubdevices(); + int MLCD2_0X4_BACKLIGHT___TURN_SWITCH__ONOFFVALUE = MIN_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder#initSubDevices() Init Sub Devices}' operation. + * The operation id for the 'Init' operation. * * - * @return the meta object for the 'Init Sub Devices' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder#initSubDevices() * @generated + * @ordered */ - EOperation getMSubDeviceHolder__InitSubDevices(); + int MLCD2_0X4_BACKLIGHT___INIT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickServo MBrick Servo}'. + * The operation id for the 'Enable' operation. * * - * @return the meta object for class 'MBrick Servo'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickServo * @generated + * @ordered */ - EClass getMBrickServo(); + int MLCD2_0X4_BACKLIGHT___ENABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickServo#getDeviceType Device Type}'. + * The operation id for the 'Disable' operation. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickServo#getDeviceType() - * @see #getMBrickServo() * @generated + * @ordered */ - EAttribute getMBrickServo_DeviceType(); + int MLCD2_0X4_BACKLIGHT___DISABLE = MIN_SWITCH_ACTOR_OPERATION_COUNT + 2; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickServo#init() Init}' operation. + * The number of operations of the 'MLCD2 0x4 Backlight' class. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickServo#init() * @generated + * @ordered */ - EOperation getMBrickServo__Init(); + int MLCD2_0X4_BACKLIGHT_OPERATION_COUNT = MIN_SWITCH_ACTOR_OPERATION_COUNT + 3; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration TF Brick DC Configuration}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MLCD20x4ButtonImpl MLCD2 0x4 Button}' class. * * - * @return the meta object for class 'TF Brick DC Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration + * @see org.openhab.binding.tinkerforge.internal.model.impl.MLCD20x4ButtonImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMLCD20x4Button() * @generated */ - EClass getTFBrickDCConfiguration(); + int MLCD2_0X4_BUTTON = 91; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getVelocity Velocity}'. + * The feature id for the 'Switch State' attribute. * * - * @return the meta object for the attribute 'Velocity'. - * @see org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getVelocity() - * @see #getTFBrickDCConfiguration() * @generated + * @ordered */ - EAttribute getTFBrickDCConfiguration_Velocity(); + int MLCD2_0X4_BUTTON__SWITCH_STATE = MOUT_SWITCH_ACTOR__SWITCH_STATE; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getAcceleration Acceleration}'. + * The feature id for the 'Logger' attribute. * * - * @return the meta object for the attribute 'Acceleration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getAcceleration() - * @see #getTFBrickDCConfiguration() * @generated + * @ordered */ - EAttribute getTFBrickDCConfiguration_Acceleration(); + int MLCD2_0X4_BUTTON__LOGGER = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getPwmFrequency Pwm Frequency}'. + * The feature id for the 'Uid' attribute. * * - * @return the meta object for the attribute 'Pwm Frequency'. - * @see org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getPwmFrequency() - * @see #getTFBrickDCConfiguration() * @generated + * @ordered */ - EAttribute getTFBrickDCConfiguration_PwmFrequency(); + int MLCD2_0X4_BUTTON__UID = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getDriveMode Drive Mode}'. + * The feature id for the 'Poll' attribute. * * - * @return the meta object for the attribute 'Drive Mode'. - * @see org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getDriveMode() - * @see #getTFBrickDCConfiguration() * @generated + * @ordered */ - EAttribute getTFBrickDCConfiguration_DriveMode(); + int MLCD2_0X4_BUTTON__POLL = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 2; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getSwitchOnVelocity Switch On Velocity}'. + * The feature id for the 'Enabled A' attribute. * * - * @return the meta object for the attribute 'Switch On Velocity'. - * @see org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getSwitchOnVelocity() - * @see #getTFBrickDCConfiguration() * @generated + * @ordered */ - EAttribute getTFBrickDCConfiguration_SwitchOnVelocity(); + int MLCD2_0X4_BUTTON__ENABLED_A = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 3; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC MBrick DC}'. + * The feature id for the 'Sub Id' attribute. * * - * @return the meta object for class 'MBrick DC'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC * @generated + * @ordered */ - EClass getMBrickDC(); + int MLCD2_0X4_BUTTON__SUB_ID = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 4; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getDeviceType Device Type}'. + * The feature id for the 'Mbrick' container reference. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getDeviceType() - * @see #getMBrickDC() * @generated + * @ordered */ - EAttribute getMBrickDC_DeviceType(); + int MLCD2_0X4_BUTTON__MBRICK = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 5; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getVelocity Velocity}'. + * The feature id for the 'Callback Period' attribute. * * - * @return the meta object for the attribute 'Velocity'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getVelocity() - * @see #getMBrickDC() * @generated + * @ordered */ - EAttribute getMBrickDC_Velocity(); + int MLCD2_0X4_BUTTON__CALLBACK_PERIOD = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 6; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getCurrentVelocity Current Velocity}'. + * The feature id for the 'Device Type' attribute. * * - * @return the meta object for the attribute 'Current Velocity'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getCurrentVelocity() - * @see #getMBrickDC() * @generated + * @ordered */ - EAttribute getMBrickDC_CurrentVelocity(); + int MLCD2_0X4_BUTTON__DEVICE_TYPE = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 7; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getAcceleration Acceleration}'. + * The feature id for the 'Button Num' attribute. * * - * @return the meta object for the attribute 'Acceleration'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getAcceleration() - * @see #getMBrickDC() * @generated + * @ordered */ - EAttribute getMBrickDC_Acceleration(); + int MLCD2_0X4_BUTTON__BUTTON_NUM = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 8; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getPwmFrequency Pwm Frequency}'. + * The number of structural features of the 'MLCD2 0x4 Button' class. * * - * @return the meta object for the attribute 'Pwm Frequency'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getPwmFrequency() - * @see #getMBrickDC() * @generated + * @ordered */ - EAttribute getMBrickDC_PwmFrequency(); + int MLCD2_0X4_BUTTON_FEATURE_COUNT = MOUT_SWITCH_ACTOR_FEATURE_COUNT + 9; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getDriveMode Drive Mode}'. + * The operation id for the 'Fetch Switch State' operation. * * - * @return the meta object for the attribute 'Drive Mode'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getDriveMode() - * @see #getMBrickDC() * @generated + * @ordered */ - EAttribute getMBrickDC_DriveMode(); + int MLCD2_0X4_BUTTON___FETCH_SWITCH_STATE = MOUT_SWITCH_ACTOR___FETCH_SWITCH_STATE; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getSwitchOnVelocity Switch On Velocity}'. + * The operation id for the 'Turn Switch' operation. * * - * @return the meta object for the attribute 'Switch On Velocity'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getSwitchOnVelocity() - * @see #getMBrickDC() * @generated + * @ordered */ - EAttribute getMBrickDC_SwitchOnVelocity(); + int MLCD2_0X4_BUTTON___TURN_SWITCH__ONOFFVALUE = MOUT_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#init() Init}' operation. + * The operation id for the 'Init' operation. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#init() * @generated + * @ordered */ - EOperation getMBrickDC__Init(); + int MLCD2_0X4_BUTTON___INIT = MOUT_SWITCH_ACTOR_OPERATION_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MDualRelayBricklet MDual Relay Bricklet}'. + * The operation id for the 'Enable' operation. * * - * @return the meta object for class 'MDual Relay Bricklet'. - * @see org.openhab.binding.tinkerforge.internal.model.MDualRelayBricklet * @generated + * @ordered */ - EClass getMDualRelayBricklet(); + int MLCD2_0X4_BUTTON___ENABLE = MOUT_SWITCH_ACTOR_OPERATION_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDualRelayBricklet#getDeviceType Device Type}'. + * The operation id for the 'Disable' operation. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MDualRelayBricklet#getDeviceType() - * @see #getMDualRelayBricklet() * @generated + * @ordered */ - EAttribute getMDualRelayBricklet_DeviceType(); + int MLCD2_0X4_BUTTON___DISABLE = MOUT_SWITCH_ACTOR_OPERATION_COUNT + 2; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelayBricklet MIndustrial Quad Relay Bricklet}'. + * The number of operations of the 'MLCD2 0x4 Button' class. * * - * @return the meta object for class 'MIndustrial Quad Relay Bricklet'. - * @see org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelayBricklet * @generated + * @ordered */ - EClass getMIndustrialQuadRelayBricklet(); + int MLCD2_0X4_BUTTON_OPERATION_COUNT = MOUT_SWITCH_ACTOR_OPERATION_COUNT + 3; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelay MIndustrial Quad Relay}'. + * The number of structural features of the 'TF Config' class. * * - * @return the meta object for class 'MIndustrial Quad Relay'. - * @see org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelay * @generated + * @ordered */ - EClass getMIndustrialQuadRelay(); + int TF_CONFIG_FEATURE_COUNT = 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelay#getDeviceType Device Type}'. + * The number of operations of the 'TF Config' class. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelay#getDeviceType() - * @see #getMIndustrialQuadRelay() * @generated + * @ordered */ - EAttribute getMIndustrialQuadRelay_DeviceType(); + int TF_CONFIG_OPERATION_COUNT = 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalIn4 MBricklet Industrial Digital In4}'. + * The feature id for the 'Uid' attribute. * * - * @return the meta object for class 'MBricklet Industrial Digital In4'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalIn4 * @generated + * @ordered */ - EClass getMBrickletIndustrialDigitalIn4(); + int OHTF_DEVICE__UID = 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalIn4#getDeviceType Device Type}'. + * The feature id for the 'Subid' attribute. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalIn4#getDeviceType() - * @see #getMBrickletIndustrialDigitalIn4() * @generated + * @ordered */ - EAttribute getMBrickletIndustrialDigitalIn4_DeviceType(); + int OHTF_DEVICE__SUBID = 1; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MIndustrialDigitalIn MIndustrial Digital In}'. + * The feature id for the 'Ohid' attribute. * * - * @return the meta object for class 'MIndustrial Digital In'. - * @see org.openhab.binding.tinkerforge.internal.model.MIndustrialDigitalIn * @generated + * @ordered */ - EClass getMIndustrialDigitalIn(); + int OHTF_DEVICE__OHID = 2; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalOut4 MBricklet Industrial Digital Out4}'. + * The feature id for the 'Sub Device Ids' attribute list. * * - * @return the meta object for class 'MBricklet Industrial Digital Out4'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalOut4 * @generated + * @ordered */ - EClass getMBrickletIndustrialDigitalOut4(); + int OHTF_DEVICE__SUB_DEVICE_IDS = 3; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorDigitalOut4 Digital Actor Digital Out4}'. + * The feature id for the 'Tf Config' containment reference. * * - * @return the meta object for class 'Digital Actor Digital Out4'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorDigitalOut4 * @generated + * @ordered */ - EClass getDigitalActorDigitalOut4(); + int OHTF_DEVICE__TF_CONFIG = 4; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorDigitalOut4#getPin Pin}'. + * The feature id for the 'Oh Config' container reference. * * - * @return the meta object for the attribute 'Pin'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorDigitalOut4#getPin() - * @see #getDigitalActorDigitalOut4() * @generated + * @ordered */ - EAttribute getDigitalActorDigitalOut4_Pin(); + int OHTF_DEVICE__OH_CONFIG = 5; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor Digital Actor}'. + * The number of structural features of the 'OHTF Device' class. * * - * @return the meta object for class 'Digital Actor'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor * @generated + * @ordered */ - EClass getDigitalActor(); + int OHTF_DEVICE_FEATURE_COUNT = 6; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor#getDigitalState Digital State}'. + * The operation id for the 'Is Valid Sub Id' operation. * * - * @return the meta object for the attribute 'Digital State'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor#getDigitalState() - * @see #getDigitalActor() * @generated + * @ordered */ - EAttribute getDigitalActor_DigitalState(); + int OHTF_DEVICE___IS_VALID_SUB_ID__STRING = 0; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) Turn Digital}' operation. + * The number of operations of the 'OHTF Device' class. * * - * @return the meta object for the 'Turn Digital' operation. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) * @generated + * @ordered */ - EOperation getDigitalActor__TurnDigital__HighLowValue(); + int OHTF_DEVICE_OPERATION_COUNT = 1; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor#fetchDigitalValue() Fetch Digital Value}' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.OHTFSubDeviceAdminDeviceImpl OHTF Sub Device Admin Device}' class. * * - * @return the meta object for the 'Fetch Digital Value' operation. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor#fetchDigitalValue() + * @see org.openhab.binding.tinkerforge.internal.model.impl.OHTFSubDeviceAdminDeviceImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getOHTFSubDeviceAdminDevice() * @generated */ - EOperation getDigitalActor__FetchDigitalValue(); + int OHTF_SUB_DEVICE_ADMIN_DEVICE = 94; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.NumberActor Number Actor}'. + * The feature id for the 'Uid' attribute. * * - * @return the meta object for class 'Number Actor'. - * @see org.openhab.binding.tinkerforge.internal.model.NumberActor * @generated + * @ordered */ - EClass getNumberActor(); + int OHTF_SUB_DEVICE_ADMIN_DEVICE__UID = OHTF_DEVICE__UID; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.NumberActor#setNumber(java.math.BigDecimal) Set Number}' operation. + * The feature id for the 'Subid' attribute. * * - * @return the meta object for the 'Set Number' operation. - * @see org.openhab.binding.tinkerforge.internal.model.NumberActor#setNumber(java.math.BigDecimal) * @generated + * @ordered */ - EOperation getNumberActor__SetNumber__BigDecimal(); + int OHTF_SUB_DEVICE_ADMIN_DEVICE__SUBID = OHTF_DEVICE__SUBID; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.ColorActor Color Actor}'. + * The feature id for the 'Ohid' attribute. * * - * @return the meta object for class 'Color Actor'. - * @see org.openhab.binding.tinkerforge.internal.model.ColorActor * @generated + * @ordered */ - EClass getColorActor(); + int OHTF_SUB_DEVICE_ADMIN_DEVICE__OHID = OHTF_DEVICE__OHID; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.ColorActor#setColor(org.openhab.core.library.types.HSBType, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) Set Color}' operation. + * The feature id for the 'Sub Device Ids' attribute list. * * - * @return the meta object for the 'Set Color' operation. - * @see org.openhab.binding.tinkerforge.internal.model.ColorActor#setColor(org.openhab.core.library.types.HSBType, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) * @generated + * @ordered */ - EOperation getColorActor__SetColor__HSBType_DeviceOptions(); + int OHTF_SUB_DEVICE_ADMIN_DEVICE__SUB_DEVICE_IDS = OHTF_DEVICE__SUB_DEVICE_IDS; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLEDStrip MBricklet LED Strip}'. + * The feature id for the 'Tf Config' containment reference. * * - * @return the meta object for class 'MBricklet LED Strip'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLEDStrip * @generated + * @ordered */ - EClass getMBrickletLEDStrip(); + int OHTF_SUB_DEVICE_ADMIN_DEVICE__TF_CONFIG = OHTF_DEVICE__TF_CONFIG; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletSegmentDisplay4x7 MBricklet Segment Display4x7}'. + * The feature id for the 'Oh Config' container reference. * * - * @return the meta object for class 'MBricklet Segment Display4x7'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletSegmentDisplay4x7 * @generated + * @ordered */ - EClass getMBrickletSegmentDisplay4x7(); + int OHTF_SUB_DEVICE_ADMIN_DEVICE__OH_CONFIG = OHTF_DEVICE__OH_CONFIG; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16 Digital Actor IO16}'. + * The number of structural features of the 'OHTF Sub Device Admin Device' class. * * - * @return the meta object for class 'Digital Actor IO16'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16 * @generated + * @ordered */ - EClass getDigitalActorIO16(); + int OHTF_SUB_DEVICE_ADMIN_DEVICE_FEATURE_COUNT = OHTF_DEVICE_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getDeviceType Device Type}'. + * The operation id for the 'Is Valid Sub Id' operation. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getDeviceType() - * @see #getDigitalActorIO16() * @generated + * @ordered */ - EAttribute getDigitalActorIO16_DeviceType(); + int OHTF_SUB_DEVICE_ADMIN_DEVICE___IS_VALID_SUB_ID__STRING = OHTF_DEVICE_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getPort Port}'. + * The number of operations of the 'OHTF Sub Device Admin Device' class. * * - * @return the meta object for the attribute 'Port'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getPort() - * @see #getDigitalActorIO16() * @generated + * @ordered */ - EAttribute getDigitalActorIO16_Port(); + int OHTF_SUB_DEVICE_ADMIN_DEVICE_OPERATION_COUNT = OHTF_DEVICE_OPERATION_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getPin Pin}'. + * The feature id for the 'Oh Tf Devices' containment reference list. * * - * @return the meta object for the attribute 'Pin'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getPin() - * @see #getDigitalActorIO16() * @generated + * @ordered */ - EAttribute getDigitalActorIO16_Pin(); + int OH_CONFIG__OH_TF_DEVICES = 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getDefaultState Default State}'. + * The number of structural features of the 'OH Config' class. * * - * @return the meta object for the attribute 'Default State'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getDefaultState() - * @see #getDigitalActorIO16() * @generated + * @ordered */ - EAttribute getDigitalActorIO16_DefaultState(); + int OH_CONFIG_FEATURE_COUNT = 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#isKeepOnReconnect Keep On Reconnect}'. + * The operation id for the 'Get Config By TF Id' operation. * * - * @return the meta object for the attribute 'Keep On Reconnect'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#isKeepOnReconnect() - * @see #getDigitalActorIO16() * @generated + * @ordered */ - EAttribute getDigitalActorIO16_KeepOnReconnect(); + int OH_CONFIG___GET_CONFIG_BY_TF_ID__STRING_STRING = 0; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) Turn Digital}' operation. + * The operation id for the 'Get Config By OH Id' operation. * * - * @return the meta object for the 'Turn Digital' operation. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) * @generated + * @ordered */ - EOperation getDigitalActorIO16__TurnDigital__HighLowValue(); + int OH_CONFIG___GET_CONFIG_BY_OH_ID__STRING = 1; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#fetchDigitalValue() Fetch Digital Value}' operation. + * The number of operations of the 'OH Config' class. * * - * @return the meta object for the 'Fetch Digital Value' operation. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#fetchDigitalValue() * @generated + * @ordered */ - EOperation getDigitalActorIO16__FetchDigitalValue(); + int OH_CONFIG_OPERATION_COUNT = 2; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MActor MActor}'. + * The number of structural features of the 'TF Null Configuration' class. * * - * @return the meta object for class 'MActor'. - * @see org.openhab.binding.tinkerforge.internal.model.MActor * @generated + * @ordered */ - EClass getMActor(); + int TF_NULL_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MSwitchActor MSwitch Actor}'. + * The number of operations of the 'TF Null Configuration' class. * * - * @return the meta object for class 'MSwitch Actor'. - * @see org.openhab.binding.tinkerforge.internal.model.MSwitchActor * @generated + * @ordered */ - EClass getMSwitchActor(); + int TF_NULL_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MSwitchActor#getSwitchState Switch State}'. + * The feature id for the 'Threshold' attribute. * * - * @return the meta object for the attribute 'Switch State'. - * @see org.openhab.binding.tinkerforge.internal.model.MSwitchActor#getSwitchState() - * @see #getMSwitchActor() * @generated + * @ordered */ - EAttribute getMSwitchActor_SwitchState(); + int TF_BASE_CONFIGURATION__THRESHOLD = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MSwitchActor#turnSwitch(org.openhab.binding.tinkerforge.internal.types.OnOffValue) Turn Switch}' operation. + * The feature id for the 'Callback Period' attribute. * * - * @return the meta object for the 'Turn Switch' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MSwitchActor#turnSwitch(org.openhab.binding.tinkerforge.internal.types.OnOffValue) * @generated + * @ordered */ - EOperation getMSwitchActor__TurnSwitch__OnOffValue(); + int TF_BASE_CONFIGURATION__CALLBACK_PERIOD = TF_CONFIG_FEATURE_COUNT + 1; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MSwitchActor#fetchSwitchState() Fetch Switch State}' operation. + * The number of structural features of the 'TF Base Configuration' class. * * - * @return the meta object for the 'Fetch Switch State' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MSwitchActor#fetchSwitchState() * @generated + * @ordered */ - EOperation getMSwitchActor__FetchSwitchState(); + int TF_BASE_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 2; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MOutSwitchActor MOut Switch Actor}'. + * The number of operations of the 'TF Base Configuration' class. * * - * @return the meta object for class 'MOut Switch Actor'. - * @see org.openhab.binding.tinkerforge.internal.model.MOutSwitchActor * @generated + * @ordered */ - EClass getMOutSwitchActor(); + int TF_BASE_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MInSwitchActor MIn Switch Actor}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFObjectTemperatureConfigurationImpl TF Object Temperature Configuration}' class. * * - * @return the meta object for class 'MIn Switch Actor'. - * @see org.openhab.binding.tinkerforge.internal.model.MInSwitchActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.TFObjectTemperatureConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFObjectTemperatureConfiguration() * @generated */ - EClass getMInSwitchActor(); + int TF_OBJECT_TEMPERATURE_CONFIGURATION = 98; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.GenericDevice Generic Device}'. + * The feature id for the 'Threshold' attribute. * * - * @return the meta object for class 'Generic Device'. - * @see org.openhab.binding.tinkerforge.internal.model.GenericDevice * @generated + * @ordered */ - EClass getGenericDevice(); + int TF_OBJECT_TEMPERATURE_CONFIGURATION__THRESHOLD = TF_BASE_CONFIGURATION__THRESHOLD; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.GenericDevice#getGenericDeviceId Generic Device Id}'. + * The feature id for the 'Callback Period' attribute. * * - * @return the meta object for the attribute 'Generic Device Id'. - * @see org.openhab.binding.tinkerforge.internal.model.GenericDevice#getGenericDeviceId() - * @see #getGenericDevice() * @generated + * @ordered */ - EAttribute getGenericDevice_GenericDeviceId(); + int TF_OBJECT_TEMPERATURE_CONFIGURATION__CALLBACK_PERIOD = TF_BASE_CONFIGURATION__CALLBACK_PERIOD; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration TFIO Actor Configuration}'. + * The feature id for the 'Emissivity' attribute. * * - * @return the meta object for class 'TFIO Actor Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration * @generated + * @ordered */ - EClass getTFIOActorConfiguration(); + int TF_OBJECT_TEMPERATURE_CONFIGURATION__EMISSIVITY = TF_BASE_CONFIGURATION_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration#getDefaultState Default State}'. + * The number of structural features of the 'TF Object Temperature Configuration' class. * * - * @return the meta object for the attribute 'Default State'. - * @see org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration#getDefaultState() - * @see #getTFIOActorConfiguration() * @generated + * @ordered */ - EAttribute getTFIOActorConfiguration_DefaultState(); + int TF_OBJECT_TEMPERATURE_CONFIGURATION_FEATURE_COUNT = TF_BASE_CONFIGURATION_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration#isKeepOnReconnect Keep On Reconnect}'. + * The number of operations of the 'TF Object Temperature Configuration' class. * * - * @return the meta object for the attribute 'Keep On Reconnect'. - * @see org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration#isKeepOnReconnect() - * @see #getTFIOActorConfiguration() * @generated + * @ordered */ - EAttribute getTFIOActorConfiguration_KeepOnReconnect(); + int TF_OBJECT_TEMPERATURE_CONFIGURATION_OPERATION_COUNT = TF_BASE_CONFIGURATION_OPERATION_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFInterruptListenerConfiguration TF Interrupt Listener Configuration}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFMoistureBrickletConfigurationImpl TF Moisture Bricklet Configuration}' class. * * - * @return the meta object for class 'TF Interrupt Listener Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFInterruptListenerConfiguration + * @see org.openhab.binding.tinkerforge.internal.model.impl.TFMoistureBrickletConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFMoistureBrickletConfiguration() * @generated */ - EClass getTFInterruptListenerConfiguration(); + int TF_MOISTURE_BRICKLET_CONFIGURATION = 99; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFInterruptListenerConfiguration#getDebouncePeriod Debounce Period}'. + * The feature id for the 'Threshold' attribute. * * - * @return the meta object for the attribute 'Debounce Period'. - * @see org.openhab.binding.tinkerforge.internal.model.TFInterruptListenerConfiguration#getDebouncePeriod() - * @see #getTFInterruptListenerConfiguration() * @generated + * @ordered */ - EAttribute getTFInterruptListenerConfiguration_DebouncePeriod(); + int TF_MOISTURE_BRICKLET_CONFIGURATION__THRESHOLD = TF_BASE_CONFIGURATION__THRESHOLD; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIO16 MBricklet IO16}'. + * The feature id for the 'Callback Period' attribute. * * - * @return the meta object for class 'MBricklet IO16'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIO16 * @generated + * @ordered */ - EClass getMBrickletIO16(); + int TF_MOISTURE_BRICKLET_CONFIGURATION__CALLBACK_PERIOD = TF_BASE_CONFIGURATION__CALLBACK_PERIOD; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIO16#getDeviceType Device Type}'. + * The feature id for the 'Moving Average' attribute. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIO16#getDeviceType() - * @see #getMBrickletIO16() * @generated + * @ordered */ - EAttribute getMBrickletIO16_DeviceType(); + int TF_MOISTURE_BRICKLET_CONFIGURATION__MOVING_AVERAGE = TF_BASE_CONFIGURATION_FEATURE_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.IODevice IO Device}'. + * The number of structural features of the 'TF Moisture Bricklet Configuration' class. * * - * @return the meta object for class 'IO Device'. - * @see org.openhab.binding.tinkerforge.internal.model.IODevice * @generated + * @ordered */ - EClass getIODevice(); + int TF_MOISTURE_BRICKLET_CONFIGURATION_FEATURE_COUNT = TF_BASE_CONFIGURATION_FEATURE_COUNT + 1; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFIOSensorConfiguration TFIO Sensor Configuration}'. + * The number of operations of the 'TF Moisture Bricklet Configuration' class. * * - * @return the meta object for class 'TFIO Sensor Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFIOSensorConfiguration * @generated + * @ordered */ - EClass getTFIOSensorConfiguration(); + int TF_MOISTURE_BRICKLET_CONFIGURATION_OPERATION_COUNT = TF_BASE_CONFIGURATION_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFIOSensorConfiguration#isPullUpResistorEnabled Pull Up Resistor Enabled}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFDistanceUSBrickletConfigurationImpl TF Distance US Bricklet Configuration}' class. * * - * @return the meta object for the attribute 'Pull Up Resistor Enabled'. - * @see org.openhab.binding.tinkerforge.internal.model.TFIOSensorConfiguration#isPullUpResistorEnabled() - * @see #getTFIOSensorConfiguration() + * @see org.openhab.binding.tinkerforge.internal.model.impl.TFDistanceUSBrickletConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFDistanceUSBrickletConfiguration() * @generated */ - EAttribute getTFIOSensorConfiguration_PullUpResistorEnabled(); + int TF_DISTANCE_US_BRICKLET_CONFIGURATION = 100; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensor Digital Sensor}'. + * The feature id for the 'Threshold' attribute. * * - * @return the meta object for class 'Digital Sensor'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensor * @generated + * @ordered */ - EClass getDigitalSensor(); + int TF_DISTANCE_US_BRICKLET_CONFIGURATION__THRESHOLD = TF_BASE_CONFIGURATION__THRESHOLD; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getDeviceType Device Type}'. + * The feature id for the 'Callback Period' attribute. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getDeviceType() - * @see #getDigitalSensor() * @generated + * @ordered */ - EAttribute getDigitalSensor_DeviceType(); + int TF_DISTANCE_US_BRICKLET_CONFIGURATION__CALLBACK_PERIOD = TF_BASE_CONFIGURATION__CALLBACK_PERIOD; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensor#isPullUpResistorEnabled Pull Up Resistor Enabled}'. + * The feature id for the 'Moving Average' attribute. * * - * @return the meta object for the attribute 'Pull Up Resistor Enabled'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensor#isPullUpResistorEnabled() - * @see #getDigitalSensor() * @generated + * @ordered */ - EAttribute getDigitalSensor_PullUpResistorEnabled(); + int TF_DISTANCE_US_BRICKLET_CONFIGURATION__MOVING_AVERAGE = TF_BASE_CONFIGURATION_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getPort Port}'. + * The number of structural features of the 'TF Distance US Bricklet Configuration' class. * * - * @return the meta object for the attribute 'Port'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getPort() - * @see #getDigitalSensor() * @generated + * @ordered */ - EAttribute getDigitalSensor_Port(); + int TF_DISTANCE_US_BRICKLET_CONFIGURATION_FEATURE_COUNT = TF_BASE_CONFIGURATION_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getPin Pin}'. + * The number of operations of the 'TF Distance US Bricklet Configuration' class. * * - * @return the meta object for the attribute 'Pin'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getPin() - * @see #getDigitalSensor() * @generated + * @ordered */ - EAttribute getDigitalSensor_Pin(); + int TF_DISTANCE_US_BRICKLET_CONFIGURATION_OPERATION_COUNT = TF_BASE_CONFIGURATION_OPERATION_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIO4 MBricklet IO4}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFVoltageCurrentConfigurationImpl TF Voltage Current Configuration}' class. * * - * @return the meta object for class 'MBricklet IO4'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIO4 + * @see org.openhab.binding.tinkerforge.internal.model.impl.TFVoltageCurrentConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFVoltageCurrentConfiguration() * @generated */ - EClass getMBrickletIO4(); + int TF_VOLTAGE_CURRENT_CONFIGURATION = 101; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIO4#getDeviceType Device Type}'. + * The feature id for the 'Averaging' attribute. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIO4#getDeviceType() - * @see #getMBrickletIO4() * @generated + * @ordered */ - EAttribute getMBrickletIO4_DeviceType(); + int TF_VOLTAGE_CURRENT_CONFIGURATION__AVERAGING = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.IO4Device IO4 Device}'. + * The feature id for the 'Voltage Conversion Time' attribute. * * - * @return the meta object for class 'IO4 Device'. - * @see org.openhab.binding.tinkerforge.internal.model.IO4Device * @generated + * @ordered */ - EClass getIO4Device(); + int TF_VOLTAGE_CURRENT_CONFIGURATION__VOLTAGE_CONVERSION_TIME = TF_CONFIG_FEATURE_COUNT + 1; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4 Digital Sensor IO4}'. + * The feature id for the 'Current Conversion Time' attribute. * * - * @return the meta object for class 'Digital Sensor IO4'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4 * @generated + * @ordered */ - EClass getDigitalSensorIO4(); + int TF_VOLTAGE_CURRENT_CONFIGURATION__CURRENT_CONVERSION_TIME = TF_CONFIG_FEATURE_COUNT + 2; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#getDeviceType Device Type}'. + * The number of structural features of the 'TF Voltage Current Configuration' class. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#getDeviceType() - * @see #getDigitalSensorIO4() * @generated + * @ordered */ - EAttribute getDigitalSensorIO4_DeviceType(); + int TF_VOLTAGE_CURRENT_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 3; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#isPullUpResistorEnabled Pull Up Resistor Enabled}'. + * The number of operations of the 'TF Voltage Current Configuration' class. * * - * @return the meta object for the attribute 'Pull Up Resistor Enabled'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#isPullUpResistorEnabled() - * @see #getDigitalSensorIO4() * @generated + * @ordered */ - EAttribute getDigitalSensorIO4_PullUpResistorEnabled(); + int TF_VOLTAGE_CURRENT_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#getPin Pin}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.BrickletRemoteSwitchConfigurationImpl Bricklet Remote Switch Configuration}' class. * * - * @return the meta object for the attribute 'Pin'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#getPin() - * @see #getDigitalSensorIO4() + * @see org.openhab.binding.tinkerforge.internal.model.impl.BrickletRemoteSwitchConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getBrickletRemoteSwitchConfiguration() * @generated */ - EAttribute getDigitalSensorIO4_Pin(); + int BRICKLET_REMOTE_SWITCH_CONFIGURATION = 107; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4 Digital Actor IO4}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchAConfigurationImpl Remote Switch AConfiguration}' class. * * - * @return the meta object for class 'Digital Actor IO4'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4 + * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchAConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchAConfiguration() * @generated */ - EClass getDigitalActorIO4(); + int REMOTE_SWITCH_ACONFIGURATION = 108; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getDeviceType Device Type}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBConfigurationImpl Remote Switch BConfiguration}' class. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getDeviceType() - * @see #getDigitalActorIO4() + * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchBConfiguration() * @generated */ - EAttribute getDigitalActorIO4_DeviceType(); + int REMOTE_SWITCH_BCONFIGURATION = 109; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getPin Pin}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchCConfigurationImpl Remote Switch CConfiguration}' class. * * - * @return the meta object for the attribute 'Pin'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getPin() - * @see #getDigitalActorIO4() + * @see org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchCConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getRemoteSwitchCConfiguration() * @generated */ - EAttribute getDigitalActorIO4_Pin(); + int REMOTE_SWITCH_CCONFIGURATION = 110; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getDefaultState Default State}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MultiTouchDeviceConfigurationImpl Multi Touch Device Configuration}' class. * * - * @return the meta object for the attribute 'Default State'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getDefaultState() - * @see #getDigitalActorIO4() + * @see org.openhab.binding.tinkerforge.internal.model.impl.MultiTouchDeviceConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMultiTouchDeviceConfiguration() * @generated */ - EAttribute getDigitalActorIO4_DefaultState(); + int MULTI_TOUCH_DEVICE_CONFIGURATION = 111; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#isKeepOnReconnect Keep On Reconnect}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.BrickletMultiTouchConfigurationImpl Bricklet Multi Touch Configuration}' class. * * - * @return the meta object for the attribute 'Keep On Reconnect'. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#isKeepOnReconnect() - * @see #getDigitalActorIO4() + * @see org.openhab.binding.tinkerforge.internal.model.impl.BrickletMultiTouchConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getBrickletMultiTouchConfiguration() * @generated */ - EAttribute getDigitalActorIO4_KeepOnReconnect(); + int BRICKLET_MULTI_TOUCH_CONFIGURATION = 112; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) Turn Digital}' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DimmableConfigurationImpl Dimmable Configuration}' class. * * - * @return the meta object for the 'Turn Digital' operation. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) + * @see org.openhab.binding.tinkerforge.internal.model.impl.DimmableConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDimmableConfiguration() * @generated */ - EOperation getDigitalActorIO4__TurnDigital__HighLowValue(); + int DIMMABLE_CONFIGURATION = 113; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#fetchDigitalValue() Fetch Digital Value}' operation. + * The feature id for the 'Min Value' attribute. * * - * @return the meta object for the 'Fetch Digital Value' operation. - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#fetchDigitalValue() * @generated + * @ordered */ - EOperation getDigitalActorIO4__FetchDigitalValue(); + int DIMMABLE_CONFIGURATION__MIN_VALUE = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch MBricklet Multi Touch}'. + * The feature id for the 'Max Value' attribute. * * - * @return the meta object for class 'MBricklet Multi Touch'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch * @generated + * @ordered */ - EClass getMBrickletMultiTouch(); + int DIMMABLE_CONFIGURATION__MAX_VALUE = TF_CONFIG_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getDeviceType Device Type}'. + * The number of structural features of the 'Dimmable Configuration' class. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getDeviceType() - * @see #getMBrickletMultiTouch() * @generated + * @ordered */ - EAttribute getMBrickletMultiTouch_DeviceType(); + int DIMMABLE_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 2; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getRecalibrate Recalibrate}'. + * The number of operations of the 'Dimmable Configuration' class. * * - * @return the meta object for the attribute 'Recalibrate'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getRecalibrate() - * @see #getMBrickletMultiTouch() * @generated + * @ordered */ - EAttribute getMBrickletMultiTouch_Recalibrate(); + int DIMMABLE_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getSensitivity Sensitivity}'. + * The feature id for the 'Min Value' attribute. * * - * @return the meta object for the attribute 'Sensitivity'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getSensitivity() - * @see #getMBrickletMultiTouch() * @generated + * @ordered */ - EAttribute getMBrickletMultiTouch_Sensitivity(); + int TF_BRICK_DC_CONFIGURATION__MIN_VALUE = DIMMABLE_CONFIGURATION__MIN_VALUE; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice Multi Touch Device}'. + * The feature id for the 'Max Value' attribute. * * - * @return the meta object for class 'Multi Touch Device'. - * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice * @generated + * @ordered */ - EClass getMultiTouchDevice(); + int TF_BRICK_DC_CONFIGURATION__MAX_VALUE = DIMMABLE_CONFIGURATION__MAX_VALUE; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice#getPin Pin}'. + * The feature id for the 'Threshold' attribute. * * - * @return the meta object for the attribute 'Pin'. - * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice#getPin() - * @see #getMultiTouchDevice() * @generated + * @ordered */ - EAttribute getMultiTouchDevice_Pin(); + int TF_BRICK_DC_CONFIGURATION__THRESHOLD = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice#getDisableElectrode Disable Electrode}'. + * The feature id for the 'Callback Period' attribute. * * - * @return the meta object for the attribute 'Disable Electrode'. - * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice#getDisableElectrode() - * @see #getMultiTouchDevice() * @generated + * @ordered */ - EAttribute getMultiTouchDevice_DisableElectrode(); + int TF_BRICK_DC_CONFIGURATION__CALLBACK_PERIOD = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 1; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.Electrode Electrode}'. + * The feature id for the 'Velocity' attribute. * * - * @return the meta object for class 'Electrode'. - * @see org.openhab.binding.tinkerforge.internal.model.Electrode * @generated + * @ordered */ - EClass getElectrode(); + int TF_BRICK_DC_CONFIGURATION__VELOCITY = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 2; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.Electrode#getDeviceType Device Type}'. + * The feature id for the 'Acceleration' attribute. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.Electrode#getDeviceType() - * @see #getElectrode() * @generated + * @ordered */ - EAttribute getElectrode_DeviceType(); + int TF_BRICK_DC_CONFIGURATION__ACCELERATION = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 3; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.Proximity Proximity}'. + * The feature id for the 'Pwm Frequency' attribute. * * - * @return the meta object for class 'Proximity'. - * @see org.openhab.binding.tinkerforge.internal.model.Proximity * @generated + * @ordered */ - EClass getProximity(); + int TF_BRICK_DC_CONFIGURATION__PWM_FREQUENCY = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 4; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.Proximity#getDeviceType Device Type}'. + * The feature id for the 'Drive Mode' attribute. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.Proximity#getDeviceType() - * @see #getProximity() * @generated + * @ordered */ - EAttribute getProximity_DeviceType(); + int TF_BRICK_DC_CONFIGURATION__DRIVE_MODE = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 5; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector MBricklet Motion Detector}'. + * The number of structural features of the 'TF Brick DC Configuration' class. * * - * @return the meta object for class 'MBricklet Motion Detector'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector * @generated + * @ordered */ - EClass getMBrickletMotionDetector(); + int TF_BRICK_DC_CONFIGURATION_FEATURE_COUNT = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 6; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector#getDeviceType Device Type}'. + * The number of operations of the 'TF Brick DC Configuration' class. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector#getDeviceType() - * @see #getMBrickletMotionDetector() * @generated + * @ordered */ - EAttribute getMBrickletMotionDetector_DeviceType(); + int TF_BRICK_DC_CONFIGURATION_OPERATION_COUNT = DIMMABLE_CONFIGURATION_OPERATION_COUNT + 0; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector#init() Init}' operation. + * The feature id for the 'Default State' attribute. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector#init() * @generated + * @ordered */ - EOperation getMBrickletMotionDetector__Init(); + int TFIO_ACTOR_CONFIGURATION__DEFAULT_STATE = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect MBricklet Hall Effect}'. + * The feature id for the 'Keep On Reconnect' attribute. * * - * @return the meta object for class 'MBricklet Hall Effect'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect * @generated + * @ordered */ - EClass getMBrickletHallEffect(); + int TFIO_ACTOR_CONFIGURATION__KEEP_ON_RECONNECT = TF_CONFIG_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect#getDeviceType Device Type}'. + * The number of structural features of the 'TFIO Actor Configuration' class. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect#getDeviceType() - * @see #getMBrickletHallEffect() * @generated + * @ordered */ - EAttribute getMBrickletHallEffect_DeviceType(); + int TFIO_ACTOR_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 2; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect#init() Init}' operation. + * The number of operations of the 'TFIO Actor Configuration' class. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect#init() * @generated + * @ordered */ - EOperation getMBrickletHallEffect__Init(); + int TFIO_ACTOR_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MSubDevice MSub Device}'. + * The feature id for the 'Debounce Period' attribute. * * - * @return the meta object for class 'MSub Device'. - * @see org.openhab.binding.tinkerforge.internal.model.MSubDevice * @generated + * @ordered */ - EClass getMSubDevice(); + int TF_INTERRUPT_LISTENER_CONFIGURATION__DEBOUNCE_PERIOD = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MSubDevice#getSubId Sub Id}'. + * The number of structural features of the 'TF Interrupt Listener Configuration' class. * * - * @return the meta object for the attribute 'Sub Id'. - * @see org.openhab.binding.tinkerforge.internal.model.MSubDevice#getSubId() - * @see #getMSubDevice() * @generated + * @ordered */ - EAttribute getMSubDevice_SubId(); + int TF_INTERRUPT_LISTENER_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 1; /** - * Returns the meta object for the container reference '{@link org.openhab.binding.tinkerforge.internal.model.MSubDevice#getMbrick Mbrick}'. + * The number of operations of the 'TF Interrupt Listener Configuration' class. * * - * @return the meta object for the container reference 'Mbrick'. - * @see org.openhab.binding.tinkerforge.internal.model.MSubDevice#getMbrick() - * @see #getMSubDevice() * @generated + * @ordered */ - EReference getMSubDevice_Mbrick(); + int TF_INTERRUPT_LISTENER_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MDualRelay MDual Relay}'. + * The feature id for the 'Pull Up Resistor Enabled' attribute. * * - * @return the meta object for class 'MDual Relay'. - * @see org.openhab.binding.tinkerforge.internal.model.MDualRelay * @generated + * @ordered */ - EClass getMDualRelay(); + int TFIO_SENSOR_CONFIGURATION__PULL_UP_RESISTOR_ENABLED = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDualRelay#getDeviceType Device Type}'. + * The number of structural features of the 'TFIO Sensor Configuration' class. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MDualRelay#getDeviceType() - * @see #getMDualRelay() * @generated + * @ordered */ - EAttribute getMDualRelay_DeviceType(); + int TFIO_SENSOR_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 1; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch MBricklet Remote Switch}'. + * The number of operations of the 'TFIO Sensor Configuration' class. * * - * @return the meta object for class 'MBricklet Remote Switch'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch * @generated + * @ordered */ - EClass getMBrickletRemoteSwitch(); + int TFIO_SENSOR_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getDeviceType Device Type}'. + * The feature id for the 'Min Value' attribute. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getDeviceType() - * @see #getMBrickletRemoteSwitch() * @generated + * @ordered */ - EAttribute getMBrickletRemoteSwitch_DeviceType(); + int TF_SERVO_CONFIGURATION__MIN_VALUE = DIMMABLE_CONFIGURATION__MIN_VALUE; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeADevices Type ADevices}'. + * The feature id for the 'Max Value' attribute. * * - * @return the meta object for the attribute 'Type ADevices'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeADevices() - * @see #getMBrickletRemoteSwitch() * @generated + * @ordered */ - EAttribute getMBrickletRemoteSwitch_TypeADevices(); + int TF_SERVO_CONFIGURATION__MAX_VALUE = DIMMABLE_CONFIGURATION__MAX_VALUE; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeBDevices Type BDevices}'. + * The feature id for the 'Velocity' attribute. * * - * @return the meta object for the attribute 'Type BDevices'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeBDevices() - * @see #getMBrickletRemoteSwitch() * @generated + * @ordered */ - EAttribute getMBrickletRemoteSwitch_TypeBDevices(); + int TF_SERVO_CONFIGURATION__VELOCITY = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeCDevices Type CDevices}'. + * The feature id for the 'Acceleration' attribute. * * - * @return the meta object for the attribute 'Type CDevices'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeCDevices() - * @see #getMBrickletRemoteSwitch() * @generated + * @ordered */ - EAttribute getMBrickletRemoteSwitch_TypeCDevices(); + int TF_SERVO_CONFIGURATION__ACCELERATION = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 1; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitch Remote Switch}'. + * The feature id for the 'Servo Voltage' attribute. * * - * @return the meta object for class 'Remote Switch'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitch * @generated + * @ordered */ - EClass getRemoteSwitch(); + int TF_SERVO_CONFIGURATION__SERVO_VOLTAGE = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 2; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA Remote Switch A}'. + * The feature id for the 'Pulse Width Min' attribute. * * - * @return the meta object for class 'Remote Switch A'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA * @generated + * @ordered */ - EClass getRemoteSwitchA(); + int TF_SERVO_CONFIGURATION__PULSE_WIDTH_MIN = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 3; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getDeviceType Device Type}'. + * The feature id for the 'Pulse Width Max' attribute. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getDeviceType() - * @see #getRemoteSwitchA() * @generated + * @ordered */ - EAttribute getRemoteSwitchA_DeviceType(); + int TF_SERVO_CONFIGURATION__PULSE_WIDTH_MAX = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 4; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getHouseCode House Code}'. + * The feature id for the 'Period' attribute. * * - * @return the meta object for the attribute 'House Code'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getHouseCode() - * @see #getRemoteSwitchA() * @generated + * @ordered */ - EAttribute getRemoteSwitchA_HouseCode(); + int TF_SERVO_CONFIGURATION__PERIOD = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 5; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getReceiverCode Receiver Code}'. + * The feature id for the 'Output Voltage' attribute. * * - * @return the meta object for the attribute 'Receiver Code'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getReceiverCode() - * @see #getRemoteSwitchA() * @generated + * @ordered */ - EAttribute getRemoteSwitchA_ReceiverCode(); + int TF_SERVO_CONFIGURATION__OUTPUT_VOLTAGE = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 6; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getRepeats Repeats}'. + * The number of structural features of the 'TF Servo Configuration' class. * * - * @return the meta object for the attribute 'Repeats'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getRepeats() - * @see #getRemoteSwitchA() * @generated + * @ordered */ - EAttribute getRemoteSwitchA_Repeats(); + int TF_SERVO_CONFIGURATION_FEATURE_COUNT = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 7; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB Remote Switch B}'. + * The number of operations of the 'TF Servo Configuration' class. * * - * @return the meta object for class 'Remote Switch B'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB * @generated + * @ordered */ - EClass getRemoteSwitchB(); + int TF_SERVO_CONFIGURATION_OPERATION_COUNT = DIMMABLE_CONFIGURATION_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getDeviceType Device Type}'. + * The feature id for the 'Type ADevices' attribute. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getDeviceType() - * @see #getRemoteSwitchB() * @generated + * @ordered */ - EAttribute getRemoteSwitchB_DeviceType(); + int BRICKLET_REMOTE_SWITCH_CONFIGURATION__TYPE_ADEVICES = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getAddress Address}'. + * The feature id for the 'Type BDevices' attribute. * * - * @return the meta object for the attribute 'Address'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getAddress() - * @see #getRemoteSwitchB() * @generated + * @ordered */ - EAttribute getRemoteSwitchB_Address(); + int BRICKLET_REMOTE_SWITCH_CONFIGURATION__TYPE_BDEVICES = TF_CONFIG_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getUnit Unit}'. + * The feature id for the 'Type CDevices' attribute. * * - * @return the meta object for the attribute 'Unit'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getUnit() - * @see #getRemoteSwitchB() * @generated + * @ordered */ - EAttribute getRemoteSwitchB_Unit(); + int BRICKLET_REMOTE_SWITCH_CONFIGURATION__TYPE_CDEVICES = TF_CONFIG_FEATURE_COUNT + 2; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getRepeats Repeats}'. + * The number of structural features of the 'Bricklet Remote Switch Configuration' class. * * - * @return the meta object for the attribute 'Repeats'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getRepeats() - * @see #getRemoteSwitchB() * @generated + * @ordered */ - EAttribute getRemoteSwitchB_Repeats(); + int BRICKLET_REMOTE_SWITCH_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 3; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC Remote Switch C}'. + * The number of operations of the 'Bricklet Remote Switch Configuration' class. * * - * @return the meta object for class 'Remote Switch C'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC * @generated + * @ordered */ - EClass getRemoteSwitchC(); + int BRICKLET_REMOTE_SWITCH_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getDeviceType Device Type}'. + * The feature id for the 'House Code' attribute. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getDeviceType() - * @see #getRemoteSwitchC() * @generated + * @ordered */ - EAttribute getRemoteSwitchC_DeviceType(); + int REMOTE_SWITCH_ACONFIGURATION__HOUSE_CODE = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getSystemCode System Code}'. + * The feature id for the 'Receiver Code' attribute. * * - * @return the meta object for the attribute 'System Code'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getSystemCode() - * @see #getRemoteSwitchC() * @generated + * @ordered */ - EAttribute getRemoteSwitchC_SystemCode(); + int REMOTE_SWITCH_ACONFIGURATION__RECEIVER_CODE = TF_CONFIG_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getDeviceCode Device Code}'. + * The feature id for the 'Repeats' attribute. * * - * @return the meta object for the attribute 'Device Code'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getDeviceCode() - * @see #getRemoteSwitchC() * @generated + * @ordered */ - EAttribute getRemoteSwitchC_DeviceCode(); + int REMOTE_SWITCH_ACONFIGURATION__REPEATS = TF_CONFIG_FEATURE_COUNT + 2; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getRepeats Repeats}'. + * The number of structural features of the 'Remote Switch AConfiguration' class. * * - * @return the meta object for the attribute 'Repeats'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getRepeats() - * @see #getRemoteSwitchC() * @generated + * @ordered */ - EAttribute getRemoteSwitchC_Repeats(); + int REMOTE_SWITCH_ACONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 3; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFNullConfiguration TF Null Configuration}'. + * The number of operations of the 'Remote Switch AConfiguration' class. * * - * @return the meta object for class 'TF Null Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFNullConfiguration * @generated + * @ordered */ - EClass getTFNullConfiguration(); + int REMOTE_SWITCH_ACONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration TF Servo Configuration}'. + * The feature id for the 'Min Value' attribute. * * - * @return the meta object for class 'TF Servo Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration * @generated + * @ordered */ - EClass getTFServoConfiguration(); + int REMOTE_SWITCH_BCONFIGURATION__MIN_VALUE = DIMMABLE_CONFIGURATION__MIN_VALUE; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getVelocity Velocity}'. + * The feature id for the 'Max Value' attribute. * * - * @return the meta object for the attribute 'Velocity'. - * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getVelocity() - * @see #getTFServoConfiguration() * @generated + * @ordered */ - EAttribute getTFServoConfiguration_Velocity(); + int REMOTE_SWITCH_BCONFIGURATION__MAX_VALUE = DIMMABLE_CONFIGURATION__MAX_VALUE; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getAcceleration Acceleration}'. + * The feature id for the 'Address' attribute. * * - * @return the meta object for the attribute 'Acceleration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getAcceleration() - * @see #getTFServoConfiguration() * @generated + * @ordered */ - EAttribute getTFServoConfiguration_Acceleration(); + int REMOTE_SWITCH_BCONFIGURATION__ADDRESS = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getServoVoltage Servo Voltage}'. + * The feature id for the 'Unit' attribute. * * - * @return the meta object for the attribute 'Servo Voltage'. - * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getServoVoltage() - * @see #getTFServoConfiguration() * @generated + * @ordered */ - EAttribute getTFServoConfiguration_ServoVoltage(); + int REMOTE_SWITCH_BCONFIGURATION__UNIT = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPulseWidthMin Pulse Width Min}'. + * The feature id for the 'Repeats' attribute. * * - * @return the meta object for the attribute 'Pulse Width Min'. - * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPulseWidthMin() - * @see #getTFServoConfiguration() * @generated + * @ordered */ - EAttribute getTFServoConfiguration_PulseWidthMin(); + int REMOTE_SWITCH_BCONFIGURATION__REPEATS = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 2; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPulseWidthMax Pulse Width Max}'. + * The number of structural features of the 'Remote Switch BConfiguration' class. * * - * @return the meta object for the attribute 'Pulse Width Max'. - * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPulseWidthMax() - * @see #getTFServoConfiguration() * @generated + * @ordered */ - EAttribute getTFServoConfiguration_PulseWidthMax(); + int REMOTE_SWITCH_BCONFIGURATION_FEATURE_COUNT = DIMMABLE_CONFIGURATION_FEATURE_COUNT + 3; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPeriod Period}'. + * The number of operations of the 'Remote Switch BConfiguration' class. * * - * @return the meta object for the attribute 'Period'. - * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPeriod() - * @see #getTFServoConfiguration() * @generated + * @ordered */ - EAttribute getTFServoConfiguration_Period(); + int REMOTE_SWITCH_BCONFIGURATION_OPERATION_COUNT = DIMMABLE_CONFIGURATION_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getOutputVoltage Output Voltage}'. + * The feature id for the 'System Code' attribute. * * - * @return the meta object for the attribute 'Output Voltage'. - * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getOutputVoltage() - * @see #getTFServoConfiguration() * @generated + * @ordered */ - EAttribute getTFServoConfiguration_OutputVoltage(); + int REMOTE_SWITCH_CCONFIGURATION__SYSTEM_CODE = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration Bricklet Remote Switch Configuration}'. + * The feature id for the 'Device Code' attribute. * * - * @return the meta object for class 'Bricklet Remote Switch Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration * @generated + * @ordered */ - EClass getBrickletRemoteSwitchConfiguration(); + int REMOTE_SWITCH_CCONFIGURATION__DEVICE_CODE = TF_CONFIG_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeADevices Type ADevices}'. + * The feature id for the 'Repeats' attribute. * * - * @return the meta object for the attribute 'Type ADevices'. - * @see org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeADevices() - * @see #getBrickletRemoteSwitchConfiguration() * @generated + * @ordered */ - EAttribute getBrickletRemoteSwitchConfiguration_TypeADevices(); + int REMOTE_SWITCH_CCONFIGURATION__REPEATS = TF_CONFIG_FEATURE_COUNT + 2; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeBDevices Type BDevices}'. + * The number of structural features of the 'Remote Switch CConfiguration' class. * * - * @return the meta object for the attribute 'Type BDevices'. - * @see org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeBDevices() - * @see #getBrickletRemoteSwitchConfiguration() * @generated + * @ordered */ - EAttribute getBrickletRemoteSwitchConfiguration_TypeBDevices(); + int REMOTE_SWITCH_CCONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 3; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeCDevices Type CDevices}'. + * The number of operations of the 'Remote Switch CConfiguration' class. * * - * @return the meta object for the attribute 'Type CDevices'. - * @see org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeCDevices() - * @see #getBrickletRemoteSwitchConfiguration() * @generated + * @ordered */ - EAttribute getBrickletRemoteSwitchConfiguration_TypeCDevices(); + int REMOTE_SWITCH_CCONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration Remote Switch AConfiguration}'. + * The feature id for the 'Disable Electrode' attribute. * * - * @return the meta object for class 'Remote Switch AConfiguration'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration * @generated + * @ordered */ - EClass getRemoteSwitchAConfiguration(); + int MULTI_TOUCH_DEVICE_CONFIGURATION__DISABLE_ELECTRODE = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getHouseCode House Code}'. + * The number of structural features of the 'Multi Touch Device Configuration' class. * * - * @return the meta object for the attribute 'House Code'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getHouseCode() - * @see #getRemoteSwitchAConfiguration() * @generated + * @ordered */ - EAttribute getRemoteSwitchAConfiguration_HouseCode(); + int MULTI_TOUCH_DEVICE_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getReceiverCode Receiver Code}'. + * The number of operations of the 'Multi Touch Device Configuration' class. * * - * @return the meta object for the attribute 'Receiver Code'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getReceiverCode() - * @see #getRemoteSwitchAConfiguration() * @generated + * @ordered */ - EAttribute getRemoteSwitchAConfiguration_ReceiverCode(); + int MULTI_TOUCH_DEVICE_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getRepeats Repeats}'. + * The feature id for the 'Recalibrate' attribute. * * - * @return the meta object for the attribute 'Repeats'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getRepeats() - * @see #getRemoteSwitchAConfiguration() * @generated + * @ordered */ - EAttribute getRemoteSwitchAConfiguration_Repeats(); + int BRICKLET_MULTI_TOUCH_CONFIGURATION__RECALIBRATE = TF_CONFIG_FEATURE_COUNT + 0; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration Remote Switch BConfiguration}'. + * The feature id for the 'Sensitivity' attribute. * * - * @return the meta object for class 'Remote Switch BConfiguration'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration * @generated + * @ordered */ - EClass getRemoteSwitchBConfiguration(); + int BRICKLET_MULTI_TOUCH_CONFIGURATION__SENSITIVITY = TF_CONFIG_FEATURE_COUNT + 1; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getAddress Address}'. + * The number of structural features of the 'Bricklet Multi Touch Configuration' class. * * - * @return the meta object for the attribute 'Address'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getAddress() - * @see #getRemoteSwitchBConfiguration() * @generated + * @ordered */ - EAttribute getRemoteSwitchBConfiguration_Address(); + int BRICKLET_MULTI_TOUCH_CONFIGURATION_FEATURE_COUNT = TF_CONFIG_FEATURE_COUNT + 2; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getUnit Unit}'. + * The number of operations of the 'Bricklet Multi Touch Configuration' class. * * - * @return the meta object for the attribute 'Unit'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getUnit() - * @see #getRemoteSwitchBConfiguration() * @generated + * @ordered */ - EAttribute getRemoteSwitchBConfiguration_Unit(); + int BRICKLET_MULTI_TOUCH_CONFIGURATION_OPERATION_COUNT = TF_CONFIG_OPERATION_COUNT + 0; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getRepeats Repeats}'. + * The meta object id for the 'Switch State' data type. * * - * @return the meta object for the attribute 'Repeats'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getRepeats() - * @see #getRemoteSwitchBConfiguration() + * @see org.openhab.binding.tinkerforge.internal.types.OnOffValue + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getSwitchState() * @generated */ - EAttribute getRemoteSwitchBConfiguration_Repeats(); + int SWITCH_STATE = 143; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration Remote Switch CConfiguration}'. + * The meta object id for the 'Digital Value' data type. * * - * @return the meta object for class 'Remote Switch CConfiguration'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration + * @see org.openhab.binding.tinkerforge.internal.types.HighLowValue + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalValue() * @generated */ - EClass getRemoteSwitchCConfiguration(); + int DIGITAL_VALUE = 144; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getSystemCode System Code}'. + * The meta object id for the 'Tinker Bricklet IO16' data type. * * - * @return the meta object for the attribute 'System Code'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getSystemCode() - * @see #getRemoteSwitchCConfiguration() + * @see com.tinkerforge.BrickletIO16 + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletIO16() * @generated */ - EAttribute getRemoteSwitchCConfiguration_SystemCode(); + int TINKER_BRICKLET_IO16 = 145; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getDeviceCode Device Code}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.DCDriveMode DC Drive Mode}' enum. * * - * @return the meta object for the attribute 'Device Code'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getDeviceCode() - * @see #getRemoteSwitchCConfiguration() + * @see org.openhab.binding.tinkerforge.internal.model.DCDriveMode + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDCDriveMode() * @generated */ - EAttribute getRemoteSwitchCConfiguration_DeviceCode(); + int DC_DRIVE_MODE = 131; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getRepeats Repeats}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsServo Config Opts Servo}' enum. * * - * @return the meta object for the attribute 'Repeats'. - * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getRepeats() - * @see #getRemoteSwitchCConfiguration() + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsServo + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getConfigOptsServo() * @generated */ - EAttribute getRemoteSwitchCConfiguration_Repeats(); + int CONFIG_OPTS_SERVO = 132; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchDeviceConfiguration Multi Touch Device Configuration}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.NoSubIds No Sub Ids}' enum. * * - * @return the meta object for class 'Multi Touch Device Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchDeviceConfiguration + * @see org.openhab.binding.tinkerforge.internal.model.NoSubIds + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getNoSubIds() * @generated */ - EClass getMultiTouchDeviceConfiguration(); + int NO_SUB_IDS = 114; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchDeviceConfiguration#getDisableElectrode Disable Electrode}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.IndustrialDigitalInSubIDs Industrial Digital In Sub IDs}' enum. * * - * @return the meta object for the attribute 'Disable Electrode'. - * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchDeviceConfiguration#getDisableElectrode() - * @see #getMultiTouchDeviceConfiguration() + * @see org.openhab.binding.tinkerforge.internal.model.IndustrialDigitalInSubIDs + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIndustrialDigitalInSubIDs() * @generated */ - EAttribute getMultiTouchDeviceConfiguration_DisableElectrode(); + int INDUSTRIAL_DIGITAL_IN_SUB_IDS = 115; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration Bricklet Multi Touch Configuration}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.IndustrialQuadRelayIDs Industrial Quad Relay IDs}' enum. * * - * @return the meta object for class 'Bricklet Multi Touch Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration + * @see org.openhab.binding.tinkerforge.internal.model.IndustrialQuadRelayIDs + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIndustrialQuadRelayIDs() * @generated */ - EClass getBrickletMultiTouchConfiguration(); + int INDUSTRIAL_QUAD_RELAY_IDS = 116; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration#getRecalibrate Recalibrate}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.ServoSubIDs Servo Sub IDs}' enum. * * - * @return the meta object for the attribute 'Recalibrate'. - * @see org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration#getRecalibrate() - * @see #getBrickletMultiTouchConfiguration() + * @see org.openhab.binding.tinkerforge.internal.model.ServoSubIDs + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getServoSubIDs() * @generated */ - EAttribute getBrickletMultiTouchConfiguration_Recalibrate(); + int SERVO_SUB_IDS = 117; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration#getSensitivity Sensitivity}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.BarometerSubIDs Barometer Sub IDs}' enum. * * - * @return the meta object for the attribute 'Sensitivity'. - * @see org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration#getSensitivity() - * @see #getBrickletMultiTouchConfiguration() + * @see org.openhab.binding.tinkerforge.internal.model.BarometerSubIDs + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getBarometerSubIDs() * @generated */ - EAttribute getBrickletMultiTouchConfiguration_Sensitivity(); + int BAROMETER_SUB_IDS = 118; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MServo MServo}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.IO16SubIds IO16 Sub Ids}' enum. * * - * @return the meta object for class 'MServo'. - * @see org.openhab.binding.tinkerforge.internal.model.MServo + * @see org.openhab.binding.tinkerforge.internal.model.IO16SubIds + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIO16SubIds() * @generated */ - EClass getMServo(); + int IO16_SUB_IDS = 119; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getDeviceType Device Type}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.IO4SubIds IO4 Sub Ids}' enum. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MServo#getDeviceType() - * @see #getMServo() + * @see org.openhab.binding.tinkerforge.internal.model.IO4SubIds + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIO4SubIds() * @generated */ - EAttribute getMServo_DeviceType(); + int IO4_SUB_IDS = 120; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getVelocity Velocity}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.DualRelaySubIds Dual Relay Sub Ids}' enum. * * - * @return the meta object for the attribute 'Velocity'. - * @see org.openhab.binding.tinkerforge.internal.model.MServo#getVelocity() - * @see #getMServo() + * @see org.openhab.binding.tinkerforge.internal.model.DualRelaySubIds + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualRelaySubIds() * @generated */ - EAttribute getMServo_Velocity(); + int DUAL_RELAY_SUB_IDS = 121; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getAcceleration Acceleration}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.LCDButtonSubIds LCD Button Sub Ids}' enum. * * - * @return the meta object for the attribute 'Acceleration'. - * @see org.openhab.binding.tinkerforge.internal.model.MServo#getAcceleration() - * @see #getMServo() + * @see org.openhab.binding.tinkerforge.internal.model.LCDButtonSubIds + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getLCDButtonSubIds() * @generated */ - EAttribute getMServo_Acceleration(); + int LCD_BUTTON_SUB_IDS = 122; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getPulseWidthMin Pulse Width Min}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.LCDBacklightSubIds LCD Backlight Sub Ids}' enum. * * - * @return the meta object for the attribute 'Pulse Width Min'. - * @see org.openhab.binding.tinkerforge.internal.model.MServo#getPulseWidthMin() - * @see #getMServo() + * @see org.openhab.binding.tinkerforge.internal.model.LCDBacklightSubIds + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getLCDBacklightSubIds() * @generated */ - EAttribute getMServo_PulseWidthMin(); + int LCD_BACKLIGHT_SUB_IDS = 123; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getPulseWidthMax Pulse Width Max}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchSubIds Multi Touch Sub Ids}' enum. * * - * @return the meta object for the attribute 'Pulse Width Max'. - * @see org.openhab.binding.tinkerforge.internal.model.MServo#getPulseWidthMax() - * @see #getMServo() + * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchSubIds + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMultiTouchSubIds() * @generated */ - EAttribute getMServo_PulseWidthMax(); + int MULTI_TOUCH_SUB_IDS = 124; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getPeriod Period}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.TemperatureIRSubIds Temperature IR Sub Ids}' enum. * * - * @return the meta object for the attribute 'Period'. - * @see org.openhab.binding.tinkerforge.internal.model.MServo#getPeriod() - * @see #getMServo() + * @see org.openhab.binding.tinkerforge.internal.model.TemperatureIRSubIds + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTemperatureIRSubIds() * @generated */ - EAttribute getMServo_Period(); + int TEMPERATURE_IR_SUB_IDS = 125; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getOutputVoltage Output Voltage}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.VoltageCurrentSubIds Voltage Current Sub Ids}' enum. * * - * @return the meta object for the attribute 'Output Voltage'. - * @see org.openhab.binding.tinkerforge.internal.model.MServo#getOutputVoltage() - * @see #getMServo() + * @see org.openhab.binding.tinkerforge.internal.model.VoltageCurrentSubIds + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getVoltageCurrentSubIds() * @generated */ - EAttribute getMServo_OutputVoltage(); + int VOLTAGE_CURRENT_SUB_IDS = 126; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getServoCurrentPosition Servo Current Position}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsMove Config Opts Move}' enum. * * - * @return the meta object for the attribute 'Servo Current Position'. - * @see org.openhab.binding.tinkerforge.internal.model.MServo#getServoCurrentPosition() - * @see #getMServo() + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsMove + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getConfigOptsMove() * @generated */ - EAttribute getMServo_ServoCurrentPosition(); + int CONFIG_OPTS_MOVE = 127; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getServoDestinationPosition Servo Destination Position}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsDimmable Config Opts Dimmable}' enum. * * - * @return the meta object for the attribute 'Servo Destination Position'. - * @see org.openhab.binding.tinkerforge.internal.model.MServo#getServoDestinationPosition() - * @see #getMServo() + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsDimmable + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getConfigOptsDimmable() * @generated */ - EAttribute getMServo_ServoDestinationPosition(); + int CONFIG_OPTS_DIMMABLE = 128; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MServo#init() Init}' operation. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsSetPoint Config Opts Set Point}' enum. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MServo#init() + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsSetPoint + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getConfigOptsSetPoint() * @generated */ - EOperation getMServo__Init(); + int CONFIG_OPTS_SET_POINT = 129; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.CallbackListener Callback Listener}'. + * The meta object id for the '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsSwitchSpeed Config Opts Switch Speed}' enum. * * - * @return the meta object for class 'Callback Listener'. - * @see org.openhab.binding.tinkerforge.internal.model.CallbackListener + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsSwitchSpeed + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getConfigOptsSwitchSpeed() * @generated */ - EClass getCallbackListener(); + int CONFIG_OPTS_SWITCH_SPEED = 130; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.CallbackListener#getCallbackPeriod Callback Period}'. + * The meta object id for the 'MIP Connection' data type. * * - * @return the meta object for the attribute 'Callback Period'. - * @see org.openhab.binding.tinkerforge.internal.model.CallbackListener#getCallbackPeriod() - * @see #getCallbackListener() + * @see com.tinkerforge.IPConnection + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMIPConnection() * @generated */ - EAttribute getCallbackListener_CallbackPeriod(); + int MIP_CONNECTION = 133; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.InterruptListener Interrupt Listener}'. + * The meta object id for the 'MTinker Device' data type. * * - * @return the meta object for class 'Interrupt Listener'. - * @see org.openhab.binding.tinkerforge.internal.model.InterruptListener + * @see com.tinkerforge.Device + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerDevice() * @generated */ - EClass getInterruptListener(); + int MTINKER_DEVICE = 134; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.InterruptListener#getDebouncePeriod Debounce Period}'. + * The meta object id for the 'MLogger' data type. * * - * @return the meta object for the attribute 'Debounce Period'. - * @see org.openhab.binding.tinkerforge.internal.model.InterruptListener#getDebouncePeriod() - * @see #getInterruptListener() + * @see org.slf4j.Logger + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMLogger() * @generated */ - EAttribute getInterruptListener_DebouncePeriod(); + int MLOGGER = 135; + /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MSensor MSensor}'. + * The meta object id for the 'MAtomic Boolean' data type. * * - * @return the meta object for class 'MSensor'. - * @see org.openhab.binding.tinkerforge.internal.model.MSensor + * @see java.util.concurrent.atomic.AtomicBoolean + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMAtomicBoolean() * @generated */ - EClass getMSensor(); + int MATOMIC_BOOLEAN = 136; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MSensor#getSensorValue Sensor Value}'. + * The meta object id for the 'MTinkerforge Device' data type. * * - * @return the meta object for the attribute 'Sensor Value'. - * @see org.openhab.binding.tinkerforge.internal.model.MSensor#getSensorValue() - * @see #getMSensor() + * @see com.tinkerforge.Device + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerforgeDevice() * @generated */ - EAttribute getMSensor_SensorValue(); + int MTINKERFORGE_DEVICE = 137; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MSensor#fetchSensorValue() Fetch Sensor Value}' operation. + * The meta object id for the 'MTinker Brick DC' data type. * * - * @return the meta object for the 'Fetch Sensor Value' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MSensor#fetchSensorValue() + * @see com.tinkerforge.BrickDC + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickDC() * @generated */ - EOperation getMSensor__FetchSensorValue(); + int MTINKER_BRICK_DC = 138; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity MBricklet Humidity}'. + * The meta object id for the 'MTinker Brick Servo' data type. * * - * @return the meta object for class 'MBricklet Humidity'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity + * @see com.tinkerforge.BrickServo + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickServo() * @generated */ - EClass getMBrickletHumidity(); + int MTINKER_BRICK_SERVO = 146; + /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#getDeviceType Device Type}'. + * The meta object id for the 'MTinkerforge Value' data type. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#getDeviceType() - * @see #getMBrickletHumidity() + * @see org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerforgeValue() * @generated */ - EAttribute getMBrickletHumidity_DeviceType(); + int MTINKERFORGE_VALUE = 147; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#getThreshold Threshold}'. + * The meta object id for the 'MDecimal Value' data type. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#getThreshold() - * @see #getMBrickletHumidity() + * @see org.openhab.binding.tinkerforge.internal.types.DecimalValue + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMDecimalValue() * @generated */ - EAttribute getMBrickletHumidity_Threshold(); + int MDECIMAL_VALUE = 148; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#init() Init}' operation. + * The meta object id for the 'MTinker Bricklet Humidity' data type. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#init() + * @see com.tinkerforge.BrickletHumidity + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletHumidity() * @generated */ - EOperation getMBrickletHumidity__Init(); + int MTINKER_BRICKLET_HUMIDITY = 149; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR MBricklet Distance IR}'. + * The meta object id for the 'MTinker Bricklet Distance IR' data type. * * - * @return the meta object for class 'MBricklet Distance IR'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR + * @see com.tinkerforge.BrickletDistanceIR + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletDistanceIR() * @generated */ - EClass getMBrickletDistanceIR(); + int MTINKER_BRICKLET_DISTANCE_IR = 150; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#getDeviceType Device Type}'. + * The meta object id for the 'MTinker Bricklet Temperature' data type. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#getDeviceType() - * @see #getMBrickletDistanceIR() + * @see com.tinkerforge.BrickletTemperature + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletTemperature() * @generated */ - EAttribute getMBrickletDistanceIR_DeviceType(); + int MTINKER_BRICKLET_TEMPERATURE = 151; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#getThreshold Threshold}'. + * The meta object id for the 'MTinker Bricklet Barometer' data type. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#getThreshold() - * @see #getMBrickletDistanceIR() + * @see com.tinkerforge.BrickletBarometer + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletBarometer() * @generated */ - EAttribute getMBrickletDistanceIR_Threshold(); + int MTINKER_BRICKLET_BAROMETER = 152; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#init() Init}' operation. + * The meta object id for the 'MTinker Bricklet Ambient Light' data type. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#init() + * @see com.tinkerforge.BrickletAmbientLight + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletAmbientLight() * @generated */ - EOperation getMBrickletDistanceIR__Init(); + int MTINKER_BRICKLET_AMBIENT_LIGHT = 153; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature MBricklet Temperature}'. + * The meta object id for the 'MTinker Bricklet LCD2 0x4' data type. * * - * @return the meta object for class 'MBricklet Temperature'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature + * @see com.tinkerforge.BrickletLCD20x4 + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletLCD20x4() * @generated */ - EClass getMBrickletTemperature(); + int MTINKER_BRICKLET_LCD2_0X4 = 154; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#getDeviceType Device Type}'. + * The meta object id for the 'Tinker Bricklet Remote Switch' data type. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#getDeviceType() - * @see #getMBrickletTemperature() + * @see com.tinkerforge.BrickletRemoteSwitch + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletRemoteSwitch() * @generated */ - EAttribute getMBrickletTemperature_DeviceType(); + int TINKER_BRICKLET_REMOTE_SWITCH = 155; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#getThreshold Threshold}'. + * The meta object id for the 'Tinker Bricklet Motion Detector' data type. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#getThreshold() - * @see #getMBrickletTemperature() + * @see com.tinkerforge.BrickletMotionDetector + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletMotionDetector() * @generated */ - EAttribute getMBrickletTemperature_Threshold(); + int TINKER_BRICKLET_MOTION_DETECTOR = 156; /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#init() Init}' operation. + * The meta object id for the 'Tinker Bricklet Multi Touch' data type. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#init() + * @see com.tinkerforge.BrickletMultiTouch + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletMultiTouch() * @generated */ - EOperation getMBrickletTemperature__Init(); + int TINKER_BRICKLET_MULTI_TOUCH = 157; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperatureIR MBricklet Temperature IR}'. + * The meta object id for the 'Tinker Bricklet Temperature IR' data type. * * - * @return the meta object for class 'MBricklet Temperature IR'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperatureIR + * @see com.tinkerforge.BrickletTemperatureIR + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletTemperatureIR() * @generated */ - EClass getMBrickletTemperatureIR(); + int TINKER_BRICKLET_TEMPERATURE_IR = 158; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperatureIR#getDeviceType Device Type}'. + * The meta object id for the 'Tinker Bricklet Sound Intensity' data type. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperatureIR#getDeviceType() - * @see #getMBrickletTemperatureIR() + * @see com.tinkerforge.BrickletSoundIntensity + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletSoundIntensity() * @generated */ - EAttribute getMBrickletTemperatureIR_DeviceType(); + int TINKER_BRICKLET_SOUND_INTENSITY = 159; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice MTemperature IR Device}'. + * The meta object id for the 'Tinker Bricklet Moisture' data type. * * - * @return the meta object for class 'MTemperature IR Device'. - * @see org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice + * @see com.tinkerforge.BrickletMoisture + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletMoisture() * @generated */ - EClass getMTemperatureIRDevice(); + int TINKER_BRICKLET_MOISTURE = 160; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice#getThreshold Threshold}'. + * The meta object id for the 'Tinker Bricklet Distance US' data type. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice#getThreshold() - * @see #getMTemperatureIRDevice() + * @see com.tinkerforge.BrickletDistanceUS + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletDistanceUS() * @generated */ - EAttribute getMTemperatureIRDevice_Threshold(); + int TINKER_BRICKLET_DISTANCE_US = 161; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.ObjectTemperature Object Temperature}'. + * The meta object id for the 'Tinker Bricklet Voltage Current' data type. * * - * @return the meta object for class 'Object Temperature'. - * @see org.openhab.binding.tinkerforge.internal.model.ObjectTemperature + * @see com.tinkerforge.BrickletVoltageCurrent + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletVoltageCurrent() * @generated */ - EClass getObjectTemperature(); + int TINKER_BRICKLET_VOLTAGE_CURRENT = 162; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.ObjectTemperature#getDeviceType Device Type}'. + * The meta object id for the 'Tinker Bricklet Tilt' data type. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.ObjectTemperature#getDeviceType() - * @see #getObjectTemperature() + * @see com.tinkerforge.BrickletTilt + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletTilt() * @generated */ - EAttribute getObjectTemperature_DeviceType(); + int TINKER_BRICKLET_TILT = 163; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.ObjectTemperature#getEmissivity Emissivity}'. + * The meta object id for the 'Tinker Bricklet IO4' data type. * * - * @return the meta object for the attribute 'Emissivity'. - * @see org.openhab.binding.tinkerforge.internal.model.ObjectTemperature#getEmissivity() - * @see #getObjectTemperature() + * @see com.tinkerforge.BrickletIO4 + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletIO4() * @generated */ - EAttribute getObjectTemperature_Emissivity(); + int TINKER_BRICKLET_IO4 = 164; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.AmbientTemperature Ambient Temperature}'. + * The meta object id for the 'Tinker Bricklet Hall Effect' data type. * * - * @return the meta object for class 'Ambient Temperature'. - * @see org.openhab.binding.tinkerforge.internal.model.AmbientTemperature + * @see com.tinkerforge.BrickletHallEffect + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletHallEffect() * @generated */ - EClass getAmbientTemperature(); + int TINKER_BRICKLET_HALL_EFFECT = 165; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.AmbientTemperature#getDeviceType Device Type}'. + * The meta object id for the 'Tinker Bricklet Segment Display4x7' data type. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.AmbientTemperature#getDeviceType() - * @see #getAmbientTemperature() + * @see com.tinkerforge.BrickletSegmentDisplay4x7 + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletSegmentDisplay4x7() * @generated */ - EAttribute getAmbientTemperature_DeviceType(); + int TINKER_BRICKLET_SEGMENT_DISPLAY4X7 = 166; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTilt MBricklet Tilt}'. + * The meta object id for the 'Tinker Bricklet LED Strip' data type. * * - * @return the meta object for class 'MBricklet Tilt'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTilt + * @see com.tinkerforge.BrickletLEDStrip + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletLEDStrip() * @generated */ - EClass getMBrickletTilt(); + int TINKER_BRICKLET_LED_STRIP = 167; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTilt#getDeviceType Device Type}'. + * The meta object id for the 'Bricklet Joystick' data type. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTilt#getDeviceType() - * @see #getMBrickletTilt() + * @see com.tinkerforge.BrickletJoystick + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getBrickletJoystick() * @generated */ - EAttribute getMBrickletTilt_DeviceType(); + int BRICKLET_JOYSTICK = 168; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent MBricklet Voltage Current}'. + * The meta object id for the 'Tinker Bricklet Linear Poti' data type. * * - * @return the meta object for class 'MBricklet Voltage Current'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent + * @see com.tinkerforge.BrickletLinearPoti + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletLinearPoti() * @generated */ - EClass getMBrickletVoltageCurrent(); + int TINKER_BRICKLET_LINEAR_POTI = 169; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getDeviceType Device Type}'. + * The meta object id for the 'Tinker Bricklet Dual Button' data type. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getDeviceType() - * @see #getMBrickletVoltageCurrent() + * @see com.tinkerforge.BrickletDualButton + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletDualButton() * @generated */ - EAttribute getMBrickletVoltageCurrent_DeviceType(); + int TINKER_BRICKLET_DUAL_BUTTON = 170; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getAveraging Averaging}'. + * The meta object id for the 'HSB Type' data type. * * - * @return the meta object for the attribute 'Averaging'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getAveraging() - * @see #getMBrickletVoltageCurrent() + * @see org.openhab.core.library.types.HSBType + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getHSBType() * @generated */ - EAttribute getMBrickletVoltageCurrent_Averaging(); + int HSB_TYPE = 171; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getVoltageConversionTime Voltage Conversion Time}'. + * The meta object id for the 'Up Down Type' data type. * * - * @return the meta object for the attribute 'Voltage Conversion Time'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getVoltageConversionTime() - * @see #getMBrickletVoltageCurrent() + * @see org.openhab.core.library.types.UpDownType + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getUpDownType() * @generated */ - EAttribute getMBrickletVoltageCurrent_VoltageConversionTime(); + int UP_DOWN_TYPE = 172; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getCurrentConversionTime Current Conversion Time}'. + * The meta object id for the 'Percent Value' data type. * * - * @return the meta object for the attribute 'Current Conversion Time'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getCurrentConversionTime() - * @see #getMBrickletVoltageCurrent() + * @see org.openhab.binding.tinkerforge.internal.types.PercentValue + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getPercentValue() * @generated */ - EAttribute getMBrickletVoltageCurrent_CurrentConversionTime(); + int PERCENT_VALUE = 173; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.VoltageCurrentDevice Voltage Current Device}'. + * The meta object id for the 'Device Options' data type. * * - * @return the meta object for class 'Voltage Current Device'. - * @see org.openhab.binding.tinkerforge.internal.model.VoltageCurrentDevice + * @see org.openhab.binding.tinkerforge.internal.config.DeviceOptions + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDeviceOptions() * @generated */ - EClass getVoltageCurrentDevice(); + int DEVICE_OPTIONS = 174; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage VC Device Voltage}'. + * The meta object id for the 'Percent Type' data type. * * - * @return the meta object for class 'VC Device Voltage'. - * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage + * @see org.openhab.core.library.types.PercentType + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getPercentType() * @generated */ - EClass getVCDeviceVoltage(); + int PERCENT_TYPE = 175; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage#getDeviceType Device Type}'. + * The meta object id for the 'Increase Decrease Type' data type. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage#getDeviceType() - * @see #getVCDeviceVoltage() + * @see org.openhab.core.library.types.IncreaseDecreaseType + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIncreaseDecreaseType() * @generated */ - EAttribute getVCDeviceVoltage_DeviceType(); + int INCREASE_DECREASE_TYPE = 176; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage#getThreshold Threshold}'. + * The meta object id for the 'Direction Value' data type. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage#getThreshold() - * @see #getVCDeviceVoltage() + * @see org.openhab.binding.tinkerforge.internal.types.DirectionValue + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDirectionValue() * @generated */ - EAttribute getVCDeviceVoltage_Threshold(); + int DIRECTION_VALUE = 177; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent VC Device Current}'. + * The meta object id for the 'Enum' data type. * * - * @return the meta object for class 'VC Device Current'. - * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent + * @see java.lang.Enum + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getEnum() * @generated */ - EClass getVCDeviceCurrent(); + int ENUM = 178; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent#getDeviceType Device Type}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFConfig TF Config}'. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent#getDeviceType() - * @see #getVCDeviceCurrent() + * @return the meta object for class 'TF Config'. + * @see org.openhab.binding.tinkerforge.internal.model.TFConfig * @generated */ - EAttribute getVCDeviceCurrent_DeviceType(); + EClass getTFConfig(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent#getThreshold Threshold}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice OHTF Device}'. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent#getThreshold() - * @see #getVCDeviceCurrent() + * @return the meta object for class 'OHTF Device'. + * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice * @generated */ - EAttribute getVCDeviceCurrent_Threshold(); + EClass getOHTFDevice(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.VCDevicePower VC Device Power}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getUid Uid}'. * * - * @return the meta object for class 'VC Device Power'. - * @see org.openhab.binding.tinkerforge.internal.model.VCDevicePower + * @return the meta object for the attribute 'Uid'. + * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getUid() + * @see #getOHTFDevice() * @generated */ - EClass getVCDevicePower(); + EAttribute getOHTFDevice_Uid(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDevicePower#getDeviceType Device Type}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getSubid Subid}'. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.VCDevicePower#getDeviceType() - * @see #getVCDevicePower() + * @return the meta object for the attribute 'Subid'. + * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getSubid() + * @see #getOHTFDevice() * @generated */ - EAttribute getVCDevicePower_DeviceType(); + EAttribute getOHTFDevice_Subid(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDevicePower#getThreshold Threshold}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getOhid Ohid}'. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.VCDevicePower#getThreshold() - * @see #getVCDevicePower() + * @return the meta object for the attribute 'Ohid'. + * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getOhid() + * @see #getOHTFDevice() * @generated */ - EAttribute getVCDevicePower_Threshold(); + EAttribute getOHTFDevice_Ohid(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration TF Base Configuration}'. + * Returns the meta object for the attribute list '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getSubDeviceIds Sub Device Ids}'. * * - * @return the meta object for class 'TF Base Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration + * @return the meta object for the attribute list 'Sub Device Ids'. + * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getSubDeviceIds() + * @see #getOHTFDevice() * @generated */ - EClass getTFBaseConfiguration(); + EAttribute getOHTFDevice_SubDeviceIds(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration#getThreshold Threshold}'. + * Returns the meta object for the containment reference '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getTfConfig Tf Config}'. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration#getThreshold() - * @see #getTFBaseConfiguration() + * @return the meta object for the containment reference 'Tf Config'. + * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getTfConfig() + * @see #getOHTFDevice() * @generated */ - EAttribute getTFBaseConfiguration_Threshold(); + EReference getOHTFDevice_TfConfig(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration#getCallbackPeriod Callback Period}'. + * Returns the meta object for the container reference '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getOhConfig Oh Config}'. * * - * @return the meta object for the attribute 'Callback Period'. - * @see org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration#getCallbackPeriod() - * @see #getTFBaseConfiguration() + * @return the meta object for the container reference 'Oh Config'. + * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#getOhConfig() + * @see #getOHTFDevice() * @generated */ - EAttribute getTFBaseConfiguration_CallbackPeriod(); + EReference getOHTFDevice_OhConfig(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFObjectTemperatureConfiguration TF Object Temperature Configuration}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.OHTFDevice#isValidSubId(java.lang.String) Is Valid Sub Id}' operation. * * - * @return the meta object for class 'TF Object Temperature Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFObjectTemperatureConfiguration + * @return the meta object for the 'Is Valid Sub Id' operation. + * @see org.openhab.binding.tinkerforge.internal.model.OHTFDevice#isValidSubId(java.lang.String) * @generated */ - EClass getTFObjectTemperatureConfiguration(); + EOperation getOHTFDevice__IsValidSubId__String(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFObjectTemperatureConfiguration#getEmissivity Emissivity}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.OHTFSubDeviceAdminDevice OHTF Sub Device Admin Device}'. * * - * @return the meta object for the attribute 'Emissivity'. - * @see org.openhab.binding.tinkerforge.internal.model.TFObjectTemperatureConfiguration#getEmissivity() - * @see #getTFObjectTemperatureConfiguration() + * @return the meta object for class 'OHTF Sub Device Admin Device'. + * @see org.openhab.binding.tinkerforge.internal.model.OHTFSubDeviceAdminDevice * @generated */ - EAttribute getTFObjectTemperatureConfiguration_Emissivity(); + EClass getOHTFSubDeviceAdminDevice(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFMoistureBrickletConfiguration TF Moisture Bricklet Configuration}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.OHTFSubDeviceAdminDevice#isValidSubId(java.lang.String) Is Valid Sub Id}' operation. * * - * @return the meta object for class 'TF Moisture Bricklet Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFMoistureBrickletConfiguration + * @return the meta object for the 'Is Valid Sub Id' operation. + * @see org.openhab.binding.tinkerforge.internal.model.OHTFSubDeviceAdminDevice#isValidSubId(java.lang.String) * @generated */ - EClass getTFMoistureBrickletConfiguration(); + EOperation getOHTFSubDeviceAdminDevice__IsValidSubId__String(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFMoistureBrickletConfiguration#getMovingAverage Moving Average}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.OHConfig OH Config}'. * * - * @return the meta object for the attribute 'Moving Average'. - * @see org.openhab.binding.tinkerforge.internal.model.TFMoistureBrickletConfiguration#getMovingAverage() - * @see #getTFMoistureBrickletConfiguration() + * @return the meta object for class 'OH Config'. + * @see org.openhab.binding.tinkerforge.internal.model.OHConfig * @generated */ - EAttribute getTFMoistureBrickletConfiguration_MovingAverage(); + EClass getOHConfig(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFDistanceUSBrickletConfiguration TF Distance US Bricklet Configuration}'. + * Returns the meta object for the containment reference list '{@link org.openhab.binding.tinkerforge.internal.model.OHConfig#getOhTfDevices Oh Tf Devices}'. * * - * @return the meta object for class 'TF Distance US Bricklet Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFDistanceUSBrickletConfiguration + * @return the meta object for the containment reference list 'Oh Tf Devices'. + * @see org.openhab.binding.tinkerforge.internal.model.OHConfig#getOhTfDevices() + * @see #getOHConfig() * @generated */ - EClass getTFDistanceUSBrickletConfiguration(); + EReference getOHConfig_OhTfDevices(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFDistanceUSBrickletConfiguration#getMovingAverage Moving Average}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.OHConfig#getConfigByTFId(java.lang.String, java.lang.String) Get Config By TF Id}' operation. * * - * @return the meta object for the attribute 'Moving Average'. - * @see org.openhab.binding.tinkerforge.internal.model.TFDistanceUSBrickletConfiguration#getMovingAverage() - * @see #getTFDistanceUSBrickletConfiguration() + * @return the meta object for the 'Get Config By TF Id' operation. + * @see org.openhab.binding.tinkerforge.internal.model.OHConfig#getConfigByTFId(java.lang.String, java.lang.String) * @generated */ - EAttribute getTFDistanceUSBrickletConfiguration_MovingAverage(); + EOperation getOHConfig__GetConfigByTFId__String_String(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration TF Voltage Current Configuration}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.OHConfig#getConfigByOHId(java.lang.String) Get Config By OH Id}' operation. * * - * @return the meta object for class 'TF Voltage Current Configuration'. - * @see org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration + * @return the meta object for the 'Get Config By OH Id' operation. + * @see org.openhab.binding.tinkerforge.internal.model.OHConfig#getConfigByOHId(java.lang.String) * @generated */ - EClass getTFVoltageCurrentConfiguration(); + EOperation getOHConfig__GetConfigByOHId__String(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getAveraging Averaging}'. + * The meta object id for the 'MTinker Bricklet Dual Relay' data type. * * - * @return the meta object for the attribute 'Averaging'. - * @see org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getAveraging() - * @see #getTFVoltageCurrentConfiguration() + * @see com.tinkerforge.BrickletDualRelay + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletDualRelay() * @generated */ - EAttribute getTFVoltageCurrentConfiguration_Averaging(); + int MTINKER_BRICKLET_DUAL_RELAY = 139; + /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getVoltageConversionTime Voltage Conversion Time}'. + * The meta object id for the 'MTinker Bricklet Industrial Quad Relay' data type. * * - * @return the meta object for the attribute 'Voltage Conversion Time'. - * @see org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getVoltageConversionTime() - * @see #getTFVoltageCurrentConfiguration() + * @see com.tinkerforge.BrickletIndustrialQuadRelay + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletIndustrialQuadRelay() * @generated */ - EAttribute getTFVoltageCurrentConfiguration_VoltageConversionTime(); + int MTINKER_BRICKLET_INDUSTRIAL_QUAD_RELAY = 140; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getCurrentConversionTime Current Conversion Time}'. + * The meta object id for the 'MTinker Bricklet Industrial Digital In4' data type. * * - * @return the meta object for the attribute 'Current Conversion Time'. - * @see org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getCurrentConversionTime() - * @see #getTFVoltageCurrentConfiguration() + * @see com.tinkerforge.BrickletIndustrialDigitalIn4 + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletIndustrialDigitalIn4() * @generated */ - EAttribute getTFVoltageCurrentConfiguration_CurrentConversionTime(); + int MTINKER_BRICKLET_INDUSTRIAL_DIGITAL_IN4 = 141; /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer MBricklet Barometer}'. + * The meta object id for the 'MTinker Bricklet Industrial Digital Out4' data type. * * - * @return the meta object for class 'MBricklet Barometer'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer + * @see com.tinkerforge.BrickletIndustrialDigitalOut4 + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTinkerBrickletIndustrialDigitalOut4() * @generated */ - EClass getMBrickletBarometer(); + int MTINKER_BRICKLET_INDUSTRIAL_DIGITAL_OUT4 = 142; /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#getDeviceType Device Type}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem Ecosystem}'. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#getDeviceType() - * @see #getMBrickletBarometer() + * @return the meta object for class 'Ecosystem'. + * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem * @generated */ - EAttribute getMBrickletBarometer_DeviceType(); + EClass getEcosystem(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#getThreshold Threshold}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#getLogger Logger}'. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#getThreshold() - * @see #getMBrickletBarometer() + * @return the meta object for the attribute 'Logger'. + * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#getLogger() + * @see #getEcosystem() * @generated */ - EAttribute getMBrickletBarometer_Threshold(); + EAttribute getEcosystem_Logger(); /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#init() Init}' operation. + * Returns the meta object for the containment reference list '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#getMbrickds Mbrickds}'. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#init() + * @return the meta object for the containment reference list 'Mbrickds'. + * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#getMbrickds() + * @see #getEcosystem() * @generated */ - EOperation getMBrickletBarometer__Init(); + EReference getEcosystem_Mbrickds(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature MBarometer Temperature}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#getBrickd(java.lang.String, int) Get Brickd}' operation. * * - * @return the meta object for class 'MBarometer Temperature'. - * @see org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature + * @return the meta object for the 'Get Brickd' operation. + * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#getBrickd(java.lang.String, int) * @generated */ - EClass getMBarometerTemperature(); + EOperation getEcosystem__GetBrickd__String_int(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature#getDeviceType Device Type}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#getDevice(java.lang.String, java.lang.String) Get Device}' operation. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature#getDeviceType() - * @see #getMBarometerTemperature() + * @return the meta object for the 'Get Device' operation. + * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#getDevice(java.lang.String, java.lang.String) * @generated */ - EAttribute getMBarometerTemperature_DeviceType(); + EOperation getEcosystem__GetDevice__String_String(); /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature#init() Init}' operation. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#getDevices4GenericId(java.lang.String, java.lang.String) Get Devices4 Generic Id}' operation. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature#init() + * @return the meta object for the 'Get Devices4 Generic Id' operation. + * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#getDevices4GenericId(java.lang.String, java.lang.String) * @generated */ - EOperation getMBarometerTemperature__Init(); + EOperation getEcosystem__GetDevices4GenericId__String_String(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight MBricklet Ambient Light}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.Ecosystem#disconnect() Disconnect}' operation. * * - * @return the meta object for class 'MBricklet Ambient Light'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight + * @return the meta object for the 'Disconnect' operation. + * @see org.openhab.binding.tinkerforge.internal.model.Ecosystem#disconnect() * @generated */ - EClass getMBrickletAmbientLight(); + EOperation getEcosystem__Disconnect(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#getDeviceType Device Type}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd MBrickd}'. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#getDeviceType() - * @see #getMBrickletAmbientLight() + * @return the meta object for class 'MBrickd'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd * @generated */ - EAttribute getMBrickletAmbientLight_DeviceType(); + EClass getMBrickd(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#getThreshold Threshold}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getLogger Logger}'. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#getThreshold() - * @see #getMBrickletAmbientLight() + * @return the meta object for the attribute 'Logger'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getLogger() + * @see #getMBrickd() * @generated */ - EAttribute getMBrickletAmbientLight_Threshold(); + EAttribute getMBrickd_Logger(); /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#init() Init}' operation. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getIpConnection Ip Connection}'. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#init() + * @return the meta object for the attribute 'Ip Connection'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getIpConnection() + * @see #getMBrickd() * @generated */ - EOperation getMBrickletAmbientLight__Init(); + EAttribute getMBrickd_IpConnection(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity MBricklet Sound Intensity}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getHost Host}'. * * - * @return the meta object for class 'MBricklet Sound Intensity'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity + * @return the meta object for the attribute 'Host'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getHost() + * @see #getMBrickd() * @generated */ - EClass getMBrickletSoundIntensity(); + EAttribute getMBrickd_Host(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#getDeviceType Device Type}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getPort Port}'. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#getDeviceType() - * @see #getMBrickletSoundIntensity() + * @return the meta object for the attribute 'Port'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getPort() + * @see #getMBrickd() * @generated */ - EAttribute getMBrickletSoundIntensity_DeviceType(); + EAttribute getMBrickd_Port(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#getThreshold Threshold}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#isIsConnected Is Connected}'. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#getThreshold() - * @see #getMBrickletSoundIntensity() + * @return the meta object for the attribute 'Is Connected'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#isIsConnected() + * @see #getMBrickd() * @generated */ - EAttribute getMBrickletSoundIntensity_Threshold(); + EAttribute getMBrickd_IsConnected(); /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#init() Init}' operation. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#isAutoReconnect Auto Reconnect}'. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#init() + * @return the meta object for the attribute 'Auto Reconnect'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#isAutoReconnect() + * @see #getMBrickd() * @generated */ - EOperation getMBrickletSoundIntensity__Init(); + EAttribute getMBrickd_AutoReconnect(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture MBricklet Moisture}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#isReconnected Reconnected}'. * * - * @return the meta object for class 'MBricklet Moisture'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture + * @return the meta object for the attribute 'Reconnected'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#isReconnected() + * @see #getMBrickd() * @generated */ - EClass getMBrickletMoisture(); + EAttribute getMBrickd_Reconnected(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getDeviceType Device Type}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getTimeout Timeout}'. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getDeviceType() - * @see #getMBrickletMoisture() + * @return the meta object for the attribute 'Timeout'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getTimeout() + * @see #getMBrickd() * @generated */ - EAttribute getMBrickletMoisture_DeviceType(); + EAttribute getMBrickd_Timeout(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getThreshold Threshold}'. + * Returns the meta object for the containment reference list '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getMdevices Mdevices}'. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getThreshold() - * @see #getMBrickletMoisture() + * @return the meta object for the containment reference list 'Mdevices'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getMdevices() + * @see #getMBrickd() * @generated */ - EAttribute getMBrickletMoisture_Threshold(); + EReference getMBrickd_Mdevices(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getMovingAverage Moving Average}'. + * Returns the meta object for the container reference '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getEcosystem Ecosystem}'. * * - * @return the meta object for the attribute 'Moving Average'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getMovingAverage() - * @see #getMBrickletMoisture() + * @return the meta object for the container reference 'Ecosystem'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getEcosystem() + * @see #getMBrickd() * @generated */ - EAttribute getMBrickletMoisture_MovingAverage(); + EReference getMBrickd_Ecosystem(); /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#init() Init}' operation. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#connect() Connect}' operation. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#init() + * @return the meta object for the 'Connect' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#connect() * @generated */ - EOperation getMBrickletMoisture__Init(); + EOperation getMBrickd__Connect(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS MBricklet Distance US}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#disconnect() Disconnect}' operation. * * - * @return the meta object for class 'MBricklet Distance US'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS + * @return the meta object for the 'Disconnect' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#disconnect() * @generated */ - EClass getMBrickletDistanceUS(); + EOperation getMBrickd__Disconnect(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getDeviceType Device Type}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#init() Init}' operation. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getDeviceType() - * @see #getMBrickletDistanceUS() + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#init() * @generated */ - EAttribute getMBrickletDistanceUS_DeviceType(); + EOperation getMBrickd__Init(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getThreshold Threshold}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickd#getDevice(java.lang.String) Get Device}' operation. * * - * @return the meta object for the attribute 'Threshold'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getThreshold() - * @see #getMBrickletDistanceUS() + * @return the meta object for the 'Get Device' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickd#getDevice(java.lang.String) * @generated */ - EAttribute getMBrickletDistanceUS_Threshold(); + EOperation getMBrickd__GetDevice__String(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getMovingAverage Moving Average}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin Sub Device Admin}'. * * - * @return the meta object for the attribute 'Moving Average'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getMovingAverage() - * @see #getMBrickletDistanceUS() + * @return the meta object for class 'Sub Device Admin'. + * @see org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin * @generated */ - EAttribute getMBrickletDistanceUS_MovingAverage(); + EClass getSubDeviceAdmin(); /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#init() Init}' operation. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin#addSubDevice(java.lang.String, java.lang.String) Add Sub Device}' operation. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#init() + * @return the meta object for the 'Add Sub Device' operation. + * @see org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin#addSubDevice(java.lang.String, java.lang.String) * @generated */ - EOperation getMBrickletDistanceUS__Init(); + EOperation getSubDeviceAdmin__AddSubDevice__String_String(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4 MBricklet LCD2 0x4}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer MTF Config Consumer}'. * * - * @return the meta object for class 'MBricklet LCD2 0x4'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4 + * @return the meta object for class 'MTF Config Consumer'. + * @see org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer * @generated */ - EClass getMBrickletLCD20x4(); + EClass getMTFConfigConsumer(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getDeviceType Device Type}'. + * Returns the meta object for the containment reference '{@link org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer#getTfConfig Tf Config}'. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getDeviceType() - * @see #getMBrickletLCD20x4() + * @return the meta object for the containment reference 'Tf Config'. + * @see org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer#getTfConfig() + * @see #getMTFConfigConsumer() * @generated */ - EAttribute getMBrickletLCD20x4_DeviceType(); + EReference getMTFConfigConsumer_TfConfig(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getPositionPrefix Position Prefix}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice MBase Device}'. * * - * @return the meta object for the attribute 'Position Prefix'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getPositionPrefix() - * @see #getMBrickletLCD20x4() + * @return the meta object for class 'MBase Device'. + * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice * @generated */ - EAttribute getMBrickletLCD20x4_PositionPrefix(); + EClass getMBaseDevice(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getPositonSuffix Positon Suffix}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getLogger Logger}'. * * - * @return the meta object for the attribute 'Positon Suffix'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getPositonSuffix() - * @see #getMBrickletLCD20x4() + * @return the meta object for the attribute 'Logger'. + * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getLogger() + * @see #getMBaseDevice() * @generated */ - EAttribute getMBrickletLCD20x4_PositonSuffix(); + EAttribute getMBaseDevice_Logger(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#isDisplayErrors Display Errors}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getUid Uid}'. * * - * @return the meta object for the attribute 'Display Errors'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#isDisplayErrors() - * @see #getMBrickletLCD20x4() + * @return the meta object for the attribute 'Uid'. + * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getUid() + * @see #getMBaseDevice() * @generated */ - EAttribute getMBrickletLCD20x4_DisplayErrors(); + EAttribute getMBaseDevice_Uid(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getErrorPrefix Error Prefix}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#isPoll Poll}'. * * - * @return the meta object for the attribute 'Error Prefix'. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getErrorPrefix() - * @see #getMBrickletLCD20x4() + * @return the meta object for the attribute 'Poll'. + * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#isPoll() + * @see #getMBaseDevice() * @generated */ - EAttribute getMBrickletLCD20x4_ErrorPrefix(); + EAttribute getMBaseDevice_Poll(); /** - * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#init() Init}' operation. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getEnabledA Enabled A}'. * * - * @return the meta object for the 'Init' operation. - * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#init() + * @return the meta object for the attribute 'Enabled A'. + * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#getEnabledA() + * @see #getMBaseDevice() * @generated */ - EOperation getMBrickletLCD20x4__Init(); + EAttribute getMBaseDevice_EnabledA(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MTextActor MText Actor}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#init() Init}' operation. * * - * @return the meta object for class 'MText Actor'. - * @see org.openhab.binding.tinkerforge.internal.model.MTextActor + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#init() * @generated */ - EClass getMTextActor(); + EOperation getMBaseDevice__Init(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MTextActor#getText Text}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#enable() Enable}' operation. * * - * @return the meta object for the attribute 'Text'. - * @see org.openhab.binding.tinkerforge.internal.model.MTextActor#getText() - * @see #getMTextActor() + * @return the meta object for the 'Enable' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#enable() * @generated */ - EAttribute getMTextActor_Text(); + EOperation getMBaseDevice__Enable(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MLCDSubDevice MLCD Sub Device}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice#disable() Disable}' operation. * * - * @return the meta object for class 'MLCD Sub Device'. - * @see org.openhab.binding.tinkerforge.internal.model.MLCDSubDevice + * @return the meta object for the 'Disable' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice#disable() * @generated */ - EClass getMLCDSubDevice(); + EOperation getMBaseDevice__Disable(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MLCD20x4Backlight MLCD2 0x4 Backlight}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MDevice MDevice}'. * * - * @return the meta object for class 'MLCD2 0x4 Backlight'. - * @see org.openhab.binding.tinkerforge.internal.model.MLCD20x4Backlight + * @return the meta object for class 'MDevice'. + * @see org.openhab.binding.tinkerforge.internal.model.MDevice * @generated */ - EClass getMLCD20x4Backlight(); + EClass getMDevice(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MLCD20x4Backlight#getDeviceType Device Type}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getTinkerforgeDevice Tinkerforge Device}'. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MLCD20x4Backlight#getDeviceType() - * @see #getMLCD20x4Backlight() + * @return the meta object for the attribute 'Tinkerforge Device'. + * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getTinkerforgeDevice() + * @see #getMDevice() * @generated */ - EAttribute getMLCD20x4Backlight_DeviceType(); + EAttribute getMDevice_TinkerforgeDevice(); /** - * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button MLCD2 0x4 Button}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getIpConnection Ip Connection}'. * * - * @return the meta object for class 'MLCD2 0x4 Button'. - * @see org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button + * @return the meta object for the attribute 'Ip Connection'. + * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getIpConnection() + * @see #getMDevice() * @generated */ - EClass getMLCD20x4Button(); + EAttribute getMDevice_IpConnection(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button#getDeviceType Device Type}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getConnectedUid Connected Uid}'. * * - * @return the meta object for the attribute 'Device Type'. - * @see org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button#getDeviceType() - * @see #getMLCD20x4Button() + * @return the meta object for the attribute 'Connected Uid'. + * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getConnectedUid() + * @see #getMDevice() * @generated */ - EAttribute getMLCD20x4Button_DeviceType(); + EAttribute getMDevice_ConnectedUid(); /** - * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button#getButtonNum Button Num}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getPosition Position}'. * * - * @return the meta object for the attribute 'Button Num'. - * @see org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button#getButtonNum() - * @see #getMLCD20x4Button() + * @return the meta object for the attribute 'Position'. + * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getPosition() + * @see #getMDevice() * @generated */ - EAttribute getMLCD20x4Button_ButtonNum(); + EAttribute getMDevice_Position(); /** - * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.types.OnOffValue Switch State}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getDeviceIdentifier Device Identifier}'. * * - * @return the meta object for data type 'Switch State'. - * @see org.openhab.binding.tinkerforge.internal.types.OnOffValue - * @model instanceClass="org.openhab.binding.tinkerforge.internal.types.OnOffValue" + * @return the meta object for the attribute 'Device Identifier'. + * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getDeviceIdentifier() + * @see #getMDevice() * @generated */ - EDataType getSwitchState(); + EAttribute getMDevice_DeviceIdentifier(); /** - * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.types.HighLowValue Digital Value}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getName Name}'. * * - * @return the meta object for data type 'Digital Value'. - * @see org.openhab.binding.tinkerforge.internal.types.HighLowValue - * @model instanceClass="org.openhab.binding.tinkerforge.internal.types.HighLowValue" + * @return the meta object for the attribute 'Name'. + * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getName() + * @see #getMDevice() * @generated */ - EDataType getDigitalValue(); + EAttribute getMDevice_Name(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletIO16 Tinker Bricklet IO16}'. + * Returns the meta object for the container reference '{@link org.openhab.binding.tinkerforge.internal.model.MDevice#getBrickd Brickd}'. * * - * @return the meta object for data type 'Tinker Bricklet IO16'. - * @see com.tinkerforge.BrickletIO16 - * @model instanceClass="com.tinkerforge.BrickletIO16" + * @return the meta object for the container reference 'Brickd'. + * @see org.openhab.binding.tinkerforge.internal.model.MDevice#getBrickd() + * @see #getMDevice() * @generated */ - EDataType getTinkerBrickletIO16(); + EReference getMDevice_Brickd(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.DCDriveMode DC Drive Mode}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder MSub Device Holder}'. * * - * @return the meta object for enum 'DC Drive Mode'. - * @see org.openhab.binding.tinkerforge.internal.model.DCDriveMode + * @return the meta object for class 'MSub Device Holder'. + * @see org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder * @generated */ - EEnum getDCDriveMode(); + EClass getMSubDeviceHolder(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.NoSubIds No Sub Ids}'. + * Returns the meta object for the containment reference list '{@link org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder#getMsubdevices Msubdevices}'. * * - * @return the meta object for enum 'No Sub Ids'. - * @see org.openhab.binding.tinkerforge.internal.model.NoSubIds + * @return the meta object for the containment reference list 'Msubdevices'. + * @see org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder#getMsubdevices() + * @see #getMSubDeviceHolder() * @generated */ - EEnum getNoSubIds(); + EReference getMSubDeviceHolder_Msubdevices(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.IndustrialDigitalInSubIDs Industrial Digital In Sub IDs}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder#initSubDevices() Init Sub Devices}' operation. * * - * @return the meta object for enum 'Industrial Digital In Sub IDs'. - * @see org.openhab.binding.tinkerforge.internal.model.IndustrialDigitalInSubIDs + * @return the meta object for the 'Init Sub Devices' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder#initSubDevices() * @generated */ - EEnum getIndustrialDigitalInSubIDs(); + EOperation getMSubDeviceHolder__InitSubDevices(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.IndustrialQuadRelayIDs Industrial Quad Relay IDs}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickServo MBrick Servo}'. * * - * @return the meta object for enum 'Industrial Quad Relay IDs'. - * @see org.openhab.binding.tinkerforge.internal.model.IndustrialQuadRelayIDs + * @return the meta object for class 'MBrick Servo'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickServo * @generated */ - EEnum getIndustrialQuadRelayIDs(); + EClass getMBrickServo(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.ServoSubIDs Servo Sub IDs}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickServo#getDeviceType Device Type}'. * * - * @return the meta object for enum 'Servo Sub IDs'. - * @see org.openhab.binding.tinkerforge.internal.model.ServoSubIDs + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickServo#getDeviceType() + * @see #getMBrickServo() * @generated */ - EEnum getServoSubIDs(); + EAttribute getMBrickServo_DeviceType(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.BarometerSubIDs Barometer Sub IDs}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickServo#init() Init}' operation. * * - * @return the meta object for enum 'Barometer Sub IDs'. - * @see org.openhab.binding.tinkerforge.internal.model.BarometerSubIDs + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickServo#init() * @generated */ - EEnum getBarometerSubIDs(); + EOperation getMBrickServo__Init(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.IO16SubIds IO16 Sub Ids}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration TF Brick DC Configuration}'. * * - * @return the meta object for enum 'IO16 Sub Ids'. - * @see org.openhab.binding.tinkerforge.internal.model.IO16SubIds + * @return the meta object for class 'TF Brick DC Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration * @generated */ - EEnum getIO16SubIds(); + EClass getTFBrickDCConfiguration(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.IO4SubIds IO4 Sub Ids}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getVelocity Velocity}'. * * - * @return the meta object for enum 'IO4 Sub Ids'. - * @see org.openhab.binding.tinkerforge.internal.model.IO4SubIds + * @return the meta object for the attribute 'Velocity'. + * @see org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getVelocity() + * @see #getTFBrickDCConfiguration() * @generated */ - EEnum getIO4SubIds(); + EAttribute getTFBrickDCConfiguration_Velocity(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.DualRelaySubIds Dual Relay Sub Ids}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getAcceleration Acceleration}'. * * - * @return the meta object for enum 'Dual Relay Sub Ids'. - * @see org.openhab.binding.tinkerforge.internal.model.DualRelaySubIds + * @return the meta object for the attribute 'Acceleration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getAcceleration() + * @see #getTFBrickDCConfiguration() * @generated */ - EEnum getDualRelaySubIds(); + EAttribute getTFBrickDCConfiguration_Acceleration(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.LCDButtonSubIds LCD Button Sub Ids}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getPwmFrequency Pwm Frequency}'. * * - * @return the meta object for enum 'LCD Button Sub Ids'. - * @see org.openhab.binding.tinkerforge.internal.model.LCDButtonSubIds + * @return the meta object for the attribute 'Pwm Frequency'. + * @see org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getPwmFrequency() + * @see #getTFBrickDCConfiguration() * @generated */ - EEnum getLCDButtonSubIds(); + EAttribute getTFBrickDCConfiguration_PwmFrequency(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.LCDBacklightSubIds LCD Backlight Sub Ids}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getDriveMode Drive Mode}'. * * - * @return the meta object for enum 'LCD Backlight Sub Ids'. - * @see org.openhab.binding.tinkerforge.internal.model.LCDBacklightSubIds + * @return the meta object for the attribute 'Drive Mode'. + * @see org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getDriveMode() + * @see #getTFBrickDCConfiguration() * @generated */ - EEnum getLCDBacklightSubIds(); + EAttribute getTFBrickDCConfiguration_DriveMode(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchSubIds Multi Touch Sub Ids}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC MBrick DC}'. * * - * @return the meta object for enum 'Multi Touch Sub Ids'. - * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchSubIds + * @return the meta object for class 'MBrick DC'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC * @generated */ - EEnum getMultiTouchSubIds(); + EClass getMBrickDC(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.TemperatureIRSubIds Temperature IR Sub Ids}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getThreshold Threshold}'. * * - * @return the meta object for enum 'Temperature IR Sub Ids'. - * @see org.openhab.binding.tinkerforge.internal.model.TemperatureIRSubIds + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getThreshold() + * @see #getMBrickDC() * @generated */ - EEnum getTemperatureIRSubIds(); + EAttribute getMBrickDC_Threshold(); /** - * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.VoltageCurrentSubIds Voltage Current Sub Ids}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getMaxVelocity Max Velocity}'. * * - * @return the meta object for enum 'Voltage Current Sub Ids'. - * @see org.openhab.binding.tinkerforge.internal.model.VoltageCurrentSubIds + * @return the meta object for the attribute 'Max Velocity'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getMaxVelocity() + * @see #getMBrickDC() * @generated */ - EEnum getVoltageCurrentSubIds(); + EAttribute getMBrickDC_MaxVelocity(); /** - * Returns the meta object for data type '{@link com.tinkerforge.IPConnection MIP Connection}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getMinVelocity Min Velocity}'. * * - * @return the meta object for data type 'MIP Connection'. - * @see com.tinkerforge.IPConnection - * @model instanceClass="com.tinkerforge.IPConnection" + * @return the meta object for the attribute 'Min Velocity'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getMinVelocity() + * @see #getMBrickDC() * @generated */ - EDataType getMIPConnection(); + EAttribute getMBrickDC_MinVelocity(); /** - * Returns the meta object for data type '{@link com.tinkerforge.Device MTinker Device}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getDeviceType Device Type}'. * * - * @return the meta object for data type 'MTinker Device'. - * @see com.tinkerforge.Device - * @model instanceClass="com.tinkerforge.Device" + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getDeviceType() + * @see #getMBrickDC() * @generated */ - EDataType getMTinkerDevice(); + EAttribute getMBrickDC_DeviceType(); /** - * Returns the meta object for data type '{@link org.slf4j.Logger MLogger}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getVelocity Velocity}'. * * - * @return the meta object for data type 'MLogger'. - * @see org.slf4j.Logger - * @model instanceClass="org.slf4j.Logger" + * @return the meta object for the attribute 'Velocity'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getVelocity() + * @see #getMBrickDC() * @generated */ - EDataType getMLogger(); + EAttribute getMBrickDC_Velocity(); /** - * Returns the meta object for data type '{@link java.util.concurrent.atomic.AtomicBoolean MAtomic Boolean}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getTargetvelocity Targetvelocity}'. * * - * @return the meta object for data type 'MAtomic Boolean'. - * @see java.util.concurrent.atomic.AtomicBoolean - * @model instanceClass="java.util.concurrent.atomic.AtomicBoolean" + * @return the meta object for the attribute 'Targetvelocity'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getTargetvelocity() + * @see #getMBrickDC() * @generated */ - EDataType getMAtomicBoolean(); + EAttribute getMBrickDC_Targetvelocity(); /** - * Returns the meta object for data type '{@link com.tinkerforge.Device MTinkerforge Device}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getCurrentVelocity Current Velocity}'. * * - * @return the meta object for data type 'MTinkerforge Device'. - * @see com.tinkerforge.Device - * @model instanceClass="com.tinkerforge.Device" + * @return the meta object for the attribute 'Current Velocity'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getCurrentVelocity() + * @see #getMBrickDC() * @generated */ - EDataType getMTinkerforgeDevice(); + EAttribute getMBrickDC_CurrentVelocity(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickDC MTinker Brick DC}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getAcceleration Acceleration}'. * * - * @return the meta object for data type 'MTinker Brick DC'. - * @see com.tinkerforge.BrickDC - * @model instanceClass="com.tinkerforge.BrickDC" + * @return the meta object for the attribute 'Acceleration'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getAcceleration() + * @see #getMBrickDC() * @generated */ - EDataType getMTinkerBrickDC(); + EAttribute getMBrickDC_Acceleration(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickServo MTinker Brick Servo}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getPwmFrequency Pwm Frequency}'. * * - * @return the meta object for data type 'MTinker Brick Servo'. - * @see com.tinkerforge.BrickServo - * @model instanceClass="com.tinkerforge.BrickServo" + * @return the meta object for the attribute 'Pwm Frequency'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getPwmFrequency() + * @see #getMBrickDC() * @generated */ - EDataType getMTinkerBrickServo(); + EAttribute getMBrickDC_PwmFrequency(); /** - * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue MTinkerforge Value}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#getDriveMode Drive Mode}'. * * - * @return the meta object for data type 'MTinkerforge Value'. - * @see org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue - * @model instanceClass="org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue" + * @return the meta object for the attribute 'Drive Mode'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#getDriveMode() + * @see #getMBrickDC() * @generated */ - EDataType getMTinkerforgeValue(); + EAttribute getMBrickDC_DriveMode(); /** - * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.types.DecimalValue MDecimal Value}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#init() Init}' operation. * * - * @return the meta object for data type 'MDecimal Value'. - * @see org.openhab.binding.tinkerforge.internal.types.DecimalValue - * @model instanceClass="org.openhab.binding.tinkerforge.internal.types.DecimalValue" + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#init() * @generated */ - EDataType getMDecimalValue(); + EOperation getMBrickDC__Init(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletHumidity MTinker Bricklet Humidity}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickDC#setSpeed(java.lang.Short, int, java.lang.String) Set Speed}' operation. * * - * @return the meta object for data type 'MTinker Bricklet Humidity'. - * @see com.tinkerforge.BrickletHumidity - * @model instanceClass="com.tinkerforge.BrickletHumidity" + * @return the meta object for the 'Set Speed' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickDC#setSpeed(java.lang.Short, int, java.lang.String) * @generated */ - EDataType getMTinkerBrickletHumidity(); + EOperation getMBrickDC__SetSpeed__Short_int_String(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletDistanceIR MTinker Bricklet Distance IR}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MDualRelayBricklet MDual Relay Bricklet}'. * * - * @return the meta object for data type 'MTinker Bricklet Distance IR'. - * @see com.tinkerforge.BrickletDistanceIR - * @model instanceClass="com.tinkerforge.BrickletDistanceIR" + * @return the meta object for class 'MDual Relay Bricklet'. + * @see org.openhab.binding.tinkerforge.internal.model.MDualRelayBricklet * @generated */ - EDataType getMTinkerBrickletDistanceIR(); + EClass getMDualRelayBricklet(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletTemperature MTinker Bricklet Temperature}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDualRelayBricklet#getDeviceType Device Type}'. * * - * @return the meta object for data type 'MTinker Bricklet Temperature'. - * @see com.tinkerforge.BrickletTemperature - * @model instanceClass="com.tinkerforge.BrickletTemperature" + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MDualRelayBricklet#getDeviceType() + * @see #getMDualRelayBricklet() * @generated */ - EDataType getMTinkerBrickletTemperature(); + EAttribute getMDualRelayBricklet_DeviceType(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletBarometer MTinker Bricklet Barometer}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelayBricklet MIndustrial Quad Relay Bricklet}'. * * - * @return the meta object for data type 'MTinker Bricklet Barometer'. - * @see com.tinkerforge.BrickletBarometer - * @model instanceClass="com.tinkerforge.BrickletBarometer" + * @return the meta object for class 'MIndustrial Quad Relay Bricklet'. + * @see org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelayBricklet * @generated */ - EDataType getMTinkerBrickletBarometer(); + EClass getMIndustrialQuadRelayBricklet(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletAmbientLight MTinker Bricklet Ambient Light}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelay MIndustrial Quad Relay}'. * * - * @return the meta object for data type 'MTinker Bricklet Ambient Light'. - * @see com.tinkerforge.BrickletAmbientLight - * @model instanceClass="com.tinkerforge.BrickletAmbientLight" + * @return the meta object for class 'MIndustrial Quad Relay'. + * @see org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelay * @generated */ - EDataType getMTinkerBrickletAmbientLight(); + EClass getMIndustrialQuadRelay(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletLCD20x4 MTinker Bricklet LCD2 0x4}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelay#getDeviceType Device Type}'. * * - * @return the meta object for data type 'MTinker Bricklet LCD2 0x4'. - * @see com.tinkerforge.BrickletLCD20x4 - * @model instanceClass="com.tinkerforge.BrickletLCD20x4" + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MIndustrialQuadRelay#getDeviceType() + * @see #getMIndustrialQuadRelay() * @generated */ - EDataType getMTinkerBrickletLCD20x4(); + EAttribute getMIndustrialQuadRelay_DeviceType(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletRemoteSwitch Tinker Bricklet Remote Switch}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalIn4 MBricklet Industrial Digital In4}'. * * - * @return the meta object for data type 'Tinker Bricklet Remote Switch'. - * @see com.tinkerforge.BrickletRemoteSwitch - * @model instanceClass="com.tinkerforge.BrickletRemoteSwitch" + * @return the meta object for class 'MBricklet Industrial Digital In4'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalIn4 * @generated */ - EDataType getTinkerBrickletRemoteSwitch(); + EClass getMBrickletIndustrialDigitalIn4(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletMotionDetector Tinker Bricklet Motion Detector}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalIn4#getDeviceType Device Type}'. * * - * @return the meta object for data type 'Tinker Bricklet Motion Detector'. - * @see com.tinkerforge.BrickletMotionDetector - * @model instanceClass="com.tinkerforge.BrickletMotionDetector" + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalIn4#getDeviceType() + * @see #getMBrickletIndustrialDigitalIn4() * @generated */ - EDataType getTinkerBrickletMotionDetector(); + EAttribute getMBrickletIndustrialDigitalIn4_DeviceType(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletMultiTouch Tinker Bricklet Multi Touch}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MIndustrialDigitalIn MIndustrial Digital In}'. * * - * @return the meta object for data type 'Tinker Bricklet Multi Touch'. - * @see com.tinkerforge.BrickletMultiTouch - * @model instanceClass="com.tinkerforge.BrickletMultiTouch" + * @return the meta object for class 'MIndustrial Digital In'. + * @see org.openhab.binding.tinkerforge.internal.model.MIndustrialDigitalIn * @generated */ - EDataType getTinkerBrickletMultiTouch(); + EClass getMIndustrialDigitalIn(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletTemperatureIR Tinker Bricklet Temperature IR}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalOut4 MBricklet Industrial Digital Out4}'. * * - * @return the meta object for data type 'Tinker Bricklet Temperature IR'. - * @see com.tinkerforge.BrickletTemperatureIR - * @model instanceClass="com.tinkerforge.BrickletTemperatureIR" + * @return the meta object for class 'MBricklet Industrial Digital Out4'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalOut4 * @generated */ - EDataType getTinkerBrickletTemperatureIR(); + EClass getMBrickletIndustrialDigitalOut4(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletSoundIntensity Tinker Bricklet Sound Intensity}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorDigitalOut4 Digital Actor Digital Out4}'. * * - * @return the meta object for data type 'Tinker Bricklet Sound Intensity'. - * @see com.tinkerforge.BrickletSoundIntensity - * @model instanceClass="com.tinkerforge.BrickletSoundIntensity" + * @return the meta object for class 'Digital Actor Digital Out4'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorDigitalOut4 * @generated */ - EDataType getTinkerBrickletSoundIntensity(); + EClass getDigitalActorDigitalOut4(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletMoisture Tinker Bricklet Moisture}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorDigitalOut4#getPin Pin}'. * * - * @return the meta object for data type 'Tinker Bricklet Moisture'. - * @see com.tinkerforge.BrickletMoisture - * @model instanceClass="com.tinkerforge.BrickletMoisture" + * @return the meta object for the attribute 'Pin'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorDigitalOut4#getPin() + * @see #getDigitalActorDigitalOut4() * @generated */ - EDataType getTinkerBrickletMoisture(); + EAttribute getDigitalActorDigitalOut4_Pin(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletDistanceUS Tinker Bricklet Distance US}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor Digital Actor}'. * * - * @return the meta object for data type 'Tinker Bricklet Distance US'. - * @see com.tinkerforge.BrickletDistanceUS - * @model instanceClass="com.tinkerforge.BrickletDistanceUS" + * @return the meta object for class 'Digital Actor'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor * @generated */ - EDataType getTinkerBrickletDistanceUS(); + EClass getDigitalActor(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletVoltageCurrent Tinker Bricklet Voltage Current}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor#getDigitalState Digital State}'. * * - * @return the meta object for data type 'Tinker Bricklet Voltage Current'. - * @see com.tinkerforge.BrickletVoltageCurrent - * @model instanceClass="com.tinkerforge.BrickletVoltageCurrent" + * @return the meta object for the attribute 'Digital State'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor#getDigitalState() + * @see #getDigitalActor() * @generated */ - EDataType getTinkerBrickletVoltageCurrent(); + EAttribute getDigitalActor_DigitalState(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletTilt Tinker Bricklet Tilt}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) Turn Digital}' operation. * * - * @return the meta object for data type 'Tinker Bricklet Tilt'. - * @see com.tinkerforge.BrickletTilt - * @model instanceClass="com.tinkerforge.BrickletTilt" + * @return the meta object for the 'Turn Digital' operation. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) * @generated */ - EDataType getTinkerBrickletTilt(); + EOperation getDigitalActor__TurnDigital__HighLowValue(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletIO4 Tinker Bricklet IO4}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor#fetchDigitalValue() Fetch Digital Value}' operation. * * - * @return the meta object for data type 'Tinker Bricklet IO4'. - * @see com.tinkerforge.BrickletIO4 - * @model instanceClass="com.tinkerforge.BrickletIO4" + * @return the meta object for the 'Fetch Digital Value' operation. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor#fetchDigitalValue() * @generated */ - EDataType getTinkerBrickletIO4(); + EOperation getDigitalActor__FetchDigitalValue(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletHallEffect Tinker Bricklet Hall Effect}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.NumberActor Number Actor}'. * * - * @return the meta object for data type 'Tinker Bricklet Hall Effect'. - * @see com.tinkerforge.BrickletHallEffect - * @model instanceClass="com.tinkerforge.BrickletHallEffect" + * @return the meta object for class 'Number Actor'. + * @see org.openhab.binding.tinkerforge.internal.model.NumberActor * @generated */ - EDataType getTinkerBrickletHallEffect(); + EClass getNumberActor(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletSegmentDisplay4x7 Tinker Bricklet Segment Display4x7}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.NumberActor#setNumber(java.math.BigDecimal) Set Number}' operation. * * - * @return the meta object for data type 'Tinker Bricklet Segment Display4x7'. - * @see com.tinkerforge.BrickletSegmentDisplay4x7 - * @model instanceClass="com.tinkerforge.BrickletSegmentDisplay4x7" + * @return the meta object for the 'Set Number' operation. + * @see org.openhab.binding.tinkerforge.internal.model.NumberActor#setNumber(java.math.BigDecimal) * @generated */ - EDataType getTinkerBrickletSegmentDisplay4x7(); + EOperation getNumberActor__SetNumber__BigDecimal(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletLEDStrip Tinker Bricklet LED Strip}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.ColorActor Color Actor}'. * * - * @return the meta object for data type 'Tinker Bricklet LED Strip'. - * @see com.tinkerforge.BrickletLEDStrip - * @model instanceClass="com.tinkerforge.BrickletLEDStrip" + * @return the meta object for class 'Color Actor'. + * @see org.openhab.binding.tinkerforge.internal.model.ColorActor * @generated */ - EDataType getTinkerBrickletLEDStrip(); + EClass getColorActor(); /** - * Returns the meta object for data type '{@link org.openhab.core.library.types.HSBType HSB Type}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.ColorActor#setColor(org.openhab.core.library.types.HSBType, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) Set Color}' operation. * * - * @return the meta object for data type 'HSB Type'. - * @see org.openhab.core.library.types.HSBType - * @model instanceClass="org.openhab.core.library.types.HSBType" + * @return the meta object for the 'Set Color' operation. + * @see org.openhab.binding.tinkerforge.internal.model.ColorActor#setColor(org.openhab.core.library.types.HSBType, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) * @generated */ - EDataType getHSBType(); + EOperation getColorActor__SetColor__HSBType_DeviceOptions(); /** - * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.config.DeviceOptions Device Options}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MoveActor Move Actor}'. * * - * @return the meta object for data type 'Device Options'. - * @see org.openhab.binding.tinkerforge.internal.config.DeviceOptions - * @model instanceClass="org.openhab.binding.tinkerforge.internal.config.DeviceOptions" + * @return the meta object for class 'Move Actor'. + * @see org.openhab.binding.tinkerforge.internal.model.MoveActor * @generated */ - EDataType getDeviceOptions(); + EClass getMoveActor(); /** - * Returns the meta object for data type '{@link java.lang.Enum Enum}'. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MoveActor#getDirection Direction}'. * * - * @return the meta object for data type 'Enum'. - * @see java.lang.Enum - * @model instanceClass="java.lang.Enum" + * @return the meta object for the attribute 'Direction'. + * @see org.openhab.binding.tinkerforge.internal.model.MoveActor#getDirection() + * @see #getMoveActor() * @generated */ - EDataType getEnum(); + EAttribute getMoveActor_Direction(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletDualRelay MTinker Bricklet Dual Relay}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MoveActor#move(org.openhab.core.library.types.UpDownType, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) Move}' operation. * * - * @return the meta object for data type 'MTinker Bricklet Dual Relay'. - * @see com.tinkerforge.BrickletDualRelay - * @model instanceClass="com.tinkerforge.BrickletDualRelay" + * @return the meta object for the 'Move' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MoveActor#move(org.openhab.core.library.types.UpDownType, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) * @generated */ - EDataType getMTinkerBrickletDualRelay(); + EOperation getMoveActor__Move__UpDownType_DeviceOptions(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletIndustrialQuadRelay MTinker Bricklet Industrial Quad Relay}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MoveActor#stop() Stop}' operation. * * - * @return the meta object for data type 'MTinker Bricklet Industrial Quad Relay'. - * @see com.tinkerforge.BrickletIndustrialQuadRelay - * @model instanceClass="com.tinkerforge.BrickletIndustrialQuadRelay" + * @return the meta object for the 'Stop' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MoveActor#stop() * @generated */ - EDataType getMTinkerBrickletIndustrialQuadRelay(); + EOperation getMoveActor__Stop(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletIndustrialDigitalIn4 MTinker Bricklet Industrial Digital In4}'. + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MoveActor#moveon(org.openhab.binding.tinkerforge.internal.config.DeviceOptions) Moveon}' operation. * * - * @return the meta object for data type 'MTinker Bricklet Industrial Digital In4'. - * @see com.tinkerforge.BrickletIndustrialDigitalIn4 - * @model instanceClass="com.tinkerforge.BrickletIndustrialDigitalIn4" + * @return the meta object for the 'Moveon' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MoveActor#moveon(org.openhab.binding.tinkerforge.internal.config.DeviceOptions) * @generated */ - EDataType getMTinkerBrickletIndustrialDigitalIn4(); + EOperation getMoveActor__Moveon__DeviceOptions(); /** - * Returns the meta object for data type '{@link com.tinkerforge.BrickletIndustrialDigitalOut4 MTinker Bricklet Industrial Digital Out4}'. + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DimmableActor Dimmable Actor}'. * * - * @return the meta object for data type 'MTinker Bricklet Industrial Digital Out4'. - * @see com.tinkerforge.BrickletIndustrialDigitalOut4 - * @model instanceClass="com.tinkerforge.BrickletIndustrialDigitalOut4" + * @return the meta object for class 'Dimmable Actor'. + * @see org.openhab.binding.tinkerforge.internal.model.DimmableActor * @generated */ - EDataType getMTinkerBrickletIndustrialDigitalOut4(); + EClass getDimmableActor(); /** - * Returns the factory that creates the instances of the model. + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DimmableActor#getMinValue Min Value}'. * * - * @return the factory that creates the instances of the model. + * @return the meta object for the attribute 'Min Value'. + * @see org.openhab.binding.tinkerforge.internal.model.DimmableActor#getMinValue() + * @see #getDimmableActor() * @generated */ - ModelFactory getModelFactory(); + EAttribute getDimmableActor_MinValue(); /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DimmableActor#getMaxValue Max Value}'. * - * Defines literals for the meta objects that represent - *
        - *
      • each class,
      • - *
      • each feature of each class,
      • - *
      • each operation of each class,
      • - *
      • each enum,
      • - *
      • and each data type
      • - *
      * + * @return the meta object for the attribute 'Max Value'. + * @see org.openhab.binding.tinkerforge.internal.model.DimmableActor#getMaxValue() + * @see #getDimmableActor() * @generated */ - interface Literals - { - /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.TFConfig TF Config}' class. - * - * - * @see org.openhab.binding.tinkerforge.internal.model.TFConfig - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFConfig() - * @generated - */ - EClass TF_CONFIG = eINSTANCE.getTFConfig(); + EAttribute getDimmableActor_MaxValue(); - /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.OHTFDeviceImpl OHTF Device}' class. - * - * - * @see org.openhab.binding.tinkerforge.internal.model.impl.OHTFDeviceImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getOHTFDevice() - * @generated - */ - EClass OHTF_DEVICE = eINSTANCE.getOHTFDevice(); + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DimmableActor#dimm(org.openhab.core.library.types.IncreaseDecreaseType, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) Dimm}' operation. + * + * + * @return the meta object for the 'Dimm' operation. + * @see org.openhab.binding.tinkerforge.internal.model.DimmableActor#dimm(org.openhab.core.library.types.IncreaseDecreaseType, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) + * @generated + */ + EOperation getDimmableActor__Dimm__IncreaseDecreaseType_DeviceOptions(); - /** - * The meta object literal for the 'Uid' attribute feature. - * - * - * @generated - */ - EAttribute OHTF_DEVICE__UID = eINSTANCE.getOHTFDevice_Uid(); + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.SetPointActor Set Point Actor}'. + * + * + * @return the meta object for class 'Set Point Actor'. + * @see org.openhab.binding.tinkerforge.internal.model.SetPointActor + * @generated + */ + EClass getSetPointActor(); - /** - * The meta object literal for the 'Subid' attribute feature. - * - * - * @generated - */ - EAttribute OHTF_DEVICE__SUBID = eINSTANCE.getOHTFDevice_Subid(); + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.SetPointActor#getPercentValue Percent Value}'. + * + * + * @return the meta object for the attribute 'Percent Value'. + * @see org.openhab.binding.tinkerforge.internal.model.SetPointActor#getPercentValue() + * @see #getSetPointActor() + * @generated + */ + EAttribute getSetPointActor_PercentValue(); - /** - * The meta object literal for the 'Ohid' attribute feature. - * - * - * @generated - */ - EAttribute OHTF_DEVICE__OHID = eINSTANCE.getOHTFDevice_Ohid(); + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.SetPointActor#setValue(java.math.BigDecimal, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) Set Value}' operation. + * + * + * @return the meta object for the 'Set Value' operation. + * @see org.openhab.binding.tinkerforge.internal.model.SetPointActor#setValue(java.math.BigDecimal, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) + * @generated + */ + EOperation getSetPointActor__SetValue__BigDecimal_DeviceOptions(); - /** - * The meta object literal for the 'Sub Device Ids' attribute list feature. - * - * - * @generated - */ - EAttribute OHTF_DEVICE__SUB_DEVICE_IDS = eINSTANCE.getOHTFDevice_SubDeviceIds(); + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.SetPointActor#setValue(org.openhab.core.library.types.PercentType, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) Set Value}' operation. + * + * + * @return the meta object for the 'Set Value' operation. + * @see org.openhab.binding.tinkerforge.internal.model.SetPointActor#setValue(org.openhab.core.library.types.PercentType, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) + * @generated + */ + EOperation getSetPointActor__SetValue__PercentType_DeviceOptions(); - /** - * The meta object literal for the 'Tf Config' containment reference feature. - * - * - * @generated - */ - EReference OHTF_DEVICE__TF_CONFIG = eINSTANCE.getOHTFDevice_TfConfig(); + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDualButton MBricklet Dual Button}'. + * + * + * @return the meta object for class 'MBricklet Dual Button'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDualButton + * @generated + */ + EClass getMBrickletDualButton(); - /** - * The meta object literal for the 'Oh Config' container reference feature. - * - * - * @generated - */ - EReference OHTF_DEVICE__OH_CONFIG = eINSTANCE.getOHTFDevice_OhConfig(); + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonDevice Dual Button Device}'. + * + * + * @return the meta object for class 'Dual Button Device'. + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonDevice + * @generated + */ + EClass getDualButtonDevice(); - /** - * The meta object literal for the 'Is Valid Sub Id' operation. + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonLeftButton Dual Button Left Button}'. + * + * + * @return the meta object for class 'Dual Button Left Button'. + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonLeftButton + * @generated + */ + EClass getDualButtonLeftButton(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonRightButton Dual Button Right Button}'. + * + * + * @return the meta object for class 'Dual Button Right Button'. + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonRightButton + * @generated + */ + EClass getDualButtonRightButton(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonLeftLed Dual Button Left Led}'. + * + * + * @return the meta object for class 'Dual Button Left Led'. + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonLeftLed + * @generated + */ + EClass getDualButtonLeftLed(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonRightLed Dual Button Right Led}'. + * + * + * @return the meta object for class 'Dual Button Right Led'. + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonRightLed + * @generated + */ + EClass getDualButtonRightLed(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLinearPoti MBricklet Linear Poti}'. + * + * + * @return the meta object for class 'MBricklet Linear Poti'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLinearPoti + * @generated + */ + EClass getMBrickletLinearPoti(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLinearPoti#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLinearPoti#getDeviceType() + * @see #getMBrickletLinearPoti() + * @generated + */ + EAttribute getMBrickletLinearPoti_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick MBricklet Joystick}'. + * + * + * @return the meta object for class 'MBricklet Joystick'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick + * @generated + */ + EClass getMBrickletJoystick(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick#getDeviceType() + * @see #getMBrickletJoystick() + * @generated + */ + EAttribute getMBrickletJoystick_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.JoystickDevice Joystick Device}'. + * + * + * @return the meta object for class 'Joystick Device'. + * @see org.openhab.binding.tinkerforge.internal.model.JoystickDevice + * @generated + */ + EClass getJoystickDevice(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.JoystickXPosition Joystick XPosition}'. + * + * + * @return the meta object for class 'Joystick XPosition'. + * @see org.openhab.binding.tinkerforge.internal.model.JoystickXPosition + * @generated + */ + EClass getJoystickXPosition(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.JoystickXPosition#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.JoystickXPosition#getDeviceType() + * @see #getJoystickXPosition() + * @generated + */ + EAttribute getJoystickXPosition_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.JoystickYPosition Joystick YPosition}'. + * + * + * @return the meta object for class 'Joystick YPosition'. + * @see org.openhab.binding.tinkerforge.internal.model.JoystickYPosition + * @generated + */ + EClass getJoystickYPosition(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.JoystickYPosition#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.JoystickYPosition#getDeviceType() + * @see #getJoystickYPosition() + * @generated + */ + EAttribute getJoystickYPosition_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.JoystickButton Joystick Button}'. + * + * + * @return the meta object for class 'Joystick Button'. + * @see org.openhab.binding.tinkerforge.internal.model.JoystickButton + * @generated + */ + EClass getJoystickButton(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.JoystickButton#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.JoystickButton#getDeviceType() + * @see #getJoystickButton() + * @generated + */ + EAttribute getJoystickButton_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLEDStrip MBricklet LED Strip}'. + * + * + * @return the meta object for class 'MBricklet LED Strip'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLEDStrip + * @generated + */ + EClass getMBrickletLEDStrip(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletSegmentDisplay4x7 MBricklet Segment Display4x7}'. + * + * + * @return the meta object for class 'MBricklet Segment Display4x7'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletSegmentDisplay4x7 + * @generated + */ + EClass getMBrickletSegmentDisplay4x7(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16 Digital Actor IO16}'. + * + * + * @return the meta object for class 'Digital Actor IO16'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16 + * @generated + */ + EClass getDigitalActorIO16(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getDeviceType() + * @see #getDigitalActorIO16() + * @generated + */ + EAttribute getDigitalActorIO16_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getPort Port}'. + * + * + * @return the meta object for the attribute 'Port'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getPort() + * @see #getDigitalActorIO16() + * @generated + */ + EAttribute getDigitalActorIO16_Port(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getPin Pin}'. + * + * + * @return the meta object for the attribute 'Pin'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getPin() + * @see #getDigitalActorIO16() + * @generated + */ + EAttribute getDigitalActorIO16_Pin(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getDefaultState Default State}'. + * + * + * @return the meta object for the attribute 'Default State'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#getDefaultState() + * @see #getDigitalActorIO16() + * @generated + */ + EAttribute getDigitalActorIO16_DefaultState(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#isKeepOnReconnect Keep On Reconnect}'. + * + * + * @return the meta object for the attribute 'Keep On Reconnect'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#isKeepOnReconnect() + * @see #getDigitalActorIO16() + * @generated + */ + EAttribute getDigitalActorIO16_KeepOnReconnect(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) Turn Digital}' operation. + * + * + * @return the meta object for the 'Turn Digital' operation. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) + * @generated + */ + EOperation getDigitalActorIO16__TurnDigital__HighLowValue(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#fetchDigitalValue() Fetch Digital Value}' operation. + * + * + * @return the meta object for the 'Fetch Digital Value' operation. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO16#fetchDigitalValue() + * @generated + */ + EOperation getDigitalActorIO16__FetchDigitalValue(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MActor MActor}'. + * + * + * @return the meta object for class 'MActor'. + * @see org.openhab.binding.tinkerforge.internal.model.MActor + * @generated + */ + EClass getMActor(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.SwitchSensor Switch Sensor}'. + * + * + * @return the meta object for class 'Switch Sensor'. + * @see org.openhab.binding.tinkerforge.internal.model.SwitchSensor + * @generated + */ + EClass getSwitchSensor(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.SwitchSensor#fetchSwitchState() Fetch Switch State}' operation. + * + * + * @return the meta object for the 'Fetch Switch State' operation. + * @see org.openhab.binding.tinkerforge.internal.model.SwitchSensor#fetchSwitchState() + * @generated + */ + EOperation getSwitchSensor__FetchSwitchState(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MSwitchActor MSwitch Actor}'. + * + * + * @return the meta object for class 'MSwitch Actor'. + * @see org.openhab.binding.tinkerforge.internal.model.MSwitchActor + * @generated + */ + EClass getMSwitchActor(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MSwitchActor#getSwitchState Switch State}'. + * + * + * @return the meta object for the attribute 'Switch State'. + * @see org.openhab.binding.tinkerforge.internal.model.MSwitchActor#getSwitchState() + * @see #getMSwitchActor() + * @generated + */ + EAttribute getMSwitchActor_SwitchState(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MSwitchActor#turnSwitch(org.openhab.binding.tinkerforge.internal.types.OnOffValue) Turn Switch}' operation. + * + * + * @return the meta object for the 'Turn Switch' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MSwitchActor#turnSwitch(org.openhab.binding.tinkerforge.internal.types.OnOffValue) + * @generated + */ + EOperation getMSwitchActor__TurnSwitch__OnOffValue(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor Programmable Switch Actor}'. + * + * + * @return the meta object for class 'Programmable Switch Actor'. + * @see org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor + * @generated + */ + EClass getProgrammableSwitchActor(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor#getSwitchState Switch State}'. + * + * + * @return the meta object for the attribute 'Switch State'. + * @see org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor#getSwitchState() + * @see #getProgrammableSwitchActor() + * @generated + */ + EAttribute getProgrammableSwitchActor_SwitchState(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor#turnSwitch(org.openhab.binding.tinkerforge.internal.types.OnOffValue, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) Turn Switch}' operation. + * + * + * @return the meta object for the 'Turn Switch' operation. + * @see org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor#turnSwitch(org.openhab.binding.tinkerforge.internal.types.OnOffValue, org.openhab.binding.tinkerforge.internal.config.DeviceOptions) + * @generated + */ + EOperation getProgrammableSwitchActor__TurnSwitch__OnOffValue_DeviceOptions(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MOutSwitchActor MOut Switch Actor}'. + * + * + * @return the meta object for class 'MOut Switch Actor'. + * @see org.openhab.binding.tinkerforge.internal.model.MOutSwitchActor + * @generated + */ + EClass getMOutSwitchActor(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MInSwitchActor MIn Switch Actor}'. + * + * + * @return the meta object for class 'MIn Switch Actor'. + * @see org.openhab.binding.tinkerforge.internal.model.MInSwitchActor + * @generated + */ + EClass getMInSwitchActor(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.GenericDevice Generic Device}'. + * + * + * @return the meta object for class 'Generic Device'. + * @see org.openhab.binding.tinkerforge.internal.model.GenericDevice + * @generated + */ + EClass getGenericDevice(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.GenericDevice#getGenericDeviceId Generic Device Id}'. + * + * + * @return the meta object for the attribute 'Generic Device Id'. + * @see org.openhab.binding.tinkerforge.internal.model.GenericDevice#getGenericDeviceId() + * @see #getGenericDevice() + * @generated + */ + EAttribute getGenericDevice_GenericDeviceId(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration TFIO Actor Configuration}'. + * + * + * @return the meta object for class 'TFIO Actor Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration + * @generated + */ + EClass getTFIOActorConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration#getDefaultState Default State}'. + * + * + * @return the meta object for the attribute 'Default State'. + * @see org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration#getDefaultState() + * @see #getTFIOActorConfiguration() + * @generated + */ + EAttribute getTFIOActorConfiguration_DefaultState(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration#isKeepOnReconnect Keep On Reconnect}'. + * + * + * @return the meta object for the attribute 'Keep On Reconnect'. + * @see org.openhab.binding.tinkerforge.internal.model.TFIOActorConfiguration#isKeepOnReconnect() + * @see #getTFIOActorConfiguration() + * @generated + */ + EAttribute getTFIOActorConfiguration_KeepOnReconnect(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFInterruptListenerConfiguration TF Interrupt Listener Configuration}'. + * + * + * @return the meta object for class 'TF Interrupt Listener Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFInterruptListenerConfiguration + * @generated + */ + EClass getTFInterruptListenerConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFInterruptListenerConfiguration#getDebouncePeriod Debounce Period}'. + * + * + * @return the meta object for the attribute 'Debounce Period'. + * @see org.openhab.binding.tinkerforge.internal.model.TFInterruptListenerConfiguration#getDebouncePeriod() + * @see #getTFInterruptListenerConfiguration() + * @generated + */ + EAttribute getTFInterruptListenerConfiguration_DebouncePeriod(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIO16 MBricklet IO16}'. + * + * + * @return the meta object for class 'MBricklet IO16'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIO16 + * @generated + */ + EClass getMBrickletIO16(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIO16#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIO16#getDeviceType() + * @see #getMBrickletIO16() + * @generated + */ + EAttribute getMBrickletIO16_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.IODevice IO Device}'. + * + * + * @return the meta object for class 'IO Device'. + * @see org.openhab.binding.tinkerforge.internal.model.IODevice + * @generated + */ + EClass getIODevice(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFIOSensorConfiguration TFIO Sensor Configuration}'. + * + * + * @return the meta object for class 'TFIO Sensor Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFIOSensorConfiguration + * @generated + */ + EClass getTFIOSensorConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFIOSensorConfiguration#isPullUpResistorEnabled Pull Up Resistor Enabled}'. + * + * + * @return the meta object for the attribute 'Pull Up Resistor Enabled'. + * @see org.openhab.binding.tinkerforge.internal.model.TFIOSensorConfiguration#isPullUpResistorEnabled() + * @see #getTFIOSensorConfiguration() + * @generated + */ + EAttribute getTFIOSensorConfiguration_PullUpResistorEnabled(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensor Digital Sensor}'. + * + * + * @return the meta object for class 'Digital Sensor'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensor + * @generated + */ + EClass getDigitalSensor(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getDeviceType() + * @see #getDigitalSensor() + * @generated + */ + EAttribute getDigitalSensor_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensor#isPullUpResistorEnabled Pull Up Resistor Enabled}'. + * + * + * @return the meta object for the attribute 'Pull Up Resistor Enabled'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensor#isPullUpResistorEnabled() + * @see #getDigitalSensor() + * @generated + */ + EAttribute getDigitalSensor_PullUpResistorEnabled(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getPort Port}'. + * + * + * @return the meta object for the attribute 'Port'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getPort() + * @see #getDigitalSensor() + * @generated + */ + EAttribute getDigitalSensor_Port(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getPin Pin}'. + * + * + * @return the meta object for the attribute 'Pin'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensor#getPin() + * @see #getDigitalSensor() + * @generated + */ + EAttribute getDigitalSensor_Pin(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIO4 MBricklet IO4}'. + * + * + * @return the meta object for class 'MBricklet IO4'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIO4 + * @generated + */ + EClass getMBrickletIO4(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletIO4#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletIO4#getDeviceType() + * @see #getMBrickletIO4() + * @generated + */ + EAttribute getMBrickletIO4_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.IO4Device IO4 Device}'. + * + * + * @return the meta object for class 'IO4 Device'. + * @see org.openhab.binding.tinkerforge.internal.model.IO4Device + * @generated + */ + EClass getIO4Device(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4 Digital Sensor IO4}'. + * + * + * @return the meta object for class 'Digital Sensor IO4'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4 + * @generated + */ + EClass getDigitalSensorIO4(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#getDeviceType() + * @see #getDigitalSensorIO4() + * @generated + */ + EAttribute getDigitalSensorIO4_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#isPullUpResistorEnabled Pull Up Resistor Enabled}'. + * + * + * @return the meta object for the attribute 'Pull Up Resistor Enabled'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#isPullUpResistorEnabled() + * @see #getDigitalSensorIO4() + * @generated + */ + EAttribute getDigitalSensorIO4_PullUpResistorEnabled(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#getPin Pin}'. + * + * + * @return the meta object for the attribute 'Pin'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4#getPin() + * @see #getDigitalSensorIO4() + * @generated + */ + EAttribute getDigitalSensorIO4_Pin(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4 Digital Actor IO4}'. + * + * + * @return the meta object for class 'Digital Actor IO4'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4 + * @generated + */ + EClass getDigitalActorIO4(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getDeviceType() + * @see #getDigitalActorIO4() + * @generated + */ + EAttribute getDigitalActorIO4_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getPin Pin}'. + * + * + * @return the meta object for the attribute 'Pin'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getPin() + * @see #getDigitalActorIO4() + * @generated + */ + EAttribute getDigitalActorIO4_Pin(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getDefaultState Default State}'. + * + * + * @return the meta object for the attribute 'Default State'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#getDefaultState() + * @see #getDigitalActorIO4() + * @generated + */ + EAttribute getDigitalActorIO4_DefaultState(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#isKeepOnReconnect Keep On Reconnect}'. + * + * + * @return the meta object for the attribute 'Keep On Reconnect'. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#isKeepOnReconnect() + * @see #getDigitalActorIO4() + * @generated + */ + EAttribute getDigitalActorIO4_KeepOnReconnect(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) Turn Digital}' operation. + * + * + * @return the meta object for the 'Turn Digital' operation. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#turnDigital(org.openhab.binding.tinkerforge.internal.types.HighLowValue) + * @generated + */ + EOperation getDigitalActorIO4__TurnDigital__HighLowValue(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#fetchDigitalValue() Fetch Digital Value}' operation. + * + * + * @return the meta object for the 'Fetch Digital Value' operation. + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4#fetchDigitalValue() + * @generated + */ + EOperation getDigitalActorIO4__FetchDigitalValue(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch MBricklet Multi Touch}'. + * + * + * @return the meta object for class 'MBricklet Multi Touch'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch + * @generated + */ + EClass getMBrickletMultiTouch(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getDeviceType() + * @see #getMBrickletMultiTouch() + * @generated + */ + EAttribute getMBrickletMultiTouch_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getRecalibrate Recalibrate}'. + * + * + * @return the meta object for the attribute 'Recalibrate'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getRecalibrate() + * @see #getMBrickletMultiTouch() + * @generated + */ + EAttribute getMBrickletMultiTouch_Recalibrate(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getSensitivity Sensitivity}'. + * + * + * @return the meta object for the attribute 'Sensitivity'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch#getSensitivity() + * @see #getMBrickletMultiTouch() + * @generated + */ + EAttribute getMBrickletMultiTouch_Sensitivity(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice Multi Touch Device}'. + * + * + * @return the meta object for class 'Multi Touch Device'. + * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice + * @generated + */ + EClass getMultiTouchDevice(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice#getPin Pin}'. + * + * + * @return the meta object for the attribute 'Pin'. + * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice#getPin() + * @see #getMultiTouchDevice() + * @generated + */ + EAttribute getMultiTouchDevice_Pin(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice#getDisableElectrode Disable Electrode}'. + * + * + * @return the meta object for the attribute 'Disable Electrode'. + * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice#getDisableElectrode() + * @see #getMultiTouchDevice() + * @generated + */ + EAttribute getMultiTouchDevice_DisableElectrode(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.Electrode Electrode}'. + * + * + * @return the meta object for class 'Electrode'. + * @see org.openhab.binding.tinkerforge.internal.model.Electrode + * @generated + */ + EClass getElectrode(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.Electrode#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.Electrode#getDeviceType() + * @see #getElectrode() + * @generated + */ + EAttribute getElectrode_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.Proximity Proximity}'. + * + * + * @return the meta object for class 'Proximity'. + * @see org.openhab.binding.tinkerforge.internal.model.Proximity + * @generated + */ + EClass getProximity(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.Proximity#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.Proximity#getDeviceType() + * @see #getProximity() + * @generated + */ + EAttribute getProximity_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector MBricklet Motion Detector}'. + * + * + * @return the meta object for class 'MBricklet Motion Detector'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector + * @generated + */ + EClass getMBrickletMotionDetector(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector#getDeviceType() + * @see #getMBrickletMotionDetector() + * @generated + */ + EAttribute getMBrickletMotionDetector_DeviceType(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector#init() + * @generated + */ + EOperation getMBrickletMotionDetector__Init(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect MBricklet Hall Effect}'. + * + * + * @return the meta object for class 'MBricklet Hall Effect'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect + * @generated + */ + EClass getMBrickletHallEffect(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect#getDeviceType() + * @see #getMBrickletHallEffect() + * @generated + */ + EAttribute getMBrickletHallEffect_DeviceType(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect#init() + * @generated + */ + EOperation getMBrickletHallEffect__Init(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MSubDevice MSub Device}'. + * + * + * @return the meta object for class 'MSub Device'. + * @see org.openhab.binding.tinkerforge.internal.model.MSubDevice + * @generated + */ + EClass getMSubDevice(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MSubDevice#getSubId Sub Id}'. + * + * + * @return the meta object for the attribute 'Sub Id'. + * @see org.openhab.binding.tinkerforge.internal.model.MSubDevice#getSubId() + * @see #getMSubDevice() + * @generated + */ + EAttribute getMSubDevice_SubId(); + + /** + * Returns the meta object for the container reference '{@link org.openhab.binding.tinkerforge.internal.model.MSubDevice#getMbrick Mbrick}'. + * + * + * @return the meta object for the container reference 'Mbrick'. + * @see org.openhab.binding.tinkerforge.internal.model.MSubDevice#getMbrick() + * @see #getMSubDevice() + * @generated + */ + EReference getMSubDevice_Mbrick(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MDualRelay MDual Relay}'. + * + * + * @return the meta object for class 'MDual Relay'. + * @see org.openhab.binding.tinkerforge.internal.model.MDualRelay + * @generated + */ + EClass getMDualRelay(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MDualRelay#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MDualRelay#getDeviceType() + * @see #getMDualRelay() + * @generated + */ + EAttribute getMDualRelay_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch MBricklet Remote Switch}'. + * + * + * @return the meta object for class 'MBricklet Remote Switch'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch + * @generated + */ + EClass getMBrickletRemoteSwitch(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getDeviceType() + * @see #getMBrickletRemoteSwitch() + * @generated + */ + EAttribute getMBrickletRemoteSwitch_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeADevices Type ADevices}'. + * + * + * @return the meta object for the attribute 'Type ADevices'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeADevices() + * @see #getMBrickletRemoteSwitch() + * @generated + */ + EAttribute getMBrickletRemoteSwitch_TypeADevices(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeBDevices Type BDevices}'. + * + * + * @return the meta object for the attribute 'Type BDevices'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeBDevices() + * @see #getMBrickletRemoteSwitch() + * @generated + */ + EAttribute getMBrickletRemoteSwitch_TypeBDevices(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeCDevices Type CDevices}'. + * + * + * @return the meta object for the attribute 'Type CDevices'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch#getTypeCDevices() + * @see #getMBrickletRemoteSwitch() + * @generated + */ + EAttribute getMBrickletRemoteSwitch_TypeCDevices(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitch Remote Switch}'. + * + * + * @return the meta object for class 'Remote Switch'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitch + * @generated + */ + EClass getRemoteSwitch(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA Remote Switch A}'. + * + * + * @return the meta object for class 'Remote Switch A'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA + * @generated + */ + EClass getRemoteSwitchA(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getDeviceType() + * @see #getRemoteSwitchA() + * @generated + */ + EAttribute getRemoteSwitchA_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getHouseCode House Code}'. + * + * + * @return the meta object for the attribute 'House Code'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getHouseCode() + * @see #getRemoteSwitchA() + * @generated + */ + EAttribute getRemoteSwitchA_HouseCode(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getReceiverCode Receiver Code}'. + * + * + * @return the meta object for the attribute 'Receiver Code'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getReceiverCode() + * @see #getRemoteSwitchA() + * @generated + */ + EAttribute getRemoteSwitchA_ReceiverCode(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getRepeats Repeats}'. + * + * + * @return the meta object for the attribute 'Repeats'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA#getRepeats() + * @see #getRemoteSwitchA() + * @generated + */ + EAttribute getRemoteSwitchA_Repeats(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB Remote Switch B}'. + * + * + * @return the meta object for class 'Remote Switch B'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB + * @generated + */ + EClass getRemoteSwitchB(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getDeviceType() + * @see #getRemoteSwitchB() + * @generated + */ + EAttribute getRemoteSwitchB_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getAddress Address}'. + * + * + * @return the meta object for the attribute 'Address'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getAddress() + * @see #getRemoteSwitchB() + * @generated + */ + EAttribute getRemoteSwitchB_Address(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getUnit Unit}'. + * + * + * @return the meta object for the attribute 'Unit'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getUnit() + * @see #getRemoteSwitchB() + * @generated + */ + EAttribute getRemoteSwitchB_Unit(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getRepeats Repeats}'. + * + * + * @return the meta object for the attribute 'Repeats'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getRepeats() + * @see #getRemoteSwitchB() + * @generated + */ + EAttribute getRemoteSwitchB_Repeats(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getTargetDimmvalue Target Dimmvalue}'. + * + * + * @return the meta object for the attribute 'Target Dimmvalue'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getTargetDimmvalue() + * @see #getRemoteSwitchB() + * @generated + */ + EAttribute getRemoteSwitchB_TargetDimmvalue(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC Remote Switch C}'. + * + * + * @return the meta object for class 'Remote Switch C'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC + * @generated + */ + EClass getRemoteSwitchC(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getDeviceType() + * @see #getRemoteSwitchC() + * @generated + */ + EAttribute getRemoteSwitchC_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getSystemCode System Code}'. + * + * + * @return the meta object for the attribute 'System Code'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getSystemCode() + * @see #getRemoteSwitchC() + * @generated + */ + EAttribute getRemoteSwitchC_SystemCode(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getDeviceCode Device Code}'. + * + * + * @return the meta object for the attribute 'Device Code'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getDeviceCode() + * @see #getRemoteSwitchC() + * @generated + */ + EAttribute getRemoteSwitchC_DeviceCode(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getRepeats Repeats}'. + * + * + * @return the meta object for the attribute 'Repeats'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC#getRepeats() + * @see #getRemoteSwitchC() + * @generated + */ + EAttribute getRemoteSwitchC_Repeats(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFNullConfiguration TF Null Configuration}'. + * + * + * @return the meta object for class 'TF Null Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFNullConfiguration + * @generated + */ + EClass getTFNullConfiguration(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration TF Servo Configuration}'. + * + * + * @return the meta object for class 'TF Servo Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration + * @generated + */ + EClass getTFServoConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getVelocity Velocity}'. + * + * + * @return the meta object for the attribute 'Velocity'. + * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getVelocity() + * @see #getTFServoConfiguration() + * @generated + */ + EAttribute getTFServoConfiguration_Velocity(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getAcceleration Acceleration}'. + * + * + * @return the meta object for the attribute 'Acceleration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getAcceleration() + * @see #getTFServoConfiguration() + * @generated + */ + EAttribute getTFServoConfiguration_Acceleration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getServoVoltage Servo Voltage}'. + * + * + * @return the meta object for the attribute 'Servo Voltage'. + * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getServoVoltage() + * @see #getTFServoConfiguration() + * @generated + */ + EAttribute getTFServoConfiguration_ServoVoltage(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPulseWidthMin Pulse Width Min}'. + * + * + * @return the meta object for the attribute 'Pulse Width Min'. + * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPulseWidthMin() + * @see #getTFServoConfiguration() + * @generated + */ + EAttribute getTFServoConfiguration_PulseWidthMin(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPulseWidthMax Pulse Width Max}'. + * + * + * @return the meta object for the attribute 'Pulse Width Max'. + * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPulseWidthMax() + * @see #getTFServoConfiguration() + * @generated + */ + EAttribute getTFServoConfiguration_PulseWidthMax(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPeriod Period}'. + * + * + * @return the meta object for the attribute 'Period'. + * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getPeriod() + * @see #getTFServoConfiguration() + * @generated + */ + EAttribute getTFServoConfiguration_Period(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getOutputVoltage Output Voltage}'. + * + * + * @return the meta object for the attribute 'Output Voltage'. + * @see org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration#getOutputVoltage() + * @see #getTFServoConfiguration() + * @generated + */ + EAttribute getTFServoConfiguration_OutputVoltage(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration Bricklet Remote Switch Configuration}'. + * + * + * @return the meta object for class 'Bricklet Remote Switch Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration + * @generated + */ + EClass getBrickletRemoteSwitchConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeADevices Type ADevices}'. + * + * + * @return the meta object for the attribute 'Type ADevices'. + * @see org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeADevices() + * @see #getBrickletRemoteSwitchConfiguration() + * @generated + */ + EAttribute getBrickletRemoteSwitchConfiguration_TypeADevices(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeBDevices Type BDevices}'. + * + * + * @return the meta object for the attribute 'Type BDevices'. + * @see org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeBDevices() + * @see #getBrickletRemoteSwitchConfiguration() + * @generated + */ + EAttribute getBrickletRemoteSwitchConfiguration_TypeBDevices(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeCDevices Type CDevices}'. + * + * + * @return the meta object for the attribute 'Type CDevices'. + * @see org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration#getTypeCDevices() + * @see #getBrickletRemoteSwitchConfiguration() + * @generated + */ + EAttribute getBrickletRemoteSwitchConfiguration_TypeCDevices(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration Remote Switch AConfiguration}'. + * + * + * @return the meta object for class 'Remote Switch AConfiguration'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration + * @generated + */ + EClass getRemoteSwitchAConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getHouseCode House Code}'. + * + * + * @return the meta object for the attribute 'House Code'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getHouseCode() + * @see #getRemoteSwitchAConfiguration() + * @generated + */ + EAttribute getRemoteSwitchAConfiguration_HouseCode(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getReceiverCode Receiver Code}'. + * + * + * @return the meta object for the attribute 'Receiver Code'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getReceiverCode() + * @see #getRemoteSwitchAConfiguration() + * @generated + */ + EAttribute getRemoteSwitchAConfiguration_ReceiverCode(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getRepeats Repeats}'. + * + * + * @return the meta object for the attribute 'Repeats'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchAConfiguration#getRepeats() + * @see #getRemoteSwitchAConfiguration() + * @generated + */ + EAttribute getRemoteSwitchAConfiguration_Repeats(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration Remote Switch BConfiguration}'. + * + * + * @return the meta object for class 'Remote Switch BConfiguration'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration + * @generated + */ + EClass getRemoteSwitchBConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getAddress Address}'. + * + * + * @return the meta object for the attribute 'Address'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getAddress() + * @see #getRemoteSwitchBConfiguration() + * @generated + */ + EAttribute getRemoteSwitchBConfiguration_Address(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getUnit Unit}'. + * + * + * @return the meta object for the attribute 'Unit'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getUnit() + * @see #getRemoteSwitchBConfiguration() + * @generated + */ + EAttribute getRemoteSwitchBConfiguration_Unit(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getRepeats Repeats}'. + * + * + * @return the meta object for the attribute 'Repeats'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration#getRepeats() + * @see #getRemoteSwitchBConfiguration() + * @generated + */ + EAttribute getRemoteSwitchBConfiguration_Repeats(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration Remote Switch CConfiguration}'. + * + * + * @return the meta object for class 'Remote Switch CConfiguration'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration + * @generated + */ + EClass getRemoteSwitchCConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getSystemCode System Code}'. + * + * + * @return the meta object for the attribute 'System Code'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getSystemCode() + * @see #getRemoteSwitchCConfiguration() + * @generated + */ + EAttribute getRemoteSwitchCConfiguration_SystemCode(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getDeviceCode Device Code}'. + * + * + * @return the meta object for the attribute 'Device Code'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getDeviceCode() + * @see #getRemoteSwitchCConfiguration() + * @generated + */ + EAttribute getRemoteSwitchCConfiguration_DeviceCode(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getRepeats Repeats}'. + * + * + * @return the meta object for the attribute 'Repeats'. + * @see org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration#getRepeats() + * @see #getRemoteSwitchCConfiguration() + * @generated + */ + EAttribute getRemoteSwitchCConfiguration_Repeats(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchDeviceConfiguration Multi Touch Device Configuration}'. + * + * + * @return the meta object for class 'Multi Touch Device Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchDeviceConfiguration + * @generated + */ + EClass getMultiTouchDeviceConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchDeviceConfiguration#getDisableElectrode Disable Electrode}'. + * + * + * @return the meta object for the attribute 'Disable Electrode'. + * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchDeviceConfiguration#getDisableElectrode() + * @see #getMultiTouchDeviceConfiguration() + * @generated + */ + EAttribute getMultiTouchDeviceConfiguration_DisableElectrode(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration Bricklet Multi Touch Configuration}'. + * + * + * @return the meta object for class 'Bricklet Multi Touch Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration + * @generated + */ + EClass getBrickletMultiTouchConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration#getRecalibrate Recalibrate}'. + * + * + * @return the meta object for the attribute 'Recalibrate'. + * @see org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration#getRecalibrate() + * @see #getBrickletMultiTouchConfiguration() + * @generated + */ + EAttribute getBrickletMultiTouchConfiguration_Recalibrate(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration#getSensitivity Sensitivity}'. + * + * + * @return the meta object for the attribute 'Sensitivity'. + * @see org.openhab.binding.tinkerforge.internal.model.BrickletMultiTouchConfiguration#getSensitivity() + * @see #getBrickletMultiTouchConfiguration() + * @generated + */ + EAttribute getBrickletMultiTouchConfiguration_Sensitivity(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration Dimmable Configuration}'. + * + * + * @return the meta object for class 'Dimmable Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration + * @generated + */ + EClass getDimmableConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration#getMinValue Min Value}'. + * + * + * @return the meta object for the attribute 'Min Value'. + * @see org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration#getMinValue() + * @see #getDimmableConfiguration() + * @generated + */ + EAttribute getDimmableConfiguration_MinValue(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration#getMaxValue Max Value}'. + * + * + * @return the meta object for the attribute 'Max Value'. + * @see org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration#getMaxValue() + * @see #getDimmableConfiguration() + * @generated + */ + EAttribute getDimmableConfiguration_MaxValue(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MServo MServo}'. + * + * + * @return the meta object for class 'MServo'. + * @see org.openhab.binding.tinkerforge.internal.model.MServo + * @generated + */ + EClass getMServo(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#getDeviceType() + * @see #getMServo() + * @generated + */ + EAttribute getMServo_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getVelocity Velocity}'. + * + * + * @return the meta object for the attribute 'Velocity'. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#getVelocity() + * @see #getMServo() + * @generated + */ + EAttribute getMServo_Velocity(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getAcceleration Acceleration}'. + * + * + * @return the meta object for the attribute 'Acceleration'. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#getAcceleration() + * @see #getMServo() + * @generated + */ + EAttribute getMServo_Acceleration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getMaxPosition Max Position}'. + * + * + * @return the meta object for the attribute 'Max Position'. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#getMaxPosition() + * @see #getMServo() + * @generated + */ + EAttribute getMServo_MaxPosition(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getMinPosition Min Position}'. + * + * + * @return the meta object for the attribute 'Min Position'. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#getMinPosition() + * @see #getMServo() + * @generated + */ + EAttribute getMServo_MinPosition(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getPulseWidthMin Pulse Width Min}'. + * + * + * @return the meta object for the attribute 'Pulse Width Min'. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#getPulseWidthMin() + * @see #getMServo() + * @generated + */ + EAttribute getMServo_PulseWidthMin(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getPulseWidthMax Pulse Width Max}'. + * + * + * @return the meta object for the attribute 'Pulse Width Max'. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#getPulseWidthMax() + * @see #getMServo() + * @generated + */ + EAttribute getMServo_PulseWidthMax(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getPeriod Period}'. + * + * + * @return the meta object for the attribute 'Period'. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#getPeriod() + * @see #getMServo() + * @generated + */ + EAttribute getMServo_Period(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getOutputVoltage Output Voltage}'. + * + * + * @return the meta object for the attribute 'Output Voltage'. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#getOutputVoltage() + * @see #getMServo() + * @generated + */ + EAttribute getMServo_OutputVoltage(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MServo#getTargetPosition Target Position}'. + * + * + * @return the meta object for the attribute 'Target Position'. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#getTargetPosition() + * @see #getMServo() + * @generated + */ + EAttribute getMServo_TargetPosition(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MServo#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#init() + * @generated + */ + EOperation getMServo__Init(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MServo#setPoint(java.lang.Short, int, int) Set Point}' operation. + * + * + * @return the meta object for the 'Set Point' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MServo#setPoint(java.lang.Short, int, int) + * @generated + */ + EOperation getMServo__SetPoint__Short_int_int(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.CallbackListener Callback Listener}'. + * + * + * @return the meta object for class 'Callback Listener'. + * @see org.openhab.binding.tinkerforge.internal.model.CallbackListener + * @generated + */ + EClass getCallbackListener(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.CallbackListener#getCallbackPeriod Callback Period}'. + * + * + * @return the meta object for the attribute 'Callback Period'. + * @see org.openhab.binding.tinkerforge.internal.model.CallbackListener#getCallbackPeriod() + * @see #getCallbackListener() + * @generated + */ + EAttribute getCallbackListener_CallbackPeriod(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.InterruptListener Interrupt Listener}'. + * + * + * @return the meta object for class 'Interrupt Listener'. + * @see org.openhab.binding.tinkerforge.internal.model.InterruptListener + * @generated + */ + EClass getInterruptListener(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.InterruptListener#getDebouncePeriod Debounce Period}'. + * + * + * @return the meta object for the attribute 'Debounce Period'. + * @see org.openhab.binding.tinkerforge.internal.model.InterruptListener#getDebouncePeriod() + * @see #getInterruptListener() + * @generated + */ + EAttribute getInterruptListener_DebouncePeriod(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MSensor MSensor}'. + * + * + * @return the meta object for class 'MSensor'. + * @see org.openhab.binding.tinkerforge.internal.model.MSensor + * @generated + */ + EClass getMSensor(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MSensor#getSensorValue Sensor Value}'. + * + * + * @return the meta object for the attribute 'Sensor Value'. + * @see org.openhab.binding.tinkerforge.internal.model.MSensor#getSensorValue() + * @see #getMSensor() + * @generated + */ + EAttribute getMSensor_SensorValue(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MSensor#fetchSensorValue() Fetch Sensor Value}' operation. + * + * + * @return the meta object for the 'Fetch Sensor Value' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MSensor#fetchSensorValue() + * @generated + */ + EOperation getMSensor__FetchSensorValue(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity MBricklet Humidity}'. + * + * + * @return the meta object for class 'MBricklet Humidity'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity + * @generated + */ + EClass getMBrickletHumidity(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#getDeviceType() + * @see #getMBrickletHumidity() + * @generated + */ + EAttribute getMBrickletHumidity_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#getThreshold() + * @see #getMBrickletHumidity() + * @generated + */ + EAttribute getMBrickletHumidity_Threshold(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity#init() + * @generated + */ + EOperation getMBrickletHumidity__Init(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR MBricklet Distance IR}'. + * + * + * @return the meta object for class 'MBricklet Distance IR'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR + * @generated + */ + EClass getMBrickletDistanceIR(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#getDeviceType() + * @see #getMBrickletDistanceIR() + * @generated + */ + EAttribute getMBrickletDistanceIR_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#getThreshold() + * @see #getMBrickletDistanceIR() + * @generated + */ + EAttribute getMBrickletDistanceIR_Threshold(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR#init() + * @generated + */ + EOperation getMBrickletDistanceIR__Init(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature MBricklet Temperature}'. + * + * + * @return the meta object for class 'MBricklet Temperature'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature + * @generated + */ + EClass getMBrickletTemperature(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#getDeviceType() + * @see #getMBrickletTemperature() + * @generated + */ + EAttribute getMBrickletTemperature_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#getThreshold() + * @see #getMBrickletTemperature() + * @generated + */ + EAttribute getMBrickletTemperature_Threshold(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperature#init() + * @generated + */ + EOperation getMBrickletTemperature__Init(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperatureIR MBricklet Temperature IR}'. + * + * + * @return the meta object for class 'MBricklet Temperature IR'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperatureIR + * @generated + */ + EClass getMBrickletTemperatureIR(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTemperatureIR#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTemperatureIR#getDeviceType() + * @see #getMBrickletTemperatureIR() + * @generated + */ + EAttribute getMBrickletTemperatureIR_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice MTemperature IR Device}'. + * + * + * @return the meta object for class 'MTemperature IR Device'. + * @see org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice + * @generated + */ + EClass getMTemperatureIRDevice(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.MTemperatureIRDevice#getThreshold() + * @see #getMTemperatureIRDevice() + * @generated + */ + EAttribute getMTemperatureIRDevice_Threshold(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.ObjectTemperature Object Temperature}'. + * + * + * @return the meta object for class 'Object Temperature'. + * @see org.openhab.binding.tinkerforge.internal.model.ObjectTemperature + * @generated + */ + EClass getObjectTemperature(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.ObjectTemperature#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.ObjectTemperature#getDeviceType() + * @see #getObjectTemperature() + * @generated + */ + EAttribute getObjectTemperature_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.ObjectTemperature#getEmissivity Emissivity}'. + * + * + * @return the meta object for the attribute 'Emissivity'. + * @see org.openhab.binding.tinkerforge.internal.model.ObjectTemperature#getEmissivity() + * @see #getObjectTemperature() + * @generated + */ + EAttribute getObjectTemperature_Emissivity(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.AmbientTemperature Ambient Temperature}'. + * + * + * @return the meta object for class 'Ambient Temperature'. + * @see org.openhab.binding.tinkerforge.internal.model.AmbientTemperature + * @generated + */ + EClass getAmbientTemperature(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.AmbientTemperature#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.AmbientTemperature#getDeviceType() + * @see #getAmbientTemperature() + * @generated + */ + EAttribute getAmbientTemperature_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTilt MBricklet Tilt}'. + * + * + * @return the meta object for class 'MBricklet Tilt'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTilt + * @generated + */ + EClass getMBrickletTilt(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletTilt#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletTilt#getDeviceType() + * @see #getMBrickletTilt() + * @generated + */ + EAttribute getMBrickletTilt_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent MBricklet Voltage Current}'. + * + * + * @return the meta object for class 'MBricklet Voltage Current'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent + * @generated + */ + EClass getMBrickletVoltageCurrent(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getDeviceType() + * @see #getMBrickletVoltageCurrent() + * @generated + */ + EAttribute getMBrickletVoltageCurrent_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getAveraging Averaging}'. + * + * + * @return the meta object for the attribute 'Averaging'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getAveraging() + * @see #getMBrickletVoltageCurrent() + * @generated + */ + EAttribute getMBrickletVoltageCurrent_Averaging(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getVoltageConversionTime Voltage Conversion Time}'. + * + * + * @return the meta object for the attribute 'Voltage Conversion Time'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getVoltageConversionTime() + * @see #getMBrickletVoltageCurrent() + * @generated + */ + EAttribute getMBrickletVoltageCurrent_VoltageConversionTime(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getCurrentConversionTime Current Conversion Time}'. + * + * + * @return the meta object for the attribute 'Current Conversion Time'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletVoltageCurrent#getCurrentConversionTime() + * @see #getMBrickletVoltageCurrent() + * @generated + */ + EAttribute getMBrickletVoltageCurrent_CurrentConversionTime(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.VoltageCurrentDevice Voltage Current Device}'. + * + * + * @return the meta object for class 'Voltage Current Device'. + * @see org.openhab.binding.tinkerforge.internal.model.VoltageCurrentDevice + * @generated + */ + EClass getVoltageCurrentDevice(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage VC Device Voltage}'. + * + * + * @return the meta object for class 'VC Device Voltage'. + * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage + * @generated + */ + EClass getVCDeviceVoltage(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage#getDeviceType() + * @see #getVCDeviceVoltage() + * @generated + */ + EAttribute getVCDeviceVoltage_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage#getThreshold() + * @see #getVCDeviceVoltage() + * @generated + */ + EAttribute getVCDeviceVoltage_Threshold(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent VC Device Current}'. + * + * + * @return the meta object for class 'VC Device Current'. + * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent + * @generated + */ + EClass getVCDeviceCurrent(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent#getDeviceType() + * @see #getVCDeviceCurrent() + * @generated + */ + EAttribute getVCDeviceCurrent_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent#getThreshold() + * @see #getVCDeviceCurrent() + * @generated + */ + EAttribute getVCDeviceCurrent_Threshold(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.VCDevicePower VC Device Power}'. + * + * + * @return the meta object for class 'VC Device Power'. + * @see org.openhab.binding.tinkerforge.internal.model.VCDevicePower + * @generated + */ + EClass getVCDevicePower(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDevicePower#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.VCDevicePower#getDeviceType() + * @see #getVCDevicePower() + * @generated + */ + EAttribute getVCDevicePower_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.VCDevicePower#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.VCDevicePower#getThreshold() + * @see #getVCDevicePower() + * @generated + */ + EAttribute getVCDevicePower_Threshold(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration TF Base Configuration}'. + * + * + * @return the meta object for class 'TF Base Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration + * @generated + */ + EClass getTFBaseConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration#getThreshold() + * @see #getTFBaseConfiguration() + * @generated + */ + EAttribute getTFBaseConfiguration_Threshold(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration#getCallbackPeriod Callback Period}'. + * + * + * @return the meta object for the attribute 'Callback Period'. + * @see org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration#getCallbackPeriod() + * @see #getTFBaseConfiguration() + * @generated + */ + EAttribute getTFBaseConfiguration_CallbackPeriod(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFObjectTemperatureConfiguration TF Object Temperature Configuration}'. + * + * + * @return the meta object for class 'TF Object Temperature Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFObjectTemperatureConfiguration + * @generated + */ + EClass getTFObjectTemperatureConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFObjectTemperatureConfiguration#getEmissivity Emissivity}'. + * + * + * @return the meta object for the attribute 'Emissivity'. + * @see org.openhab.binding.tinkerforge.internal.model.TFObjectTemperatureConfiguration#getEmissivity() + * @see #getTFObjectTemperatureConfiguration() + * @generated + */ + EAttribute getTFObjectTemperatureConfiguration_Emissivity(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFMoistureBrickletConfiguration TF Moisture Bricklet Configuration}'. + * + * + * @return the meta object for class 'TF Moisture Bricklet Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFMoistureBrickletConfiguration + * @generated + */ + EClass getTFMoistureBrickletConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFMoistureBrickletConfiguration#getMovingAverage Moving Average}'. + * + * + * @return the meta object for the attribute 'Moving Average'. + * @see org.openhab.binding.tinkerforge.internal.model.TFMoistureBrickletConfiguration#getMovingAverage() + * @see #getTFMoistureBrickletConfiguration() + * @generated + */ + EAttribute getTFMoistureBrickletConfiguration_MovingAverage(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFDistanceUSBrickletConfiguration TF Distance US Bricklet Configuration}'. + * + * + * @return the meta object for class 'TF Distance US Bricklet Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFDistanceUSBrickletConfiguration + * @generated + */ + EClass getTFDistanceUSBrickletConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFDistanceUSBrickletConfiguration#getMovingAverage Moving Average}'. + * + * + * @return the meta object for the attribute 'Moving Average'. + * @see org.openhab.binding.tinkerforge.internal.model.TFDistanceUSBrickletConfiguration#getMovingAverage() + * @see #getTFDistanceUSBrickletConfiguration() + * @generated + */ + EAttribute getTFDistanceUSBrickletConfiguration_MovingAverage(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration TF Voltage Current Configuration}'. + * + * + * @return the meta object for class 'TF Voltage Current Configuration'. + * @see org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration + * @generated + */ + EClass getTFVoltageCurrentConfiguration(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getAveraging Averaging}'. + * + * + * @return the meta object for the attribute 'Averaging'. + * @see org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getAveraging() + * @see #getTFVoltageCurrentConfiguration() + * @generated + */ + EAttribute getTFVoltageCurrentConfiguration_Averaging(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getVoltageConversionTime Voltage Conversion Time}'. + * + * + * @return the meta object for the attribute 'Voltage Conversion Time'. + * @see org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getVoltageConversionTime() + * @see #getTFVoltageCurrentConfiguration() + * @generated + */ + EAttribute getTFVoltageCurrentConfiguration_VoltageConversionTime(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getCurrentConversionTime Current Conversion Time}'. + * + * + * @return the meta object for the attribute 'Current Conversion Time'. + * @see org.openhab.binding.tinkerforge.internal.model.TFVoltageCurrentConfiguration#getCurrentConversionTime() + * @see #getTFVoltageCurrentConfiguration() + * @generated + */ + EAttribute getTFVoltageCurrentConfiguration_CurrentConversionTime(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer MBricklet Barometer}'. + * + * + * @return the meta object for class 'MBricklet Barometer'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer + * @generated + */ + EClass getMBrickletBarometer(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#getDeviceType() + * @see #getMBrickletBarometer() + * @generated + */ + EAttribute getMBrickletBarometer_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#getThreshold() + * @see #getMBrickletBarometer() + * @generated + */ + EAttribute getMBrickletBarometer_Threshold(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer#init() + * @generated + */ + EOperation getMBrickletBarometer__Init(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature MBarometer Temperature}'. + * + * + * @return the meta object for class 'MBarometer Temperature'. + * @see org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature + * @generated + */ + EClass getMBarometerTemperature(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature#getDeviceType() + * @see #getMBarometerTemperature() + * @generated + */ + EAttribute getMBarometerTemperature_DeviceType(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBarometerTemperature#init() + * @generated + */ + EOperation getMBarometerTemperature__Init(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight MBricklet Ambient Light}'. + * + * + * @return the meta object for class 'MBricklet Ambient Light'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight + * @generated + */ + EClass getMBrickletAmbientLight(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#getDeviceType() + * @see #getMBrickletAmbientLight() + * @generated + */ + EAttribute getMBrickletAmbientLight_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#getThreshold() + * @see #getMBrickletAmbientLight() + * @generated + */ + EAttribute getMBrickletAmbientLight_Threshold(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletAmbientLight#init() + * @generated + */ + EOperation getMBrickletAmbientLight__Init(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity MBricklet Sound Intensity}'. + * + * + * @return the meta object for class 'MBricklet Sound Intensity'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity + * @generated + */ + EClass getMBrickletSoundIntensity(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#getDeviceType() + * @see #getMBrickletSoundIntensity() + * @generated + */ + EAttribute getMBrickletSoundIntensity_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#getThreshold() + * @see #getMBrickletSoundIntensity() + * @generated + */ + EAttribute getMBrickletSoundIntensity_Threshold(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletSoundIntensity#init() + * @generated + */ + EOperation getMBrickletSoundIntensity__Init(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture MBricklet Moisture}'. + * + * + * @return the meta object for class 'MBricklet Moisture'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture + * @generated + */ + EClass getMBrickletMoisture(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getDeviceType() + * @see #getMBrickletMoisture() + * @generated + */ + EAttribute getMBrickletMoisture_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getThreshold() + * @see #getMBrickletMoisture() + * @generated + */ + EAttribute getMBrickletMoisture_Threshold(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getMovingAverage Moving Average}'. + * + * + * @return the meta object for the attribute 'Moving Average'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#getMovingAverage() + * @see #getMBrickletMoisture() + * @generated + */ + EAttribute getMBrickletMoisture_MovingAverage(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture#init() + * @generated + */ + EOperation getMBrickletMoisture__Init(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS MBricklet Distance US}'. + * + * + * @return the meta object for class 'MBricklet Distance US'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS + * @generated + */ + EClass getMBrickletDistanceUS(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getDeviceType() + * @see #getMBrickletDistanceUS() + * @generated + */ + EAttribute getMBrickletDistanceUS_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getThreshold Threshold}'. + * + * + * @return the meta object for the attribute 'Threshold'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getThreshold() + * @see #getMBrickletDistanceUS() + * @generated + */ + EAttribute getMBrickletDistanceUS_Threshold(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getMovingAverage Moving Average}'. + * + * + * @return the meta object for the attribute 'Moving Average'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#getMovingAverage() + * @see #getMBrickletDistanceUS() + * @generated + */ + EAttribute getMBrickletDistanceUS_MovingAverage(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS#init() + * @generated + */ + EOperation getMBrickletDistanceUS__Init(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4 MBricklet LCD2 0x4}'. + * + * + * @return the meta object for class 'MBricklet LCD2 0x4'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4 + * @generated + */ + EClass getMBrickletLCD20x4(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getDeviceType() + * @see #getMBrickletLCD20x4() + * @generated + */ + EAttribute getMBrickletLCD20x4_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getPositionPrefix Position Prefix}'. + * + * + * @return the meta object for the attribute 'Position Prefix'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getPositionPrefix() + * @see #getMBrickletLCD20x4() + * @generated + */ + EAttribute getMBrickletLCD20x4_PositionPrefix(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getPositonSuffix Positon Suffix}'. + * + * + * @return the meta object for the attribute 'Positon Suffix'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getPositonSuffix() + * @see #getMBrickletLCD20x4() + * @generated + */ + EAttribute getMBrickletLCD20x4_PositonSuffix(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#isDisplayErrors Display Errors}'. + * + * + * @return the meta object for the attribute 'Display Errors'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#isDisplayErrors() + * @see #getMBrickletLCD20x4() + * @generated + */ + EAttribute getMBrickletLCD20x4_DisplayErrors(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getErrorPrefix Error Prefix}'. + * + * + * @return the meta object for the attribute 'Error Prefix'. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#getErrorPrefix() + * @see #getMBrickletLCD20x4() + * @generated + */ + EAttribute getMBrickletLCD20x4_ErrorPrefix(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#init() Init}' operation. + * + * + * @return the meta object for the 'Init' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#init() + * @generated + */ + EOperation getMBrickletLCD20x4__Init(); + + /** + * Returns the meta object for the '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#clear() Clear}' operation. + * + * + * @return the meta object for the 'Clear' operation. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4#clear() + * @generated + */ + EOperation getMBrickletLCD20x4__Clear(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MTextActor MText Actor}'. + * + * + * @return the meta object for class 'MText Actor'. + * @see org.openhab.binding.tinkerforge.internal.model.MTextActor + * @generated + */ + EClass getMTextActor(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MTextActor#getText Text}'. + * + * + * @return the meta object for the attribute 'Text'. + * @see org.openhab.binding.tinkerforge.internal.model.MTextActor#getText() + * @see #getMTextActor() + * @generated + */ + EAttribute getMTextActor_Text(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MLCDSubDevice MLCD Sub Device}'. + * + * + * @return the meta object for class 'MLCD Sub Device'. + * @see org.openhab.binding.tinkerforge.internal.model.MLCDSubDevice + * @generated + */ + EClass getMLCDSubDevice(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MLCD20x4Backlight MLCD2 0x4 Backlight}'. + * + * + * @return the meta object for class 'MLCD2 0x4 Backlight'. + * @see org.openhab.binding.tinkerforge.internal.model.MLCD20x4Backlight + * @generated + */ + EClass getMLCD20x4Backlight(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MLCD20x4Backlight#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MLCD20x4Backlight#getDeviceType() + * @see #getMLCD20x4Backlight() + * @generated + */ + EAttribute getMLCD20x4Backlight_DeviceType(); + + /** + * Returns the meta object for class '{@link org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button MLCD2 0x4 Button}'. + * + * + * @return the meta object for class 'MLCD2 0x4 Button'. + * @see org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button + * @generated + */ + EClass getMLCD20x4Button(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button#getDeviceType Device Type}'. + * + * + * @return the meta object for the attribute 'Device Type'. + * @see org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button#getDeviceType() + * @see #getMLCD20x4Button() + * @generated + */ + EAttribute getMLCD20x4Button_DeviceType(); + + /** + * Returns the meta object for the attribute '{@link org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button#getButtonNum Button Num}'. + * + * + * @return the meta object for the attribute 'Button Num'. + * @see org.openhab.binding.tinkerforge.internal.model.MLCD20x4Button#getButtonNum() + * @see #getMLCD20x4Button() + * @generated + */ + EAttribute getMLCD20x4Button_ButtonNum(); + + /** + * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.types.OnOffValue Switch State}'. + * + * + * @return the meta object for data type 'Switch State'. + * @see org.openhab.binding.tinkerforge.internal.types.OnOffValue + * @model instanceClass="org.openhab.binding.tinkerforge.internal.types.OnOffValue" + * @generated + */ + EDataType getSwitchState(); + + /** + * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.types.HighLowValue Digital Value}'. + * + * + * @return the meta object for data type 'Digital Value'. + * @see org.openhab.binding.tinkerforge.internal.types.HighLowValue + * @model instanceClass="org.openhab.binding.tinkerforge.internal.types.HighLowValue" + * @generated + */ + EDataType getDigitalValue(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletIO16 Tinker Bricklet IO16}'. + * + * + * @return the meta object for data type 'Tinker Bricklet IO16'. + * @see com.tinkerforge.BrickletIO16 + * @model instanceClass="com.tinkerforge.BrickletIO16" + * @generated + */ + EDataType getTinkerBrickletIO16(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.DCDriveMode DC Drive Mode}'. + * + * + * @return the meta object for enum 'DC Drive Mode'. + * @see org.openhab.binding.tinkerforge.internal.model.DCDriveMode + * @generated + */ + EEnum getDCDriveMode(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsServo Config Opts Servo}'. + * + * + * @return the meta object for enum 'Config Opts Servo'. + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsServo + * @generated + */ + EEnum getConfigOptsServo(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.NoSubIds No Sub Ids}'. + * + * + * @return the meta object for enum 'No Sub Ids'. + * @see org.openhab.binding.tinkerforge.internal.model.NoSubIds + * @generated + */ + EEnum getNoSubIds(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.IndustrialDigitalInSubIDs Industrial Digital In Sub IDs}'. + * + * + * @return the meta object for enum 'Industrial Digital In Sub IDs'. + * @see org.openhab.binding.tinkerforge.internal.model.IndustrialDigitalInSubIDs + * @generated + */ + EEnum getIndustrialDigitalInSubIDs(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.IndustrialQuadRelayIDs Industrial Quad Relay IDs}'. + * + * + * @return the meta object for enum 'Industrial Quad Relay IDs'. + * @see org.openhab.binding.tinkerforge.internal.model.IndustrialQuadRelayIDs + * @generated + */ + EEnum getIndustrialQuadRelayIDs(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.ServoSubIDs Servo Sub IDs}'. + * + * + * @return the meta object for enum 'Servo Sub IDs'. + * @see org.openhab.binding.tinkerforge.internal.model.ServoSubIDs + * @generated + */ + EEnum getServoSubIDs(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.BarometerSubIDs Barometer Sub IDs}'. + * + * + * @return the meta object for enum 'Barometer Sub IDs'. + * @see org.openhab.binding.tinkerforge.internal.model.BarometerSubIDs + * @generated + */ + EEnum getBarometerSubIDs(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.IO16SubIds IO16 Sub Ids}'. + * + * + * @return the meta object for enum 'IO16 Sub Ids'. + * @see org.openhab.binding.tinkerforge.internal.model.IO16SubIds + * @generated + */ + EEnum getIO16SubIds(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.IO4SubIds IO4 Sub Ids}'. + * + * + * @return the meta object for enum 'IO4 Sub Ids'. + * @see org.openhab.binding.tinkerforge.internal.model.IO4SubIds + * @generated + */ + EEnum getIO4SubIds(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.DualRelaySubIds Dual Relay Sub Ids}'. + * + * + * @return the meta object for enum 'Dual Relay Sub Ids'. + * @see org.openhab.binding.tinkerforge.internal.model.DualRelaySubIds + * @generated + */ + EEnum getDualRelaySubIds(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.LCDButtonSubIds LCD Button Sub Ids}'. + * + * + * @return the meta object for enum 'LCD Button Sub Ids'. + * @see org.openhab.binding.tinkerforge.internal.model.LCDButtonSubIds + * @generated + */ + EEnum getLCDButtonSubIds(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.LCDBacklightSubIds LCD Backlight Sub Ids}'. + * + * + * @return the meta object for enum 'LCD Backlight Sub Ids'. + * @see org.openhab.binding.tinkerforge.internal.model.LCDBacklightSubIds + * @generated + */ + EEnum getLCDBacklightSubIds(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.MultiTouchSubIds Multi Touch Sub Ids}'. + * + * + * @return the meta object for enum 'Multi Touch Sub Ids'. + * @see org.openhab.binding.tinkerforge.internal.model.MultiTouchSubIds + * @generated + */ + EEnum getMultiTouchSubIds(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.TemperatureIRSubIds Temperature IR Sub Ids}'. + * + * + * @return the meta object for enum 'Temperature IR Sub Ids'. + * @see org.openhab.binding.tinkerforge.internal.model.TemperatureIRSubIds + * @generated + */ + EEnum getTemperatureIRSubIds(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.VoltageCurrentSubIds Voltage Current Sub Ids}'. + * + * + * @return the meta object for enum 'Voltage Current Sub Ids'. + * @see org.openhab.binding.tinkerforge.internal.model.VoltageCurrentSubIds + * @generated + */ + EEnum getVoltageCurrentSubIds(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsMove Config Opts Move}'. + * + * + * @return the meta object for enum 'Config Opts Move'. + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsMove + * @generated + */ + EEnum getConfigOptsMove(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsDimmable Config Opts Dimmable}'. + * + * + * @return the meta object for enum 'Config Opts Dimmable'. + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsDimmable + * @generated + */ + EEnum getConfigOptsDimmable(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsSetPoint Config Opts Set Point}'. + * + * + * @return the meta object for enum 'Config Opts Set Point'. + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsSetPoint + * @generated + */ + EEnum getConfigOptsSetPoint(); + + /** + * Returns the meta object for enum '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsSwitchSpeed Config Opts Switch Speed}'. + * + * + * @return the meta object for enum 'Config Opts Switch Speed'. + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsSwitchSpeed + * @generated + */ + EEnum getConfigOptsSwitchSpeed(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.IPConnection MIP Connection}'. + * + * + * @return the meta object for data type 'MIP Connection'. + * @see com.tinkerforge.IPConnection + * @model instanceClass="com.tinkerforge.IPConnection" + * @generated + */ + EDataType getMIPConnection(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.Device MTinker Device}'. + * + * + * @return the meta object for data type 'MTinker Device'. + * @see com.tinkerforge.Device + * @model instanceClass="com.tinkerforge.Device" + * @generated + */ + EDataType getMTinkerDevice(); + + /** + * Returns the meta object for data type '{@link org.slf4j.Logger MLogger}'. + * + * + * @return the meta object for data type 'MLogger'. + * @see org.slf4j.Logger + * @model instanceClass="org.slf4j.Logger" + * @generated + */ + EDataType getMLogger(); + + /** + * Returns the meta object for data type '{@link java.util.concurrent.atomic.AtomicBoolean MAtomic Boolean}'. + * + * + * @return the meta object for data type 'MAtomic Boolean'. + * @see java.util.concurrent.atomic.AtomicBoolean + * @model instanceClass="java.util.concurrent.atomic.AtomicBoolean" + * @generated + */ + EDataType getMAtomicBoolean(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.Device MTinkerforge Device}'. + * + * + * @return the meta object for data type 'MTinkerforge Device'. + * @see com.tinkerforge.Device + * @model instanceClass="com.tinkerforge.Device" + * @generated + */ + EDataType getMTinkerforgeDevice(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickDC MTinker Brick DC}'. + * + * + * @return the meta object for data type 'MTinker Brick DC'. + * @see com.tinkerforge.BrickDC + * @model instanceClass="com.tinkerforge.BrickDC" + * @generated + */ + EDataType getMTinkerBrickDC(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickServo MTinker Brick Servo}'. + * + * + * @return the meta object for data type 'MTinker Brick Servo'. + * @see com.tinkerforge.BrickServo + * @model instanceClass="com.tinkerforge.BrickServo" + * @generated + */ + EDataType getMTinkerBrickServo(); + + /** + * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue MTinkerforge Value}'. + * + * + * @return the meta object for data type 'MTinkerforge Value'. + * @see org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue + * @model instanceClass="org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue" + * @generated + */ + EDataType getMTinkerforgeValue(); + + /** + * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.types.DecimalValue MDecimal Value}'. + * + * + * @return the meta object for data type 'MDecimal Value'. + * @see org.openhab.binding.tinkerforge.internal.types.DecimalValue + * @model instanceClass="org.openhab.binding.tinkerforge.internal.types.DecimalValue" + * @generated + */ + EDataType getMDecimalValue(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletHumidity MTinker Bricklet Humidity}'. + * + * + * @return the meta object for data type 'MTinker Bricklet Humidity'. + * @see com.tinkerforge.BrickletHumidity + * @model instanceClass="com.tinkerforge.BrickletHumidity" + * @generated + */ + EDataType getMTinkerBrickletHumidity(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletDistanceIR MTinker Bricklet Distance IR}'. + * + * + * @return the meta object for data type 'MTinker Bricklet Distance IR'. + * @see com.tinkerforge.BrickletDistanceIR + * @model instanceClass="com.tinkerforge.BrickletDistanceIR" + * @generated + */ + EDataType getMTinkerBrickletDistanceIR(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletTemperature MTinker Bricklet Temperature}'. + * + * + * @return the meta object for data type 'MTinker Bricklet Temperature'. + * @see com.tinkerforge.BrickletTemperature + * @model instanceClass="com.tinkerforge.BrickletTemperature" + * @generated + */ + EDataType getMTinkerBrickletTemperature(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletBarometer MTinker Bricklet Barometer}'. + * + * + * @return the meta object for data type 'MTinker Bricklet Barometer'. + * @see com.tinkerforge.BrickletBarometer + * @model instanceClass="com.tinkerforge.BrickletBarometer" + * @generated + */ + EDataType getMTinkerBrickletBarometer(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletAmbientLight MTinker Bricklet Ambient Light}'. + * + * + * @return the meta object for data type 'MTinker Bricklet Ambient Light'. + * @see com.tinkerforge.BrickletAmbientLight + * @model instanceClass="com.tinkerforge.BrickletAmbientLight" + * @generated + */ + EDataType getMTinkerBrickletAmbientLight(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletLCD20x4 MTinker Bricklet LCD2 0x4}'. + * + * + * @return the meta object for data type 'MTinker Bricklet LCD2 0x4'. + * @see com.tinkerforge.BrickletLCD20x4 + * @model instanceClass="com.tinkerforge.BrickletLCD20x4" + * @generated + */ + EDataType getMTinkerBrickletLCD20x4(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletRemoteSwitch Tinker Bricklet Remote Switch}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Remote Switch'. + * @see com.tinkerforge.BrickletRemoteSwitch + * @model instanceClass="com.tinkerforge.BrickletRemoteSwitch" + * @generated + */ + EDataType getTinkerBrickletRemoteSwitch(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletMotionDetector Tinker Bricklet Motion Detector}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Motion Detector'. + * @see com.tinkerforge.BrickletMotionDetector + * @model instanceClass="com.tinkerforge.BrickletMotionDetector" + * @generated + */ + EDataType getTinkerBrickletMotionDetector(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletMultiTouch Tinker Bricklet Multi Touch}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Multi Touch'. + * @see com.tinkerforge.BrickletMultiTouch + * @model instanceClass="com.tinkerforge.BrickletMultiTouch" + * @generated + */ + EDataType getTinkerBrickletMultiTouch(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletTemperatureIR Tinker Bricklet Temperature IR}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Temperature IR'. + * @see com.tinkerforge.BrickletTemperatureIR + * @model instanceClass="com.tinkerforge.BrickletTemperatureIR" + * @generated + */ + EDataType getTinkerBrickletTemperatureIR(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletSoundIntensity Tinker Bricklet Sound Intensity}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Sound Intensity'. + * @see com.tinkerforge.BrickletSoundIntensity + * @model instanceClass="com.tinkerforge.BrickletSoundIntensity" + * @generated + */ + EDataType getTinkerBrickletSoundIntensity(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletMoisture Tinker Bricklet Moisture}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Moisture'. + * @see com.tinkerforge.BrickletMoisture + * @model instanceClass="com.tinkerforge.BrickletMoisture" + * @generated + */ + EDataType getTinkerBrickletMoisture(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletDistanceUS Tinker Bricklet Distance US}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Distance US'. + * @see com.tinkerforge.BrickletDistanceUS + * @model instanceClass="com.tinkerforge.BrickletDistanceUS" + * @generated + */ + EDataType getTinkerBrickletDistanceUS(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletVoltageCurrent Tinker Bricklet Voltage Current}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Voltage Current'. + * @see com.tinkerforge.BrickletVoltageCurrent + * @model instanceClass="com.tinkerforge.BrickletVoltageCurrent" + * @generated + */ + EDataType getTinkerBrickletVoltageCurrent(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletTilt Tinker Bricklet Tilt}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Tilt'. + * @see com.tinkerforge.BrickletTilt + * @model instanceClass="com.tinkerforge.BrickletTilt" + * @generated + */ + EDataType getTinkerBrickletTilt(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletIO4 Tinker Bricklet IO4}'. + * + * + * @return the meta object for data type 'Tinker Bricklet IO4'. + * @see com.tinkerforge.BrickletIO4 + * @model instanceClass="com.tinkerforge.BrickletIO4" + * @generated + */ + EDataType getTinkerBrickletIO4(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletHallEffect Tinker Bricklet Hall Effect}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Hall Effect'. + * @see com.tinkerforge.BrickletHallEffect + * @model instanceClass="com.tinkerforge.BrickletHallEffect" + * @generated + */ + EDataType getTinkerBrickletHallEffect(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletSegmentDisplay4x7 Tinker Bricklet Segment Display4x7}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Segment Display4x7'. + * @see com.tinkerforge.BrickletSegmentDisplay4x7 + * @model instanceClass="com.tinkerforge.BrickletSegmentDisplay4x7" + * @generated + */ + EDataType getTinkerBrickletSegmentDisplay4x7(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletLEDStrip Tinker Bricklet LED Strip}'. + * + * + * @return the meta object for data type 'Tinker Bricklet LED Strip'. + * @see com.tinkerforge.BrickletLEDStrip + * @model instanceClass="com.tinkerforge.BrickletLEDStrip" + * @generated + */ + EDataType getTinkerBrickletLEDStrip(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletJoystick Bricklet Joystick}'. + * + * + * @return the meta object for data type 'Bricklet Joystick'. + * @see com.tinkerforge.BrickletJoystick + * @model instanceClass="com.tinkerforge.BrickletJoystick" + * @generated + */ + EDataType getBrickletJoystick(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletLinearPoti Tinker Bricklet Linear Poti}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Linear Poti'. + * @see com.tinkerforge.BrickletLinearPoti + * @model instanceClass="com.tinkerforge.BrickletLinearPoti" + * @generated + */ + EDataType getTinkerBrickletLinearPoti(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletDualButton Tinker Bricklet Dual Button}'. + * + * + * @return the meta object for data type 'Tinker Bricklet Dual Button'. + * @see com.tinkerforge.BrickletDualButton + * @model instanceClass="com.tinkerforge.BrickletDualButton" + * @generated + */ + EDataType getTinkerBrickletDualButton(); + + /** + * Returns the meta object for data type '{@link org.openhab.core.library.types.HSBType HSB Type}'. + * + * + * @return the meta object for data type 'HSB Type'. + * @see org.openhab.core.library.types.HSBType + * @model instanceClass="org.openhab.core.library.types.HSBType" + * @generated + */ + EDataType getHSBType(); + + /** + * Returns the meta object for data type '{@link org.openhab.core.library.types.UpDownType Up Down Type}'. + * + * + * @return the meta object for data type 'Up Down Type'. + * @see org.openhab.core.library.types.UpDownType + * @model instanceClass="org.openhab.core.library.types.UpDownType" + * @generated + */ + EDataType getUpDownType(); + + /** + * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.types.PercentValue Percent Value}'. + * + * + * @return the meta object for data type 'Percent Value'. + * @see org.openhab.binding.tinkerforge.internal.types.PercentValue + * @model instanceClass="org.openhab.binding.tinkerforge.internal.types.PercentValue" + * @generated + */ + EDataType getPercentValue(); + + /** + * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.config.DeviceOptions Device Options}'. + * + * + * @return the meta object for data type 'Device Options'. + * @see org.openhab.binding.tinkerforge.internal.config.DeviceOptions + * @model instanceClass="org.openhab.binding.tinkerforge.internal.config.DeviceOptions" + * @generated + */ + EDataType getDeviceOptions(); + + /** + * Returns the meta object for data type '{@link org.openhab.core.library.types.PercentType Percent Type}'. + * + * + * @return the meta object for data type 'Percent Type'. + * @see org.openhab.core.library.types.PercentType + * @model instanceClass="org.openhab.core.library.types.PercentType" + * @generated + */ + EDataType getPercentType(); + + /** + * Returns the meta object for data type '{@link org.openhab.core.library.types.IncreaseDecreaseType Increase Decrease Type}'. + * + * + * @return the meta object for data type 'Increase Decrease Type'. + * @see org.openhab.core.library.types.IncreaseDecreaseType + * @model instanceClass="org.openhab.core.library.types.IncreaseDecreaseType" + * @generated + */ + EDataType getIncreaseDecreaseType(); + + /** + * Returns the meta object for data type '{@link org.openhab.binding.tinkerforge.internal.types.DirectionValue Direction Value}'. + * + * + * @return the meta object for data type 'Direction Value'. + * @see org.openhab.binding.tinkerforge.internal.types.DirectionValue + * @model instanceClass="org.openhab.binding.tinkerforge.internal.types.DirectionValue" + * @generated + */ + EDataType getDirectionValue(); + + /** + * Returns the meta object for data type '{@link java.lang.Enum Enum}'. + * + * + * @return the meta object for data type 'Enum'. + * @see java.lang.Enum + * @model instanceClass="java.lang.Enum" + * @generated + */ + EDataType getEnum(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletDualRelay MTinker Bricklet Dual Relay}'. + * + * + * @return the meta object for data type 'MTinker Bricklet Dual Relay'. + * @see com.tinkerforge.BrickletDualRelay + * @model instanceClass="com.tinkerforge.BrickletDualRelay" + * @generated + */ + EDataType getMTinkerBrickletDualRelay(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletIndustrialQuadRelay MTinker Bricklet Industrial Quad Relay}'. + * + * + * @return the meta object for data type 'MTinker Bricklet Industrial Quad Relay'. + * @see com.tinkerforge.BrickletIndustrialQuadRelay + * @model instanceClass="com.tinkerforge.BrickletIndustrialQuadRelay" + * @generated + */ + EDataType getMTinkerBrickletIndustrialQuadRelay(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletIndustrialDigitalIn4 MTinker Bricklet Industrial Digital In4}'. + * + * + * @return the meta object for data type 'MTinker Bricklet Industrial Digital In4'. + * @see com.tinkerforge.BrickletIndustrialDigitalIn4 + * @model instanceClass="com.tinkerforge.BrickletIndustrialDigitalIn4" + * @generated + */ + EDataType getMTinkerBrickletIndustrialDigitalIn4(); + + /** + * Returns the meta object for data type '{@link com.tinkerforge.BrickletIndustrialDigitalOut4 MTinker Bricklet Industrial Digital Out4}'. + * + * + * @return the meta object for data type 'MTinker Bricklet Industrial Digital Out4'. + * @see com.tinkerforge.BrickletIndustrialDigitalOut4 + * @model instanceClass="com.tinkerforge.BrickletIndustrialDigitalOut4" + * @generated + */ + EDataType getMTinkerBrickletIndustrialDigitalOut4(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + ModelFactory getModelFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
        + *
      • each class,
      • + *
      • each feature of each class,
      • + *
      • each operation of each class,
      • + *
      • each enum,
      • + *
      • and each data type
      • + *
      + * + * @generated + */ + interface Literals + { + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.TFConfig TF Config}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.TFConfig + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFConfig() + * @generated + */ + EClass TF_CONFIG = eINSTANCE.getTFConfig(); + + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.OHTFDeviceImpl OHTF Device}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.impl.OHTFDeviceImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getOHTFDevice() + * @generated + */ + EClass OHTF_DEVICE = eINSTANCE.getOHTFDevice(); + + /** + * The meta object literal for the 'Uid' attribute feature. + * + * + * @generated + */ + EAttribute OHTF_DEVICE__UID = eINSTANCE.getOHTFDevice_Uid(); + + /** + * The meta object literal for the 'Subid' attribute feature. + * + * + * @generated + */ + EAttribute OHTF_DEVICE__SUBID = eINSTANCE.getOHTFDevice_Subid(); + + /** + * The meta object literal for the 'Ohid' attribute feature. + * + * + * @generated + */ + EAttribute OHTF_DEVICE__OHID = eINSTANCE.getOHTFDevice_Ohid(); + + /** + * The meta object literal for the 'Sub Device Ids' attribute list feature. + * + * + * @generated + */ + EAttribute OHTF_DEVICE__SUB_DEVICE_IDS = eINSTANCE.getOHTFDevice_SubDeviceIds(); + + /** + * The meta object literal for the 'Tf Config' containment reference feature. + * + * + * @generated + */ + EReference OHTF_DEVICE__TF_CONFIG = eINSTANCE.getOHTFDevice_TfConfig(); + + /** + * The meta object literal for the 'Oh Config' container reference feature. + * + * + * @generated + */ + EReference OHTF_DEVICE__OH_CONFIG = eINSTANCE.getOHTFDevice_OhConfig(); + + /** + * The meta object literal for the 'Is Valid Sub Id' operation. + * + * + * @generated + */ + EOperation OHTF_DEVICE___IS_VALID_SUB_ID__STRING = eINSTANCE.getOHTFDevice__IsValidSubId__String(); + + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.OHTFSubDeviceAdminDeviceImpl OHTF Sub Device Admin Device}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.impl.OHTFSubDeviceAdminDeviceImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getOHTFSubDeviceAdminDevice() + * @generated + */ + EClass OHTF_SUB_DEVICE_ADMIN_DEVICE = eINSTANCE.getOHTFSubDeviceAdminDevice(); + + /** + * The meta object literal for the 'Is Valid Sub Id' operation. + * + * + * @generated + */ + EOperation OHTF_SUB_DEVICE_ADMIN_DEVICE___IS_VALID_SUB_ID__STRING = eINSTANCE.getOHTFSubDeviceAdminDevice__IsValidSubId__String(); + + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.OHConfigImpl OH Config}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.impl.OHConfigImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getOHConfig() + * @generated + */ + EClass OH_CONFIG = eINSTANCE.getOHConfig(); + + /** + * The meta object literal for the 'Oh Tf Devices' containment reference list feature. + * + * + * @generated + */ + EReference OH_CONFIG__OH_TF_DEVICES = eINSTANCE.getOHConfig_OhTfDevices(); + + /** + * The meta object literal for the 'Get Config By TF Id' operation. + * + * + * @generated + */ + EOperation OH_CONFIG___GET_CONFIG_BY_TF_ID__STRING_STRING = eINSTANCE.getOHConfig__GetConfigByTFId__String_String(); + + /** + * The meta object literal for the 'Get Config By OH Id' operation. + * + * + * @generated + */ + EOperation OH_CONFIG___GET_CONFIG_BY_OH_ID__STRING = eINSTANCE.getOHConfig__GetConfigByOHId__String(); + + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.EcosystemImpl Ecosystem}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.impl.EcosystemImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getEcosystem() + * @generated + */ + EClass ECOSYSTEM = eINSTANCE.getEcosystem(); + + /** + * The meta object literal for the 'Logger' attribute feature. + * + * + * @generated + */ + EAttribute ECOSYSTEM__LOGGER = eINSTANCE.getEcosystem_Logger(); + + /** + * The meta object literal for the 'Mbrickds' containment reference list feature. + * + * + * @generated + */ + EReference ECOSYSTEM__MBRICKDS = eINSTANCE.getEcosystem_Mbrickds(); + + /** + * The meta object literal for the 'Get Brickd' operation. + * + * + * @generated + */ + EOperation ECOSYSTEM___GET_BRICKD__STRING_INT = eINSTANCE.getEcosystem__GetBrickd__String_int(); + + /** + * The meta object literal for the 'Get Device' operation. + * + * + * @generated + */ + EOperation ECOSYSTEM___GET_DEVICE__STRING_STRING = eINSTANCE.getEcosystem__GetDevice__String_String(); + + /** + * The meta object literal for the 'Get Devices4 Generic Id' operation. + * + * + * @generated + */ + EOperation ECOSYSTEM___GET_DEVICES4_GENERIC_ID__STRING_STRING = eINSTANCE.getEcosystem__GetDevices4GenericId__String_String(); + + /** + * The meta object literal for the 'Disconnect' operation. + * + * + * @generated + */ + EOperation ECOSYSTEM___DISCONNECT = eINSTANCE.getEcosystem__Disconnect(); + + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickdImpl MBrickd}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickdImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickd() + * @generated + */ + EClass MBRICKD = eINSTANCE.getMBrickd(); + + /** + * The meta object literal for the 'Logger' attribute feature. + * + * + * @generated + */ + EAttribute MBRICKD__LOGGER = eINSTANCE.getMBrickd_Logger(); + + /** + * The meta object literal for the 'Ip Connection' attribute feature. + * + * + * @generated + */ + EAttribute MBRICKD__IP_CONNECTION = eINSTANCE.getMBrickd_IpConnection(); + + /** + * The meta object literal for the 'Host' attribute feature. + * + * + * @generated + */ + EAttribute MBRICKD__HOST = eINSTANCE.getMBrickd_Host(); + + /** + * The meta object literal for the 'Port' attribute feature. + * + * + * @generated + */ + EAttribute MBRICKD__PORT = eINSTANCE.getMBrickd_Port(); + + /** + * The meta object literal for the 'Is Connected' attribute feature. + * + * + * @generated + */ + EAttribute MBRICKD__IS_CONNECTED = eINSTANCE.getMBrickd_IsConnected(); + + /** + * The meta object literal for the 'Auto Reconnect' attribute feature. + * + * + * @generated + */ + EAttribute MBRICKD__AUTO_RECONNECT = eINSTANCE.getMBrickd_AutoReconnect(); + + /** + * The meta object literal for the 'Reconnected' attribute feature. + * + * + * @generated + */ + EAttribute MBRICKD__RECONNECTED = eINSTANCE.getMBrickd_Reconnected(); + + /** + * The meta object literal for the 'Timeout' attribute feature. + * + * + * @generated + */ + EAttribute MBRICKD__TIMEOUT = eINSTANCE.getMBrickd_Timeout(); + + /** + * The meta object literal for the 'Mdevices' containment reference list feature. + * + * + * @generated + */ + EReference MBRICKD__MDEVICES = eINSTANCE.getMBrickd_Mdevices(); + + /** + * The meta object literal for the 'Ecosystem' container reference feature. + * + * + * @generated + */ + EReference MBRICKD__ECOSYSTEM = eINSTANCE.getMBrickd_Ecosystem(); + + /** + * The meta object literal for the 'Connect' operation. + * + * + * @generated + */ + EOperation MBRICKD___CONNECT = eINSTANCE.getMBrickd__Connect(); + + /** + * The meta object literal for the 'Disconnect' operation. + * + * + * @generated + */ + EOperation MBRICKD___DISCONNECT = eINSTANCE.getMBrickd__Disconnect(); + + /** + * The meta object literal for the 'Init' operation. + * + * + * @generated + */ + EOperation MBRICKD___INIT = eINSTANCE.getMBrickd__Init(); + + /** + * The meta object literal for the 'Get Device' operation. + * + * + * @generated + */ + EOperation MBRICKD___GET_DEVICE__STRING = eINSTANCE.getMBrickd__GetDevice__String(); + + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin Sub Device Admin}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getSubDeviceAdmin() + * @generated + */ + EClass SUB_DEVICE_ADMIN = eINSTANCE.getSubDeviceAdmin(); + + /** + * The meta object literal for the 'Add Sub Device' operation. + * + * + * @generated + */ + EOperation SUB_DEVICE_ADMIN___ADD_SUB_DEVICE__STRING_STRING = eINSTANCE.getSubDeviceAdmin__AddSubDevice__String_String(); + + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer MTF Config Consumer}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTFConfigConsumer() + * @generated + */ + EClass MTF_CONFIG_CONSUMER = eINSTANCE.getMTFConfigConsumer(); + + /** + * The meta object literal for the 'Tf Config' containment reference feature. + * + * + * @generated + */ + EReference MTF_CONFIG_CONSUMER__TF_CONFIG = eINSTANCE.getMTFConfigConsumer_TfConfig(); + + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice MBase Device}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBaseDevice() * @generated */ - EOperation OHTF_DEVICE___IS_VALID_SUB_ID__STRING = eINSTANCE.getOHTFDevice__IsValidSubId__String(); + EClass MBASE_DEVICE = eINSTANCE.getMBaseDevice(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.OHTFSubDeviceAdminDeviceImpl OHTF Sub Device Admin Device}' class. + * The meta object literal for the 'Logger' attribute feature. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.OHTFSubDeviceAdminDeviceImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getOHTFSubDeviceAdminDevice() * @generated */ - EClass OHTF_SUB_DEVICE_ADMIN_DEVICE = eINSTANCE.getOHTFSubDeviceAdminDevice(); + EAttribute MBASE_DEVICE__LOGGER = eINSTANCE.getMBaseDevice_Logger(); /** - * The meta object literal for the 'Is Valid Sub Id' operation. + * The meta object literal for the 'Uid' attribute feature. * * * @generated */ - EOperation OHTF_SUB_DEVICE_ADMIN_DEVICE___IS_VALID_SUB_ID__STRING = eINSTANCE.getOHTFSubDeviceAdminDevice__IsValidSubId__String(); + EAttribute MBASE_DEVICE__UID = eINSTANCE.getMBaseDevice_Uid(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.OHConfigImpl OH Config}' class. + * The meta object literal for the 'Poll' attribute feature. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.OHConfigImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getOHConfig() * @generated */ - EClass OH_CONFIG = eINSTANCE.getOHConfig(); + EAttribute MBASE_DEVICE__POLL = eINSTANCE.getMBaseDevice_Poll(); /** - * The meta object literal for the 'Oh Tf Devices' containment reference list feature. + * The meta object literal for the 'Enabled A' attribute feature. * * * @generated */ - EReference OH_CONFIG__OH_TF_DEVICES = eINSTANCE.getOHConfig_OhTfDevices(); + EAttribute MBASE_DEVICE__ENABLED_A = eINSTANCE.getMBaseDevice_EnabledA(); /** - * The meta object literal for the 'Get Config By TF Id' operation. + * The meta object literal for the 'Init' operation. * * * @generated */ - EOperation OH_CONFIG___GET_CONFIG_BY_TF_ID__STRING_STRING = eINSTANCE.getOHConfig__GetConfigByTFId__String_String(); + EOperation MBASE_DEVICE___INIT = eINSTANCE.getMBaseDevice__Init(); /** - * The meta object literal for the 'Get Config By OH Id' operation. + * The meta object literal for the 'Enable' operation. * * * @generated */ - EOperation OH_CONFIG___GET_CONFIG_BY_OH_ID__STRING = eINSTANCE.getOHConfig__GetConfigByOHId__String(); + EOperation MBASE_DEVICE___ENABLE = eINSTANCE.getMBaseDevice__Enable(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.EcosystemImpl Ecosystem}' class. + * The meta object literal for the 'Disable' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.EcosystemImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getEcosystem() * @generated */ - EClass ECOSYSTEM = eINSTANCE.getEcosystem(); + EOperation MBASE_DEVICE___DISABLE = eINSTANCE.getMBaseDevice__Disable(); /** - * The meta object literal for the 'Logger' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MDevice MDevice}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.MDevice + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMDevice() * @generated */ - EAttribute ECOSYSTEM__LOGGER = eINSTANCE.getEcosystem_Logger(); + EClass MDEVICE = eINSTANCE.getMDevice(); /** - * The meta object literal for the 'Mbrickds' containment reference list feature. + * The meta object literal for the 'Tinkerforge Device' attribute feature. * * * @generated */ - EReference ECOSYSTEM__MBRICKDS = eINSTANCE.getEcosystem_Mbrickds(); + EAttribute MDEVICE__TINKERFORGE_DEVICE = eINSTANCE.getMDevice_TinkerforgeDevice(); /** - * The meta object literal for the 'Get Brickd' operation. + * The meta object literal for the 'Ip Connection' attribute feature. * * * @generated */ - EOperation ECOSYSTEM___GET_BRICKD__STRING_INT = eINSTANCE.getEcosystem__GetBrickd__String_int(); + EAttribute MDEVICE__IP_CONNECTION = eINSTANCE.getMDevice_IpConnection(); /** - * The meta object literal for the 'Get Device' operation. + * The meta object literal for the 'Connected Uid' attribute feature. * * * @generated */ - EOperation ECOSYSTEM___GET_DEVICE__STRING_STRING = eINSTANCE.getEcosystem__GetDevice__String_String(); + EAttribute MDEVICE__CONNECTED_UID = eINSTANCE.getMDevice_ConnectedUid(); /** - * The meta object literal for the 'Get Devices4 Generic Id' operation. + * The meta object literal for the 'Position' attribute feature. * * * @generated */ - EOperation ECOSYSTEM___GET_DEVICES4_GENERIC_ID__STRING_STRING = eINSTANCE.getEcosystem__GetDevices4GenericId__String_String(); + EAttribute MDEVICE__POSITION = eINSTANCE.getMDevice_Position(); /** - * The meta object literal for the 'Disconnect' operation. + * The meta object literal for the 'Device Identifier' attribute feature. * * * @generated */ - EOperation ECOSYSTEM___DISCONNECT = eINSTANCE.getEcosystem__Disconnect(); + EAttribute MDEVICE__DEVICE_IDENTIFIER = eINSTANCE.getMDevice_DeviceIdentifier(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickdImpl MBrickd}' class. + * The meta object literal for the 'Name' attribute feature. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickdImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickd() * @generated */ - EClass MBRICKD = eINSTANCE.getMBrickd(); + EAttribute MDEVICE__NAME = eINSTANCE.getMDevice_Name(); /** - * The meta object literal for the 'Logger' attribute feature. + * The meta object literal for the 'Brickd' container reference feature. * * * @generated */ - EAttribute MBRICKD__LOGGER = eINSTANCE.getMBrickd_Logger(); + EReference MDEVICE__BRICKD = eINSTANCE.getMDevice_Brickd(); /** - * The meta object literal for the 'Ip Connection' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder MSub Device Holder}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMSubDeviceHolder() * @generated */ - EAttribute MBRICKD__IP_CONNECTION = eINSTANCE.getMBrickd_IpConnection(); + EClass MSUB_DEVICE_HOLDER = eINSTANCE.getMSubDeviceHolder(); /** - * The meta object literal for the 'Host' attribute feature. + * The meta object literal for the 'Msubdevices' containment reference list feature. * * * @generated */ - EAttribute MBRICKD__HOST = eINSTANCE.getMBrickd_Host(); + EReference MSUB_DEVICE_HOLDER__MSUBDEVICES = eINSTANCE.getMSubDeviceHolder_Msubdevices(); /** - * The meta object literal for the 'Port' attribute feature. + * The meta object literal for the 'Init Sub Devices' operation. * * * @generated */ - EAttribute MBRICKD__PORT = eINSTANCE.getMBrickd_Port(); + EOperation MSUB_DEVICE_HOLDER___INIT_SUB_DEVICES = eINSTANCE.getMSubDeviceHolder__InitSubDevices(); /** - * The meta object literal for the 'Is Connected' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickServoImpl MBrick Servo}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickServoImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickServo() * @generated */ - EAttribute MBRICKD__IS_CONNECTED = eINSTANCE.getMBrickd_IsConnected(); + EClass MBRICK_SERVO = eINSTANCE.getMBrickServo(); /** - * The meta object literal for the 'Auto Reconnect' attribute feature. + * The meta object literal for the 'Device Type' attribute feature. * * * @generated */ - EAttribute MBRICKD__AUTO_RECONNECT = eINSTANCE.getMBrickd_AutoReconnect(); + EAttribute MBRICK_SERVO__DEVICE_TYPE = eINSTANCE.getMBrickServo_DeviceType(); /** - * The meta object literal for the 'Reconnected' attribute feature. + * The meta object literal for the 'Init' operation. * * * @generated */ - EAttribute MBRICKD__RECONNECTED = eINSTANCE.getMBrickd_Reconnected(); + EOperation MBRICK_SERVO___INIT = eINSTANCE.getMBrickServo__Init(); /** - * The meta object literal for the 'Timeout' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl TF Brick DC Configuration}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFBrickDCConfiguration() * @generated */ - EAttribute MBRICKD__TIMEOUT = eINSTANCE.getMBrickd_Timeout(); + EClass TF_BRICK_DC_CONFIGURATION = eINSTANCE.getTFBrickDCConfiguration(); /** - * The meta object literal for the 'Mdevices' containment reference list feature. + * The meta object literal for the 'Velocity' attribute feature. * * * @generated */ - EReference MBRICKD__MDEVICES = eINSTANCE.getMBrickd_Mdevices(); + EAttribute TF_BRICK_DC_CONFIGURATION__VELOCITY = eINSTANCE.getTFBrickDCConfiguration_Velocity(); /** - * The meta object literal for the 'Ecosystem' container reference feature. + * The meta object literal for the 'Acceleration' attribute feature. * * * @generated */ - EReference MBRICKD__ECOSYSTEM = eINSTANCE.getMBrickd_Ecosystem(); + EAttribute TF_BRICK_DC_CONFIGURATION__ACCELERATION = eINSTANCE.getTFBrickDCConfiguration_Acceleration(); /** - * The meta object literal for the 'Connect' operation. + * The meta object literal for the 'Pwm Frequency' attribute feature. * * * @generated */ - EOperation MBRICKD___CONNECT = eINSTANCE.getMBrickd__Connect(); + EAttribute TF_BRICK_DC_CONFIGURATION__PWM_FREQUENCY = eINSTANCE.getTFBrickDCConfiguration_PwmFrequency(); /** - * The meta object literal for the 'Disconnect' operation. + * The meta object literal for the 'Drive Mode' attribute feature. * * * @generated */ - EOperation MBRICKD___DISCONNECT = eINSTANCE.getMBrickd__Disconnect(); + EAttribute TF_BRICK_DC_CONFIGURATION__DRIVE_MODE = eINSTANCE.getTFBrickDCConfiguration_DriveMode(); /** - * The meta object literal for the 'Init' operation. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl MBrick DC}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickDC() * @generated */ - EOperation MBRICKD___INIT = eINSTANCE.getMBrickd__Init(); + EClass MBRICK_DC = eINSTANCE.getMBrickDC(); /** - * The meta object literal for the 'Get Device' operation. + * The meta object literal for the 'Threshold' attribute feature. * * * @generated */ - EOperation MBRICKD___GET_DEVICE__STRING = eINSTANCE.getMBrickd__GetDevice__String(); + EAttribute MBRICK_DC__THRESHOLD = eINSTANCE.getMBrickDC_Threshold(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin Sub Device Admin}' class. + * The meta object literal for the 'Max Velocity' attribute feature. * * - * @see org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getSubDeviceAdmin() * @generated */ - EClass SUB_DEVICE_ADMIN = eINSTANCE.getSubDeviceAdmin(); + EAttribute MBRICK_DC__MAX_VELOCITY = eINSTANCE.getMBrickDC_MaxVelocity(); /** - * The meta object literal for the 'Add Sub Device' operation. + * The meta object literal for the 'Min Velocity' attribute feature. * * * @generated */ - EOperation SUB_DEVICE_ADMIN___ADD_SUB_DEVICE__STRING_STRING = eINSTANCE.getSubDeviceAdmin__AddSubDevice__String_String(); + EAttribute MBRICK_DC__MIN_VELOCITY = eINSTANCE.getMBrickDC_MinVelocity(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer MTF Config Consumer}' class. + * The meta object literal for the 'Device Type' attribute feature. * * - * @see org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMTFConfigConsumer() * @generated */ - EClass MTF_CONFIG_CONSUMER = eINSTANCE.getMTFConfigConsumer(); + EAttribute MBRICK_DC__DEVICE_TYPE = eINSTANCE.getMBrickDC_DeviceType(); /** - * The meta object literal for the 'Tf Config' containment reference feature. + * The meta object literal for the 'Velocity' attribute feature. * * * @generated */ - EReference MTF_CONFIG_CONSUMER__TF_CONFIG = eINSTANCE.getMTFConfigConsumer_TfConfig(); + EAttribute MBRICK_DC__VELOCITY = eINSTANCE.getMBrickDC_Velocity(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MBaseDevice MBase Device}' class. + * The meta object literal for the 'Targetvelocity' attribute feature. * * - * @see org.openhab.binding.tinkerforge.internal.model.MBaseDevice - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBaseDevice() * @generated */ - EClass MBASE_DEVICE = eINSTANCE.getMBaseDevice(); + EAttribute MBRICK_DC__TARGETVELOCITY = eINSTANCE.getMBrickDC_Targetvelocity(); /** - * The meta object literal for the 'Logger' attribute feature. + * The meta object literal for the 'Current Velocity' attribute feature. * * * @generated */ - EAttribute MBASE_DEVICE__LOGGER = eINSTANCE.getMBaseDevice_Logger(); + EAttribute MBRICK_DC__CURRENT_VELOCITY = eINSTANCE.getMBrickDC_CurrentVelocity(); /** - * The meta object literal for the 'Uid' attribute feature. + * The meta object literal for the 'Acceleration' attribute feature. * * * @generated */ - EAttribute MBASE_DEVICE__UID = eINSTANCE.getMBaseDevice_Uid(); + EAttribute MBRICK_DC__ACCELERATION = eINSTANCE.getMBrickDC_Acceleration(); /** - * The meta object literal for the 'Poll' attribute feature. + * The meta object literal for the 'Pwm Frequency' attribute feature. * * * @generated */ - EAttribute MBASE_DEVICE__POLL = eINSTANCE.getMBaseDevice_Poll(); + EAttribute MBRICK_DC__PWM_FREQUENCY = eINSTANCE.getMBrickDC_PwmFrequency(); /** - * The meta object literal for the 'Enabled A' attribute feature. + * The meta object literal for the 'Drive Mode' attribute feature. * * * @generated */ - EAttribute MBASE_DEVICE__ENABLED_A = eINSTANCE.getMBaseDevice_EnabledA(); + EAttribute MBRICK_DC__DRIVE_MODE = eINSTANCE.getMBrickDC_DriveMode(); /** * The meta object literal for the 'Init' operation. @@ -17200,437 +20682,457 @@ interface Literals * * @generated */ - EOperation MBASE_DEVICE___INIT = eINSTANCE.getMBaseDevice__Init(); + EOperation MBRICK_DC___INIT = eINSTANCE.getMBrickDC__Init(); /** - * The meta object literal for the 'Enable' operation. + * The meta object literal for the 'Set Speed' operation. * * * @generated */ - EOperation MBASE_DEVICE___ENABLE = eINSTANCE.getMBaseDevice__Enable(); + EOperation MBRICK_DC___SET_SPEED__SHORT_INT_STRING = eINSTANCE.getMBrickDC__SetSpeed__Short_int_String(); /** - * The meta object literal for the 'Disable' operation. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MDualRelayBrickletImpl MDual Relay Bricklet}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MDualRelayBrickletImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMDualRelayBricklet() * @generated */ - EOperation MBASE_DEVICE___DISABLE = eINSTANCE.getMBaseDevice__Disable(); + EClass MDUAL_RELAY_BRICKLET = eINSTANCE.getMDualRelayBricklet(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MDevice MDevice}' class. + * The meta object literal for the 'Device Type' attribute feature. * * - * @see org.openhab.binding.tinkerforge.internal.model.MDevice - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMDevice() * @generated */ - EClass MDEVICE = eINSTANCE.getMDevice(); + EAttribute MDUAL_RELAY_BRICKLET__DEVICE_TYPE = eINSTANCE.getMDualRelayBricklet_DeviceType(); /** - * The meta object literal for the 'Tinkerforge Device' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialQuadRelayBrickletImpl MIndustrial Quad Relay Bricklet}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialQuadRelayBrickletImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMIndustrialQuadRelayBricklet() * @generated */ - EAttribute MDEVICE__TINKERFORGE_DEVICE = eINSTANCE.getMDevice_TinkerforgeDevice(); + EClass MINDUSTRIAL_QUAD_RELAY_BRICKLET = eINSTANCE.getMIndustrialQuadRelayBricklet(); /** - * The meta object literal for the 'Ip Connection' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialQuadRelayImpl MIndustrial Quad Relay}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialQuadRelayImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMIndustrialQuadRelay() * @generated */ - EAttribute MDEVICE__IP_CONNECTION = eINSTANCE.getMDevice_IpConnection(); + EClass MINDUSTRIAL_QUAD_RELAY = eINSTANCE.getMIndustrialQuadRelay(); /** - * The meta object literal for the 'Connected Uid' attribute feature. + * The meta object literal for the 'Device Type' attribute feature. * * * @generated */ - EAttribute MDEVICE__CONNECTED_UID = eINSTANCE.getMDevice_ConnectedUid(); + EAttribute MINDUSTRIAL_QUAD_RELAY__DEVICE_TYPE = eINSTANCE.getMIndustrialQuadRelay_DeviceType(); /** - * The meta object literal for the 'Position' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalIn4Impl MBricklet Industrial Digital In4}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalIn4Impl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletIndustrialDigitalIn4() * @generated */ - EAttribute MDEVICE__POSITION = eINSTANCE.getMDevice_Position(); + EClass MBRICKLET_INDUSTRIAL_DIGITAL_IN4 = eINSTANCE.getMBrickletIndustrialDigitalIn4(); /** - * The meta object literal for the 'Device Identifier' attribute feature. + * The meta object literal for the 'Device Type' attribute feature. * * * @generated */ - EAttribute MDEVICE__DEVICE_IDENTIFIER = eINSTANCE.getMDevice_DeviceIdentifier(); + EAttribute MBRICKLET_INDUSTRIAL_DIGITAL_IN4__DEVICE_TYPE = eINSTANCE.getMBrickletIndustrialDigitalIn4_DeviceType(); /** - * The meta object literal for the 'Name' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialDigitalInImpl MIndustrial Digital In}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialDigitalInImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMIndustrialDigitalIn() * @generated */ - EAttribute MDEVICE__NAME = eINSTANCE.getMDevice_Name(); + EClass MINDUSTRIAL_DIGITAL_IN = eINSTANCE.getMIndustrialDigitalIn(); /** - * The meta object literal for the 'Brickd' container reference feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalOut4Impl MBricklet Industrial Digital Out4}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalOut4Impl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletIndustrialDigitalOut4() * @generated */ - EReference MDEVICE__BRICKD = eINSTANCE.getMDevice_Brickd(); + EClass MBRICKLET_INDUSTRIAL_DIGITAL_OUT4 = eINSTANCE.getMBrickletIndustrialDigitalOut4(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder MSub Device Holder}' class. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorDigitalOut4Impl Digital Actor Digital Out4}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMSubDeviceHolder() + * @see org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorDigitalOut4Impl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActorDigitalOut4() * @generated */ - EClass MSUB_DEVICE_HOLDER = eINSTANCE.getMSubDeviceHolder(); + EClass DIGITAL_ACTOR_DIGITAL_OUT4 = eINSTANCE.getDigitalActorDigitalOut4(); /** - * The meta object literal for the 'Msubdevices' containment reference list feature. + * The meta object literal for the 'Pin' attribute feature. * * * @generated */ - EReference MSUB_DEVICE_HOLDER__MSUBDEVICES = eINSTANCE.getMSubDeviceHolder_Msubdevices(); + EAttribute DIGITAL_ACTOR_DIGITAL_OUT4__PIN = eINSTANCE.getDigitalActorDigitalOut4_Pin(); /** - * The meta object literal for the 'Init Sub Devices' operation. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor Digital Actor}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActor() * @generated */ - EOperation MSUB_DEVICE_HOLDER___INIT_SUB_DEVICES = eINSTANCE.getMSubDeviceHolder__InitSubDevices(); + EClass DIGITAL_ACTOR = eINSTANCE.getDigitalActor(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickServoImpl MBrick Servo}' class. + * The meta object literal for the 'Digital State' attribute feature. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickServoImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickServo() * @generated */ - EClass MBRICK_SERVO = eINSTANCE.getMBrickServo(); + EAttribute DIGITAL_ACTOR__DIGITAL_STATE = eINSTANCE.getDigitalActor_DigitalState(); /** - * The meta object literal for the 'Device Type' attribute feature. + * The meta object literal for the 'Turn Digital' operation. * * * @generated */ - EAttribute MBRICK_SERVO__DEVICE_TYPE = eINSTANCE.getMBrickServo_DeviceType(); + EOperation DIGITAL_ACTOR___TURN_DIGITAL__HIGHLOWVALUE = eINSTANCE.getDigitalActor__TurnDigital__HighLowValue(); /** - * The meta object literal for the 'Init' operation. + * The meta object literal for the 'Fetch Digital Value' operation. * * * @generated */ - EOperation MBRICK_SERVO___INIT = eINSTANCE.getMBrickServo__Init(); + EOperation DIGITAL_ACTOR___FETCH_DIGITAL_VALUE = eINSTANCE.getDigitalActor__FetchDigitalValue(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl TF Brick DC Configuration}' class. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.NumberActor Number Actor}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTFBrickDCConfiguration() + * @see org.openhab.binding.tinkerforge.internal.model.NumberActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getNumberActor() * @generated */ - EClass TF_BRICK_DC_CONFIGURATION = eINSTANCE.getTFBrickDCConfiguration(); + EClass NUMBER_ACTOR = eINSTANCE.getNumberActor(); /** - * The meta object literal for the 'Velocity' attribute feature. + * The meta object literal for the 'Set Number' operation. * * * @generated */ - EAttribute TF_BRICK_DC_CONFIGURATION__VELOCITY = eINSTANCE.getTFBrickDCConfiguration_Velocity(); + EOperation NUMBER_ACTOR___SET_NUMBER__BIGDECIMAL = eINSTANCE.getNumberActor__SetNumber__BigDecimal(); /** - * The meta object literal for the 'Acceleration' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.ColorActor Color Actor}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.ColorActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getColorActor() * @generated */ - EAttribute TF_BRICK_DC_CONFIGURATION__ACCELERATION = eINSTANCE.getTFBrickDCConfiguration_Acceleration(); + EClass COLOR_ACTOR = eINSTANCE.getColorActor(); /** - * The meta object literal for the 'Pwm Frequency' attribute feature. + * The meta object literal for the 'Set Color' operation. * * * @generated */ - EAttribute TF_BRICK_DC_CONFIGURATION__PWM_FREQUENCY = eINSTANCE.getTFBrickDCConfiguration_PwmFrequency(); + EOperation COLOR_ACTOR___SET_COLOR__HSBTYPE_DEVICEOPTIONS = eINSTANCE.getColorActor__SetColor__HSBType_DeviceOptions(); /** - * The meta object literal for the 'Drive Mode' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MoveActor Move Actor}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.MoveActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMoveActor() * @generated */ - EAttribute TF_BRICK_DC_CONFIGURATION__DRIVE_MODE = eINSTANCE.getTFBrickDCConfiguration_DriveMode(); + EClass MOVE_ACTOR = eINSTANCE.getMoveActor(); /** - * The meta object literal for the 'Switch On Velocity' attribute feature. + * The meta object literal for the 'Direction' attribute feature. * * * @generated */ - EAttribute TF_BRICK_DC_CONFIGURATION__SWITCH_ON_VELOCITY = eINSTANCE.getTFBrickDCConfiguration_SwitchOnVelocity(); + EAttribute MOVE_ACTOR__DIRECTION = eINSTANCE.getMoveActor_Direction(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl MBrick DC}' class. + * The meta object literal for the 'Move' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickDC() * @generated */ - EClass MBRICK_DC = eINSTANCE.getMBrickDC(); + EOperation MOVE_ACTOR___MOVE__UPDOWNTYPE_DEVICEOPTIONS = eINSTANCE.getMoveActor__Move__UpDownType_DeviceOptions(); /** - * The meta object literal for the 'Device Type' attribute feature. + * The meta object literal for the 'Stop' operation. * * * @generated */ - EAttribute MBRICK_DC__DEVICE_TYPE = eINSTANCE.getMBrickDC_DeviceType(); + EOperation MOVE_ACTOR___STOP = eINSTANCE.getMoveActor__Stop(); /** - * The meta object literal for the 'Velocity' attribute feature. + * The meta object literal for the 'Moveon' operation. * * * @generated */ - EAttribute MBRICK_DC__VELOCITY = eINSTANCE.getMBrickDC_Velocity(); + EOperation MOVE_ACTOR___MOVEON__DEVICEOPTIONS = eINSTANCE.getMoveActor__Moveon__DeviceOptions(); /** - * The meta object literal for the 'Current Velocity' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.DimmableActor Dimmable Actor}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.DimmableActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDimmableActor() * @generated */ - EAttribute MBRICK_DC__CURRENT_VELOCITY = eINSTANCE.getMBrickDC_CurrentVelocity(); + EClass DIMMABLE_ACTOR = eINSTANCE.getDimmableActor(); /** - * The meta object literal for the 'Acceleration' attribute feature. + * The meta object literal for the 'Min Value' attribute feature. * * * @generated */ - EAttribute MBRICK_DC__ACCELERATION = eINSTANCE.getMBrickDC_Acceleration(); + EAttribute DIMMABLE_ACTOR__MIN_VALUE = eINSTANCE.getDimmableActor_MinValue(); /** - * The meta object literal for the 'Pwm Frequency' attribute feature. + * The meta object literal for the 'Max Value' attribute feature. * * * @generated */ - EAttribute MBRICK_DC__PWM_FREQUENCY = eINSTANCE.getMBrickDC_PwmFrequency(); + EAttribute DIMMABLE_ACTOR__MAX_VALUE = eINSTANCE.getDimmableActor_MaxValue(); /** - * The meta object literal for the 'Drive Mode' attribute feature. + * The meta object literal for the 'Dimm' operation. * * * @generated */ - EAttribute MBRICK_DC__DRIVE_MODE = eINSTANCE.getMBrickDC_DriveMode(); + EOperation DIMMABLE_ACTOR___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS = eINSTANCE.getDimmableActor__Dimm__IncreaseDecreaseType_DeviceOptions(); /** - * The meta object literal for the 'Switch On Velocity' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.SetPointActor Set Point Actor}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.SetPointActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getSetPointActor() * @generated */ - EAttribute MBRICK_DC__SWITCH_ON_VELOCITY = eINSTANCE.getMBrickDC_SwitchOnVelocity(); + EClass SET_POINT_ACTOR = eINSTANCE.getSetPointActor(); /** - * The meta object literal for the 'Init' operation. + * The meta object literal for the 'Percent Value' attribute feature. * * * @generated */ - EOperation MBRICK_DC___INIT = eINSTANCE.getMBrickDC__Init(); + EAttribute SET_POINT_ACTOR__PERCENT_VALUE = eINSTANCE.getSetPointActor_PercentValue(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MDualRelayBrickletImpl MDual Relay Bricklet}' class. + * The meta object literal for the 'Set Value' operation. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MDualRelayBrickletImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMDualRelayBricklet() * @generated */ - EClass MDUAL_RELAY_BRICKLET = eINSTANCE.getMDualRelayBricklet(); + EOperation SET_POINT_ACTOR___SET_VALUE__BIGDECIMAL_DEVICEOPTIONS = eINSTANCE.getSetPointActor__SetValue__BigDecimal_DeviceOptions(); /** - * The meta object literal for the 'Device Type' attribute feature. + * The meta object literal for the 'Set Value' operation. * * * @generated */ - EAttribute MDUAL_RELAY_BRICKLET__DEVICE_TYPE = eINSTANCE.getMDualRelayBricklet_DeviceType(); + EOperation SET_POINT_ACTOR___SET_VALUE__PERCENTTYPE_DEVICEOPTIONS = eINSTANCE.getSetPointActor__SetValue__PercentType_DeviceOptions(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialQuadRelayBrickletImpl MIndustrial Quad Relay Bricklet}' class. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl MBricklet Dual Button}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialQuadRelayBrickletImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMIndustrialQuadRelayBricklet() + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletDualButton() * @generated */ - EClass MINDUSTRIAL_QUAD_RELAY_BRICKLET = eINSTANCE.getMIndustrialQuadRelayBricklet(); + EClass MBRICKLET_DUAL_BUTTON = eINSTANCE.getMBrickletDualButton(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialQuadRelayImpl MIndustrial Quad Relay}' class. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonDevice Dual Button Device}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialQuadRelayImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMIndustrialQuadRelay() + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonDevice + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualButtonDevice() * @generated */ - EClass MINDUSTRIAL_QUAD_RELAY = eINSTANCE.getMIndustrialQuadRelay(); + EClass DUAL_BUTTON_DEVICE = eINSTANCE.getDualButtonDevice(); /** - * The meta object literal for the 'Device Type' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftButtonImpl Dual Button Left Button}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftButtonImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualButtonLeftButton() * @generated */ - EAttribute MINDUSTRIAL_QUAD_RELAY__DEVICE_TYPE = eINSTANCE.getMIndustrialQuadRelay_DeviceType(); + EClass DUAL_BUTTON_LEFT_BUTTON = eINSTANCE.getDualButtonLeftButton(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalIn4Impl MBricklet Industrial Digital In4}' class. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightButtonImpl Dual Button Right Button}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalIn4Impl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletIndustrialDigitalIn4() + * @see org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightButtonImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualButtonRightButton() * @generated */ - EClass MBRICKLET_INDUSTRIAL_DIGITAL_IN4 = eINSTANCE.getMBrickletIndustrialDigitalIn4(); + EClass DUAL_BUTTON_RIGHT_BUTTON = eINSTANCE.getDualButtonRightButton(); /** - * The meta object literal for the 'Device Type' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftLedImpl Dual Button Left Led}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftLedImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualButtonLeftLed() * @generated */ - EAttribute MBRICKLET_INDUSTRIAL_DIGITAL_IN4__DEVICE_TYPE = eINSTANCE.getMBrickletIndustrialDigitalIn4_DeviceType(); + EClass DUAL_BUTTON_LEFT_LED = eINSTANCE.getDualButtonLeftLed(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialDigitalInImpl MIndustrial Digital In}' class. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightLedImpl Dual Button Right Led}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MIndustrialDigitalInImpl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMIndustrialDigitalIn() + * @see org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightLedImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDualButtonRightLed() * @generated */ - EClass MINDUSTRIAL_DIGITAL_IN = eINSTANCE.getMIndustrialDigitalIn(); + EClass DUAL_BUTTON_RIGHT_LED = eINSTANCE.getDualButtonRightLed(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalOut4Impl MBricklet Industrial Digital Out4}' class. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl MBricklet Linear Poti}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletIndustrialDigitalOut4Impl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletIndustrialDigitalOut4() + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletLinearPoti() * @generated */ - EClass MBRICKLET_INDUSTRIAL_DIGITAL_OUT4 = eINSTANCE.getMBrickletIndustrialDigitalOut4(); + EClass MBRICKLET_LINEAR_POTI = eINSTANCE.getMBrickletLinearPoti(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorDigitalOut4Impl Digital Actor Digital Out4}' class. + * The meta object literal for the 'Device Type' attribute feature. * * - * @see org.openhab.binding.tinkerforge.internal.model.impl.DigitalActorDigitalOut4Impl - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActorDigitalOut4() * @generated */ - EClass DIGITAL_ACTOR_DIGITAL_OUT4 = eINSTANCE.getDigitalActorDigitalOut4(); + EAttribute MBRICKLET_LINEAR_POTI__DEVICE_TYPE = eINSTANCE.getMBrickletLinearPoti_DeviceType(); /** - * The meta object literal for the 'Pin' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl MBricklet Joystick}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getMBrickletJoystick() * @generated */ - EAttribute DIGITAL_ACTOR_DIGITAL_OUT4__PIN = eINSTANCE.getDigitalActorDigitalOut4_Pin(); + EClass MBRICKLET_JOYSTICK = eINSTANCE.getMBrickletJoystick(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.DigitalActor Digital Actor}' class. + * The meta object literal for the 'Device Type' attribute feature. * * - * @see org.openhab.binding.tinkerforge.internal.model.DigitalActor - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDigitalActor() * @generated */ - EClass DIGITAL_ACTOR = eINSTANCE.getDigitalActor(); + EAttribute MBRICKLET_JOYSTICK__DEVICE_TYPE = eINSTANCE.getMBrickletJoystick_DeviceType(); /** - * The meta object literal for the 'Digital State' attribute feature. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.JoystickDevice Joystick Device}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.JoystickDevice + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getJoystickDevice() * @generated */ - EAttribute DIGITAL_ACTOR__DIGITAL_STATE = eINSTANCE.getDigitalActor_DigitalState(); + EClass JOYSTICK_DEVICE = eINSTANCE.getJoystickDevice(); /** - * The meta object literal for the 'Turn Digital' operation. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl Joystick XPosition}' class. * * + * @see org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getJoystickXPosition() * @generated */ - EOperation DIGITAL_ACTOR___TURN_DIGITAL__HIGHLOWVALUE = eINSTANCE.getDigitalActor__TurnDigital__HighLowValue(); + EClass JOYSTICK_XPOSITION = eINSTANCE.getJoystickXPosition(); /** - * The meta object literal for the 'Fetch Digital Value' operation. + * The meta object literal for the 'Device Type' attribute feature. * * * @generated */ - EOperation DIGITAL_ACTOR___FETCH_DIGITAL_VALUE = eINSTANCE.getDigitalActor__FetchDigitalValue(); + EAttribute JOYSTICK_XPOSITION__DEVICE_TYPE = eINSTANCE.getJoystickXPosition_DeviceType(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.NumberActor Number Actor}' class. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl Joystick YPosition}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.NumberActor - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getNumberActor() + * @see org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getJoystickYPosition() * @generated */ - EClass NUMBER_ACTOR = eINSTANCE.getNumberActor(); + EClass JOYSTICK_YPOSITION = eINSTANCE.getJoystickYPosition(); /** - * The meta object literal for the 'Set Number' operation. + * The meta object literal for the 'Device Type' attribute feature. * * * @generated */ - EOperation NUMBER_ACTOR___SET_NUMBER__BIGDECIMAL = eINSTANCE.getNumberActor__SetNumber__BigDecimal(); + EAttribute JOYSTICK_YPOSITION__DEVICE_TYPE = eINSTANCE.getJoystickYPosition_DeviceType(); /** - * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.ColorActor Color Actor}' class. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl Joystick Button}' class. * * - * @see org.openhab.binding.tinkerforge.internal.model.ColorActor - * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getColorActor() + * @see org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getJoystickButton() * @generated */ - EClass COLOR_ACTOR = eINSTANCE.getColorActor(); + EClass JOYSTICK_BUTTON = eINSTANCE.getJoystickButton(); /** - * The meta object literal for the 'Set Color' operation. + * The meta object literal for the 'Device Type' attribute feature. * * * @generated */ - EOperation COLOR_ACTOR___SET_COLOR__HSBTYPE_DEVICEOPTIONS = eINSTANCE.getColorActor__SetColor__HSBType_DeviceOptions(); + EAttribute JOYSTICK_BUTTON__DEVICE_TYPE = eINSTANCE.getJoystickButton_DeviceType(); /** * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLEDStripImpl MBricklet LED Strip}' class. @@ -17728,6 +21230,24 @@ interface Literals */ EClass MACTOR = eINSTANCE.getMActor(); + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.SwitchSensor Switch Sensor}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.SwitchSensor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getSwitchSensor() + * @generated + */ + EClass SWITCH_SENSOR = eINSTANCE.getSwitchSensor(); + + /** + * The meta object literal for the 'Fetch Switch State' operation. + * + * + * @generated + */ + EOperation SWITCH_SENSOR___FETCH_SWITCH_STATE = eINSTANCE.getSwitchSensor__FetchSwitchState(); + /** * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MSwitchActor MSwitch Actor}' class. * @@ -17755,12 +21275,30 @@ interface Literals EOperation MSWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE = eINSTANCE.getMSwitchActor__TurnSwitch__OnOffValue(); /** - * The meta object literal for the 'Fetch Switch State' operation. + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor Programmable Switch Actor}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getProgrammableSwitchActor() + * @generated + */ + EClass PROGRAMMABLE_SWITCH_ACTOR = eINSTANCE.getProgrammableSwitchActor(); + + /** + * The meta object literal for the 'Switch State' attribute feature. + * + * + * @generated + */ + EAttribute PROGRAMMABLE_SWITCH_ACTOR__SWITCH_STATE = eINSTANCE.getProgrammableSwitchActor_SwitchState(); + + /** + * The meta object literal for the 'Turn Switch' operation. * * * @generated */ - EOperation MSWITCH_ACTOR___FETCH_SWITCH_STATE = eINSTANCE.getMSwitchActor__FetchSwitchState(); + EOperation PROGRAMMABLE_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE_DEVICEOPTIONS = eINSTANCE.getProgrammableSwitchActor__TurnSwitch__OnOffValue_DeviceOptions(); /** * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MOutSwitchActor MOut Switch Actor}' class. @@ -18380,6 +21918,14 @@ interface Literals */ EAttribute REMOTE_SWITCH_B__REPEATS = eINSTANCE.getRemoteSwitchB_Repeats(); + /** + * The meta object literal for the 'Target Dimmvalue' attribute feature. + * + * + * @generated + */ + EAttribute REMOTE_SWITCH_B__TARGET_DIMMVALUE = eINSTANCE.getRemoteSwitchB_TargetDimmvalue(); + /** * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchCImpl Remote Switch C}' class. * @@ -18678,6 +22224,32 @@ interface Literals */ EAttribute BRICKLET_MULTI_TOUCH_CONFIGURATION__SENSITIVITY = eINSTANCE.getBrickletMultiTouchConfiguration_Sensitivity(); + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.DimmableConfigurationImpl Dimmable Configuration}' class. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.impl.DimmableConfigurationImpl + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDimmableConfiguration() + * @generated + */ + EClass DIMMABLE_CONFIGURATION = eINSTANCE.getDimmableConfiguration(); + + /** + * The meta object literal for the 'Min Value' attribute feature. + * + * + * @generated + */ + EAttribute DIMMABLE_CONFIGURATION__MIN_VALUE = eINSTANCE.getDimmableConfiguration_MinValue(); + + /** + * The meta object literal for the 'Max Value' attribute feature. + * + * + * @generated + */ + EAttribute DIMMABLE_CONFIGURATION__MAX_VALUE = eINSTANCE.getDimmableConfiguration_MaxValue(); + /** * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl MServo}' class. * @@ -18712,6 +22284,22 @@ interface Literals */ EAttribute MSERVO__ACCELERATION = eINSTANCE.getMServo_Acceleration(); + /** + * The meta object literal for the 'Max Position' attribute feature. + * + * + * @generated + */ + EAttribute MSERVO__MAX_POSITION = eINSTANCE.getMServo_MaxPosition(); + + /** + * The meta object literal for the 'Min Position' attribute feature. + * + * + * @generated + */ + EAttribute MSERVO__MIN_POSITION = eINSTANCE.getMServo_MinPosition(); + /** * The meta object literal for the 'Pulse Width Min' attribute feature. * @@ -18745,28 +22333,28 @@ interface Literals EAttribute MSERVO__OUTPUT_VOLTAGE = eINSTANCE.getMServo_OutputVoltage(); /** - * The meta object literal for the 'Servo Current Position' attribute feature. + * The meta object literal for the 'Target Position' attribute feature. * * * @generated */ - EAttribute MSERVO__SERVO_CURRENT_POSITION = eINSTANCE.getMServo_ServoCurrentPosition(); + EAttribute MSERVO__TARGET_POSITION = eINSTANCE.getMServo_TargetPosition(); /** - * The meta object literal for the 'Servo Destination Position' attribute feature. + * The meta object literal for the 'Init' operation. * * * @generated */ - EAttribute MSERVO__SERVO_DESTINATION_POSITION = eINSTANCE.getMServo_ServoDestinationPosition(); + EOperation MSERVO___INIT = eINSTANCE.getMServo__Init(); /** - * The meta object literal for the 'Init' operation. + * The meta object literal for the 'Set Point' operation. * * * @generated */ - EOperation MSERVO___INIT = eINSTANCE.getMServo__Init(); + EOperation MSERVO___SET_POINT__SHORT_INT_INT = eINSTANCE.getMServo__SetPoint__Short_int_int(); /** * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.CallbackListener Callback Listener}' class. @@ -19544,6 +23132,14 @@ interface Literals */ EOperation MBRICKLET_LCD2_0X4___INIT = eINSTANCE.getMBrickletLCD20x4__Init(); + /** + * The meta object literal for the 'Clear' operation. + * + * + * @generated + */ + EOperation MBRICKLET_LCD2_0X4___CLEAR = eINSTANCE.getMBrickletLCD20x4__Clear(); + /** * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.MTextActor MText Actor}' class. * @@ -19656,6 +23252,16 @@ interface Literals */ EEnum DC_DRIVE_MODE = eINSTANCE.getDCDriveMode(); + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsServo Config Opts Servo}' enum. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsServo + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getConfigOptsServo() + * @generated + */ + EEnum CONFIG_OPTS_SERVO = eINSTANCE.getConfigOptsServo(); + /** * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.NoSubIds No Sub Ids}' enum. * @@ -19786,6 +23392,46 @@ interface Literals */ EEnum VOLTAGE_CURRENT_SUB_IDS = eINSTANCE.getVoltageCurrentSubIds(); + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsMove Config Opts Move}' enum. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsMove + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getConfigOptsMove() + * @generated + */ + EEnum CONFIG_OPTS_MOVE = eINSTANCE.getConfigOptsMove(); + + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsDimmable Config Opts Dimmable}' enum. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsDimmable + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getConfigOptsDimmable() + * @generated + */ + EEnum CONFIG_OPTS_DIMMABLE = eINSTANCE.getConfigOptsDimmable(); + + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsSetPoint Config Opts Set Point}' enum. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsSetPoint + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getConfigOptsSetPoint() + * @generated + */ + EEnum CONFIG_OPTS_SET_POINT = eINSTANCE.getConfigOptsSetPoint(); + + /** + * The meta object literal for the '{@link org.openhab.binding.tinkerforge.internal.model.ConfigOptsSwitchSpeed Config Opts Switch Speed}' enum. + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ConfigOptsSwitchSpeed + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getConfigOptsSwitchSpeed() + * @generated + */ + EEnum CONFIG_OPTS_SWITCH_SPEED = eINSTANCE.getConfigOptsSwitchSpeed(); + /** * The meta object literal for the 'MIP Connection' data type. * @@ -20066,6 +23712,36 @@ interface Literals */ EDataType TINKER_BRICKLET_LED_STRIP = eINSTANCE.getTinkerBrickletLEDStrip(); + /** + * The meta object literal for the 'Bricklet Joystick' data type. + * + * + * @see com.tinkerforge.BrickletJoystick + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getBrickletJoystick() + * @generated + */ + EDataType BRICKLET_JOYSTICK = eINSTANCE.getBrickletJoystick(); + + /** + * The meta object literal for the 'Tinker Bricklet Linear Poti' data type. + * + * + * @see com.tinkerforge.BrickletLinearPoti + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletLinearPoti() + * @generated + */ + EDataType TINKER_BRICKLET_LINEAR_POTI = eINSTANCE.getTinkerBrickletLinearPoti(); + + /** + * The meta object literal for the 'Tinker Bricklet Dual Button' data type. + * + * + * @see com.tinkerforge.BrickletDualButton + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getTinkerBrickletDualButton() + * @generated + */ + EDataType TINKER_BRICKLET_DUAL_BUTTON = eINSTANCE.getTinkerBrickletDualButton(); + /** * The meta object literal for the 'HSB Type' data type. * @@ -20076,6 +23752,26 @@ interface Literals */ EDataType HSB_TYPE = eINSTANCE.getHSBType(); + /** + * The meta object literal for the 'Up Down Type' data type. + * + * + * @see org.openhab.core.library.types.UpDownType + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getUpDownType() + * @generated + */ + EDataType UP_DOWN_TYPE = eINSTANCE.getUpDownType(); + + /** + * The meta object literal for the 'Percent Value' data type. + * + * + * @see org.openhab.binding.tinkerforge.internal.types.PercentValue + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getPercentValue() + * @generated + */ + EDataType PERCENT_VALUE = eINSTANCE.getPercentValue(); + /** * The meta object literal for the 'Device Options' data type. * @@ -20086,6 +23782,36 @@ interface Literals */ EDataType DEVICE_OPTIONS = eINSTANCE.getDeviceOptions(); + /** + * The meta object literal for the 'Percent Type' data type. + * + * + * @see org.openhab.core.library.types.PercentType + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getPercentType() + * @generated + */ + EDataType PERCENT_TYPE = eINSTANCE.getPercentType(); + + /** + * The meta object literal for the 'Increase Decrease Type' data type. + * + * + * @see org.openhab.core.library.types.IncreaseDecreaseType + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getIncreaseDecreaseType() + * @generated + */ + EDataType INCREASE_DECREASE_TYPE = eINSTANCE.getIncreaseDecreaseType(); + + /** + * The meta object literal for the 'Direction Value' data type. + * + * + * @see org.openhab.binding.tinkerforge.internal.types.DirectionValue + * @see org.openhab.binding.tinkerforge.internal.model.impl.ModelPackageImpl#getDirectionValue() + * @generated + */ + EDataType DIRECTION_VALUE = eINSTANCE.getDirectionValue(); + /** * The meta object literal for the 'Enum' data type. * diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MoveActor.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MoveActor.java new file mode 100644 index 00000000000..1f63f139e72 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/MoveActor.java @@ -0,0 +1,80 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import org.eclipse.emf.ecore.EObject; + +import org.openhab.binding.tinkerforge.internal.config.DeviceOptions; + +import org.openhab.binding.tinkerforge.internal.types.DirectionValue; +import org.openhab.core.library.types.UpDownType; + +/** + * + * A representation of the model object 'Move Actor'. + * + * + *

      + * The following features are supported: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.MoveActor#getDirection Direction}
      • + *
      + *

      + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMoveActor() + * @model interface="true" abstract="true" + * @generated + */ +public interface MoveActor extends EObject +{ + /** + * Returns the value of the 'Direction' attribute. + * + *

      + * If the meaning of the 'Direction' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Direction' attribute. + * @see #setDirection(DirectionValue) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getMoveActor_Direction() + * @model unique="false" dataType="org.openhab.binding.tinkerforge.internal.model.DirectionValue" + * @generated + */ + DirectionValue getDirection(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.MoveActor#getDirection Direction}' attribute. + * + * + * @param value the new value of the 'Direction' attribute. + * @see #getDirection() + * @generated + */ + void setDirection(DirectionValue value); + + /** + * + * + * @model directionDataType="org.openhab.binding.tinkerforge.internal.model.UpDownType" directionUnique="false" optsDataType="org.openhab.binding.tinkerforge.internal.model.DeviceOptions" optsUnique="false" + * @generated + */ + void move(UpDownType direction, DeviceOptions opts); + + /** + * + * + * @model + * @generated + */ + void stop(); + + /** + * + * + * @model optsDataType="org.openhab.binding.tinkerforge.internal.model.DeviceOptions" optsUnique="false" + * @generated + */ + void moveon(DeviceOptions opts); + +} // MoveActor diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ProgrammableSwitch.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ProgrammableSwitch.java new file mode 100644 index 00000000000..e332634b1e5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ProgrammableSwitch.java @@ -0,0 +1,71 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import org.eclipse.emf.ecore.EObject; + +import org.openhab.binding.tinkerforge.internal.config.DeviceOptions; + +import org.openhab.binding.tinkerforge.internal.types.OnOffValue; + +/** + * + * A representation of the model object 'Programmable Switch'. + * + * + *

      + * The following features are supported: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitch#getSwitchState Switch State}
      • + *
      + *

      + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getProgrammableSwitch() + * @model interface="true" abstract="true" + * @generated + */ +public interface ProgrammableSwitch extends EObject +{ + /** + * Returns the value of the 'Switch State' attribute. + * + *

      + * If the meaning of the 'Switch State' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Switch State' attribute. + * @see #setSwitchState(OnOffValue) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getProgrammableSwitch_SwitchState() + * @model unique="false" dataType="org.openhab.binding.tinkerforge.internal.model.SwitchState" + * @generated + */ + OnOffValue getSwitchState(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitch#getSwitchState Switch State}' attribute. + * + * + * @param value the new value of the 'Switch State' attribute. + * @see #getSwitchState() + * @generated + */ + void setSwitchState(OnOffValue value); + + /** + * + * + * @model stateDataType="org.openhab.binding.tinkerforge.internal.model.SwitchState" stateUnique="false" optsDataType="org.openhab.binding.tinkerforge.internal.model.DeviceOptions" optsUnique="false" + * @generated + */ + void turnSwitch(OnOffValue state, DeviceOptions opts); + + /** + * + * + * @model + * @generated + */ + void fetchSwitchState(); + +} // ProgrammableSwitch diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ProgrammableSwitchActor.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ProgrammableSwitchActor.java new file mode 100644 index 00000000000..f36c5b6069f --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ProgrammableSwitchActor.java @@ -0,0 +1,63 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import org.eclipse.emf.ecore.EObject; + +import org.openhab.binding.tinkerforge.internal.config.DeviceOptions; + +import org.openhab.binding.tinkerforge.internal.types.OnOffValue; + +/** + * + * A representation of the model object 'Programmable Switch Actor'. + * + * + *

      + * The following features are supported: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor#getSwitchState Switch State}
      • + *
      + *

      + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getProgrammableSwitchActor() + * @model interface="true" abstract="true" + * @generated + */ +public interface ProgrammableSwitchActor extends SwitchSensor +{ + /** + * Returns the value of the 'Switch State' attribute. + * + *

      + * If the meaning of the 'Switch State' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Switch State' attribute. + * @see #setSwitchState(OnOffValue) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getProgrammableSwitchActor_SwitchState() + * @model unique="false" dataType="org.openhab.binding.tinkerforge.internal.model.SwitchState" + * @generated + */ + OnOffValue getSwitchState(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor#getSwitchState Switch State}' attribute. + * + * + * @param value the new value of the 'Switch State' attribute. + * @see #getSwitchState() + * @generated + */ + void setSwitchState(OnOffValue value); + + /** + * + * + * @model stateDataType="org.openhab.binding.tinkerforge.internal.model.SwitchState" stateUnique="false" optsDataType="org.openhab.binding.tinkerforge.internal.model.DeviceOptions" optsUnique="false" + * @generated + */ + void turnSwitch(OnOffValue state, DeviceOptions opts); + +} // ProgrammableSwitchActor diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/RemoteSwitchB.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/RemoteSwitchB.java index bde9da58c96..bad6c07e945 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/RemoteSwitchB.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/RemoteSwitchB.java @@ -8,6 +8,8 @@ */ package org.openhab.binding.tinkerforge.internal.model; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; + /** * @@ -24,14 +26,15 @@ *
    • {@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getAddress Address}
    • *
    • {@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getUnit Unit}
    • *
    • {@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getRepeats Repeats}
    • + *
    • {@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getTargetDimmvalue Target Dimmvalue}
    • * *

      * * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getRemoteSwitchB() - * @model + * @model superTypes="org.openhab.binding.tinkerforge.internal.model.MSensor org.openhab.binding.tinkerforge.internal.model.RemoteSwitch org.openhab.binding.tinkerforge.internal.model.DimmableActor" * @generated */ -public interface RemoteSwitchB extends RemoteSwitch, MTFConfigConsumer +public interface RemoteSwitchB extends MSensor, RemoteSwitch, DimmableActor { /** @@ -127,4 +130,31 @@ public interface RemoteSwitchB extends RemoteSwitch, MTFConfigConsumerTarget Dimmvalue' attribute. + * The default value is "0". + * + *

      + * If the meaning of the 'Target Dimmvalue' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Target Dimmvalue' attribute. + * @see #setTargetDimmvalue(Short) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getRemoteSwitchB_TargetDimmvalue() + * @model default="0" unique="false" + * @generated + */ + Short getTargetDimmvalue(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB#getTargetDimmvalue Target Dimmvalue}' attribute. + * + * + * @param value the new value of the 'Target Dimmvalue' attribute. + * @see #getTargetDimmvalue() + * @generated + */ + void setTargetDimmvalue(Short value); } // RemoteSwitchB diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/RemoteSwitchBConfiguration.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/RemoteSwitchBConfiguration.java index 0bb2cc3de58..a023bd121d9 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/RemoteSwitchBConfiguration.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/RemoteSwitchBConfiguration.java @@ -30,7 +30,7 @@ * @model * @generated */ -public interface RemoteSwitchBConfiguration extends TFConfig +public interface RemoteSwitchBConfiguration extends DimmableConfiguration { /** diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/SetPointActor.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/SetPointActor.java new file mode 100644 index 00000000000..4a603daea0f --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/SetPointActor.java @@ -0,0 +1,71 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.math.BigDecimal; + +import org.openhab.binding.tinkerforge.internal.config.DeviceOptions; +import org.openhab.binding.tinkerforge.internal.types.PercentValue; +import org.openhab.core.library.types.PercentType; + +/** + * + * A representation of the model object 'Set Point Actor'. + * + * + *

      + * The following features are supported: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.SetPointActor#getPercentValue Percent Value}
      • + *
      + *

      + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getSetPointActor() + * @model interface="true" abstract="true" + * @generated + */ +public interface SetPointActor extends DimmableActor +{ + /** + * Returns the value of the 'Percent Value' attribute. + * + *

      + * If the meaning of the 'Percent Value' attribute isn't clear, + * there really should be more of a description here... + *

      + * + * @return the value of the 'Percent Value' attribute. + * @see #setPercentValue(PercentValue) + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getSetPointActor_PercentValue() + * @model unique="false" dataType="org.openhab.binding.tinkerforge.internal.model.PercentValue" + * @generated + */ + PercentValue getPercentValue(); + + /** + * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.SetPointActor#getPercentValue Percent Value}' attribute. + * + * + * @param value the new value of the 'Percent Value' attribute. + * @see #getPercentValue() + * @generated + */ + void setPercentValue(PercentValue value); + + /** + * + * + * @model newValueUnique="false" optsDataType="org.openhab.binding.tinkerforge.internal.model.DeviceOptions" optsUnique="false" + * @generated + */ + void setValue(BigDecimal newValue, DeviceOptions opts); + + /** + * + * + * @model newValueDataType="org.openhab.binding.tinkerforge.internal.model.PercentType" newValueUnique="false" optsDataType="org.openhab.binding.tinkerforge.internal.model.DeviceOptions" optsUnique="false" + * @generated + */ + void setValue(PercentType newValue, DeviceOptions opts); + +} // SetPointActor diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/SwitchSensor.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/SwitchSensor.java new file mode 100644 index 00000000000..eb909de9da8 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/SwitchSensor.java @@ -0,0 +1,27 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'Switch Sensor'. + * + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getSwitchSensor() + * @model interface="true" abstract="true" + * @generated + */ +public interface SwitchSensor extends EObject +{ + + /** + * + * + * @model + * @generated + */ + void fetchSwitchState(); +} // SwitchSensor diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/TFBrickDCConfiguration.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/TFBrickDCConfiguration.java index 3d91221dc51..ed2419f337b 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/TFBrickDCConfiguration.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/TFBrickDCConfiguration.java @@ -24,7 +24,6 @@ *
    • {@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getAcceleration Acceleration}
    • *
    • {@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getPwmFrequency Pwm Frequency}
    • *
    • {@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getDriveMode Drive Mode}
    • - *
    • {@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getSwitchOnVelocity Switch On Velocity}
    • * *

      * @@ -32,7 +31,7 @@ * @model * @generated */ -public interface TFBrickDCConfiguration extends TFConfig +public interface TFBrickDCConfiguration extends DimmableConfiguration, TFBaseConfiguration { /** * Returns the value of the 'Velocity' attribute. @@ -121,12 +120,12 @@ public interface TFBrickDCConfiguration extends TFConfig *

      * * @return the value of the 'Drive Mode' attribute. - * @see #setDriveMode(int) + * @see #setDriveMode(String) * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getTFBrickDCConfiguration_DriveMode() * @model unique="false" * @generated */ - int getDriveMode(); + String getDriveMode(); /** * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getDriveMode Drive Mode}' attribute. @@ -136,32 +135,6 @@ public interface TFBrickDCConfiguration extends TFConfig * @see #getDriveMode() * @generated */ - void setDriveMode(int value); - - /** - * Returns the value of the 'Switch On Velocity' attribute. - * - *

      - * If the meaning of the 'Switch On Velocity' attribute isn't clear, - * there really should be more of a description here... - *

      - * - * @return the value of the 'Switch On Velocity' attribute. - * @see #setSwitchOnVelocity(short) - * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getTFBrickDCConfiguration_SwitchOnVelocity() - * @model unique="false" - * @generated - */ - short getSwitchOnVelocity(); - - /** - * Sets the value of the '{@link org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration#getSwitchOnVelocity Switch On Velocity}' attribute. - * - * - * @param value the new value of the 'Switch On Velocity' attribute. - * @see #getSwitchOnVelocity() - * @generated - */ - void setSwitchOnVelocity(short value); + void setDriveMode(String value); } // TFBrickDCConfiguration diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/TFServoConfiguration.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/TFServoConfiguration.java index c3f6601a1e9..a0365c1efcd 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/TFServoConfiguration.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/TFServoConfiguration.java @@ -34,7 +34,7 @@ * @model * @generated */ -public interface TFServoConfiguration extends TFConfig +public interface TFServoConfiguration extends DimmableConfiguration { /** * Returns the value of the 'Velocity' attribute. diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ValueActor.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ValueActor.java new file mode 100644 index 00000000000..0691a9c71f5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/ValueActor.java @@ -0,0 +1,37 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model; + +import java.math.BigDecimal; + +import org.openhab.core.library.types.PercentType; + +/** + * + * A representation of the model object 'Value Actor'. + * + * + * + * @see org.openhab.binding.tinkerforge.internal.model.ModelPackage#getValueActor() + * @model interface="true" abstract="true" + * @generated + */ +public interface ValueActor extends DimmableActor +{ + /** + * + * + * @model newValueUnique="false" + * @generated + */ + void setValue(BigDecimal newValue); + + /** + * + * + * @model newValueDataType="org.openhab.binding.tinkerforge.internal.model.PercentType" newValueUnique="false" + * @generated + */ + void setValue(PercentType newValue); + +} // ValueActor diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DimmableConfigurationImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DimmableConfigurationImpl.java new file mode 100644 index 00000000000..8363dda79a5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DimmableConfigurationImpl.java @@ -0,0 +1,235 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.math.BigDecimal; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; + +import org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; + +/** + * + * An implementation of the model object 'Dimmable Configuration'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DimmableConfigurationImpl#getMinValue Min Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DimmableConfigurationImpl#getMaxValue Max Value}
      • + *
      + *

      + * + * @generated + */ +public class DimmableConfigurationImpl extends MinimalEObjectImpl.Container implements DimmableConfiguration +{ + /** + * The default value of the '{@link #getMinValue() Min Value}' attribute. + * + * + * @see #getMinValue() + * @generated + * @ordered + */ + protected static final BigDecimal MIN_VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getMinValue() Min Value}' attribute. + * + * + * @see #getMinValue() + * @generated + * @ordered + */ + protected BigDecimal minValue = MIN_VALUE_EDEFAULT; + + /** + * The default value of the '{@link #getMaxValue() Max Value}' attribute. + * + * + * @see #getMaxValue() + * @generated + * @ordered + */ + protected static final BigDecimal MAX_VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getMaxValue() Max Value}' attribute. + * + * + * @see #getMaxValue() + * @generated + * @ordered + */ + protected BigDecimal maxValue = MAX_VALUE_EDEFAULT; + + /** + * + * + * @generated + */ + protected DimmableConfigurationImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.DIMMABLE_CONFIGURATION; + } + + /** + * + * + * @generated + */ + public BigDecimal getMinValue() + { + return minValue; + } + + /** + * + * + * @generated + */ + public void setMinValue(BigDecimal newMinValue) + { + BigDecimal oldMinValue = minValue; + minValue = newMinValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DIMMABLE_CONFIGURATION__MIN_VALUE, oldMinValue, minValue)); + } + + /** + * + * + * @generated + */ + public BigDecimal getMaxValue() + { + return maxValue; + } + + /** + * + * + * @generated + */ + public void setMaxValue(BigDecimal newMaxValue) + { + BigDecimal oldMaxValue = maxValue; + maxValue = newMaxValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DIMMABLE_CONFIGURATION__MAX_VALUE, oldMaxValue, maxValue)); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.DIMMABLE_CONFIGURATION__MIN_VALUE: + return getMinValue(); + case ModelPackage.DIMMABLE_CONFIGURATION__MAX_VALUE: + return getMaxValue(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.DIMMABLE_CONFIGURATION__MIN_VALUE: + setMinValue((BigDecimal)newValue); + return; + case ModelPackage.DIMMABLE_CONFIGURATION__MAX_VALUE: + setMaxValue((BigDecimal)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.DIMMABLE_CONFIGURATION__MIN_VALUE: + setMinValue(MIN_VALUE_EDEFAULT); + return; + case ModelPackage.DIMMABLE_CONFIGURATION__MAX_VALUE: + setMaxValue(MAX_VALUE_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.DIMMABLE_CONFIGURATION__MIN_VALUE: + return MIN_VALUE_EDEFAULT == null ? minValue != null : !MIN_VALUE_EDEFAULT.equals(minValue); + case ModelPackage.DIMMABLE_CONFIGURATION__MAX_VALUE: + return MAX_VALUE_EDEFAULT == null ? maxValue != null : !MAX_VALUE_EDEFAULT.equals(maxValue); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (minValue: "); + result.append(minValue); + result.append(", maxValue: "); + result.append(maxValue); + result.append(')'); + return result.toString(); + } + +} //DimmableConfigurationImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonDeviceImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonDeviceImpl.java new file mode 100644 index 00000000000..24995921f09 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonDeviceImpl.java @@ -0,0 +1,580 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.lang.reflect.InvocationTargetException; + +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; + +import org.eclipse.emf.ecore.util.EcoreUtil; + +import org.openhab.binding.tinkerforge.internal.model.DualButtonDevice; +import org.openhab.binding.tinkerforge.internal.model.MBrickletDualButton; +import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; + +import org.slf4j.Logger; + +/** + * + * An implementation of the model object 'Dual Button Device'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonDeviceImpl#getLogger Logger}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonDeviceImpl#getUid Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonDeviceImpl#isPoll Poll}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonDeviceImpl#getEnabledA Enabled A}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonDeviceImpl#getSubId Sub Id}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonDeviceImpl#getMbrick Mbrick}
      • + *
      + *

      + * + * @generated + */ +public class DualButtonDeviceImpl extends MinimalEObjectImpl.Container implements DualButtonDevice +{ + /** + * The default value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected static final Logger LOGGER_EDEFAULT = null; + + /** + * The cached value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected Logger logger = LOGGER_EDEFAULT; + + /** + * The default value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected static final String UID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected String uid = UID_EDEFAULT; + + /** + * The default value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected static final boolean POLL_EDEFAULT = true; + + /** + * The cached value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected boolean poll = POLL_EDEFAULT; + + /** + * The default value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected static final AtomicBoolean ENABLED_A_EDEFAULT = null; + + /** + * The cached value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected AtomicBoolean enabledA = ENABLED_A_EDEFAULT; + + /** + * The default value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected static final String SUB_ID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected String subId = SUB_ID_EDEFAULT; + + /** + * + * + * @generated + */ + protected DualButtonDeviceImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.DUAL_BUTTON_DEVICE; + } + + /** + * + * + * @generated + */ + public Logger getLogger() + { + return logger; + } + + /** + * + * + * @generated + */ + public void setLogger(Logger newLogger) + { + Logger oldLogger = logger; + logger = newLogger; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_DEVICE__LOGGER, oldLogger, logger)); + } + + /** + * + * + * @generated + */ + public String getUid() + { + return uid; + } + + /** + * + * + * @generated + */ + public void setUid(String newUid) + { + String oldUid = uid; + uid = newUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_DEVICE__UID, oldUid, uid)); + } + + /** + * + * + * @generated + */ + public boolean isPoll() + { + return poll; + } + + /** + * + * + * @generated + */ + public void setPoll(boolean newPoll) + { + boolean oldPoll = poll; + poll = newPoll; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_DEVICE__POLL, oldPoll, poll)); + } + + /** + * + * + * @generated + */ + public AtomicBoolean getEnabledA() + { + return enabledA; + } + + /** + * + * + * @generated + */ + public void setEnabledA(AtomicBoolean newEnabledA) + { + AtomicBoolean oldEnabledA = enabledA; + enabledA = newEnabledA; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_DEVICE__ENABLED_A, oldEnabledA, enabledA)); + } + + /** + * + * + * @generated + */ + public String getSubId() + { + return subId; + } + + /** + * + * + * @generated + */ + public void setSubId(String newSubId) + { + String oldSubId = subId; + subId = newSubId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_DEVICE__SUB_ID, oldSubId, subId)); + } + + /** + * + * + * @generated + */ + public MBrickletDualButton getMbrick() + { + if (eContainerFeatureID() != ModelPackage.DUAL_BUTTON_DEVICE__MBRICK) return null; + return (MBrickletDualButton)eContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetMbrick(MBrickletDualButton newMbrick, NotificationChain msgs) + { + msgs = eBasicSetContainer((InternalEObject)newMbrick, ModelPackage.DUAL_BUTTON_DEVICE__MBRICK, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setMbrick(MBrickletDualButton newMbrick) + { + if (newMbrick != eInternalContainer() || (eContainerFeatureID() != ModelPackage.DUAL_BUTTON_DEVICE__MBRICK && newMbrick != null)) + { + if (EcoreUtil.isAncestor(this, newMbrick)) + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + NotificationChain msgs = null; + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + if (newMbrick != null) + msgs = ((InternalEObject)newMbrick).eInverseAdd(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + msgs = basicSetMbrick(newMbrick, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_DEVICE__MBRICK, newMbrick, newMbrick)); + } + + /** + * + * + * @generated + */ + public void init() + { + // TODO: implement this method + // Ensure that you remove @generated or mark it @generated NOT + throw new UnsupportedOperationException(); + } + + /** + * + * + * @generated + */ + public void enable() + { + // TODO: implement this method + // Ensure that you remove @generated or mark it @generated NOT + throw new UnsupportedOperationException(); + } + + /** + * + * + * @generated + */ + public void disable() + { + // TODO: implement this method + // Ensure that you remove @generated or mark it @generated NOT + throw new UnsupportedOperationException(); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_DEVICE__MBRICK: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetMbrick((MBrickletDualButton)otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_DEVICE__MBRICK: + return basicSetMbrick(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) + { + switch (eContainerFeatureID()) + { + case ModelPackage.DUAL_BUTTON_DEVICE__MBRICK: + return eInternalContainer().eInverseRemove(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_DEVICE__LOGGER: + return getLogger(); + case ModelPackage.DUAL_BUTTON_DEVICE__UID: + return getUid(); + case ModelPackage.DUAL_BUTTON_DEVICE__POLL: + return isPoll(); + case ModelPackage.DUAL_BUTTON_DEVICE__ENABLED_A: + return getEnabledA(); + case ModelPackage.DUAL_BUTTON_DEVICE__SUB_ID: + return getSubId(); + case ModelPackage.DUAL_BUTTON_DEVICE__MBRICK: + return getMbrick(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_DEVICE__LOGGER: + setLogger((Logger)newValue); + return; + case ModelPackage.DUAL_BUTTON_DEVICE__UID: + setUid((String)newValue); + return; + case ModelPackage.DUAL_BUTTON_DEVICE__POLL: + setPoll((Boolean)newValue); + return; + case ModelPackage.DUAL_BUTTON_DEVICE__ENABLED_A: + setEnabledA((AtomicBoolean)newValue); + return; + case ModelPackage.DUAL_BUTTON_DEVICE__SUB_ID: + setSubId((String)newValue); + return; + case ModelPackage.DUAL_BUTTON_DEVICE__MBRICK: + setMbrick((MBrickletDualButton)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_DEVICE__LOGGER: + setLogger(LOGGER_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_DEVICE__UID: + setUid(UID_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_DEVICE__POLL: + setPoll(POLL_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_DEVICE__ENABLED_A: + setEnabledA(ENABLED_A_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_DEVICE__SUB_ID: + setSubId(SUB_ID_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_DEVICE__MBRICK: + setMbrick((MBrickletDualButton)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_DEVICE__LOGGER: + return LOGGER_EDEFAULT == null ? logger != null : !LOGGER_EDEFAULT.equals(logger); + case ModelPackage.DUAL_BUTTON_DEVICE__UID: + return UID_EDEFAULT == null ? uid != null : !UID_EDEFAULT.equals(uid); + case ModelPackage.DUAL_BUTTON_DEVICE__POLL: + return poll != POLL_EDEFAULT; + case ModelPackage.DUAL_BUTTON_DEVICE__ENABLED_A: + return ENABLED_A_EDEFAULT == null ? enabledA != null : !ENABLED_A_EDEFAULT.equals(enabledA); + case ModelPackage.DUAL_BUTTON_DEVICE__SUB_ID: + return SUB_ID_EDEFAULT == null ? subId != null : !SUB_ID_EDEFAULT.equals(subId); + case ModelPackage.DUAL_BUTTON_DEVICE__MBRICK: + return getMbrick() != null; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public Object eInvoke(int operationID, EList arguments) throws InvocationTargetException + { + switch (operationID) + { + case ModelPackage.DUAL_BUTTON_DEVICE___INIT: + init(); + return null; + case ModelPackage.DUAL_BUTTON_DEVICE___ENABLE: + enable(); + return null; + case ModelPackage.DUAL_BUTTON_DEVICE___DISABLE: + disable(); + return null; + } + return super.eInvoke(operationID, arguments); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (logger: "); + result.append(logger); + result.append(", uid: "); + result.append(uid); + result.append(", poll: "); + result.append(poll); + result.append(", enabledA: "); + result.append(enabledA); + result.append(", subId: "); + result.append(subId); + result.append(')'); + return result.toString(); + } + +} //DualButtonDeviceImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonLeftButtonImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonLeftButtonImpl.java new file mode 100644 index 00000000000..89e748a9198 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonLeftButtonImpl.java @@ -0,0 +1,718 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.openhab.binding.tinkerforge.internal.TinkerforgeErrorHandler; +import org.openhab.binding.tinkerforge.internal.model.DualButtonLeftButton; +import org.openhab.binding.tinkerforge.internal.model.MBrickletDualButton; +import org.openhab.binding.tinkerforge.internal.model.MSensor; +import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.types.HighLowValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerforge.BrickletDualButton; +import com.tinkerforge.BrickletDualButton.ButtonState; +import com.tinkerforge.NotConnectedException; +import com.tinkerforge.TimeoutException; + +/** + * + * An implementation of the model object 'Dual Button Left Button'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftButtonImpl#getLogger Logger}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftButtonImpl#getUid Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftButtonImpl#isPoll Poll}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftButtonImpl#getEnabledA Enabled A}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftButtonImpl#getSubId Sub Id}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftButtonImpl#getMbrick Mbrick}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftButtonImpl#getSensorValue Sensor Value}
      • + *
      + *

      + * + * @generated + */ +public class DualButtonLeftButtonImpl extends MinimalEObjectImpl.Container implements DualButtonLeftButton +{ + /** + * The default value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected static final Logger LOGGER_EDEFAULT = null; + /** + * The cached value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected Logger logger = LOGGER_EDEFAULT; + /** + * The default value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected static final String UID_EDEFAULT = null; + /** + * The cached value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected String uid = UID_EDEFAULT; + /** + * The default value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected static final boolean POLL_EDEFAULT = true; + /** + * The cached value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected boolean poll = POLL_EDEFAULT; + /** + * The default value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected static final AtomicBoolean ENABLED_A_EDEFAULT = null; + /** + * The cached value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected AtomicBoolean enabledA = ENABLED_A_EDEFAULT; + /** + * The default value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected static final String SUB_ID_EDEFAULT = null; + /** + * The cached value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected String subId = SUB_ID_EDEFAULT; + /** + * The cached value of the '{@link #getSensorValue() Sensor Value}' attribute. + * + * + * @see #getSensorValue() + * @generated + * @ordered + */ + protected HighLowValue sensorValue; + private StateListener listener; + private BrickletDualButton tinkerforgeDevice; + + /** + * + * + * @generated + */ + protected DualButtonLeftButtonImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.DUAL_BUTTON_LEFT_BUTTON; + } + + /** + * + * + * @generated + */ + public Logger getLogger() + { + return logger; + } + + /** + * + * + * @generated + */ + public void setLogger(Logger newLogger) + { + Logger oldLogger = logger; + logger = newLogger; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_BUTTON__LOGGER, oldLogger, logger)); + } + + /** + * + * + * @generated + */ + public String getUid() + { + return uid; + } + + /** + * + * + * @generated + */ + public void setUid(String newUid) + { + String oldUid = uid; + uid = newUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_BUTTON__UID, oldUid, uid)); + } + + /** + * + * + * @generated + */ + public boolean isPoll() + { + return poll; + } + + /** + * + * + * @generated + */ + public void setPoll(boolean newPoll) + { + boolean oldPoll = poll; + poll = newPoll; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_BUTTON__POLL, oldPoll, poll)); + } + + /** + * + * + * @generated + */ + public AtomicBoolean getEnabledA() + { + return enabledA; + } + + /** + * + * + * @generated + */ + public void setEnabledA(AtomicBoolean newEnabledA) + { + AtomicBoolean oldEnabledA = enabledA; + enabledA = newEnabledA; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_BUTTON__ENABLED_A, oldEnabledA, enabledA)); + } + + /** + * + * + * @generated + */ + public String getSubId() + { + return subId; + } + + /** + * + * + * @generated + */ + public void setSubId(String newSubId) + { + String oldSubId = subId; + subId = newSubId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SUB_ID, oldSubId, subId)); + } + + /** + * + * + * @generated + */ + public MBrickletDualButton getMbrick() + { + if (eContainerFeatureID() != ModelPackage.DUAL_BUTTON_LEFT_BUTTON__MBRICK) return null; + return (MBrickletDualButton)eContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetMbrick(MBrickletDualButton newMbrick, NotificationChain msgs) + { + msgs = eBasicSetContainer((InternalEObject)newMbrick, ModelPackage.DUAL_BUTTON_LEFT_BUTTON__MBRICK, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setMbrick(MBrickletDualButton newMbrick) + { + if (newMbrick != eInternalContainer() || (eContainerFeatureID() != ModelPackage.DUAL_BUTTON_LEFT_BUTTON__MBRICK && newMbrick != null)) + { + if (EcoreUtil.isAncestor(this, newMbrick)) + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + NotificationChain msgs = null; + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + if (newMbrick != null) + msgs = ((InternalEObject)newMbrick).eInverseAdd(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + msgs = basicSetMbrick(newMbrick, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_BUTTON__MBRICK, newMbrick, newMbrick)); + } + + /** + * + * + * @generated + */ + public HighLowValue getSensorValue() + { + return sensorValue; + } + + /** + * + * + * @generated + */ + public void setSensorValue(HighLowValue newSensorValue) + { + HighLowValue oldSensorValue = sensorValue; + sensorValue = newSensorValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SENSOR_VALUE, oldSensorValue, sensorValue)); + } + + /** + * + * + * @generated NOT + */ + public void fetchSensorValue() + { + try { + ButtonState buttonState = tinkerforgeDevice.getButtonState(); + setSensorValue(getValue4State(buttonState.buttonL)); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + public void init() + { + setEnabledA(new AtomicBoolean()); + logger = LoggerFactory.getLogger(DualButtonLeftButtonImpl.class); + } + + /** + * + * + * @generated NOT + */ + public void enable() + { + tinkerforgeDevice = getMbrick().getTinkerforgeDevice(); + listener = new StateListener(); + tinkerforgeDevice.addStateChangedListener(listener); + fetchSensorValue(); + } + + /** + * + * + * @generated NOT + */ + private class StateListener implements BrickletDualButton.StateChangedListener { + + @Override + public void stateChanged(short buttonL, short buttonR, short ledL, short ledR) { + HighLowValue value = getValue4State(buttonL); + setSensorValue(value); + } + + } + + private HighLowValue getValue4State(short state) { + return state == BrickletDualButton.BUTTON_STATE_PRESSED ? HighLowValue.LOW : HighLowValue.HIGH; + } + + /** + * + * + * @generated NOT + */ + public void disable() + { + if (listener != null) { + tinkerforgeDevice.removeStateChangedListener(listener); + } + tinkerforgeDevice = null; + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__MBRICK: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetMbrick((MBrickletDualButton)otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__MBRICK: + return basicSetMbrick(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) + { + switch (eContainerFeatureID()) + { + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__MBRICK: + return eInternalContainer().eInverseRemove(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__LOGGER: + return getLogger(); + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__UID: + return getUid(); + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__POLL: + return isPoll(); + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__ENABLED_A: + return getEnabledA(); + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SUB_ID: + return getSubId(); + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__MBRICK: + return getMbrick(); + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SENSOR_VALUE: + return getSensorValue(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__LOGGER: + setLogger((Logger)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__UID: + setUid((String)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__POLL: + setPoll((Boolean)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__ENABLED_A: + setEnabledA((AtomicBoolean)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SUB_ID: + setSubId((String)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__MBRICK: + setMbrick((MBrickletDualButton)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SENSOR_VALUE: + setSensorValue((HighLowValue)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__LOGGER: + setLogger(LOGGER_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__UID: + setUid(UID_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__POLL: + setPoll(POLL_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__ENABLED_A: + setEnabledA(ENABLED_A_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SUB_ID: + setSubId(SUB_ID_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__MBRICK: + setMbrick((MBrickletDualButton)null); + return; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SENSOR_VALUE: + setSensorValue((HighLowValue)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__LOGGER: + return LOGGER_EDEFAULT == null ? logger != null : !LOGGER_EDEFAULT.equals(logger); + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__UID: + return UID_EDEFAULT == null ? uid != null : !UID_EDEFAULT.equals(uid); + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__POLL: + return poll != POLL_EDEFAULT; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__ENABLED_A: + return ENABLED_A_EDEFAULT == null ? enabledA != null : !ENABLED_A_EDEFAULT.equals(enabledA); + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SUB_ID: + return SUB_ID_EDEFAULT == null ? subId != null : !SUB_ID_EDEFAULT.equals(subId); + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__MBRICK: + return getMbrick() != null; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SENSOR_VALUE: + return sensorValue != null; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SENSOR_VALUE: return ModelPackage.MSENSOR__SENSOR_VALUE; + default: return -1; + } + } + return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (baseFeatureID) + { + case ModelPackage.MSENSOR__SENSOR_VALUE: return ModelPackage.DUAL_BUTTON_LEFT_BUTTON__SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedOperationID(int baseOperationID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (baseOperationID) + { + case ModelPackage.MSENSOR___FETCH_SENSOR_VALUE: return ModelPackage.DUAL_BUTTON_LEFT_BUTTON___FETCH_SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedOperationID(baseOperationID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public Object eInvoke(int operationID, EList arguments) throws InvocationTargetException + { + switch (operationID) + { + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON___FETCH_SENSOR_VALUE: + fetchSensorValue(); + return null; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON___INIT: + init(); + return null; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON___ENABLE: + enable(); + return null; + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON___DISABLE: + disable(); + return null; + } + return super.eInvoke(operationID, arguments); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (logger: "); + result.append(logger); + result.append(", uid: "); + result.append(uid); + result.append(", poll: "); + result.append(poll); + result.append(", enabledA: "); + result.append(enabledA); + result.append(", subId: "); + result.append(subId); + result.append(", sensorValue: "); + result.append(sensorValue); + result.append(')'); + return result.toString(); + } + +} //DualButtonLeftButtonImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonLeftLedImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonLeftLedImpl.java new file mode 100644 index 00000000000..414089c562e --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonLeftLedImpl.java @@ -0,0 +1,765 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.openhab.binding.tinkerforge.internal.TinkerforgeErrorHandler; +import org.openhab.binding.tinkerforge.internal.model.DigitalActor; +import org.openhab.binding.tinkerforge.internal.model.DualButtonLeftLed; +import org.openhab.binding.tinkerforge.internal.model.MBrickletDualButton; +import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.types.HighLowValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerforge.BrickletDualButton; +import com.tinkerforge.BrickletDualButton.LEDState; +import com.tinkerforge.NotConnectedException; +import com.tinkerforge.TimeoutException; + +/** + * + * An implementation of the model object 'Dual Button Left Led'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftLedImpl#getLogger Logger}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftLedImpl#getUid Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftLedImpl#isPoll Poll}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftLedImpl#getEnabledA Enabled A}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftLedImpl#getSubId Sub Id}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftLedImpl#getMbrick Mbrick}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonLeftLedImpl#getDigitalState Digital State}
      • + *
      + *

      + * + * @generated + */ +public class DualButtonLeftLedImpl extends MinimalEObjectImpl.Container implements DualButtonLeftLed +{ + /** + * The default value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected static final Logger LOGGER_EDEFAULT = null; + /** + * The cached value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected Logger logger = LOGGER_EDEFAULT; + /** + * The default value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected static final String UID_EDEFAULT = null; + /** + * The cached value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected String uid = UID_EDEFAULT; + /** + * The default value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected static final boolean POLL_EDEFAULT = true; + /** + * The cached value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected boolean poll = POLL_EDEFAULT; + /** + * The default value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected static final AtomicBoolean ENABLED_A_EDEFAULT = null; + /** + * The cached value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected AtomicBoolean enabledA = ENABLED_A_EDEFAULT; + /** + * The default value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected static final String SUB_ID_EDEFAULT = null; + /** + * The cached value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected String subId = SUB_ID_EDEFAULT; + /** + * The default value of the '{@link #getDigitalState() Digital State}' attribute. + * + * + * @see #getDigitalState() + * @generated + * @ordered + */ + protected static final HighLowValue DIGITAL_STATE_EDEFAULT = null; + /** + * The cached value of the '{@link #getDigitalState() Digital State}' attribute. + * + * + * @see #getDigitalState() + * @generated + * @ordered + */ + protected HighLowValue digitalState = DIGITAL_STATE_EDEFAULT; + private BrickletDualButton tinkerforgeDevice; + private StateListener listener; + + /** + * + * + * @generated + */ + protected DualButtonLeftLedImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.DUAL_BUTTON_LEFT_LED; + } + + /** + * + * + * @generated + */ + public Logger getLogger() + { + return logger; + } + + /** + * + * + * @generated + */ + public void setLogger(Logger newLogger) + { + Logger oldLogger = logger; + logger = newLogger; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_LED__LOGGER, oldLogger, logger)); + } + + /** + * + * + * @generated + */ + public String getUid() + { + return uid; + } + + /** + * + * + * @generated + */ + public void setUid(String newUid) + { + String oldUid = uid; + uid = newUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_LED__UID, oldUid, uid)); + } + + /** + * + * + * @generated + */ + public boolean isPoll() + { + return poll; + } + + /** + * + * + * @generated + */ + public void setPoll(boolean newPoll) + { + boolean oldPoll = poll; + poll = newPoll; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_LED__POLL, oldPoll, poll)); + } + + /** + * + * + * @generated + */ + public AtomicBoolean getEnabledA() + { + return enabledA; + } + + /** + * + * + * @generated + */ + public void setEnabledA(AtomicBoolean newEnabledA) + { + AtomicBoolean oldEnabledA = enabledA; + enabledA = newEnabledA; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_LED__ENABLED_A, oldEnabledA, enabledA)); + } + + /** + * + * + * @generated + */ + public String getSubId() + { + return subId; + } + + /** + * + * + * @generated + */ + public void setSubId(String newSubId) + { + String oldSubId = subId; + subId = newSubId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_LED__SUB_ID, oldSubId, subId)); + } + + /** + * + * + * @generated + */ + public MBrickletDualButton getMbrick() + { + if (eContainerFeatureID() != ModelPackage.DUAL_BUTTON_LEFT_LED__MBRICK) return null; + return (MBrickletDualButton)eContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetMbrick(MBrickletDualButton newMbrick, NotificationChain msgs) + { + msgs = eBasicSetContainer((InternalEObject)newMbrick, ModelPackage.DUAL_BUTTON_LEFT_LED__MBRICK, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setMbrick(MBrickletDualButton newMbrick) + { + if (newMbrick != eInternalContainer() || (eContainerFeatureID() != ModelPackage.DUAL_BUTTON_LEFT_LED__MBRICK && newMbrick != null)) + { + if (EcoreUtil.isAncestor(this, newMbrick)) + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + NotificationChain msgs = null; + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + if (newMbrick != null) + msgs = ((InternalEObject)newMbrick).eInverseAdd(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + msgs = basicSetMbrick(newMbrick, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_LED__MBRICK, newMbrick, newMbrick)); + } + + /** + * + * + * @generated + */ + public HighLowValue getDigitalState() + { + return digitalState; + } + + /** + * + * + * @generated + */ + public void setDigitalState(HighLowValue newDigitalState) + { + HighLowValue oldDigitalState = digitalState; + digitalState = newDigitalState; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_LEFT_LED__DIGITAL_STATE, oldDigitalState, digitalState)); + } + + /** + * + * + * @generated NOT + */ + public void turnDigital(HighLowValue digitalState) + { + try { + tinkerforgeDevice.setSelectedLEDState(BrickletDualButton.LED_LEFT, + getState4Value(digitalState)); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + + /** + * + * + * @generated NOT + */ + public void fetchDigitalValue() + { + try { + LEDState ledState = tinkerforgeDevice.getLEDState(); + setDigitalState(getValue4State(ledState.ledL)); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + public void init() + { + setEnabledA(new AtomicBoolean()); + logger = LoggerFactory.getLogger(DualButtonLeftLedImpl.class); + } + + /** + * + * + * @generated NOT + */ + public void enable() + { + tinkerforgeDevice = getMbrick().getTinkerforgeDevice(); + listener = new StateListener(); + tinkerforgeDevice.addStateChangedListener(listener); + fetchDigitalValue(); + } + + /** + * + * + * @generated NOT + */ + private class StateListener implements BrickletDualButton.StateChangedListener { + + @Override + public void stateChanged(short buttonL, short buttonR, short ledL, short ledR) { + HighLowValue value = getValue4State(ledL); + setDigitalState(value); + } + + } + + private HighLowValue getValue4State(short state) { + HighLowValue value = HighLowValue.UNDEF; + if (state == BrickletDualButton.LED_STATE_AUTO_TOGGLE_OFF + || state == BrickletDualButton.LED_STATE_AUTO_TOGGLE_ON) { + value = HighLowValue.UNDEF; + } else if (state == BrickletDualButton.LED_STATE_ON) { + value = HighLowValue.HIGH; + } else if (state == BrickletDualButton.LED_STATE_OFF) { + value = HighLowValue.LOW; + } + return value; + } + + private short getState4Value(HighLowValue value) { + return value == HighLowValue.LOW + ? BrickletDualButton.LED_STATE_OFF + : BrickletDualButton.LED_STATE_ON; + } + + /** + * + * + * @generated NOT + */ + public void disable() + { + if (listener != null) { + tinkerforgeDevice.removeStateChangedListener(listener); + } + tinkerforgeDevice = null; + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_LED__MBRICK: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetMbrick((MBrickletDualButton)otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_LED__MBRICK: + return basicSetMbrick(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) + { + switch (eContainerFeatureID()) + { + case ModelPackage.DUAL_BUTTON_LEFT_LED__MBRICK: + return eInternalContainer().eInverseRemove(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_LED__LOGGER: + return getLogger(); + case ModelPackage.DUAL_BUTTON_LEFT_LED__UID: + return getUid(); + case ModelPackage.DUAL_BUTTON_LEFT_LED__POLL: + return isPoll(); + case ModelPackage.DUAL_BUTTON_LEFT_LED__ENABLED_A: + return getEnabledA(); + case ModelPackage.DUAL_BUTTON_LEFT_LED__SUB_ID: + return getSubId(); + case ModelPackage.DUAL_BUTTON_LEFT_LED__MBRICK: + return getMbrick(); + case ModelPackage.DUAL_BUTTON_LEFT_LED__DIGITAL_STATE: + return getDigitalState(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_LED__LOGGER: + setLogger((Logger)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__UID: + setUid((String)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__POLL: + setPoll((Boolean)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__ENABLED_A: + setEnabledA((AtomicBoolean)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__SUB_ID: + setSubId((String)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__MBRICK: + setMbrick((MBrickletDualButton)newValue); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__DIGITAL_STATE: + setDigitalState((HighLowValue)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_LED__LOGGER: + setLogger(LOGGER_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__UID: + setUid(UID_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__POLL: + setPoll(POLL_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__ENABLED_A: + setEnabledA(ENABLED_A_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__SUB_ID: + setSubId(SUB_ID_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__MBRICK: + setMbrick((MBrickletDualButton)null); + return; + case ModelPackage.DUAL_BUTTON_LEFT_LED__DIGITAL_STATE: + setDigitalState(DIGITAL_STATE_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_LED__LOGGER: + return LOGGER_EDEFAULT == null ? logger != null : !LOGGER_EDEFAULT.equals(logger); + case ModelPackage.DUAL_BUTTON_LEFT_LED__UID: + return UID_EDEFAULT == null ? uid != null : !UID_EDEFAULT.equals(uid); + case ModelPackage.DUAL_BUTTON_LEFT_LED__POLL: + return poll != POLL_EDEFAULT; + case ModelPackage.DUAL_BUTTON_LEFT_LED__ENABLED_A: + return ENABLED_A_EDEFAULT == null ? enabledA != null : !ENABLED_A_EDEFAULT.equals(enabledA); + case ModelPackage.DUAL_BUTTON_LEFT_LED__SUB_ID: + return SUB_ID_EDEFAULT == null ? subId != null : !SUB_ID_EDEFAULT.equals(subId); + case ModelPackage.DUAL_BUTTON_LEFT_LED__MBRICK: + return getMbrick() != null; + case ModelPackage.DUAL_BUTTON_LEFT_LED__DIGITAL_STATE: + return DIGITAL_STATE_EDEFAULT == null ? digitalState != null : !DIGITAL_STATE_EDEFAULT.equals(digitalState); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) + { + if (baseClass == DigitalActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.DUAL_BUTTON_LEFT_LED__DIGITAL_STATE: return ModelPackage.DIGITAL_ACTOR__DIGITAL_STATE; + default: return -1; + } + } + return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) + { + if (baseClass == DigitalActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.DIGITAL_ACTOR__DIGITAL_STATE: return ModelPackage.DUAL_BUTTON_LEFT_LED__DIGITAL_STATE; + default: return -1; + } + } + return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedOperationID(int baseOperationID, Class baseClass) + { + if (baseClass == DigitalActor.class) + { + switch (baseOperationID) + { + case ModelPackage.DIGITAL_ACTOR___TURN_DIGITAL__HIGHLOWVALUE: return ModelPackage.DUAL_BUTTON_LEFT_LED___TURN_DIGITAL__HIGHLOWVALUE; + case ModelPackage.DIGITAL_ACTOR___FETCH_DIGITAL_VALUE: return ModelPackage.DUAL_BUTTON_LEFT_LED___FETCH_DIGITAL_VALUE; + default: return -1; + } + } + return super.eDerivedOperationID(baseOperationID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public Object eInvoke(int operationID, EList arguments) throws InvocationTargetException + { + switch (operationID) + { + case ModelPackage.DUAL_BUTTON_LEFT_LED___TURN_DIGITAL__HIGHLOWVALUE: + turnDigital((HighLowValue)arguments.get(0)); + return null; + case ModelPackage.DUAL_BUTTON_LEFT_LED___FETCH_DIGITAL_VALUE: + fetchDigitalValue(); + return null; + case ModelPackage.DUAL_BUTTON_LEFT_LED___INIT: + init(); + return null; + case ModelPackage.DUAL_BUTTON_LEFT_LED___ENABLE: + enable(); + return null; + case ModelPackage.DUAL_BUTTON_LEFT_LED___DISABLE: + disable(); + return null; + } + return super.eInvoke(operationID, arguments); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (logger: "); + result.append(logger); + result.append(", uid: "); + result.append(uid); + result.append(", poll: "); + result.append(poll); + result.append(", enabledA: "); + result.append(enabledA); + result.append(", subId: "); + result.append(subId); + result.append(", digitalState: "); + result.append(digitalState); + result.append(')'); + return result.toString(); + } + +} //DualButtonLeftLedImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonRightButtonImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonRightButtonImpl.java new file mode 100644 index 00000000000..74bd9a022c9 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonRightButtonImpl.java @@ -0,0 +1,719 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.openhab.binding.tinkerforge.internal.TinkerforgeErrorHandler; +import org.openhab.binding.tinkerforge.internal.model.DualButtonRightButton; +import org.openhab.binding.tinkerforge.internal.model.MBrickletDualButton; +import org.openhab.binding.tinkerforge.internal.model.MSensor; +import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.types.HighLowValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerforge.BrickletDualButton; +import com.tinkerforge.BrickletDualButton.ButtonState; +import com.tinkerforge.NotConnectedException; +import com.tinkerforge.TimeoutException; + +/** + * + * An implementation of the model object 'Dual Button Right Button'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightButtonImpl#getLogger Logger}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightButtonImpl#getUid Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightButtonImpl#isPoll Poll}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightButtonImpl#getEnabledA Enabled A}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightButtonImpl#getSubId Sub Id}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightButtonImpl#getMbrick Mbrick}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightButtonImpl#getSensorValue Sensor Value}
      • + *
      + *

      + * + * @generated + */ +public class DualButtonRightButtonImpl extends MinimalEObjectImpl.Container implements DualButtonRightButton +{ + /** + * The default value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected static final Logger LOGGER_EDEFAULT = null; + /** + * The cached value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected Logger logger = LOGGER_EDEFAULT; + /** + * The default value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected static final String UID_EDEFAULT = null; + /** + * The cached value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected String uid = UID_EDEFAULT; + /** + * The default value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected static final boolean POLL_EDEFAULT = true; + /** + * The cached value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected boolean poll = POLL_EDEFAULT; + /** + * The default value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected static final AtomicBoolean ENABLED_A_EDEFAULT = null; + /** + * The cached value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected AtomicBoolean enabledA = ENABLED_A_EDEFAULT; + /** + * The default value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected static final String SUB_ID_EDEFAULT = null; + /** + * The cached value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected String subId = SUB_ID_EDEFAULT; + /** + * The cached value of the '{@link #getSensorValue() Sensor Value}' attribute. + * + * + * @see #getSensorValue() + * @generated + * @ordered + */ + protected HighLowValue sensorValue; + private BrickletDualButton tinkerforgeDevice; + private StateListener listener; + + /** + * + * + * @generated + */ + protected DualButtonRightButtonImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.DUAL_BUTTON_RIGHT_BUTTON; + } + + /** + * + * + * @generated + */ + public Logger getLogger() + { + return logger; + } + + /** + * + * + * @generated + */ + public void setLogger(Logger newLogger) + { + Logger oldLogger = logger; + logger = newLogger; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__LOGGER, oldLogger, logger)); + } + + /** + * + * + * @generated + */ + public String getUid() + { + return uid; + } + + /** + * + * + * @generated + */ + public void setUid(String newUid) + { + String oldUid = uid; + uid = newUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__UID, oldUid, uid)); + } + + /** + * + * + * @generated + */ + public boolean isPoll() + { + return poll; + } + + /** + * + * + * @generated + */ + public void setPoll(boolean newPoll) + { + boolean oldPoll = poll; + poll = newPoll; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__POLL, oldPoll, poll)); + } + + /** + * + * + * @generated + */ + public AtomicBoolean getEnabledA() + { + return enabledA; + } + + /** + * + * + * @generated + */ + public void setEnabledA(AtomicBoolean newEnabledA) + { + AtomicBoolean oldEnabledA = enabledA; + enabledA = newEnabledA; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__ENABLED_A, oldEnabledA, enabledA)); + } + + /** + * + * + * @generated + */ + public String getSubId() + { + return subId; + } + + /** + * + * + * @generated + */ + public void setSubId(String newSubId) + { + String oldSubId = subId; + subId = newSubId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SUB_ID, oldSubId, subId)); + } + + /** + * + * + * @generated + */ + public MBrickletDualButton getMbrick() + { + if (eContainerFeatureID() != ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__MBRICK) return null; + return (MBrickletDualButton)eContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetMbrick(MBrickletDualButton newMbrick, NotificationChain msgs) + { + msgs = eBasicSetContainer((InternalEObject)newMbrick, ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__MBRICK, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setMbrick(MBrickletDualButton newMbrick) + { + if (newMbrick != eInternalContainer() || (eContainerFeatureID() != ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__MBRICK && newMbrick != null)) + { + if (EcoreUtil.isAncestor(this, newMbrick)) + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + NotificationChain msgs = null; + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + if (newMbrick != null) + msgs = ((InternalEObject)newMbrick).eInverseAdd(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + msgs = basicSetMbrick(newMbrick, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__MBRICK, newMbrick, newMbrick)); + } + + /** + * + * + * @generated + */ + public HighLowValue getSensorValue() + { + return sensorValue; + } + + /** + * + * + * @generated + */ + public void setSensorValue(HighLowValue newSensorValue) + { + HighLowValue oldSensorValue = sensorValue; + sensorValue = newSensorValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SENSOR_VALUE, oldSensorValue, sensorValue)); + } + + /** + * + * + * @generated NOT + */ + public void fetchSensorValue() + { + try { + ButtonState buttonState = tinkerforgeDevice.getButtonState(); + setSensorValue(getValue4State(buttonState.buttonR)); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + public void init() + { + setEnabledA(new AtomicBoolean()); + logger = LoggerFactory.getLogger(DualButtonRightButtonImpl.class); + } + + /** + * + * + * @generated NOT + */ + public void enable() + { + tinkerforgeDevice = getMbrick().getTinkerforgeDevice(); + listener = new StateListener(); + tinkerforgeDevice.addStateChangedListener(listener); + fetchSensorValue(); + } + + /** + * + * + * @generated NOT + */ + private class StateListener implements BrickletDualButton.StateChangedListener { + + @Override + public void stateChanged(short buttonL, short buttonR, short ledL, short ledR) { + HighLowValue value = getValue4State(buttonR); + setSensorValue(value); + } + + } + + private HighLowValue getValue4State(short state) { + return state == BrickletDualButton.BUTTON_STATE_PRESSED ? HighLowValue.LOW : HighLowValue.HIGH; + } + + + /** + * + * + * @generated NOT + */ + public void disable() + { + if (listener != null) { + tinkerforgeDevice.removeStateChangedListener(listener); + } + tinkerforgeDevice = null; + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__MBRICK: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetMbrick((MBrickletDualButton)otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__MBRICK: + return basicSetMbrick(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) + { + switch (eContainerFeatureID()) + { + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__MBRICK: + return eInternalContainer().eInverseRemove(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__LOGGER: + return getLogger(); + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__UID: + return getUid(); + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__POLL: + return isPoll(); + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__ENABLED_A: + return getEnabledA(); + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SUB_ID: + return getSubId(); + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__MBRICK: + return getMbrick(); + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SENSOR_VALUE: + return getSensorValue(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__LOGGER: + setLogger((Logger)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__UID: + setUid((String)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__POLL: + setPoll((Boolean)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__ENABLED_A: + setEnabledA((AtomicBoolean)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SUB_ID: + setSubId((String)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__MBRICK: + setMbrick((MBrickletDualButton)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SENSOR_VALUE: + setSensorValue((HighLowValue)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__LOGGER: + setLogger(LOGGER_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__UID: + setUid(UID_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__POLL: + setPoll(POLL_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__ENABLED_A: + setEnabledA(ENABLED_A_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SUB_ID: + setSubId(SUB_ID_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__MBRICK: + setMbrick((MBrickletDualButton)null); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SENSOR_VALUE: + setSensorValue((HighLowValue)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__LOGGER: + return LOGGER_EDEFAULT == null ? logger != null : !LOGGER_EDEFAULT.equals(logger); + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__UID: + return UID_EDEFAULT == null ? uid != null : !UID_EDEFAULT.equals(uid); + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__POLL: + return poll != POLL_EDEFAULT; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__ENABLED_A: + return ENABLED_A_EDEFAULT == null ? enabledA != null : !ENABLED_A_EDEFAULT.equals(enabledA); + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SUB_ID: + return SUB_ID_EDEFAULT == null ? subId != null : !SUB_ID_EDEFAULT.equals(subId); + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__MBRICK: + return getMbrick() != null; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SENSOR_VALUE: + return sensorValue != null; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SENSOR_VALUE: return ModelPackage.MSENSOR__SENSOR_VALUE; + default: return -1; + } + } + return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (baseFeatureID) + { + case ModelPackage.MSENSOR__SENSOR_VALUE: return ModelPackage.DUAL_BUTTON_RIGHT_BUTTON__SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedOperationID(int baseOperationID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (baseOperationID) + { + case ModelPackage.MSENSOR___FETCH_SENSOR_VALUE: return ModelPackage.DUAL_BUTTON_RIGHT_BUTTON___FETCH_SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedOperationID(baseOperationID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public Object eInvoke(int operationID, EList arguments) throws InvocationTargetException + { + switch (operationID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON___FETCH_SENSOR_VALUE: + fetchSensorValue(); + return null; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON___INIT: + init(); + return null; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON___ENABLE: + enable(); + return null; + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON___DISABLE: + disable(); + return null; + } + return super.eInvoke(operationID, arguments); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (logger: "); + result.append(logger); + result.append(", uid: "); + result.append(uid); + result.append(", poll: "); + result.append(poll); + result.append(", enabledA: "); + result.append(enabledA); + result.append(", subId: "); + result.append(subId); + result.append(", sensorValue: "); + result.append(sensorValue); + result.append(')'); + return result.toString(); + } + +} //DualButtonRightButtonImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonRightLedImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonRightLedImpl.java new file mode 100644 index 00000000000..668ea96119f --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/DualButtonRightLedImpl.java @@ -0,0 +1,764 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.openhab.binding.tinkerforge.internal.TinkerforgeErrorHandler; +import org.openhab.binding.tinkerforge.internal.model.DigitalActor; +import org.openhab.binding.tinkerforge.internal.model.DualButtonRightLed; +import org.openhab.binding.tinkerforge.internal.model.MBrickletDualButton; +import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.types.HighLowValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerforge.BrickletDualButton; +import com.tinkerforge.BrickletDualButton.LEDState; +import com.tinkerforge.NotConnectedException; +import com.tinkerforge.TimeoutException; + +/** + * + * An implementation of the model object 'Dual Button Right Led'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightLedImpl#getLogger Logger}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightLedImpl#getUid Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightLedImpl#isPoll Poll}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightLedImpl#getEnabledA Enabled A}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightLedImpl#getSubId Sub Id}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightLedImpl#getMbrick Mbrick}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.DualButtonRightLedImpl#getDigitalState Digital State}
      • + *
      + *

      + * + * @generated + */ +public class DualButtonRightLedImpl extends MinimalEObjectImpl.Container implements DualButtonRightLed +{ + /** + * The default value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected static final Logger LOGGER_EDEFAULT = null; + /** + * The cached value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected Logger logger = LOGGER_EDEFAULT; + /** + * The default value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected static final String UID_EDEFAULT = null; + /** + * The cached value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected String uid = UID_EDEFAULT; + /** + * The default value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected static final boolean POLL_EDEFAULT = true; + /** + * The cached value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected boolean poll = POLL_EDEFAULT; + /** + * The default value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected static final AtomicBoolean ENABLED_A_EDEFAULT = null; + /** + * The cached value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected AtomicBoolean enabledA = ENABLED_A_EDEFAULT; + /** + * The default value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected static final String SUB_ID_EDEFAULT = null; + /** + * The cached value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected String subId = SUB_ID_EDEFAULT; + /** + * The default value of the '{@link #getDigitalState() Digital State}' attribute. + * + * + * @see #getDigitalState() + * @generated + * @ordered + */ + protected static final HighLowValue DIGITAL_STATE_EDEFAULT = null; + /** + * The cached value of the '{@link #getDigitalState() Digital State}' attribute. + * + * + * @see #getDigitalState() + * @generated + * @ordered + */ + protected HighLowValue digitalState = DIGITAL_STATE_EDEFAULT; + private BrickletDualButton tinkerforgeDevice; + private StateListener listener; + + /** + * + * + * @generated + */ + protected DualButtonRightLedImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.DUAL_BUTTON_RIGHT_LED; + } + + /** + * + * + * @generated + */ + public Logger getLogger() + { + return logger; + } + + /** + * + * + * @generated + */ + public void setLogger(Logger newLogger) + { + Logger oldLogger = logger; + logger = newLogger; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_LED__LOGGER, oldLogger, logger)); + } + + /** + * + * + * @generated + */ + public String getUid() + { + return uid; + } + + /** + * + * + * @generated + */ + public void setUid(String newUid) + { + String oldUid = uid; + uid = newUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_LED__UID, oldUid, uid)); + } + + /** + * + * + * @generated + */ + public boolean isPoll() + { + return poll; + } + + /** + * + * + * @generated + */ + public void setPoll(boolean newPoll) + { + boolean oldPoll = poll; + poll = newPoll; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_LED__POLL, oldPoll, poll)); + } + + /** + * + * + * @generated + */ + public AtomicBoolean getEnabledA() + { + return enabledA; + } + + /** + * + * + * @generated + */ + public void setEnabledA(AtomicBoolean newEnabledA) + { + AtomicBoolean oldEnabledA = enabledA; + enabledA = newEnabledA; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_LED__ENABLED_A, oldEnabledA, enabledA)); + } + + /** + * + * + * @generated + */ + public String getSubId() + { + return subId; + } + + /** + * + * + * @generated + */ + public void setSubId(String newSubId) + { + String oldSubId = subId; + subId = newSubId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_LED__SUB_ID, oldSubId, subId)); + } + + /** + * + * + * @generated + */ + public MBrickletDualButton getMbrick() + { + if (eContainerFeatureID() != ModelPackage.DUAL_BUTTON_RIGHT_LED__MBRICK) return null; + return (MBrickletDualButton)eContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetMbrick(MBrickletDualButton newMbrick, NotificationChain msgs) + { + msgs = eBasicSetContainer((InternalEObject)newMbrick, ModelPackage.DUAL_BUTTON_RIGHT_LED__MBRICK, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setMbrick(MBrickletDualButton newMbrick) + { + if (newMbrick != eInternalContainer() || (eContainerFeatureID() != ModelPackage.DUAL_BUTTON_RIGHT_LED__MBRICK && newMbrick != null)) + { + if (EcoreUtil.isAncestor(this, newMbrick)) + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + NotificationChain msgs = null; + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + if (newMbrick != null) + msgs = ((InternalEObject)newMbrick).eInverseAdd(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + msgs = basicSetMbrick(newMbrick, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_LED__MBRICK, newMbrick, newMbrick)); + } + + /** + * + * + * @generated + */ + public HighLowValue getDigitalState() + { + return digitalState; + } + + /** + * + * + * @generated + */ + public void setDigitalState(HighLowValue newDigitalState) + { + HighLowValue oldDigitalState = digitalState; + digitalState = newDigitalState; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.DUAL_BUTTON_RIGHT_LED__DIGITAL_STATE, oldDigitalState, digitalState)); + } + + /** + * + * + * @generated NOT + */ + public void turnDigital(HighLowValue digitalState) + { + try { + tinkerforgeDevice.setSelectedLEDState(BrickletDualButton.LED_RIGHT, + getState4Value(digitalState)); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + public void fetchDigitalValue() + { + try { + LEDState ledState = tinkerforgeDevice.getLEDState(); + setDigitalState(getValue4State(ledState.ledR)); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + public void init() + { + setEnabledA(new AtomicBoolean()); + logger = LoggerFactory.getLogger(DualButtonRightLedImpl.class); + } + + /** + * + * + * @generated NOT + */ + public void enable() + { + tinkerforgeDevice = getMbrick().getTinkerforgeDevice(); + listener = new StateListener(); + tinkerforgeDevice.addStateChangedListener(listener); + fetchDigitalValue(); + } + + /** + * + * + * @generated NOT + */ + private class StateListener implements BrickletDualButton.StateChangedListener { + + @Override + public void stateChanged(short buttonL, short buttonR, short ledL, short ledR) { + HighLowValue value = getValue4State(ledR); + setDigitalState(value); + } + + } + + private HighLowValue getValue4State(short state) { + HighLowValue value = HighLowValue.UNDEF; + if (state == BrickletDualButton.LED_STATE_AUTO_TOGGLE_OFF + || state == BrickletDualButton.LED_STATE_AUTO_TOGGLE_ON) { + value = HighLowValue.UNDEF; + } else if (state == BrickletDualButton.LED_STATE_ON) { + value = HighLowValue.HIGH; + } else if (state == BrickletDualButton.LED_STATE_OFF) { + value = HighLowValue.LOW; + } + return value; + } + + private short getState4Value(HighLowValue value) { + return value == HighLowValue.LOW + ? BrickletDualButton.LED_STATE_OFF + : BrickletDualButton.LED_STATE_ON; + } + + + /** + * + * + * @generated + */ + public void disable() + { + // TODO: implement this method + // Ensure that you remove @generated or mark it @generated NOT + throw new UnsupportedOperationException(); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_LED__MBRICK: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetMbrick((MBrickletDualButton)otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_LED__MBRICK: + return basicSetMbrick(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) + { + switch (eContainerFeatureID()) + { + case ModelPackage.DUAL_BUTTON_RIGHT_LED__MBRICK: + return eInternalContainer().eInverseRemove(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_LED__LOGGER: + return getLogger(); + case ModelPackage.DUAL_BUTTON_RIGHT_LED__UID: + return getUid(); + case ModelPackage.DUAL_BUTTON_RIGHT_LED__POLL: + return isPoll(); + case ModelPackage.DUAL_BUTTON_RIGHT_LED__ENABLED_A: + return getEnabledA(); + case ModelPackage.DUAL_BUTTON_RIGHT_LED__SUB_ID: + return getSubId(); + case ModelPackage.DUAL_BUTTON_RIGHT_LED__MBRICK: + return getMbrick(); + case ModelPackage.DUAL_BUTTON_RIGHT_LED__DIGITAL_STATE: + return getDigitalState(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_LED__LOGGER: + setLogger((Logger)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__UID: + setUid((String)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__POLL: + setPoll((Boolean)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__ENABLED_A: + setEnabledA((AtomicBoolean)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__SUB_ID: + setSubId((String)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__MBRICK: + setMbrick((MBrickletDualButton)newValue); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__DIGITAL_STATE: + setDigitalState((HighLowValue)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_LED__LOGGER: + setLogger(LOGGER_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__UID: + setUid(UID_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__POLL: + setPoll(POLL_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__ENABLED_A: + setEnabledA(ENABLED_A_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__SUB_ID: + setSubId(SUB_ID_EDEFAULT); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__MBRICK: + setMbrick((MBrickletDualButton)null); + return; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__DIGITAL_STATE: + setDigitalState(DIGITAL_STATE_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_LED__LOGGER: + return LOGGER_EDEFAULT == null ? logger != null : !LOGGER_EDEFAULT.equals(logger); + case ModelPackage.DUAL_BUTTON_RIGHT_LED__UID: + return UID_EDEFAULT == null ? uid != null : !UID_EDEFAULT.equals(uid); + case ModelPackage.DUAL_BUTTON_RIGHT_LED__POLL: + return poll != POLL_EDEFAULT; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__ENABLED_A: + return ENABLED_A_EDEFAULT == null ? enabledA != null : !ENABLED_A_EDEFAULT.equals(enabledA); + case ModelPackage.DUAL_BUTTON_RIGHT_LED__SUB_ID: + return SUB_ID_EDEFAULT == null ? subId != null : !SUB_ID_EDEFAULT.equals(subId); + case ModelPackage.DUAL_BUTTON_RIGHT_LED__MBRICK: + return getMbrick() != null; + case ModelPackage.DUAL_BUTTON_RIGHT_LED__DIGITAL_STATE: + return DIGITAL_STATE_EDEFAULT == null ? digitalState != null : !DIGITAL_STATE_EDEFAULT.equals(digitalState); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) + { + if (baseClass == DigitalActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_LED__DIGITAL_STATE: return ModelPackage.DIGITAL_ACTOR__DIGITAL_STATE; + default: return -1; + } + } + return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) + { + if (baseClass == DigitalActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.DIGITAL_ACTOR__DIGITAL_STATE: return ModelPackage.DUAL_BUTTON_RIGHT_LED__DIGITAL_STATE; + default: return -1; + } + } + return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedOperationID(int baseOperationID, Class baseClass) + { + if (baseClass == DigitalActor.class) + { + switch (baseOperationID) + { + case ModelPackage.DIGITAL_ACTOR___TURN_DIGITAL__HIGHLOWVALUE: return ModelPackage.DUAL_BUTTON_RIGHT_LED___TURN_DIGITAL__HIGHLOWVALUE; + case ModelPackage.DIGITAL_ACTOR___FETCH_DIGITAL_VALUE: return ModelPackage.DUAL_BUTTON_RIGHT_LED___FETCH_DIGITAL_VALUE; + default: return -1; + } + } + return super.eDerivedOperationID(baseOperationID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public Object eInvoke(int operationID, EList arguments) throws InvocationTargetException + { + switch (operationID) + { + case ModelPackage.DUAL_BUTTON_RIGHT_LED___TURN_DIGITAL__HIGHLOWVALUE: + turnDigital((HighLowValue)arguments.get(0)); + return null; + case ModelPackage.DUAL_BUTTON_RIGHT_LED___FETCH_DIGITAL_VALUE: + fetchDigitalValue(); + return null; + case ModelPackage.DUAL_BUTTON_RIGHT_LED___INIT: + init(); + return null; + case ModelPackage.DUAL_BUTTON_RIGHT_LED___ENABLE: + enable(); + return null; + case ModelPackage.DUAL_BUTTON_RIGHT_LED___DISABLE: + disable(); + return null; + } + return super.eInvoke(operationID, arguments); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (logger: "); + result.append(logger); + result.append(", uid: "); + result.append(uid); + result.append(", poll: "); + result.append(poll); + result.append(", enabledA: "); + result.append(enabledA); + result.append(", subId: "); + result.append(subId); + result.append(", digitalState: "); + result.append(digitalState); + result.append(')'); + return result.toString(); + } + +} //DualButtonRightLedImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/JoystickButtonImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/JoystickButtonImpl.java new file mode 100644 index 00000000000..4a9fba14089 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/JoystickButtonImpl.java @@ -0,0 +1,774 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.openhab.binding.tinkerforge.internal.LoggerConstants; +import org.openhab.binding.tinkerforge.internal.TinkerforgeErrorHandler; +import org.openhab.binding.tinkerforge.internal.model.JoystickButton; +import org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick; +import org.openhab.binding.tinkerforge.internal.model.MSensor; +import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.types.HighLowValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerforge.BrickletJoystick; +import com.tinkerforge.NotConnectedException; +import com.tinkerforge.TimeoutException; + +/** + * + * An implementation of the model object 'Joystick Button'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl#getLogger Logger}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl#getUid Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl#isPoll Poll}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl#getEnabledA Enabled A}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl#getSubId Sub Id}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl#getMbrick Mbrick}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl#getSensorValue Sensor Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickButtonImpl#getDeviceType Device Type}
      • + *
      + *

      + * + * @generated + */ +public class JoystickButtonImpl extends MinimalEObjectImpl.Container implements JoystickButton +{ + /** + * The default value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected static final Logger LOGGER_EDEFAULT = null; + + /** + * The cached value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected Logger logger = LOGGER_EDEFAULT; + + /** + * The default value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected static final String UID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected String uid = UID_EDEFAULT; + + /** + * The default value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected static final boolean POLL_EDEFAULT = true; + + /** + * The cached value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected boolean poll = POLL_EDEFAULT; + + /** + * The default value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected static final AtomicBoolean ENABLED_A_EDEFAULT = null; + + /** + * The cached value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected AtomicBoolean enabledA = ENABLED_A_EDEFAULT; + + /** + * The default value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected static final String SUB_ID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected String subId = SUB_ID_EDEFAULT; + + /** + * The cached value of the '{@link #getSensorValue() Sensor Value}' attribute. + * + * + * @see #getSensorValue() + * @generated + * @ordered + */ + protected HighLowValue sensorValue; + + /** + * The default value of the '{@link #getDeviceType() Device Type}' attribute. + * + * + * @see #getDeviceType() + * @generated + * @ordered + */ + protected static final String DEVICE_TYPE_EDEFAULT = "joystick_button"; + + /** + * The cached value of the '{@link #getDeviceType() Device Type}' attribute. + * + * + * @see #getDeviceType() + * @generated + * @ordered + */ + protected String deviceType = DEVICE_TYPE_EDEFAULT; + + private BrickletJoystick tinkerforgeDevice; + + private ButtonListener listener; + + /** + * + * + * @generated + */ + protected JoystickButtonImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.JOYSTICK_BUTTON; + } + + /** + * + * + * @generated + */ + public Logger getLogger() + { + return logger; + } + + /** + * + * + * @generated + */ + public void setLogger(Logger newLogger) + { + Logger oldLogger = logger; + logger = newLogger; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_BUTTON__LOGGER, oldLogger, logger)); + } + + /** + * + * + * @generated + */ + public String getUid() + { + return uid; + } + + /** + * + * + * @generated + */ + public void setUid(String newUid) + { + String oldUid = uid; + uid = newUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_BUTTON__UID, oldUid, uid)); + } + + /** + * + * + * @generated + */ + public boolean isPoll() + { + return poll; + } + + /** + * + * + * @generated + */ + public void setPoll(boolean newPoll) + { + boolean oldPoll = poll; + poll = newPoll; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_BUTTON__POLL, oldPoll, poll)); + } + + /** + * + * + * @generated + */ + public AtomicBoolean getEnabledA() + { + return enabledA; + } + + /** + * + * + * @generated + */ + public void setEnabledA(AtomicBoolean newEnabledA) + { + AtomicBoolean oldEnabledA = enabledA; + enabledA = newEnabledA; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_BUTTON__ENABLED_A, oldEnabledA, enabledA)); + } + + /** + * + * + * @generated + */ + public String getSubId() + { + return subId; + } + + /** + * + * + * @generated + */ + public void setSubId(String newSubId) + { + String oldSubId = subId; + subId = newSubId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_BUTTON__SUB_ID, oldSubId, subId)); + } + + /** + * + * + * @generated + */ + public MBrickletJoystick getMbrick() + { + if (eContainerFeatureID() != ModelPackage.JOYSTICK_BUTTON__MBRICK) return null; + return (MBrickletJoystick)eContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetMbrick(MBrickletJoystick newMbrick, NotificationChain msgs) + { + msgs = eBasicSetContainer((InternalEObject)newMbrick, ModelPackage.JOYSTICK_BUTTON__MBRICK, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setMbrick(MBrickletJoystick newMbrick) + { + if (newMbrick != eInternalContainer() || (eContainerFeatureID() != ModelPackage.JOYSTICK_BUTTON__MBRICK && newMbrick != null)) + { + if (EcoreUtil.isAncestor(this, newMbrick)) + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + NotificationChain msgs = null; + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + if (newMbrick != null) + msgs = ((InternalEObject)newMbrick).eInverseAdd(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + msgs = basicSetMbrick(newMbrick, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_BUTTON__MBRICK, newMbrick, newMbrick)); + } + + /** + * + * + * @generated + */ + public HighLowValue getSensorValue() + { + return sensorValue; + } + + /** + * + * + * @generated + */ + public void setSensorValue(HighLowValue newSensorValue) + { + HighLowValue oldSensorValue = sensorValue; + sensorValue = newSensorValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_BUTTON__SENSOR_VALUE, oldSensorValue, sensorValue)); + } + + /** + * + * + * @generated + */ + public String getDeviceType() + { + return deviceType; + } + + /** + * + * + * @generated NOT + */ + public void fetchSensorValue() + { + try { + HighLowValue value = tinkerforgeDevice.isPressed() ? HighLowValue.LOW : HighLowValue.HIGH; + setSensorValue(value); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + public void init() + { + setEnabledA(new AtomicBoolean()); + logger = LoggerFactory.getLogger(JoystickButtonImpl.class); + } + + /** + * + * + * @generated NOT + */ + public void enable() + { + tinkerforgeDevice = getMbrick().getTinkerforgeDevice(); + listener = new ButtonListener(); + tinkerforgeDevice.addPressedListener(listener); + tinkerforgeDevice.addReleasedListener(listener); + fetchSensorValue(); + } + + /** + * + * + * @generated NOT + */ + private class ButtonListener + implements + BrickletJoystick.PressedListener, + BrickletJoystick.ReleasedListener { + + @Override + public void released() { + logger.trace("{} setting new value {}", LoggerConstants.TFMODELUPDATE, HighLowValue.LOW); + setSensorValue(HighLowValue.HIGH); + } + + @Override + public void pressed() { + logger.trace("{} setting new value {}", LoggerConstants.TFMODELUPDATE, HighLowValue.HIGH); + setSensorValue(HighLowValue.LOW); + } + + } + + /** + * + * + * @generated NOT + */ + public void disable() + { + if (listener != null) { + tinkerforgeDevice.removePressedListener(listener); + tinkerforgeDevice.removeReleasedListener(listener); + } + tinkerforgeDevice = null; + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_BUTTON__MBRICK: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetMbrick((MBrickletJoystick)otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_BUTTON__MBRICK: + return basicSetMbrick(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) + { + switch (eContainerFeatureID()) + { + case ModelPackage.JOYSTICK_BUTTON__MBRICK: + return eInternalContainer().eInverseRemove(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_BUTTON__LOGGER: + return getLogger(); + case ModelPackage.JOYSTICK_BUTTON__UID: + return getUid(); + case ModelPackage.JOYSTICK_BUTTON__POLL: + return isPoll(); + case ModelPackage.JOYSTICK_BUTTON__ENABLED_A: + return getEnabledA(); + case ModelPackage.JOYSTICK_BUTTON__SUB_ID: + return getSubId(); + case ModelPackage.JOYSTICK_BUTTON__MBRICK: + return getMbrick(); + case ModelPackage.JOYSTICK_BUTTON__SENSOR_VALUE: + return getSensorValue(); + case ModelPackage.JOYSTICK_BUTTON__DEVICE_TYPE: + return getDeviceType(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_BUTTON__LOGGER: + setLogger((Logger)newValue); + return; + case ModelPackage.JOYSTICK_BUTTON__UID: + setUid((String)newValue); + return; + case ModelPackage.JOYSTICK_BUTTON__POLL: + setPoll((Boolean)newValue); + return; + case ModelPackage.JOYSTICK_BUTTON__ENABLED_A: + setEnabledA((AtomicBoolean)newValue); + return; + case ModelPackage.JOYSTICK_BUTTON__SUB_ID: + setSubId((String)newValue); + return; + case ModelPackage.JOYSTICK_BUTTON__MBRICK: + setMbrick((MBrickletJoystick)newValue); + return; + case ModelPackage.JOYSTICK_BUTTON__SENSOR_VALUE: + setSensorValue((HighLowValue)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_BUTTON__LOGGER: + setLogger(LOGGER_EDEFAULT); + return; + case ModelPackage.JOYSTICK_BUTTON__UID: + setUid(UID_EDEFAULT); + return; + case ModelPackage.JOYSTICK_BUTTON__POLL: + setPoll(POLL_EDEFAULT); + return; + case ModelPackage.JOYSTICK_BUTTON__ENABLED_A: + setEnabledA(ENABLED_A_EDEFAULT); + return; + case ModelPackage.JOYSTICK_BUTTON__SUB_ID: + setSubId(SUB_ID_EDEFAULT); + return; + case ModelPackage.JOYSTICK_BUTTON__MBRICK: + setMbrick((MBrickletJoystick)null); + return; + case ModelPackage.JOYSTICK_BUTTON__SENSOR_VALUE: + setSensorValue((HighLowValue)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_BUTTON__LOGGER: + return LOGGER_EDEFAULT == null ? logger != null : !LOGGER_EDEFAULT.equals(logger); + case ModelPackage.JOYSTICK_BUTTON__UID: + return UID_EDEFAULT == null ? uid != null : !UID_EDEFAULT.equals(uid); + case ModelPackage.JOYSTICK_BUTTON__POLL: + return poll != POLL_EDEFAULT; + case ModelPackage.JOYSTICK_BUTTON__ENABLED_A: + return ENABLED_A_EDEFAULT == null ? enabledA != null : !ENABLED_A_EDEFAULT.equals(enabledA); + case ModelPackage.JOYSTICK_BUTTON__SUB_ID: + return SUB_ID_EDEFAULT == null ? subId != null : !SUB_ID_EDEFAULT.equals(subId); + case ModelPackage.JOYSTICK_BUTTON__MBRICK: + return getMbrick() != null; + case ModelPackage.JOYSTICK_BUTTON__SENSOR_VALUE: + return sensorValue != null; + case ModelPackage.JOYSTICK_BUTTON__DEVICE_TYPE: + return DEVICE_TYPE_EDEFAULT == null ? deviceType != null : !DEVICE_TYPE_EDEFAULT.equals(deviceType); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.JOYSTICK_BUTTON__SENSOR_VALUE: return ModelPackage.MSENSOR__SENSOR_VALUE; + default: return -1; + } + } + return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (baseFeatureID) + { + case ModelPackage.MSENSOR__SENSOR_VALUE: return ModelPackage.JOYSTICK_BUTTON__SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedOperationID(int baseOperationID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (baseOperationID) + { + case ModelPackage.MSENSOR___FETCH_SENSOR_VALUE: return ModelPackage.JOYSTICK_BUTTON___FETCH_SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedOperationID(baseOperationID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public Object eInvoke(int operationID, EList arguments) throws InvocationTargetException + { + switch (operationID) + { + case ModelPackage.JOYSTICK_BUTTON___FETCH_SENSOR_VALUE: + fetchSensorValue(); + return null; + case ModelPackage.JOYSTICK_BUTTON___INIT: + init(); + return null; + case ModelPackage.JOYSTICK_BUTTON___ENABLE: + enable(); + return null; + case ModelPackage.JOYSTICK_BUTTON___DISABLE: + disable(); + return null; + } + return super.eInvoke(operationID, arguments); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (logger: "); + result.append(logger); + result.append(", uid: "); + result.append(uid); + result.append(", poll: "); + result.append(poll); + result.append(", enabledA: "); + result.append(enabledA); + result.append(", subId: "); + result.append(subId); + result.append(", sensorValue: "); + result.append(sensorValue); + result.append(", deviceType: "); + result.append(deviceType); + result.append(')'); + return result.toString(); + } + +} //JoystickButtonImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/JoystickXPositionImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/JoystickXPositionImpl.java new file mode 100644 index 00000000000..70da83431ab --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/JoystickXPositionImpl.java @@ -0,0 +1,777 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.openhab.binding.tinkerforge.internal.LoggerConstants; +import org.openhab.binding.tinkerforge.internal.TinkerforgeErrorHandler; +import org.openhab.binding.tinkerforge.internal.model.JoystickXPosition; +import org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick; +import org.openhab.binding.tinkerforge.internal.model.MSensor; +import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.tools.Tools; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerforge.BrickletJoystick; +import com.tinkerforge.BrickletJoystick.Position; +import com.tinkerforge.NotConnectedException; +import com.tinkerforge.TimeoutException; + +/** + * + * An implementation of the model object 'Joystick XPosition'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl#getLogger Logger}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl#getUid Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl#isPoll Poll}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl#getEnabledA Enabled A}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl#getSubId Sub Id}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl#getMbrick Mbrick}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl#getSensorValue Sensor Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickXPositionImpl#getDeviceType Device Type}
      • + *
      + *

      + * + * @generated + */ +public class JoystickXPositionImpl extends MinimalEObjectImpl.Container implements JoystickXPosition +{ + /** + * The default value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected static final Logger LOGGER_EDEFAULT = null; + + /** + * The cached value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected Logger logger = LOGGER_EDEFAULT; + + /** + * The default value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected static final String UID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected String uid = UID_EDEFAULT; + + /** + * The default value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected static final boolean POLL_EDEFAULT = true; + + /** + * The cached value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected boolean poll = POLL_EDEFAULT; + + /** + * The default value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected static final AtomicBoolean ENABLED_A_EDEFAULT = null; + + /** + * The cached value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected AtomicBoolean enabledA = ENABLED_A_EDEFAULT; + + /** + * The default value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected static final String SUB_ID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected String subId = SUB_ID_EDEFAULT; + + /** + * The cached value of the '{@link #getSensorValue() Sensor Value}' attribute. + * + * + * @see #getSensorValue() + * @generated + * @ordered + */ + protected DecimalValue sensorValue; + + /** + * The default value of the '{@link #getDeviceType() Device Type}' attribute. + * + * + * @see #getDeviceType() + * @generated + * @ordered + */ + protected static final String DEVICE_TYPE_EDEFAULT = "joystick_xposition"; + + /** + * The cached value of the '{@link #getDeviceType() Device Type}' attribute. + * + * + * @see #getDeviceType() + * @generated + * @ordered + */ + protected String deviceType = DEVICE_TYPE_EDEFAULT; + + private PositionListener listener; + + private BrickletJoystick tinkerforgeDevice; + + /** + * + * + * @generated + */ + protected JoystickXPositionImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.JOYSTICK_XPOSITION; + } + + /** + * + * + * @generated + */ + public Logger getLogger() + { + return logger; + } + + /** + * + * + * @generated + */ + public void setLogger(Logger newLogger) + { + Logger oldLogger = logger; + logger = newLogger; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_XPOSITION__LOGGER, oldLogger, logger)); + } + + /** + * + * + * @generated + */ + public String getUid() + { + return uid; + } + + /** + * + * + * @generated + */ + public void setUid(String newUid) + { + String oldUid = uid; + uid = newUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_XPOSITION__UID, oldUid, uid)); + } + + /** + * + * + * @generated + */ + public boolean isPoll() + { + return poll; + } + + /** + * + * + * @generated + */ + public void setPoll(boolean newPoll) + { + boolean oldPoll = poll; + poll = newPoll; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_XPOSITION__POLL, oldPoll, poll)); + } + + /** + * + * + * @generated + */ + public AtomicBoolean getEnabledA() + { + return enabledA; + } + + /** + * + * + * @generated + */ + public void setEnabledA(AtomicBoolean newEnabledA) + { + AtomicBoolean oldEnabledA = enabledA; + enabledA = newEnabledA; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_XPOSITION__ENABLED_A, oldEnabledA, enabledA)); + } + + /** + * + * + * @generated + */ + public String getSubId() + { + return subId; + } + + /** + * + * + * @generated + */ + public void setSubId(String newSubId) + { + String oldSubId = subId; + subId = newSubId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_XPOSITION__SUB_ID, oldSubId, subId)); + } + + /** + * + * + * @generated + */ + public MBrickletJoystick getMbrick() + { + if (eContainerFeatureID() != ModelPackage.JOYSTICK_XPOSITION__MBRICK) return null; + return (MBrickletJoystick)eContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetMbrick(MBrickletJoystick newMbrick, NotificationChain msgs) + { + msgs = eBasicSetContainer((InternalEObject)newMbrick, ModelPackage.JOYSTICK_XPOSITION__MBRICK, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setMbrick(MBrickletJoystick newMbrick) + { + if (newMbrick != eInternalContainer() || (eContainerFeatureID() != ModelPackage.JOYSTICK_XPOSITION__MBRICK && newMbrick != null)) + { + if (EcoreUtil.isAncestor(this, newMbrick)) + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + NotificationChain msgs = null; + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + if (newMbrick != null) + msgs = ((InternalEObject)newMbrick).eInverseAdd(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + msgs = basicSetMbrick(newMbrick, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_XPOSITION__MBRICK, newMbrick, newMbrick)); + } + + /** + * + * + * @generated + */ + public DecimalValue getSensorValue() + { + return sensorValue; + } + + /** + * + * + * @generated + */ + public void setSensorValue(DecimalValue newSensorValue) + { + DecimalValue oldSensorValue = sensorValue; + sensorValue = newSensorValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_XPOSITION__SENSOR_VALUE, oldSensorValue, sensorValue)); + } + + /** + * + * + * @generated + */ + public String getDeviceType() + { + return deviceType; + } + + /** + * + * + * @generated NOT + */ + public void fetchSensorValue() + { + try { + Position position = tinkerforgeDevice.getPosition(); + DecimalValue value = Tools.calculate(position.x); + setSensorValue(value); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + public void init() + { + setEnabledA(new AtomicBoolean()); + logger = LoggerFactory.getLogger(JoystickXPositionImpl.class); + } + + /** + * + * + * @generated NOT + */ + public void enable() + { + tinkerforgeDevice = getMbrick().getTinkerforgeDevice(); + tinkerforgeDevice.setResponseExpected(BrickletJoystick.FUNCTION_SET_POSITION_CALLBACK_PERIOD, false); + try { + logger.trace("callbackPeriod is {}", getMbrick().getCallbackPeriod()); + tinkerforgeDevice.setPositionCallbackPeriod(getMbrick().getCallbackPeriod()); + listener = new PositionListener(); + tinkerforgeDevice.addPositionListener(listener); + fetchSensorValue(); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + private class PositionListener implements BrickletJoystick.PositionListener { + + @Override + public void position(short x, short y) { + DecimalValue value = Tools.calculate(x); + logger.trace("{} got new value {}", LoggerConstants.TFMODELUPDATE, value); + logger.trace("{} setting new value {}", LoggerConstants.TFMODELUPDATE, value); + setSensorValue(value); + } + } + + /** + * + * + * @generated NOT + */ + public void disable() + { + if (listener != null) { + tinkerforgeDevice.removePositionListener(listener); + } + tinkerforgeDevice = null; + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_XPOSITION__MBRICK: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetMbrick((MBrickletJoystick)otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_XPOSITION__MBRICK: + return basicSetMbrick(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) + { + switch (eContainerFeatureID()) + { + case ModelPackage.JOYSTICK_XPOSITION__MBRICK: + return eInternalContainer().eInverseRemove(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_XPOSITION__LOGGER: + return getLogger(); + case ModelPackage.JOYSTICK_XPOSITION__UID: + return getUid(); + case ModelPackage.JOYSTICK_XPOSITION__POLL: + return isPoll(); + case ModelPackage.JOYSTICK_XPOSITION__ENABLED_A: + return getEnabledA(); + case ModelPackage.JOYSTICK_XPOSITION__SUB_ID: + return getSubId(); + case ModelPackage.JOYSTICK_XPOSITION__MBRICK: + return getMbrick(); + case ModelPackage.JOYSTICK_XPOSITION__SENSOR_VALUE: + return getSensorValue(); + case ModelPackage.JOYSTICK_XPOSITION__DEVICE_TYPE: + return getDeviceType(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_XPOSITION__LOGGER: + setLogger((Logger)newValue); + return; + case ModelPackage.JOYSTICK_XPOSITION__UID: + setUid((String)newValue); + return; + case ModelPackage.JOYSTICK_XPOSITION__POLL: + setPoll((Boolean)newValue); + return; + case ModelPackage.JOYSTICK_XPOSITION__ENABLED_A: + setEnabledA((AtomicBoolean)newValue); + return; + case ModelPackage.JOYSTICK_XPOSITION__SUB_ID: + setSubId((String)newValue); + return; + case ModelPackage.JOYSTICK_XPOSITION__MBRICK: + setMbrick((MBrickletJoystick)newValue); + return; + case ModelPackage.JOYSTICK_XPOSITION__SENSOR_VALUE: + setSensorValue((DecimalValue)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_XPOSITION__LOGGER: + setLogger(LOGGER_EDEFAULT); + return; + case ModelPackage.JOYSTICK_XPOSITION__UID: + setUid(UID_EDEFAULT); + return; + case ModelPackage.JOYSTICK_XPOSITION__POLL: + setPoll(POLL_EDEFAULT); + return; + case ModelPackage.JOYSTICK_XPOSITION__ENABLED_A: + setEnabledA(ENABLED_A_EDEFAULT); + return; + case ModelPackage.JOYSTICK_XPOSITION__SUB_ID: + setSubId(SUB_ID_EDEFAULT); + return; + case ModelPackage.JOYSTICK_XPOSITION__MBRICK: + setMbrick((MBrickletJoystick)null); + return; + case ModelPackage.JOYSTICK_XPOSITION__SENSOR_VALUE: + setSensorValue((DecimalValue)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_XPOSITION__LOGGER: + return LOGGER_EDEFAULT == null ? logger != null : !LOGGER_EDEFAULT.equals(logger); + case ModelPackage.JOYSTICK_XPOSITION__UID: + return UID_EDEFAULT == null ? uid != null : !UID_EDEFAULT.equals(uid); + case ModelPackage.JOYSTICK_XPOSITION__POLL: + return poll != POLL_EDEFAULT; + case ModelPackage.JOYSTICK_XPOSITION__ENABLED_A: + return ENABLED_A_EDEFAULT == null ? enabledA != null : !ENABLED_A_EDEFAULT.equals(enabledA); + case ModelPackage.JOYSTICK_XPOSITION__SUB_ID: + return SUB_ID_EDEFAULT == null ? subId != null : !SUB_ID_EDEFAULT.equals(subId); + case ModelPackage.JOYSTICK_XPOSITION__MBRICK: + return getMbrick() != null; + case ModelPackage.JOYSTICK_XPOSITION__SENSOR_VALUE: + return sensorValue != null; + case ModelPackage.JOYSTICK_XPOSITION__DEVICE_TYPE: + return DEVICE_TYPE_EDEFAULT == null ? deviceType != null : !DEVICE_TYPE_EDEFAULT.equals(deviceType); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.JOYSTICK_XPOSITION__SENSOR_VALUE: return ModelPackage.MSENSOR__SENSOR_VALUE; + default: return -1; + } + } + return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (baseFeatureID) + { + case ModelPackage.MSENSOR__SENSOR_VALUE: return ModelPackage.JOYSTICK_XPOSITION__SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedOperationID(int baseOperationID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (baseOperationID) + { + case ModelPackage.MSENSOR___FETCH_SENSOR_VALUE: return ModelPackage.JOYSTICK_XPOSITION___FETCH_SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedOperationID(baseOperationID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public Object eInvoke(int operationID, EList arguments) throws InvocationTargetException + { + switch (operationID) + { + case ModelPackage.JOYSTICK_XPOSITION___FETCH_SENSOR_VALUE: + fetchSensorValue(); + return null; + case ModelPackage.JOYSTICK_XPOSITION___INIT: + init(); + return null; + case ModelPackage.JOYSTICK_XPOSITION___ENABLE: + enable(); + return null; + case ModelPackage.JOYSTICK_XPOSITION___DISABLE: + disable(); + return null; + } + return super.eInvoke(operationID, arguments); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (logger: "); + result.append(logger); + result.append(", uid: "); + result.append(uid); + result.append(", poll: "); + result.append(poll); + result.append(", enabledA: "); + result.append(enabledA); + result.append(", subId: "); + result.append(subId); + result.append(", sensorValue: "); + result.append(sensorValue); + result.append(", deviceType: "); + result.append(deviceType); + result.append(')'); + return result.toString(); + } + +} //JoystickXPositionImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/JoystickYPositionImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/JoystickYPositionImpl.java new file mode 100644 index 00000000000..a79d7c496e3 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/JoystickYPositionImpl.java @@ -0,0 +1,780 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.openhab.binding.tinkerforge.internal.LoggerConstants; +import org.openhab.binding.tinkerforge.internal.TinkerforgeErrorHandler; +import org.openhab.binding.tinkerforge.internal.model.JoystickYPosition; +import org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick; +import org.openhab.binding.tinkerforge.internal.model.MSensor; +import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.tools.Tools; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerforge.BrickletJoystick; +import com.tinkerforge.BrickletJoystick.Position; +import com.tinkerforge.NotConnectedException; +import com.tinkerforge.TimeoutException; + +/** + * + * An implementation of the model object 'Joystick YPosition'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl#getLogger Logger}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl#getUid Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl#isPoll Poll}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl#getEnabledA Enabled A}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl#getSubId Sub Id}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl#getMbrick Mbrick}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl#getSensorValue Sensor Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.JoystickYPositionImpl#getDeviceType Device Type}
      • + *
      + *

      + * + * @generated + */ +public class JoystickYPositionImpl extends MinimalEObjectImpl.Container implements JoystickYPosition +{ + /** + * The default value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected static final Logger LOGGER_EDEFAULT = null; + + /** + * The cached value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected Logger logger = LOGGER_EDEFAULT; + + /** + * The default value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected static final String UID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected String uid = UID_EDEFAULT; + + /** + * The default value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected static final boolean POLL_EDEFAULT = true; + + /** + * The cached value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected boolean poll = POLL_EDEFAULT; + + /** + * The default value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected static final AtomicBoolean ENABLED_A_EDEFAULT = null; + + /** + * The cached value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected AtomicBoolean enabledA = ENABLED_A_EDEFAULT; + + /** + * The default value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected static final String SUB_ID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getSubId() Sub Id}' attribute. + * + * + * @see #getSubId() + * @generated + * @ordered + */ + protected String subId = SUB_ID_EDEFAULT; + + /** + * The cached value of the '{@link #getSensorValue() Sensor Value}' attribute. + * + * + * @see #getSensorValue() + * @generated + * @ordered + */ + protected DecimalValue sensorValue; + + /** + * The default value of the '{@link #getDeviceType() Device Type}' attribute. + * + * + * @see #getDeviceType() + * @generated + * @ordered + */ + protected static final String DEVICE_TYPE_EDEFAULT = "joystick_yposition"; + + /** + * The cached value of the '{@link #getDeviceType() Device Type}' attribute. + * + * + * @see #getDeviceType() + * @generated + * @ordered + */ + protected String deviceType = DEVICE_TYPE_EDEFAULT; + + private BrickletJoystick tinkerforgeDevice; + + private PositionListener listener; + + /** + * + * + * @generated + */ + protected JoystickYPositionImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.JOYSTICK_YPOSITION; + } + + /** + * + * + * @generated + */ + public Logger getLogger() + { + return logger; + } + + /** + * + * + * @generated + */ + public void setLogger(Logger newLogger) + { + Logger oldLogger = logger; + logger = newLogger; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_YPOSITION__LOGGER, oldLogger, logger)); + } + + /** + * + * + * @generated + */ + public String getUid() + { + return uid; + } + + /** + * + * + * @generated + */ + public void setUid(String newUid) + { + String oldUid = uid; + uid = newUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_YPOSITION__UID, oldUid, uid)); + } + + /** + * + * + * @generated + */ + public boolean isPoll() + { + return poll; + } + + /** + * + * + * @generated + */ + public void setPoll(boolean newPoll) + { + boolean oldPoll = poll; + poll = newPoll; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_YPOSITION__POLL, oldPoll, poll)); + } + + /** + * + * + * @generated + */ + public AtomicBoolean getEnabledA() + { + return enabledA; + } + + /** + * + * + * @generated + */ + public void setEnabledA(AtomicBoolean newEnabledA) + { + AtomicBoolean oldEnabledA = enabledA; + enabledA = newEnabledA; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_YPOSITION__ENABLED_A, oldEnabledA, enabledA)); + } + + /** + * + * + * @generated + */ + public String getSubId() + { + return subId; + } + + /** + * + * + * @generated + */ + public void setSubId(String newSubId) + { + String oldSubId = subId; + subId = newSubId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_YPOSITION__SUB_ID, oldSubId, subId)); + } + + /** + * + * + * @generated + */ + public MBrickletJoystick getMbrick() + { + if (eContainerFeatureID() != ModelPackage.JOYSTICK_YPOSITION__MBRICK) return null; + return (MBrickletJoystick)eContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetMbrick(MBrickletJoystick newMbrick, NotificationChain msgs) + { + msgs = eBasicSetContainer((InternalEObject)newMbrick, ModelPackage.JOYSTICK_YPOSITION__MBRICK, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setMbrick(MBrickletJoystick newMbrick) + { + if (newMbrick != eInternalContainer() || (eContainerFeatureID() != ModelPackage.JOYSTICK_YPOSITION__MBRICK && newMbrick != null)) + { + if (EcoreUtil.isAncestor(this, newMbrick)) + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + NotificationChain msgs = null; + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + if (newMbrick != null) + msgs = ((InternalEObject)newMbrick).eInverseAdd(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + msgs = basicSetMbrick(newMbrick, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_YPOSITION__MBRICK, newMbrick, newMbrick)); + } + + /** + * + * + * @generated + */ + public DecimalValue getSensorValue() + { + return sensorValue; + } + + /** + * + * + * @generated + */ + public void setSensorValue(DecimalValue newSensorValue) + { + DecimalValue oldSensorValue = sensorValue; + sensorValue = newSensorValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JOYSTICK_YPOSITION__SENSOR_VALUE, oldSensorValue, sensorValue)); + } + + /** + * + * + * @generated + */ + public String getDeviceType() + { + return deviceType; + } + + /** + * + * + * @generated NOT + */ + public void fetchSensorValue() + { + try { + Position position = tinkerforgeDevice.getPosition(); + DecimalValue value = Tools.calculate(position.y); + setSensorValue(value); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + public void init() + { + setEnabledA(new AtomicBoolean()); + logger = LoggerFactory.getLogger(JoystickYPositionImpl.class); + } + + /** + * + * + * @generated NOT + */ + public void enable() + { + tinkerforgeDevice = getMbrick().getTinkerforgeDevice(); + tinkerforgeDevice.setResponseExpected(BrickletJoystick.FUNCTION_SET_POSITION_CALLBACK_PERIOD, + false); + try { + logger.trace("callbackPeriod is {}", getMbrick().getCallbackPeriod()); + tinkerforgeDevice.setPositionCallbackPeriod(getMbrick().getCallbackPeriod()); + listener = new PositionListener(); + tinkerforgeDevice.addPositionListener(listener); + fetchSensorValue(); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + private class PositionListener implements BrickletJoystick.PositionListener { + + @Override + public void position(short x, short y) { + DecimalValue value = Tools.calculate(y); + logger.trace("{} got new value {}", LoggerConstants.TFMODELUPDATE, value); + logger.trace("{} setting new value {}", LoggerConstants.TFMODELUPDATE, value); + setSensorValue(value); + } + + } + + + /** + * + * + * @generated NOT + */ + public void disable() + { + if (listener != null) { + tinkerforgeDevice.removePositionListener(listener); + } + tinkerforgeDevice = null; + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_YPOSITION__MBRICK: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetMbrick((MBrickletJoystick)otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_YPOSITION__MBRICK: + return basicSetMbrick(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) + { + switch (eContainerFeatureID()) + { + case ModelPackage.JOYSTICK_YPOSITION__MBRICK: + return eInternalContainer().eInverseRemove(this, ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES, MSubDeviceHolder.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_YPOSITION__LOGGER: + return getLogger(); + case ModelPackage.JOYSTICK_YPOSITION__UID: + return getUid(); + case ModelPackage.JOYSTICK_YPOSITION__POLL: + return isPoll(); + case ModelPackage.JOYSTICK_YPOSITION__ENABLED_A: + return getEnabledA(); + case ModelPackage.JOYSTICK_YPOSITION__SUB_ID: + return getSubId(); + case ModelPackage.JOYSTICK_YPOSITION__MBRICK: + return getMbrick(); + case ModelPackage.JOYSTICK_YPOSITION__SENSOR_VALUE: + return getSensorValue(); + case ModelPackage.JOYSTICK_YPOSITION__DEVICE_TYPE: + return getDeviceType(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_YPOSITION__LOGGER: + setLogger((Logger)newValue); + return; + case ModelPackage.JOYSTICK_YPOSITION__UID: + setUid((String)newValue); + return; + case ModelPackage.JOYSTICK_YPOSITION__POLL: + setPoll((Boolean)newValue); + return; + case ModelPackage.JOYSTICK_YPOSITION__ENABLED_A: + setEnabledA((AtomicBoolean)newValue); + return; + case ModelPackage.JOYSTICK_YPOSITION__SUB_ID: + setSubId((String)newValue); + return; + case ModelPackage.JOYSTICK_YPOSITION__MBRICK: + setMbrick((MBrickletJoystick)newValue); + return; + case ModelPackage.JOYSTICK_YPOSITION__SENSOR_VALUE: + setSensorValue((DecimalValue)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_YPOSITION__LOGGER: + setLogger(LOGGER_EDEFAULT); + return; + case ModelPackage.JOYSTICK_YPOSITION__UID: + setUid(UID_EDEFAULT); + return; + case ModelPackage.JOYSTICK_YPOSITION__POLL: + setPoll(POLL_EDEFAULT); + return; + case ModelPackage.JOYSTICK_YPOSITION__ENABLED_A: + setEnabledA(ENABLED_A_EDEFAULT); + return; + case ModelPackage.JOYSTICK_YPOSITION__SUB_ID: + setSubId(SUB_ID_EDEFAULT); + return; + case ModelPackage.JOYSTICK_YPOSITION__MBRICK: + setMbrick((MBrickletJoystick)null); + return; + case ModelPackage.JOYSTICK_YPOSITION__SENSOR_VALUE: + setSensorValue((DecimalValue)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.JOYSTICK_YPOSITION__LOGGER: + return LOGGER_EDEFAULT == null ? logger != null : !LOGGER_EDEFAULT.equals(logger); + case ModelPackage.JOYSTICK_YPOSITION__UID: + return UID_EDEFAULT == null ? uid != null : !UID_EDEFAULT.equals(uid); + case ModelPackage.JOYSTICK_YPOSITION__POLL: + return poll != POLL_EDEFAULT; + case ModelPackage.JOYSTICK_YPOSITION__ENABLED_A: + return ENABLED_A_EDEFAULT == null ? enabledA != null : !ENABLED_A_EDEFAULT.equals(enabledA); + case ModelPackage.JOYSTICK_YPOSITION__SUB_ID: + return SUB_ID_EDEFAULT == null ? subId != null : !SUB_ID_EDEFAULT.equals(subId); + case ModelPackage.JOYSTICK_YPOSITION__MBRICK: + return getMbrick() != null; + case ModelPackage.JOYSTICK_YPOSITION__SENSOR_VALUE: + return sensorValue != null; + case ModelPackage.JOYSTICK_YPOSITION__DEVICE_TYPE: + return DEVICE_TYPE_EDEFAULT == null ? deviceType != null : !DEVICE_TYPE_EDEFAULT.equals(deviceType); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.JOYSTICK_YPOSITION__SENSOR_VALUE: return ModelPackage.MSENSOR__SENSOR_VALUE; + default: return -1; + } + } + return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (baseFeatureID) + { + case ModelPackage.MSENSOR__SENSOR_VALUE: return ModelPackage.JOYSTICK_YPOSITION__SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedOperationID(int baseOperationID, Class baseClass) + { + if (baseClass == MSensor.class) + { + switch (baseOperationID) + { + case ModelPackage.MSENSOR___FETCH_SENSOR_VALUE: return ModelPackage.JOYSTICK_YPOSITION___FETCH_SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedOperationID(baseOperationID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public Object eInvoke(int operationID, EList arguments) throws InvocationTargetException + { + switch (operationID) + { + case ModelPackage.JOYSTICK_YPOSITION___FETCH_SENSOR_VALUE: + fetchSensorValue(); + return null; + case ModelPackage.JOYSTICK_YPOSITION___INIT: + init(); + return null; + case ModelPackage.JOYSTICK_YPOSITION___ENABLE: + enable(); + return null; + case ModelPackage.JOYSTICK_YPOSITION___DISABLE: + disable(); + return null; + } + return super.eInvoke(operationID, arguments); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (logger: "); + result.append(logger); + result.append(", uid: "); + result.append(uid); + result.append(", poll: "); + result.append(poll); + result.append(", enabledA: "); + result.append(enabledA); + result.append(", subId: "); + result.append(subId); + result.append(", sensorValue: "); + result.append(sensorValue); + result.append(", deviceType: "); + result.append(deviceType); + result.append(')'); + return result.toString(); + } + +} //JoystickYPositionImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickDCImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickDCImpl.java index 412a77b3bec..98ce5fd8ad4 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickDCImpl.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickDCImpl.java @@ -9,6 +9,7 @@ package org.openhab.binding.tinkerforge.internal.model.impl; import java.lang.reflect.InvocationTargetException; +import java.math.BigDecimal; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.emf.common.notify.Notification; @@ -21,15 +22,32 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.openhab.binding.tinkerforge.internal.LoggerConstants; import org.openhab.binding.tinkerforge.internal.TinkerforgeErrorHandler; +import org.openhab.binding.tinkerforge.internal.config.DeviceOptions; +import org.openhab.binding.tinkerforge.internal.model.CallbackListener; +import org.openhab.binding.tinkerforge.internal.model.ConfigOptsDimmable; +import org.openhab.binding.tinkerforge.internal.model.ConfigOptsMove; +import org.openhab.binding.tinkerforge.internal.model.ConfigOptsSwitchSpeed; import org.openhab.binding.tinkerforge.internal.model.DCDriveMode; +import org.openhab.binding.tinkerforge.internal.model.DimmableActor; import org.openhab.binding.tinkerforge.internal.model.MBaseDevice; import org.openhab.binding.tinkerforge.internal.model.MBrickDC; import org.openhab.binding.tinkerforge.internal.model.MBrickd; import org.openhab.binding.tinkerforge.internal.model.MDevice; import org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer; import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.model.MoveActor; +import org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor; +import org.openhab.binding.tinkerforge.internal.model.SetPointActor; +import org.openhab.binding.tinkerforge.internal.model.SwitchSensor; import org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration; +import org.openhab.binding.tinkerforge.internal.tools.Tools; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; +import org.openhab.binding.tinkerforge.internal.types.DirectionValue; import org.openhab.binding.tinkerforge.internal.types.OnOffValue; +import org.openhab.binding.tinkerforge.internal.types.PercentValue; +import org.openhab.core.library.types.IncreaseDecreaseType; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.UpDownType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,15 +57,14 @@ import com.tinkerforge.TimeoutException; /** - * - * An implementation of the model object 'MBrick DC'. + * An implementation of the model object 'MBrick DC'. * * @author Theo Weiss - * @since 1.3.0 - * + * @since 1.3.0 *

      * The following features are implemented: *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getSensorValue Sensor Value}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getSwitchState Switch State}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getLogger Logger}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getUid Uid}
      • @@ -60,14 +77,22 @@ *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getDeviceIdentifier Device Identifier}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getName Name}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getBrickd Brickd}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getDirection Direction}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getTfConfig Tf Config}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getMinValue Min Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getMaxValue Max Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getPercentValue Percent Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getCallbackPeriod Callback Period}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getDeviceType Device Type}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getThreshold Threshold}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getMaxVelocity Max Velocity}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getMinVelocity Min Velocity}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getVelocity Velocity}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getTargetvelocity Targetvelocity}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getCurrentVelocity Current Velocity}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getAcceleration Acceleration}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getPwmFrequency Pwm Frequency}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getDriveMode Drive Mode}
      • - *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickDCImpl#getSwitchOnVelocity Switch On Velocity}
      • *
      *

      * @@ -75,6 +100,16 @@ */ public class MBrickDCImpl extends MinimalEObjectImpl.Container implements MBrickDC { + /** + * The cached value of the '{@link #getSensorValue() Sensor Value}' attribute. + * + * + * @see #getSensorValue() + * @generated + * @ordered + */ + protected DecimalValue sensorValue; + /** * The default value of the '{@link #getSwitchState() Switch State}' attribute. * @@ -285,6 +320,26 @@ public class MBrickDCImpl extends MinimalEObjectImpl.Container implements MBrick */ protected String name = NAME_EDEFAULT; + /** + * The default value of the '{@link #getDirection() Direction}' attribute. + * + * + * @see #getDirection() + * @generated + * @ordered + */ + protected static final DirectionValue DIRECTION_EDEFAULT = null; + + /** + * The cached value of the '{@link #getDirection() Direction}' attribute. + * + * + * @see #getDirection() + * @generated + * @ordered + */ + protected DirectionValue direction = DIRECTION_EDEFAULT; + /** * The cached value of the '{@link #getTfConfig() Tf Config}' containment reference. * @@ -295,6 +350,86 @@ public class MBrickDCImpl extends MinimalEObjectImpl.Container implements MBrick */ protected TFBrickDCConfiguration tfConfig; + /** + * The default value of the '{@link #getMinValue() Min Value}' attribute. + * + * + * @see #getMinValue() + * @generated + * @ordered + */ + protected static final BigDecimal MIN_VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getMinValue() Min Value}' attribute. + * + * + * @see #getMinValue() + * @generated + * @ordered + */ + protected BigDecimal minValue = MIN_VALUE_EDEFAULT; + + /** + * The default value of the '{@link #getMaxValue() Max Value}' attribute. + * + * + * @see #getMaxValue() + * @generated + * @ordered + */ + protected static final BigDecimal MAX_VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getMaxValue() Max Value}' attribute. + * + * + * @see #getMaxValue() + * @generated + * @ordered + */ + protected BigDecimal maxValue = MAX_VALUE_EDEFAULT; + + /** + * The default value of the '{@link #getPercentValue() Percent Value}' attribute. + * + * + * @see #getPercentValue() + * @generated + * @ordered + */ + protected static final PercentValue PERCENT_VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getPercentValue() Percent Value}' attribute. + * + * + * @see #getPercentValue() + * @generated + * @ordered + */ + protected PercentValue percentValue = PERCENT_VALUE_EDEFAULT; + + /** + * The default value of the '{@link #getCallbackPeriod() Callback Period}' attribute. + * + * + * @see #getCallbackPeriod() + * @generated + * @ordered + */ + protected static final long CALLBACK_PERIOD_EDEFAULT = 1000L; + + /** + * The cached value of the '{@link #getCallbackPeriod() Callback Period}' attribute. + * + * + * @see #getCallbackPeriod() + * @generated + * @ordered + */ + protected long callbackPeriod = CALLBACK_PERIOD_EDEFAULT; + /** * The default value of the '{@link #getDeviceType() Device Type}' attribute. * @@ -315,6 +450,66 @@ public class MBrickDCImpl extends MinimalEObjectImpl.Container implements MBrick */ protected String deviceType = DEVICE_TYPE_EDEFAULT; + /** + * The default value of the '{@link #getThreshold() Threshold}' attribute. + * + * + * @see #getThreshold() + * @generated + * @ordered + */ + protected static final BigDecimal THRESHOLD_EDEFAULT = new BigDecimal("10"); + + /** + * The cached value of the '{@link #getThreshold() Threshold}' attribute. + * + * + * @see #getThreshold() + * @generated + * @ordered + */ + protected BigDecimal threshold = THRESHOLD_EDEFAULT; + + /** + * The default value of the '{@link #getMaxVelocity() Max Velocity}' attribute. + * + * + * @see #getMaxVelocity() + * @generated + * @ordered + */ + protected static final Short MAX_VELOCITY_EDEFAULT = new Short((short)32767); + + /** + * The cached value of the '{@link #getMaxVelocity() Max Velocity}' attribute. + * + * + * @see #getMaxVelocity() + * @generated + * @ordered + */ + protected Short maxVelocity = MAX_VELOCITY_EDEFAULT; + + /** + * The default value of the '{@link #getMinVelocity() Min Velocity}' attribute. + * + * + * @see #getMinVelocity() + * @generated + * @ordered + */ + protected static final Short MIN_VELOCITY_EDEFAULT = new Short((short)-32767); + + /** + * The cached value of the '{@link #getMinVelocity() Min Velocity}' attribute. + * + * + * @see #getMinVelocity() + * @generated + * @ordered + */ + protected Short minVelocity = MIN_VELOCITY_EDEFAULT; + /** * The default value of the '{@link #getVelocity() Velocity}' attribute. * @@ -335,6 +530,26 @@ public class MBrickDCImpl extends MinimalEObjectImpl.Container implements MBrick */ protected short velocity = VELOCITY_EDEFAULT; + /** + * The default value of the '{@link #getTargetvelocity() Targetvelocity}' attribute. + * + * + * @see #getTargetvelocity() + * @generated + * @ordered + */ + protected static final short TARGETVELOCITY_EDEFAULT = 0; + + /** + * The cached value of the '{@link #getTargetvelocity() Targetvelocity}' attribute. + * + * + * @see #getTargetvelocity() + * @generated + * @ordered + */ + protected short targetvelocity = TARGETVELOCITY_EDEFAULT; + /** * The default value of the '{@link #getCurrentVelocity() Current Velocity}' attribute. * @@ -415,34 +630,37 @@ public class MBrickDCImpl extends MinimalEObjectImpl.Container implements MBrick */ protected DCDriveMode driveMode = DRIVE_MODE_EDEFAULT; + private VelocityListener listener; + /** - * The default value of the '{@link #getSwitchOnVelocity() Switch On Velocity}' attribute. * * - * @see #getSwitchOnVelocity() * @generated - * @ordered */ - protected static final short SWITCH_ON_VELOCITY_EDEFAULT = 10000; + protected MBrickDCImpl() + { + super(); + } /** - * The cached value of the '{@link #getSwitchOnVelocity() Switch On Velocity}' attribute. * * - * @see #getSwitchOnVelocity() * @generated - * @ordered */ - protected short switchOnVelocity = SWITCH_ON_VELOCITY_EDEFAULT; + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.MBRICK_DC; + } /** * * * @generated */ - protected MBrickDCImpl() + public DecimalValue getSensorValue() { - super(); + return sensorValue; } /** @@ -450,10 +668,12 @@ protected MBrickDCImpl() * * @generated */ - @Override - protected EClass eStaticClass() + public void setSensorValue(DecimalValue newSensorValue) { - return ModelPackage.Literals.MBRICK_DC; + DecimalValue oldSensorValue = sensorValue; + sensorValue = newSensorValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__SENSOR_VALUE, oldSensorValue, sensorValue)); } /** @@ -479,50 +699,6 @@ public void setSwitchState(OnOffValue newSwitchState) eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__SWITCH_STATE, oldSwitchState, switchState)); } - /** - * - * - * @generated NOT - */ - public void turnSwitch(OnOffValue state) { - logger.trace("turnSwitch called"); - try { - if (state == OnOffValue.OFF) { - tinkerforgeDevice.setVelocity((short) 0); - } else if (state == OnOffValue.ON) { - tinkerforgeDevice.setVelocity(switchOnVelocity); - } else { - logger.error("{} unkown switchstate {}", LoggerConstants.TFMODELUPDATE, state); - } - switchState = state == null ? OnOffValue.UNDEF : state; - setSwitchState(switchState); - } catch (TimeoutException e) { - TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); - } catch (NotConnectedException e) { - TinkerforgeErrorHandler.handleError(this, - TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); - } - } - - /** - * - * - * @generated NOT - */ - public void fetchSwitchState() { - OnOffValue value = OnOffValue.UNDEF; - try { - short currentVelocity = tinkerforgeDevice.getVelocity(); - value = currentVelocity == 0 ? OnOffValue.OFF : OnOffValue.ON; - setSwitchState(value); - } catch (TimeoutException e) { - TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); - } catch (NotConnectedException e) { - TinkerforgeErrorHandler.handleError(this, - TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); - } - } - /** * * @@ -851,9 +1027,9 @@ else if (eNotificationRequired()) * * @generated */ - public String getDeviceType() + public BigDecimal getMinValue() { - return deviceType; + return minValue; } /** @@ -861,9 +1037,12 @@ public String getDeviceType() * * @generated */ - public short getVelocity() + public void setMinValue(BigDecimal newMinValue) { - return velocity; + BigDecimal oldMinValue = minValue; + minValue = newMinValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__MIN_VALUE, oldMinValue, minValue)); } /** @@ -871,12 +1050,22 @@ public short getVelocity() * * @generated */ - public void setVelocity(short newVelocity) + public BigDecimal getMaxValue() { - short oldVelocity = velocity; - velocity = newVelocity; + return maxValue; + } + + /** + * + * + * @generated + */ + public void setMaxValue(BigDecimal newMaxValue) + { + BigDecimal oldMaxValue = maxValue; + maxValue = newMaxValue; if (eNotificationRequired()) - eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__VELOCITY, oldVelocity, velocity)); + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__MAX_VALUE, oldMaxValue, maxValue)); } /** @@ -884,9 +1073,9 @@ public void setVelocity(short newVelocity) * * @generated */ - public short getCurrentVelocity() + public PercentValue getPercentValue() { - return currentVelocity; + return percentValue; } /** @@ -894,12 +1083,12 @@ public short getCurrentVelocity() * * @generated */ - public void setCurrentVelocity(short newCurrentVelocity) + public void setPercentValue(PercentValue newPercentValue) { - short oldCurrentVelocity = currentVelocity; - currentVelocity = newCurrentVelocity; + PercentValue oldPercentValue = percentValue; + percentValue = newPercentValue; if (eNotificationRequired()) - eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__CURRENT_VELOCITY, oldCurrentVelocity, currentVelocity)); + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__PERCENT_VALUE, oldPercentValue, percentValue)); } /** @@ -907,9 +1096,9 @@ public void setCurrentVelocity(short newCurrentVelocity) * * @generated */ - public int getAcceleration() + public DirectionValue getDirection() { - return acceleration; + return direction; } /** @@ -917,12 +1106,12 @@ public int getAcceleration() * * @generated */ - public void setAcceleration(int newAcceleration) + public void setDirection(DirectionValue newDirection) { - int oldAcceleration = acceleration; - acceleration = newAcceleration; + DirectionValue oldDirection = direction; + direction = newDirection; if (eNotificationRequired()) - eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__ACCELERATION, oldAcceleration, acceleration)); + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__DIRECTION, oldDirection, direction)); } /** @@ -930,9 +1119,9 @@ public void setAcceleration(int newAcceleration) * * @generated */ - public int getPwmFrequency() + public long getCallbackPeriod() { - return pwmFrequency; + return callbackPeriod; } /** @@ -940,12 +1129,12 @@ public int getPwmFrequency() * * @generated */ - public void setPwmFrequency(int newPwmFrequency) + public void setCallbackPeriod(long newCallbackPeriod) { - int oldPwmFrequency = pwmFrequency; - pwmFrequency = newPwmFrequency; + long oldCallbackPeriod = callbackPeriod; + callbackPeriod = newCallbackPeriod; if (eNotificationRequired()) - eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__PWM_FREQUENCY, oldPwmFrequency, pwmFrequency)); + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__CALLBACK_PERIOD, oldCallbackPeriod, callbackPeriod)); } /** @@ -953,9 +1142,9 @@ public void setPwmFrequency(int newPwmFrequency) * * @generated */ - public DCDriveMode getDriveMode() + public BigDecimal getThreshold() { - return driveMode; + return threshold; } /** @@ -963,12 +1152,12 @@ public DCDriveMode getDriveMode() * * @generated */ - public void setDriveMode(DCDriveMode newDriveMode) + public void setThreshold(BigDecimal newThreshold) { - DCDriveMode oldDriveMode = driveMode; - driveMode = newDriveMode == null ? DRIVE_MODE_EDEFAULT : newDriveMode; + BigDecimal oldThreshold = threshold; + threshold = newThreshold; if (eNotificationRequired()) - eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__DRIVE_MODE, oldDriveMode, driveMode)); + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__THRESHOLD, oldThreshold, threshold)); } /** @@ -976,9 +1165,9 @@ public void setDriveMode(DCDriveMode newDriveMode) * * @generated */ - public short getSwitchOnVelocity() + public Short getMaxVelocity() { - return switchOnVelocity; + return maxVelocity; } /** @@ -986,78 +1175,45 @@ public short getSwitchOnVelocity() * * @generated */ - public void setSwitchOnVelocity(short newSwitchOnVelocity) + public void setMaxVelocity(Short newMaxVelocity) { - short oldSwitchOnVelocity = switchOnVelocity; - switchOnVelocity = newSwitchOnVelocity; + Short oldMaxVelocity = maxVelocity; + maxVelocity = newMaxVelocity; if (eNotificationRequired()) - eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__SWITCH_ON_VELOCITY, oldSwitchOnVelocity, switchOnVelocity)); + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__MAX_VELOCITY, oldMaxVelocity, maxVelocity)); } /** * * - * @generated NOT + * @generated */ - public void init() + public Short getMinVelocity() { - logger = LoggerFactory.getLogger(MBrickDCImpl.class); - poll = true; // don't use the setter to prevent notification - setEnabledA(new AtomicBoolean()); + return minVelocity; } /** * * - * @generated NOT + * @generated */ - public void enable() { - tinkerforgeDevice = new BrickDC(uid, ipConnection); - if (tfConfig != null) { - logger.debug("found tfConfig"); - if (tfConfig.eIsSet(tfConfig.eClass().getEStructuralFeature( - "acceleration"))) { - setAcceleration(tfConfig.getAcceleration()); - } - if (tfConfig.eIsSet(tfConfig.eClass().getEStructuralFeature( - "pwmFrequency"))) { - setPwmFrequency(tfConfig.getPwmFrequency()); - } - if (tfConfig.eIsSet(tfConfig.eClass().getEStructuralFeature( - "switchOnVelocity"))) { - setSwitchOnVelocity(tfConfig.getSwitchOnVelocity()); - } - if (tfConfig.eIsSet(tfConfig.eClass().getEStructuralFeature( - "driveMode"))) { - setDriveMode(DCDriveMode.get(tfConfig.getDriveMode())); - } - } - try { - tinkerforgeDevice.setAcceleration(acceleration); - tinkerforgeDevice.setPWMFrequency(pwmFrequency); - if (driveMode == DCDriveMode.BRAKE) - tinkerforgeDevice.setDriveMode(BrickDC.DRIVE_MODE_DRIVE_BRAKE); - else if (driveMode == DCDriveMode.COAST) - tinkerforgeDevice.setDriveMode(BrickDC.DRIVE_MODE_DRIVE_COAST); - tinkerforgeDevice.enable(); - setVelocity(getCurrentVelocity()); - } catch (TimeoutException e) { - TinkerforgeErrorHandler.handleError(this, - TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); - } catch (NotConnectedException e) { - TinkerforgeErrorHandler.handleError(this, - TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); - } - } + public void setMinVelocity(Short newMinVelocity) + { + Short oldMinVelocity = minVelocity; + minVelocity = newMinVelocity; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__MIN_VELOCITY, oldMinVelocity, minVelocity)); + } /** * * - * @generated NOT + * @generated */ - public void disable() + public String getDeviceType() { - tinkerforgeDevice = null; + return deviceType; } /** @@ -1065,17 +1221,9 @@ public void disable() * * @generated */ - @Override - public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + public short getVelocity() { - switch (featureID) - { - case ModelPackage.MBRICK_DC__BRICKD: - if (eInternalContainer() != null) - msgs = eBasicRemoveFromContainer(msgs); - return basicSetBrickd((MBrickd)otherEnd, msgs); - } - return super.eInverseAdd(otherEnd, featureID, msgs); + return velocity; } /** @@ -1083,11 +1231,588 @@ public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, No * * @generated */ - @Override - public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + public void setVelocity(short newVelocity) { - switch (featureID) - { + short oldVelocity = velocity; + velocity = newVelocity; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__VELOCITY, oldVelocity, velocity)); + } + + /** + * + * + * @generated + */ + public short getTargetvelocity() + { + return targetvelocity; + } + + /** + * + * + * @generated + */ + public void setTargetvelocity(short newTargetvelocity) + { + short oldTargetvelocity = targetvelocity; + targetvelocity = newTargetvelocity; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__TARGETVELOCITY, oldTargetvelocity, targetvelocity)); + } + + /** + * + * + * @generated + */ + public short getCurrentVelocity() + { + return currentVelocity; + } + + /** + * + * + * @generated + */ + public void setCurrentVelocity(short newCurrentVelocity) + { + short oldCurrentVelocity = currentVelocity; + currentVelocity = newCurrentVelocity; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__CURRENT_VELOCITY, oldCurrentVelocity, currentVelocity)); + } + + /** + * + * + * @generated + */ + public int getAcceleration() + { + return acceleration; + } + + /** + * + * + * @generated + */ + public void setAcceleration(int newAcceleration) + { + int oldAcceleration = acceleration; + acceleration = newAcceleration; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__ACCELERATION, oldAcceleration, acceleration)); + } + + /** + * + * + * @generated + */ + public int getPwmFrequency() + { + return pwmFrequency; + } + + /** + * + * + * @generated + */ + public void setPwmFrequency(int newPwmFrequency) + { + int oldPwmFrequency = pwmFrequency; + pwmFrequency = newPwmFrequency; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__PWM_FREQUENCY, oldPwmFrequency, pwmFrequency)); + } + + /** + * + * + * @generated + */ + public DCDriveMode getDriveMode() + { + return driveMode; + } + + /** + * + * + * @generated + */ + public void setDriveMode(DCDriveMode newDriveMode) + { + DCDriveMode oldDriveMode = driveMode; + driveMode = newDriveMode == null ? DRIVE_MODE_EDEFAULT : newDriveMode; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICK_DC__DRIVE_MODE, oldDriveMode, driveMode)); + } + + /** + * + * + * @generated NOT + */ + public void init() + { + logger = LoggerFactory.getLogger(MBrickDCImpl.class); + poll = true; // don't use the setter to prevent notification + setEnabledA(new AtomicBoolean()); + } + + /** + * + * + * @generated NOT + */ + public void setValue(BigDecimal newValue, DeviceOptions opts) + { + setPoint(newValue.shortValue(), opts); + } + + /** + * + * + * @generated NOT + */ + public void setValue(PercentType percentValue, DeviceOptions opts) + { + BigDecimal max = Tools.getBigDecimalOpt(ConfigOptsDimmable.MAX.toString(), opts); + if (max == null) { + logger.error("BrickDC dimmer option max is missing, items configuration has to be fixed!"); + return; + } else { + logger.debug("Brick DC max {}", max); + } + BigDecimal min = Tools.getBigDecimalOpt(ConfigOptsDimmable.MIN.toString(), opts); + logger.debug("Brick DC min {}", min); + if (min == null) { + logger.error("BrickDC dimmer option min is missing, items configuration has to be fixed!"); + return; + } + setPercentValue(new PercentValue(percentValue.toBigDecimal())); + BigDecimal abs = max.add(min.abs()); + Short newVelocity = + abs.divide(new BigDecimal(100)).multiply(percentValue.toBigDecimal()).subtract(min.abs()) + .shortValue(); + setPoint(newVelocity, opts); + } + + /** + * + * + * @generated NOT + */ + public void dimm(IncreaseDecreaseType increaseDecrease, DeviceOptions opts) { + logger.trace("dimmer increase increaseDecrease {} opts {}", increaseDecrease, opts); + if (opts == null) { + logger.error("Brick DC options are missing"); + return; + } + if (increaseDecrease == null) { + logger.error("Brick DC increaseDecrease may not be null!"); + return; + } + Short step = Tools.getShortOpt(ConfigOptsDimmable.STEP.toString(), opts); + if (step == null) { + logger.error("BrickDC dimmer option step is missing, items configuration has to be fixed!"); + return; + } + Short newVelocity = null; + if (increaseDecrease.equals(IncreaseDecreaseType.INCREASE)) { + newVelocity = (short) (this.targetvelocity + step); + } else if (increaseDecrease.equals(IncreaseDecreaseType.DECREASE)) { + newVelocity = (short) (this.targetvelocity - step); + } + logger.debug("Brick DC newVelocity {}", newVelocity); + setPoint(newVelocity, opts); + } + + /** + * + * + * @generated NOT + */ + private void setPoint(Short targetspeed, DeviceOptions opts) { + Integer xacceleration = Tools.getIntOpt(ConfigOptsMove.ACCELERATION.toString(), opts); + String drivemodestr = Tools.getStringOpt(ConfigOptsMove.DRIVEMODE.toString(), opts); + Short speed = null; + logger.trace("setPiont speed {} opts {}", targetspeed, opts); + if (opts == null) { + logger.error("Brick DC options are missing"); + return; + } + if (targetspeed == null) { + logger.error("Brick DC setPoint targetspeed may not be null!"); + return; + } + Short max = Tools.getShortOpt(ConfigOptsDimmable.MAX.toString(), opts); + if (max == null) { + logger.error("BrickDC dimmer option max is missing, items configuration has to be fixed!"); + return; + } else { + logger.debug("Brick DC max {}", max); + } + Short min = Tools.getShortOpt(ConfigOptsDimmable.MIN.toString(), opts); + logger.debug("Brick DC min {}", min); + if (min == null) { + logger.error("BrickDC dimmer option min is missing, items configuration has to be fixed!"); + return; + } + if (targetspeed > max) { + if (this.velocity < targetspeed) { + logger.debug("setting velocity to max speed {}, which is lower then target speed {}", max, + targetspeed); + speed = max; + } else { + logger.debug("max velocity already reached {}", max); + return; + } + } else if (targetspeed < min) { + if (this.velocity > targetspeed) { + logger.debug("setting velocity to min speed {}, which is higher then target speed {}", min, + targetspeed); + speed = min; + } else { + logger.debug("min velocity already reached {}", min); + return; + } + } else { + speed = targetspeed; + } + setSpeed(speed, xacceleration, drivemodestr, this.pwmFrequency); + } + + /** + * + * + * @generated NOT + */ + @Override + public void turnSwitch(OnOffValue state, DeviceOptions opts) { + logger.trace("turnSwitch called"); + if (state == OnOffValue.OFF) { + setSpeed((short) 0, null, null, null); + } else if (state == OnOffValue.ON) { + setSpeed(Tools.getShortOpt(ConfigOptsSwitchSpeed.SPEED.toString(), opts), null, null, null); + } else { + logger.error("{} unkown switchstate {}", LoggerConstants.TFMODELUPDATE, state); + } + } + + /** + * + * + * @generated NOT + */ + public void fetchSwitchState() { + fetchSensorValue(); + } + + /** + * + * + * @generated NOT + */ + public void fetchSensorValue() + { + try { + handleVelocity(tinkerforgeDevice.getVelocity(), false); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + public void moveon(DeviceOptions opts) { + if (direction != null && direction != DirectionValue.UNDEF) { + UpDownType directiontmp = + this.direction == DirectionValue.LEFT ? UpDownType.UP : UpDownType.DOWN; + move(directiontmp, opts); + } else { + logger.warn("cannot moveon because direction is undefined"); + } + } + + + + /** + * + * + * @generated NOT + */ + public void move(UpDownType direction, DeviceOptions opts) { + if (opts == null) { + logger.error("Brick DC options are missing"); + return; + } + if (direction == null) { + logger.error("Brick DC direction may not be null, items configuration has to be fixed!"); + return; + } + Integer itemacceleration = Tools.getIntOpt(ConfigOptsMove.ACCELERATION.toString(), opts); + String drivemodestr = Tools.getStringOpt(ConfigOptsMove.DRIVEMODE.toString(), opts); + Short speed = null; + + if (direction.equals(UpDownType.DOWN)) { + speed = Tools.getShortOpt(ConfigOptsMove.RIGHTSPEED.toString(), opts); + if (speed == null) { + logger + .error("\"rightspeed\" option missing or empty, items configuration has to be fixed!"); + return; + } else { + setDirection(DirectionValue.RIGHT); + } + } else if (direction.equals(UpDownType.UP)) { + speed = Tools.getShortOpt(ConfigOptsMove.LEFTSPEED.toString(), opts); + if (speed == null) { + logger.error("\"leftspeed\" option missing or empty, items configuration has to be fixed!"); + return; + } else { + setDirection(DirectionValue.LEFT); + } + } + setSpeed(speed, itemacceleration, drivemodestr, this.pwmFrequency); + } + + /** + * + * @generated NOT + */ + private Short driveModeFromString(String drivemodestr) { + logger.debug("drivemodestr short is: {}", drivemodestr); + Short drivemode = null; + if (drivemodestr != null) { + if (drivemodestr.equals(DCDriveMode.BRAKE.toString().toLowerCase())) { + drivemode = BrickDC.DRIVE_MODE_DRIVE_BRAKE; + } else if (drivemodestr.equals(DCDriveMode.COAST.toString().toLowerCase())) { + drivemode = BrickDC.DRIVE_MODE_DRIVE_COAST; + } else { + logger.error("invalid drivemode {}", drivemodestr); + } + } else { + // use defaults + if (driveMode == DCDriveMode.BRAKE) { + drivemode = BrickDC.DRIVE_MODE_DRIVE_BRAKE; + } else if (driveMode == DCDriveMode.COAST) { + drivemode = BrickDC.DRIVE_MODE_DRIVE_COAST; + } + + } + logger.debug("drivemode short is: {}", drivemode); + return drivemode; + } + + /** + * + * @generated NOT + */ + private boolean setSpeed(Short speed, Integer acceleration, String drivemode, Integer pwm) { + // use defaults if acceleration, drivemode or pwm are null + Short xdrivemode = driveModeFromString(drivemode); + Integer xacceleration = acceleration != null ? acceleration : this.acceleration; + Integer xpwm = pwm != null ? pwm : this.pwmFrequency; + short xspeed = 0; + if (speed == null) { + logger.warn("Brick DC got speed null, setting speed to 0"); + } else { + xspeed = speed; + } + try { + if (xdrivemode != null) { + // let Brick DC choose the drive mode + tinkerforgeDevice.setDriveMode(xdrivemode); + } + if (xacceleration != null) { + tinkerforgeDevice.setAcceleration(xacceleration); + } + if (xpwm != null) { + tinkerforgeDevice.setPWMFrequency(xpwm); + } + setTargetvelocity(xspeed); + tinkerforgeDevice.setVelocity(xspeed); + return true; + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + return false; + } + + /** + * + * + * @generated NOT + */ + public boolean setSpeed(Short velocity, int acceleration, String drivemode) { + return setSpeed(velocity, acceleration, drivemode, null); + } + + + /** + * + * + * @generated NOT + */ + public void stop() { + try { + tinkerforgeDevice.setVelocity((short) 0); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + public void enable() { + tinkerforgeDevice = new BrickDC(uid, ipConnection); + if (tfConfig != null) { + logger.debug("found tfConfig"); + if (tfConfig.eIsSet(tfConfig.eClass().getEStructuralFeature("acceleration"))) { + setAcceleration(tfConfig.getAcceleration()); + } + if (tfConfig.eIsSet(tfConfig.eClass().getEStructuralFeature("pwmFrequency"))) { + setPwmFrequency(tfConfig.getPwmFrequency()); + } + if (tfConfig.eIsSet(tfConfig.eClass().getEStructuralFeature("driveMode"))) { + setDriveMode(DCDriveMode.get(tfConfig.getDriveMode())); + } + if (tfConfig.eIsSet(tfConfig.eClass().getEStructuralFeature("threshold"))) { + setThreshold(tfConfig.getThreshold()); + } + if (tfConfig.eIsSet(tfConfig.eClass().getEStructuralFeature("callbackPeriod"))) { + setCallbackPeriod(tfConfig.getCallbackPeriod()); + } + } + try { + tinkerforgeDevice.setPWMFrequency(pwmFrequency); + if (driveMode == DCDriveMode.BRAKE) { + tinkerforgeDevice.setDriveMode(BrickDC.DRIVE_MODE_DRIVE_BRAKE); + } else if (driveMode == DCDriveMode.COAST) { + tinkerforgeDevice.setDriveMode(BrickDC.DRIVE_MODE_DRIVE_COAST); + } + tinkerforgeDevice.setCurrentVelocityPeriod((int) callbackPeriod); + listener = new VelocityListener(); + tinkerforgeDevice.addCurrentVelocityListener(listener); + tinkerforgeDevice.enable(); + handleVelocity(tinkerforgeDevice.getVelocity(), false); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + private class VelocityListener implements BrickDC.CurrentVelocityListener { + + @Override + public void currentVelocity(short velocity) { + handleVelocity(velocity); + } + + } + + /** + * + * @generated NOT + */ + private void handleVelocity(short velocity, boolean usethreshold) { + DecimalValue newValue = Tools.calculate(velocity); + logger.trace("{} got new value {}", LoggerConstants.TFMODELUPDATE, newValue); + if (usethreshold) { + if (newValue.compareTo(getSensorValue(), getThreshold()) != 0) { + logger.trace("{} setting new value {}", LoggerConstants.TFMODELUPDATE, newValue); + setSensorValue(newValue); + } else { + logger.trace("{} omitting new value {}", LoggerConstants.TFMODELUPDATE, newValue); + } + } else { + logger.trace("{} setting new value {}", LoggerConstants.TFMODELUPDATE, newValue); + setSensorValue(newValue); + } + OnOffValue newSwitchState = newValue.onOffValue(0); + logger.trace("new switchstate {} new value {}", newSwitchState, newValue); + if (newSwitchState != switchState) { + setSwitchState(newSwitchState); + } + } + + /** + * + * @generated NOT + */ + private void handleVelocity(short velocity) { + handleVelocity(velocity, true); + } + + /** + * + * + * @generated NOT + */ + public void disable() { + if (listener != null) { + tinkerforgeDevice.removeCurrentVelocityListener(listener); + } + + tinkerforgeDevice = null; + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.MBRICK_DC__BRICKD: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetBrickd((MBrickd)otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { case ModelPackage.MBRICK_DC__BRICKD: return basicSetBrickd(null, msgs); case ModelPackage.MBRICK_DC__TF_CONFIG: @@ -1122,6 +1847,8 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { + case ModelPackage.MBRICK_DC__SENSOR_VALUE: + return getSensorValue(); case ModelPackage.MBRICK_DC__SWITCH_STATE: return getSwitchState(); case ModelPackage.MBRICK_DC__LOGGER: @@ -1146,12 +1873,30 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) return getName(); case ModelPackage.MBRICK_DC__BRICKD: return getBrickd(); + case ModelPackage.MBRICK_DC__DIRECTION: + return getDirection(); case ModelPackage.MBRICK_DC__TF_CONFIG: return getTfConfig(); + case ModelPackage.MBRICK_DC__MIN_VALUE: + return getMinValue(); + case ModelPackage.MBRICK_DC__MAX_VALUE: + return getMaxValue(); + case ModelPackage.MBRICK_DC__PERCENT_VALUE: + return getPercentValue(); + case ModelPackage.MBRICK_DC__CALLBACK_PERIOD: + return getCallbackPeriod(); case ModelPackage.MBRICK_DC__DEVICE_TYPE: return getDeviceType(); + case ModelPackage.MBRICK_DC__THRESHOLD: + return getThreshold(); + case ModelPackage.MBRICK_DC__MAX_VELOCITY: + return getMaxVelocity(); + case ModelPackage.MBRICK_DC__MIN_VELOCITY: + return getMinVelocity(); case ModelPackage.MBRICK_DC__VELOCITY: return getVelocity(); + case ModelPackage.MBRICK_DC__TARGETVELOCITY: + return getTargetvelocity(); case ModelPackage.MBRICK_DC__CURRENT_VELOCITY: return getCurrentVelocity(); case ModelPackage.MBRICK_DC__ACCELERATION: @@ -1160,8 +1905,6 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) return getPwmFrequency(); case ModelPackage.MBRICK_DC__DRIVE_MODE: return getDriveMode(); - case ModelPackage.MBRICK_DC__SWITCH_ON_VELOCITY: - return getSwitchOnVelocity(); } return super.eGet(featureID, resolve, coreType); } @@ -1176,6 +1919,9 @@ public void eSet(int featureID, Object newValue) { switch (featureID) { + case ModelPackage.MBRICK_DC__SENSOR_VALUE: + setSensorValue((DecimalValue)newValue); + return; case ModelPackage.MBRICK_DC__SWITCH_STATE: setSwitchState((OnOffValue)newValue); return; @@ -1212,12 +1958,39 @@ public void eSet(int featureID, Object newValue) case ModelPackage.MBRICK_DC__BRICKD: setBrickd((MBrickd)newValue); return; + case ModelPackage.MBRICK_DC__DIRECTION: + setDirection((DirectionValue)newValue); + return; case ModelPackage.MBRICK_DC__TF_CONFIG: setTfConfig((TFBrickDCConfiguration)newValue); return; + case ModelPackage.MBRICK_DC__MIN_VALUE: + setMinValue((BigDecimal)newValue); + return; + case ModelPackage.MBRICK_DC__MAX_VALUE: + setMaxValue((BigDecimal)newValue); + return; + case ModelPackage.MBRICK_DC__PERCENT_VALUE: + setPercentValue((PercentValue)newValue); + return; + case ModelPackage.MBRICK_DC__CALLBACK_PERIOD: + setCallbackPeriod((Long)newValue); + return; + case ModelPackage.MBRICK_DC__THRESHOLD: + setThreshold((BigDecimal)newValue); + return; + case ModelPackage.MBRICK_DC__MAX_VELOCITY: + setMaxVelocity((Short)newValue); + return; + case ModelPackage.MBRICK_DC__MIN_VELOCITY: + setMinVelocity((Short)newValue); + return; case ModelPackage.MBRICK_DC__VELOCITY: setVelocity((Short)newValue); return; + case ModelPackage.MBRICK_DC__TARGETVELOCITY: + setTargetvelocity((Short)newValue); + return; case ModelPackage.MBRICK_DC__CURRENT_VELOCITY: setCurrentVelocity((Short)newValue); return; @@ -1230,9 +2003,6 @@ public void eSet(int featureID, Object newValue) case ModelPackage.MBRICK_DC__DRIVE_MODE: setDriveMode((DCDriveMode)newValue); return; - case ModelPackage.MBRICK_DC__SWITCH_ON_VELOCITY: - setSwitchOnVelocity((Short)newValue); - return; } super.eSet(featureID, newValue); } @@ -1247,6 +2017,9 @@ public void eUnset(int featureID) { switch (featureID) { + case ModelPackage.MBRICK_DC__SENSOR_VALUE: + setSensorValue((DecimalValue)null); + return; case ModelPackage.MBRICK_DC__SWITCH_STATE: setSwitchState(SWITCH_STATE_EDEFAULT); return; @@ -1283,12 +2056,39 @@ public void eUnset(int featureID) case ModelPackage.MBRICK_DC__BRICKD: setBrickd((MBrickd)null); return; + case ModelPackage.MBRICK_DC__DIRECTION: + setDirection(DIRECTION_EDEFAULT); + return; case ModelPackage.MBRICK_DC__TF_CONFIG: setTfConfig((TFBrickDCConfiguration)null); return; + case ModelPackage.MBRICK_DC__MIN_VALUE: + setMinValue(MIN_VALUE_EDEFAULT); + return; + case ModelPackage.MBRICK_DC__MAX_VALUE: + setMaxValue(MAX_VALUE_EDEFAULT); + return; + case ModelPackage.MBRICK_DC__PERCENT_VALUE: + setPercentValue(PERCENT_VALUE_EDEFAULT); + return; + case ModelPackage.MBRICK_DC__CALLBACK_PERIOD: + setCallbackPeriod(CALLBACK_PERIOD_EDEFAULT); + return; + case ModelPackage.MBRICK_DC__THRESHOLD: + setThreshold(THRESHOLD_EDEFAULT); + return; + case ModelPackage.MBRICK_DC__MAX_VELOCITY: + setMaxVelocity(MAX_VELOCITY_EDEFAULT); + return; + case ModelPackage.MBRICK_DC__MIN_VELOCITY: + setMinVelocity(MIN_VELOCITY_EDEFAULT); + return; case ModelPackage.MBRICK_DC__VELOCITY: setVelocity(VELOCITY_EDEFAULT); return; + case ModelPackage.MBRICK_DC__TARGETVELOCITY: + setTargetvelocity(TARGETVELOCITY_EDEFAULT); + return; case ModelPackage.MBRICK_DC__CURRENT_VELOCITY: setCurrentVelocity(CURRENT_VELOCITY_EDEFAULT); return; @@ -1301,9 +2101,6 @@ public void eUnset(int featureID) case ModelPackage.MBRICK_DC__DRIVE_MODE: setDriveMode(DRIVE_MODE_EDEFAULT); return; - case ModelPackage.MBRICK_DC__SWITCH_ON_VELOCITY: - setSwitchOnVelocity(SWITCH_ON_VELOCITY_EDEFAULT); - return; } super.eUnset(featureID); } @@ -1318,6 +2115,8 @@ public boolean eIsSet(int featureID) { switch (featureID) { + case ModelPackage.MBRICK_DC__SENSOR_VALUE: + return sensorValue != null; case ModelPackage.MBRICK_DC__SWITCH_STATE: return SWITCH_STATE_EDEFAULT == null ? switchState != null : !SWITCH_STATE_EDEFAULT.equals(switchState); case ModelPackage.MBRICK_DC__LOGGER: @@ -1342,12 +2141,30 @@ public boolean eIsSet(int featureID) return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name); case ModelPackage.MBRICK_DC__BRICKD: return getBrickd() != null; + case ModelPackage.MBRICK_DC__DIRECTION: + return DIRECTION_EDEFAULT == null ? direction != null : !DIRECTION_EDEFAULT.equals(direction); case ModelPackage.MBRICK_DC__TF_CONFIG: return tfConfig != null; + case ModelPackage.MBRICK_DC__MIN_VALUE: + return MIN_VALUE_EDEFAULT == null ? minValue != null : !MIN_VALUE_EDEFAULT.equals(minValue); + case ModelPackage.MBRICK_DC__MAX_VALUE: + return MAX_VALUE_EDEFAULT == null ? maxValue != null : !MAX_VALUE_EDEFAULT.equals(maxValue); + case ModelPackage.MBRICK_DC__PERCENT_VALUE: + return PERCENT_VALUE_EDEFAULT == null ? percentValue != null : !PERCENT_VALUE_EDEFAULT.equals(percentValue); + case ModelPackage.MBRICK_DC__CALLBACK_PERIOD: + return callbackPeriod != CALLBACK_PERIOD_EDEFAULT; case ModelPackage.MBRICK_DC__DEVICE_TYPE: return DEVICE_TYPE_EDEFAULT == null ? deviceType != null : !DEVICE_TYPE_EDEFAULT.equals(deviceType); + case ModelPackage.MBRICK_DC__THRESHOLD: + return THRESHOLD_EDEFAULT == null ? threshold != null : !THRESHOLD_EDEFAULT.equals(threshold); + case ModelPackage.MBRICK_DC__MAX_VELOCITY: + return MAX_VELOCITY_EDEFAULT == null ? maxVelocity != null : !MAX_VELOCITY_EDEFAULT.equals(maxVelocity); + case ModelPackage.MBRICK_DC__MIN_VELOCITY: + return MIN_VELOCITY_EDEFAULT == null ? minVelocity != null : !MIN_VELOCITY_EDEFAULT.equals(minVelocity); case ModelPackage.MBRICK_DC__VELOCITY: return velocity != VELOCITY_EDEFAULT; + case ModelPackage.MBRICK_DC__TARGETVELOCITY: + return targetvelocity != TARGETVELOCITY_EDEFAULT; case ModelPackage.MBRICK_DC__CURRENT_VELOCITY: return currentVelocity != CURRENT_VELOCITY_EDEFAULT; case ModelPackage.MBRICK_DC__ACCELERATION: @@ -1356,8 +2173,6 @@ public boolean eIsSet(int featureID) return pwmFrequency != PWM_FREQUENCY_EDEFAULT; case ModelPackage.MBRICK_DC__DRIVE_MODE: return driveMode != DRIVE_MODE_EDEFAULT; - case ModelPackage.MBRICK_DC__SWITCH_ON_VELOCITY: - return switchOnVelocity != SWITCH_ON_VELOCITY_EDEFAULT; } return super.eIsSet(featureID); } @@ -1370,6 +2185,21 @@ public boolean eIsSet(int featureID) @Override public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) { + if (baseClass == SwitchSensor.class) + { + switch (derivedFeatureID) + { + default: return -1; + } + } + if (baseClass == ProgrammableSwitchActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICK_DC__SWITCH_STATE: return ModelPackage.PROGRAMMABLE_SWITCH_ACTOR__SWITCH_STATE; + default: return -1; + } + } if (baseClass == MBaseDevice.class) { switch (derivedFeatureID) @@ -1395,6 +2225,14 @@ public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) default: return -1; } } + if (baseClass == MoveActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICK_DC__DIRECTION: return ModelPackage.MOVE_ACTOR__DIRECTION; + default: return -1; + } + } if (baseClass == MTFConfigConsumer.class) { switch (derivedFeatureID) @@ -1403,6 +2241,31 @@ public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) default: return -1; } } + if (baseClass == DimmableActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICK_DC__MIN_VALUE: return ModelPackage.DIMMABLE_ACTOR__MIN_VALUE; + case ModelPackage.MBRICK_DC__MAX_VALUE: return ModelPackage.DIMMABLE_ACTOR__MAX_VALUE; + default: return -1; + } + } + if (baseClass == SetPointActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICK_DC__PERCENT_VALUE: return ModelPackage.SET_POINT_ACTOR__PERCENT_VALUE; + default: return -1; + } + } + if (baseClass == CallbackListener.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICK_DC__CALLBACK_PERIOD: return ModelPackage.CALLBACK_LISTENER__CALLBACK_PERIOD; + default: return -1; + } + } return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); } @@ -1414,6 +2277,21 @@ public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) @Override public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) { + if (baseClass == SwitchSensor.class) + { + switch (baseFeatureID) + { + default: return -1; + } + } + if (baseClass == ProgrammableSwitchActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.PROGRAMMABLE_SWITCH_ACTOR__SWITCH_STATE: return ModelPackage.MBRICK_DC__SWITCH_STATE; + default: return -1; + } + } if (baseClass == MBaseDevice.class) { switch (baseFeatureID) @@ -1439,6 +2317,14 @@ public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) default: return -1; } } + if (baseClass == MoveActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.MOVE_ACTOR__DIRECTION: return ModelPackage.MBRICK_DC__DIRECTION; + default: return -1; + } + } if (baseClass == MTFConfigConsumer.class) { switch (baseFeatureID) @@ -1447,6 +2333,31 @@ public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) default: return -1; } } + if (baseClass == DimmableActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.DIMMABLE_ACTOR__MIN_VALUE: return ModelPackage.MBRICK_DC__MIN_VALUE; + case ModelPackage.DIMMABLE_ACTOR__MAX_VALUE: return ModelPackage.MBRICK_DC__MAX_VALUE; + default: return -1; + } + } + if (baseClass == SetPointActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.SET_POINT_ACTOR__PERCENT_VALUE: return ModelPackage.MBRICK_DC__PERCENT_VALUE; + default: return -1; + } + } + if (baseClass == CallbackListener.class) + { + switch (baseFeatureID) + { + case ModelPackage.CALLBACK_LISTENER__CALLBACK_PERIOD: return ModelPackage.MBRICK_DC__CALLBACK_PERIOD; + default: return -1; + } + } return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); } @@ -1458,6 +2369,22 @@ public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) @Override public int eDerivedOperationID(int baseOperationID, Class baseClass) { + if (baseClass == SwitchSensor.class) + { + switch (baseOperationID) + { + case ModelPackage.SWITCH_SENSOR___FETCH_SWITCH_STATE: return ModelPackage.MBRICK_DC___FETCH_SWITCH_STATE; + default: return -1; + } + } + if (baseClass == ProgrammableSwitchActor.class) + { + switch (baseOperationID) + { + case ModelPackage.PROGRAMMABLE_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE_DEVICEOPTIONS: return ModelPackage.MBRICK_DC___TURN_SWITCH__ONOFFVALUE_DEVICEOPTIONS; + default: return -1; + } + } if (baseClass == MBaseDevice.class) { switch (baseOperationID) @@ -1475,6 +2402,16 @@ public int eDerivedOperationID(int baseOperationID, Class baseClass) default: return -1; } } + if (baseClass == MoveActor.class) + { + switch (baseOperationID) + { + case ModelPackage.MOVE_ACTOR___MOVE__UPDOWNTYPE_DEVICEOPTIONS: return ModelPackage.MBRICK_DC___MOVE__UPDOWNTYPE_DEVICEOPTIONS; + case ModelPackage.MOVE_ACTOR___STOP: return ModelPackage.MBRICK_DC___STOP; + case ModelPackage.MOVE_ACTOR___MOVEON__DEVICEOPTIONS: return ModelPackage.MBRICK_DC___MOVEON__DEVICEOPTIONS; + default: return -1; + } + } if (baseClass == MTFConfigConsumer.class) { switch (baseOperationID) @@ -1482,6 +2419,30 @@ public int eDerivedOperationID(int baseOperationID, Class baseClass) default: return -1; } } + if (baseClass == DimmableActor.class) + { + switch (baseOperationID) + { + case ModelPackage.DIMMABLE_ACTOR___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS: return ModelPackage.MBRICK_DC___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS; + default: return -1; + } + } + if (baseClass == SetPointActor.class) + { + switch (baseOperationID) + { + case ModelPackage.SET_POINT_ACTOR___SET_VALUE__BIGDECIMAL_DEVICEOPTIONS: return ModelPackage.MBRICK_DC___SET_VALUE__BIGDECIMAL_DEVICEOPTIONS; + case ModelPackage.SET_POINT_ACTOR___SET_VALUE__PERCENTTYPE_DEVICEOPTIONS: return ModelPackage.MBRICK_DC___SET_VALUE__PERCENTTYPE_DEVICEOPTIONS; + default: return -1; + } + } + if (baseClass == CallbackListener.class) + { + switch (baseOperationID) + { + default: return -1; + } + } return super.eDerivedOperationID(baseOperationID, baseClass); } @@ -1498,18 +2459,41 @@ public Object eInvoke(int operationID, EList arguments) throws InvocationTarg case ModelPackage.MBRICK_DC___INIT: init(); return null; + case ModelPackage.MBRICK_DC___SET_SPEED__SHORT_INT_STRING: + return setSpeed((Short)arguments.get(0), (Integer)arguments.get(1), (String)arguments.get(2)); + case ModelPackage.MBRICK_DC___SET_VALUE__BIGDECIMAL_DEVICEOPTIONS: + setValue((BigDecimal)arguments.get(0), (DeviceOptions)arguments.get(1)); + return null; + case ModelPackage.MBRICK_DC___SET_VALUE__PERCENTTYPE_DEVICEOPTIONS: + setValue((PercentType)arguments.get(0), (DeviceOptions)arguments.get(1)); + return null; + case ModelPackage.MBRICK_DC___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS: + dimm((IncreaseDecreaseType)arguments.get(0), (DeviceOptions)arguments.get(1)); + return null; + case ModelPackage.MBRICK_DC___MOVE__UPDOWNTYPE_DEVICEOPTIONS: + move((UpDownType)arguments.get(0), (DeviceOptions)arguments.get(1)); + return null; + case ModelPackage.MBRICK_DC___STOP: + stop(); + return null; + case ModelPackage.MBRICK_DC___MOVEON__DEVICEOPTIONS: + moveon((DeviceOptions)arguments.get(0)); + return null; case ModelPackage.MBRICK_DC___ENABLE: enable(); return null; case ModelPackage.MBRICK_DC___DISABLE: disable(); return null; - case ModelPackage.MBRICK_DC___TURN_SWITCH__ONOFFVALUE: - turnSwitch((OnOffValue)arguments.get(0)); + case ModelPackage.MBRICK_DC___TURN_SWITCH__ONOFFVALUE_DEVICEOPTIONS: + turnSwitch((OnOffValue)arguments.get(0), (DeviceOptions)arguments.get(1)); return null; case ModelPackage.MBRICK_DC___FETCH_SWITCH_STATE: fetchSwitchState(); return null; + case ModelPackage.MBRICK_DC___FETCH_SENSOR_VALUE: + fetchSensorValue(); + return null; } return super.eInvoke(operationID, arguments); } @@ -1525,7 +2509,9 @@ public String toString() if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); - result.append(" (switchState: "); + result.append(" (sensorValue: "); + result.append(sensorValue); + result.append(", switchState: "); result.append(switchState); result.append(", logger: "); result.append(logger); @@ -1547,10 +2533,28 @@ public String toString() result.append(deviceIdentifier); result.append(", name: "); result.append(name); + result.append(", direction: "); + result.append(direction); + result.append(", minValue: "); + result.append(minValue); + result.append(", maxValue: "); + result.append(maxValue); + result.append(", percentValue: "); + result.append(percentValue); + result.append(", callbackPeriod: "); + result.append(callbackPeriod); result.append(", deviceType: "); result.append(deviceType); + result.append(", threshold: "); + result.append(threshold); + result.append(", maxVelocity: "); + result.append(maxVelocity); + result.append(", minVelocity: "); + result.append(minVelocity); result.append(", velocity: "); result.append(velocity); + result.append(", targetvelocity: "); + result.append(targetvelocity); result.append(", currentVelocity: "); result.append(currentVelocity); result.append(", acceleration: "); @@ -1559,8 +2563,6 @@ public String toString() result.append(pwmFrequency); result.append(", driveMode: "); result.append(driveMode); - result.append(", switchOnVelocity: "); - result.append(switchOnVelocity); result.append(')'); return result.toString(); } diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickdImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickdImpl.java index 5c8b684ee7b..78eae612a13 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickdImpl.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickdImpl.java @@ -49,6 +49,7 @@ import com.tinkerforge.BrickletBarometer; import com.tinkerforge.BrickletDistanceIR; import com.tinkerforge.BrickletDistanceUS; +import com.tinkerforge.BrickletDualButton; import com.tinkerforge.BrickletDualRelay; import com.tinkerforge.BrickletHallEffect; import com.tinkerforge.BrickletHumidity; @@ -57,8 +58,10 @@ import com.tinkerforge.BrickletIndustrialDigitalIn4; import com.tinkerforge.BrickletIndustrialDigitalOut4; import com.tinkerforge.BrickletIndustrialQuadRelay; +import com.tinkerforge.BrickletJoystick; import com.tinkerforge.BrickletLCD20x4; import com.tinkerforge.BrickletLEDStrip; +import com.tinkerforge.BrickletLinearPoti; import com.tinkerforge.BrickletMoisture; import com.tinkerforge.BrickletMotionDetector; import com.tinkerforge.BrickletMultiTouch; @@ -885,6 +888,18 @@ private void addDevice(String uid, String connectedUid, int deviceIdentifier) { logger.debug("addDevice BrickletLEDStrip"); mDevice = factory.createMBrickletLEDStrip(); mDevice.setDeviceIdentifier(BrickletLEDStrip.DEVICE_IDENTIFIER); + } else if (deviceIdentifier == BrickletJoystick.DEVICE_IDENTIFIER){ + logger.debug("addDevice BrickletJoystick"); + mDevice = factory.createMBrickletJoystick(); + mDevice.setDeviceIdentifier(BrickletJoystick.DEVICE_IDENTIFIER); + } else if (deviceIdentifier == BrickletLinearPoti.DEVICE_IDENTIFIER){ + logger.debug("addDevice BrickletLinearPoti"); + mDevice = factory.createMBrickletLinearPoti(); + mDevice.setDeviceIdentifier(BrickletLinearPoti.DEVICE_IDENTIFIER); + } else if (deviceIdentifier == BrickletDualButton.DEVICE_IDENTIFIER){ + logger.debug("addDevice BrickletDualButton"); + mDevice = factory.createMBrickletDualButton(); + mDevice.setDeviceIdentifier(BrickletDualButton.DEVICE_IDENTIFIER); } if (mDevice != null) { mDevice.setIpConnection(getIpConnection()); diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletDualButtonImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletDualButtonImpl.java new file mode 100644 index 00000000000..23c8fdaa1e5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletDualButtonImpl.java @@ -0,0 +1,995 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.util.InternalEList; +import org.openhab.binding.tinkerforge.internal.LoggerConstants; +import org.openhab.binding.tinkerforge.internal.model.DualButtonDevice; +import org.openhab.binding.tinkerforge.internal.model.DualButtonLeftButton; +import org.openhab.binding.tinkerforge.internal.model.DualButtonLeftLed; +import org.openhab.binding.tinkerforge.internal.model.DualButtonRightButton; +import org.openhab.binding.tinkerforge.internal.model.DualButtonRightLed; +import org.openhab.binding.tinkerforge.internal.model.MBrickd; +import org.openhab.binding.tinkerforge.internal.model.MBrickletDualButton; +import org.openhab.binding.tinkerforge.internal.model.MSubDevice; +import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; +import org.openhab.binding.tinkerforge.internal.model.ModelFactory; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerforge.BrickletDualButton; +import com.tinkerforge.IPConnection; + +/** + * + * An implementation of the model object 'MBricklet Dual Button'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#getLogger Logger}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#getUid Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#isPoll Poll}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#getEnabledA Enabled A}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#getTinkerforgeDevice Tinkerforge Device}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#getIpConnection Ip Connection}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#getConnectedUid Connected Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#getPosition Position}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#getDeviceIdentifier Device Identifier}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#getName Name}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#getBrickd Brickd}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletDualButtonImpl#getMsubdevices Msubdevices}
      • + *
      + *

      + * + * @generated + */ +public class MBrickletDualButtonImpl extends MinimalEObjectImpl.Container implements MBrickletDualButton +{ + /** + * The default value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected static final Logger LOGGER_EDEFAULT = null; + + /** + * The cached value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected Logger logger = LOGGER_EDEFAULT; + + /** + * The default value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected static final String UID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected String uid = UID_EDEFAULT; + + /** + * The default value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected static final boolean POLL_EDEFAULT = true; + + /** + * The cached value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected boolean poll = POLL_EDEFAULT; + + /** + * The default value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected static final AtomicBoolean ENABLED_A_EDEFAULT = null; + + /** + * The cached value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected AtomicBoolean enabledA = ENABLED_A_EDEFAULT; + + /** + * The cached value of the '{@link #getTinkerforgeDevice() Tinkerforge Device}' attribute. + * + * + * @see #getTinkerforgeDevice() + * @generated + * @ordered + */ + protected BrickletDualButton tinkerforgeDevice; + + /** + * The default value of the '{@link #getIpConnection() Ip Connection}' attribute. + * + * + * @see #getIpConnection() + * @generated + * @ordered + */ + protected static final IPConnection IP_CONNECTION_EDEFAULT = null; + + /** + * The cached value of the '{@link #getIpConnection() Ip Connection}' attribute. + * + * + * @see #getIpConnection() + * @generated + * @ordered + */ + protected IPConnection ipConnection = IP_CONNECTION_EDEFAULT; + + /** + * The default value of the '{@link #getConnectedUid() Connected Uid}' attribute. + * + * + * @see #getConnectedUid() + * @generated + * @ordered + */ + protected static final String CONNECTED_UID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getConnectedUid() Connected Uid}' attribute. + * + * + * @see #getConnectedUid() + * @generated + * @ordered + */ + protected String connectedUid = CONNECTED_UID_EDEFAULT; + + /** + * The default value of the '{@link #getPosition() Position}' attribute. + * + * + * @see #getPosition() + * @generated + * @ordered + */ + protected static final char POSITION_EDEFAULT = '\u0000'; + + /** + * The cached value of the '{@link #getPosition() Position}' attribute. + * + * + * @see #getPosition() + * @generated + * @ordered + */ + protected char position = POSITION_EDEFAULT; + + /** + * The default value of the '{@link #getDeviceIdentifier() Device Identifier}' attribute. + * + * + * @see #getDeviceIdentifier() + * @generated + * @ordered + */ + protected static final int DEVICE_IDENTIFIER_EDEFAULT = 0; + + /** + * The cached value of the '{@link #getDeviceIdentifier() Device Identifier}' attribute. + * + * + * @see #getDeviceIdentifier() + * @generated + * @ordered + */ + protected int deviceIdentifier = DEVICE_IDENTIFIER_EDEFAULT; + + /** + * The default value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected static final String NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected String name = NAME_EDEFAULT; + + /** + * The cached value of the '{@link #getMsubdevices() Msubdevices}' containment reference list. + * + * + * @see #getMsubdevices() + * @generated + * @ordered + */ + protected EList msubdevices; + + /** + * + * + * @generated + */ + protected MBrickletDualButtonImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.MBRICKLET_DUAL_BUTTON; + } + + /** + * + * + * @generated + */ + public Logger getLogger() + { + return logger; + } + + /** + * + * + * @generated + */ + public void setLogger(Logger newLogger) + { + Logger oldLogger = logger; + logger = newLogger; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_DUAL_BUTTON__LOGGER, oldLogger, logger)); + } + + /** + * + * + * @generated + */ + public String getUid() + { + return uid; + } + + /** + * + * + * @generated + */ + public void setUid(String newUid) + { + String oldUid = uid; + uid = newUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_DUAL_BUTTON__UID, oldUid, uid)); + } + + /** + * + * + * @generated + */ + public boolean isPoll() + { + return poll; + } + + /** + * + * + * @generated + */ + public void setPoll(boolean newPoll) + { + boolean oldPoll = poll; + poll = newPoll; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_DUAL_BUTTON__POLL, oldPoll, poll)); + } + + /** + * + * + * @generated + */ + public AtomicBoolean getEnabledA() + { + return enabledA; + } + + /** + * + * + * @generated + */ + public void setEnabledA(AtomicBoolean newEnabledA) + { + AtomicBoolean oldEnabledA = enabledA; + enabledA = newEnabledA; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_DUAL_BUTTON__ENABLED_A, oldEnabledA, enabledA)); + } + + /** + * + * + * @generated + */ + public BrickletDualButton getTinkerforgeDevice() + { + return tinkerforgeDevice; + } + + /** + * + * + * @generated + */ + public void setTinkerforgeDevice(BrickletDualButton newTinkerforgeDevice) + { + BrickletDualButton oldTinkerforgeDevice = tinkerforgeDevice; + tinkerforgeDevice = newTinkerforgeDevice; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_DUAL_BUTTON__TINKERFORGE_DEVICE, oldTinkerforgeDevice, tinkerforgeDevice)); + } + + /** + * + * + * @generated + */ + public IPConnection getIpConnection() + { + return ipConnection; + } + + /** + * + * + * @generated + */ + public void setIpConnection(IPConnection newIpConnection) + { + IPConnection oldIpConnection = ipConnection; + ipConnection = newIpConnection; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_DUAL_BUTTON__IP_CONNECTION, oldIpConnection, ipConnection)); + } + + /** + * + * + * @generated + */ + public String getConnectedUid() + { + return connectedUid; + } + + /** + * + * + * @generated + */ + public void setConnectedUid(String newConnectedUid) + { + String oldConnectedUid = connectedUid; + connectedUid = newConnectedUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_DUAL_BUTTON__CONNECTED_UID, oldConnectedUid, connectedUid)); + } + + /** + * + * + * @generated + */ + public char getPosition() + { + return position; + } + + /** + * + * + * @generated + */ + public void setPosition(char newPosition) + { + char oldPosition = position; + position = newPosition; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_DUAL_BUTTON__POSITION, oldPosition, position)); + } + + /** + * + * + * @generated + */ + public int getDeviceIdentifier() + { + return deviceIdentifier; + } + + /** + * + * + * @generated + */ + public void setDeviceIdentifier(int newDeviceIdentifier) + { + int oldDeviceIdentifier = deviceIdentifier; + deviceIdentifier = newDeviceIdentifier; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_DUAL_BUTTON__DEVICE_IDENTIFIER, oldDeviceIdentifier, deviceIdentifier)); + } + + /** + * + * + * @generated + */ + public String getName() + { + return name; + } + + /** + * + * + * @generated + */ + public void setName(String newName) + { + String oldName = name; + name = newName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_DUAL_BUTTON__NAME, oldName, name)); + } + + /** + * + * + * @generated + */ + public MBrickd getBrickd() + { + if (eContainerFeatureID() != ModelPackage.MBRICKLET_DUAL_BUTTON__BRICKD) return null; + return (MBrickd)eContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetBrickd(MBrickd newBrickd, NotificationChain msgs) + { + msgs = eBasicSetContainer((InternalEObject)newBrickd, ModelPackage.MBRICKLET_DUAL_BUTTON__BRICKD, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setBrickd(MBrickd newBrickd) + { + if (newBrickd != eInternalContainer() || (eContainerFeatureID() != ModelPackage.MBRICKLET_DUAL_BUTTON__BRICKD && newBrickd != null)) + { + if (EcoreUtil.isAncestor(this, newBrickd)) + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + NotificationChain msgs = null; + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + if (newBrickd != null) + msgs = ((InternalEObject)newBrickd).eInverseAdd(this, ModelPackage.MBRICKD__MDEVICES, MBrickd.class, msgs); + msgs = basicSetBrickd(newBrickd, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_DUAL_BUTTON__BRICKD, newBrickd, newBrickd)); + } + + /** + * + * + * @generated + */ + public EList getMsubdevices() + { + if (msubdevices == null) + { + msubdevices = new EObjectContainmentWithInverseEList(MSubDevice.class, this, ModelPackage.MBRICKLET_DUAL_BUTTON__MSUBDEVICES, ModelPackage.MSUB_DEVICE__MBRICK); + } + return msubdevices; + } + + /** + * + * + * @generated NOT + */ + public void initSubDevices() + { + DualButtonLeftButton leftButton = ModelFactory.eINSTANCE.createDualButtonLeftButton(); + leftButton.setUid(getUid()); + String subIdLeftButton = "dualbutton_leftbutton"; + leftButton.setSubId(subIdLeftButton); + logger.debug("{} addSubDevice {}", LoggerConstants.TFINIT, subIdLeftButton); + leftButton.init(); + leftButton.setMbrick(this); + + DualButtonRightButton rightButton = ModelFactory.eINSTANCE.createDualButtonRightButton(); + rightButton.setUid(getUid()); + String subIdRightButton = "dualbutton_rightbutton"; + rightButton.setSubId(subIdRightButton); + logger.debug("{} addSubDevice {}", LoggerConstants.TFINIT, subIdRightButton); + rightButton.init(); + rightButton.setMbrick(this); + + DualButtonLeftLed leftLed = ModelFactory.eINSTANCE.createDualButtonLeftLed(); + leftLed.setUid(getUid()); + String subidLeftLed = "dualbutton_leftled"; + leftLed.setSubId(subidLeftLed); + logger.debug("{} addSubDevice {}", LoggerConstants.TFINIT, subidLeftLed); + leftLed.init(); + leftLed.setMbrick(this); + + DualButtonRightLed rightLed = ModelFactory.eINSTANCE.createDualButtonRightLed(); + rightLed.setUid(getUid()); + String subIdRightLed = "dualbutton_rightled"; + rightLed.setSubId(subIdRightLed); + logger.debug("{} addSubDevice {}", LoggerConstants.TFINIT, subIdRightLed); + rightLed.init(); + rightLed.setMbrick(this); + } + + /** + * + * + * @generated NOT + */ + public void init() + { + setEnabledA(new AtomicBoolean()); + logger = LoggerFactory.getLogger(MBrickletDualButtonImpl.class); + } + + /** + * + * + * @generated NOT + */ + public void enable() + { + tinkerforgeDevice = new BrickletDualButton(getUid(), getIpConnection()); + } + + /** + * + * + * @generated NOT + */ + public void disable() + { + tinkerforgeDevice = null; + } + + /** + * + * + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_DUAL_BUTTON__BRICKD: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetBrickd((MBrickd)otherEnd, msgs); + case ModelPackage.MBRICKLET_DUAL_BUTTON__MSUBDEVICES: + return ((InternalEList)(InternalEList)getMsubdevices()).basicAdd(otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_DUAL_BUTTON__BRICKD: + return basicSetBrickd(null, msgs); + case ModelPackage.MBRICKLET_DUAL_BUTTON__MSUBDEVICES: + return ((InternalEList)getMsubdevices()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) + { + switch (eContainerFeatureID()) + { + case ModelPackage.MBRICKLET_DUAL_BUTTON__BRICKD: + return eInternalContainer().eInverseRemove(this, ModelPackage.MBRICKD__MDEVICES, MBrickd.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_DUAL_BUTTON__LOGGER: + return getLogger(); + case ModelPackage.MBRICKLET_DUAL_BUTTON__UID: + return getUid(); + case ModelPackage.MBRICKLET_DUAL_BUTTON__POLL: + return isPoll(); + case ModelPackage.MBRICKLET_DUAL_BUTTON__ENABLED_A: + return getEnabledA(); + case ModelPackage.MBRICKLET_DUAL_BUTTON__TINKERFORGE_DEVICE: + return getTinkerforgeDevice(); + case ModelPackage.MBRICKLET_DUAL_BUTTON__IP_CONNECTION: + return getIpConnection(); + case ModelPackage.MBRICKLET_DUAL_BUTTON__CONNECTED_UID: + return getConnectedUid(); + case ModelPackage.MBRICKLET_DUAL_BUTTON__POSITION: + return getPosition(); + case ModelPackage.MBRICKLET_DUAL_BUTTON__DEVICE_IDENTIFIER: + return getDeviceIdentifier(); + case ModelPackage.MBRICKLET_DUAL_BUTTON__NAME: + return getName(); + case ModelPackage.MBRICKLET_DUAL_BUTTON__BRICKD: + return getBrickd(); + case ModelPackage.MBRICKLET_DUAL_BUTTON__MSUBDEVICES: + return getMsubdevices(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_DUAL_BUTTON__LOGGER: + setLogger((Logger)newValue); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__UID: + setUid((String)newValue); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__POLL: + setPoll((Boolean)newValue); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__ENABLED_A: + setEnabledA((AtomicBoolean)newValue); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__TINKERFORGE_DEVICE: + setTinkerforgeDevice((BrickletDualButton)newValue); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__IP_CONNECTION: + setIpConnection((IPConnection)newValue); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__CONNECTED_UID: + setConnectedUid((String)newValue); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__POSITION: + setPosition((Character)newValue); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__DEVICE_IDENTIFIER: + setDeviceIdentifier((Integer)newValue); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__NAME: + setName((String)newValue); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__BRICKD: + setBrickd((MBrickd)newValue); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__MSUBDEVICES: + getMsubdevices().clear(); + getMsubdevices().addAll((Collection)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_DUAL_BUTTON__LOGGER: + setLogger(LOGGER_EDEFAULT); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__UID: + setUid(UID_EDEFAULT); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__POLL: + setPoll(POLL_EDEFAULT); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__ENABLED_A: + setEnabledA(ENABLED_A_EDEFAULT); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__TINKERFORGE_DEVICE: + setTinkerforgeDevice((BrickletDualButton)null); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__IP_CONNECTION: + setIpConnection(IP_CONNECTION_EDEFAULT); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__CONNECTED_UID: + setConnectedUid(CONNECTED_UID_EDEFAULT); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__POSITION: + setPosition(POSITION_EDEFAULT); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__DEVICE_IDENTIFIER: + setDeviceIdentifier(DEVICE_IDENTIFIER_EDEFAULT); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__NAME: + setName(NAME_EDEFAULT); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__BRICKD: + setBrickd((MBrickd)null); + return; + case ModelPackage.MBRICKLET_DUAL_BUTTON__MSUBDEVICES: + getMsubdevices().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_DUAL_BUTTON__LOGGER: + return LOGGER_EDEFAULT == null ? logger != null : !LOGGER_EDEFAULT.equals(logger); + case ModelPackage.MBRICKLET_DUAL_BUTTON__UID: + return UID_EDEFAULT == null ? uid != null : !UID_EDEFAULT.equals(uid); + case ModelPackage.MBRICKLET_DUAL_BUTTON__POLL: + return poll != POLL_EDEFAULT; + case ModelPackage.MBRICKLET_DUAL_BUTTON__ENABLED_A: + return ENABLED_A_EDEFAULT == null ? enabledA != null : !ENABLED_A_EDEFAULT.equals(enabledA); + case ModelPackage.MBRICKLET_DUAL_BUTTON__TINKERFORGE_DEVICE: + return tinkerforgeDevice != null; + case ModelPackage.MBRICKLET_DUAL_BUTTON__IP_CONNECTION: + return IP_CONNECTION_EDEFAULT == null ? ipConnection != null : !IP_CONNECTION_EDEFAULT.equals(ipConnection); + case ModelPackage.MBRICKLET_DUAL_BUTTON__CONNECTED_UID: + return CONNECTED_UID_EDEFAULT == null ? connectedUid != null : !CONNECTED_UID_EDEFAULT.equals(connectedUid); + case ModelPackage.MBRICKLET_DUAL_BUTTON__POSITION: + return position != POSITION_EDEFAULT; + case ModelPackage.MBRICKLET_DUAL_BUTTON__DEVICE_IDENTIFIER: + return deviceIdentifier != DEVICE_IDENTIFIER_EDEFAULT; + case ModelPackage.MBRICKLET_DUAL_BUTTON__NAME: + return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name); + case ModelPackage.MBRICKLET_DUAL_BUTTON__BRICKD: + return getBrickd() != null; + case ModelPackage.MBRICKLET_DUAL_BUTTON__MSUBDEVICES: + return msubdevices != null && !msubdevices.isEmpty(); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) + { + if (baseClass == MSubDeviceHolder.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICKLET_DUAL_BUTTON__MSUBDEVICES: return ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES; + default: return -1; + } + } + return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) + { + if (baseClass == MSubDeviceHolder.class) + { + switch (baseFeatureID) + { + case ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES: return ModelPackage.MBRICKLET_DUAL_BUTTON__MSUBDEVICES; + default: return -1; + } + } + return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedOperationID(int baseOperationID, Class baseClass) + { + if (baseClass == MSubDeviceHolder.class) + { + switch (baseOperationID) + { + case ModelPackage.MSUB_DEVICE_HOLDER___INIT_SUB_DEVICES: return ModelPackage.MBRICKLET_DUAL_BUTTON___INIT_SUB_DEVICES; + default: return -1; + } + } + return super.eDerivedOperationID(baseOperationID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public Object eInvoke(int operationID, EList arguments) throws InvocationTargetException + { + switch (operationID) + { + case ModelPackage.MBRICKLET_DUAL_BUTTON___INIT_SUB_DEVICES: + initSubDevices(); + return null; + case ModelPackage.MBRICKLET_DUAL_BUTTON___INIT: + init(); + return null; + case ModelPackage.MBRICKLET_DUAL_BUTTON___ENABLE: + enable(); + return null; + case ModelPackage.MBRICKLET_DUAL_BUTTON___DISABLE: + disable(); + return null; + } + return super.eInvoke(operationID, arguments); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (logger: "); + result.append(logger); + result.append(", uid: "); + result.append(uid); + result.append(", poll: "); + result.append(poll); + result.append(", enabledA: "); + result.append(enabledA); + result.append(", tinkerforgeDevice: "); + result.append(tinkerforgeDevice); + result.append(", ipConnection: "); + result.append(ipConnection); + result.append(", connectedUid: "); + result.append(connectedUid); + result.append(", position: "); + result.append(position); + result.append(", deviceIdentifier: "); + result.append(deviceIdentifier); + result.append(", name: "); + result.append(name); + result.append(')'); + return result.toString(); + } + +} //MBrickletDualButtonImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletJoystickImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletJoystickImpl.java new file mode 100644 index 00000000000..7c3804736a1 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletJoystickImpl.java @@ -0,0 +1,1208 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.util.InternalEList; +import org.openhab.binding.tinkerforge.internal.LoggerConstants; +import org.openhab.binding.tinkerforge.internal.model.CallbackListener; +import org.openhab.binding.tinkerforge.internal.model.JoystickButton; +import org.openhab.binding.tinkerforge.internal.model.JoystickDevice; +import org.openhab.binding.tinkerforge.internal.model.JoystickXPosition; +import org.openhab.binding.tinkerforge.internal.model.JoystickYPosition; +import org.openhab.binding.tinkerforge.internal.model.MBrickd; +import org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick; +import org.openhab.binding.tinkerforge.internal.model.MSubDevice; +import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; +import org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer; +import org.openhab.binding.tinkerforge.internal.model.ModelFactory; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerforge.BrickletJoystick; +import com.tinkerforge.IPConnection; + +/** + * + * An implementation of the model object 'MBricklet Joystick'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getLogger Logger}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getUid Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#isPoll Poll}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getEnabledA Enabled A}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getTinkerforgeDevice Tinkerforge Device}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getIpConnection Ip Connection}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getConnectedUid Connected Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getPosition Position}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getDeviceIdentifier Device Identifier}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getName Name}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getBrickd Brickd}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getMsubdevices Msubdevices}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getCallbackPeriod Callback Period}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getTfConfig Tf Config}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletJoystickImpl#getDeviceType Device Type}
      • + *
      + *

      + * + * @generated + */ +public class MBrickletJoystickImpl extends MinimalEObjectImpl.Container implements MBrickletJoystick +{ + /** + * The default value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected static final Logger LOGGER_EDEFAULT = null; + + /** + * The cached value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected Logger logger = LOGGER_EDEFAULT; + + /** + * The default value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected static final String UID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected String uid = UID_EDEFAULT; + + /** + * The default value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected static final boolean POLL_EDEFAULT = true; + + /** + * The cached value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected boolean poll = POLL_EDEFAULT; + + /** + * The default value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected static final AtomicBoolean ENABLED_A_EDEFAULT = null; + + /** + * The cached value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected AtomicBoolean enabledA = ENABLED_A_EDEFAULT; + + /** + * The cached value of the '{@link #getTinkerforgeDevice() Tinkerforge Device}' attribute. + * + * + * @see #getTinkerforgeDevice() + * @generated + * @ordered + */ + protected BrickletJoystick tinkerforgeDevice; + + /** + * The default value of the '{@link #getIpConnection() Ip Connection}' attribute. + * + * + * @see #getIpConnection() + * @generated + * @ordered + */ + protected static final IPConnection IP_CONNECTION_EDEFAULT = null; + + /** + * The cached value of the '{@link #getIpConnection() Ip Connection}' attribute. + * + * + * @see #getIpConnection() + * @generated + * @ordered + */ + protected IPConnection ipConnection = IP_CONNECTION_EDEFAULT; + + /** + * The default value of the '{@link #getConnectedUid() Connected Uid}' attribute. + * + * + * @see #getConnectedUid() + * @generated + * @ordered + */ + protected static final String CONNECTED_UID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getConnectedUid() Connected Uid}' attribute. + * + * + * @see #getConnectedUid() + * @generated + * @ordered + */ + protected String connectedUid = CONNECTED_UID_EDEFAULT; + + /** + * The default value of the '{@link #getPosition() Position}' attribute. + * + * + * @see #getPosition() + * @generated + * @ordered + */ + protected static final char POSITION_EDEFAULT = '\u0000'; + + /** + * The cached value of the '{@link #getPosition() Position}' attribute. + * + * + * @see #getPosition() + * @generated + * @ordered + */ + protected char position = POSITION_EDEFAULT; + + /** + * The default value of the '{@link #getDeviceIdentifier() Device Identifier}' attribute. + * + * + * @see #getDeviceIdentifier() + * @generated + * @ordered + */ + protected static final int DEVICE_IDENTIFIER_EDEFAULT = 0; + + /** + * The cached value of the '{@link #getDeviceIdentifier() Device Identifier}' attribute. + * + * + * @see #getDeviceIdentifier() + * @generated + * @ordered + */ + protected int deviceIdentifier = DEVICE_IDENTIFIER_EDEFAULT; + + /** + * The default value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected static final String NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected String name = NAME_EDEFAULT; + + /** + * The cached value of the '{@link #getMsubdevices() Msubdevices}' containment reference list. + * + * + * @see #getMsubdevices() + * @generated + * @ordered + */ + protected EList msubdevices; + + /** + * The default value of the '{@link #getCallbackPeriod() Callback Period}' attribute. + * + * + * @see #getCallbackPeriod() + * @generated + * @ordered + */ + protected static final long CALLBACK_PERIOD_EDEFAULT = 1000L; + + /** + * The cached value of the '{@link #getCallbackPeriod() Callback Period}' attribute. + * + * + * @see #getCallbackPeriod() + * @generated + * @ordered + */ + protected long callbackPeriod = CALLBACK_PERIOD_EDEFAULT; + + /** + * The cached value of the '{@link #getTfConfig() Tf Config}' containment reference. + * + * + * @see #getTfConfig() + * @generated + * @ordered + */ + protected TFBaseConfiguration tfConfig; + + /** + * The default value of the '{@link #getDeviceType() Device Type}' attribute. + * + * + * @see #getDeviceType() + * @generated + * @ordered + */ + protected static final String DEVICE_TYPE_EDEFAULT = "bricklet_joystick"; + + /** + * The cached value of the '{@link #getDeviceType() Device Type}' attribute. + * + * + * @see #getDeviceType() + * @generated + * @ordered + */ + protected String deviceType = DEVICE_TYPE_EDEFAULT; + + /** + * + * + * @generated + */ + protected MBrickletJoystickImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.MBRICKLET_JOYSTICK; + } + + /** + * + * + * @generated + */ + public Logger getLogger() + { + return logger; + } + + /** + * + * + * @generated + */ + public void setLogger(Logger newLogger) + { + Logger oldLogger = logger; + logger = newLogger; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__LOGGER, oldLogger, logger)); + } + + /** + * + * + * @generated + */ + public String getUid() + { + return uid; + } + + /** + * + * + * @generated + */ + public void setUid(String newUid) + { + String oldUid = uid; + uid = newUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__UID, oldUid, uid)); + } + + /** + * + * + * @generated + */ + public boolean isPoll() + { + return poll; + } + + /** + * + * + * @generated + */ + public void setPoll(boolean newPoll) + { + boolean oldPoll = poll; + poll = newPoll; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__POLL, oldPoll, poll)); + } + + /** + * + * + * @generated + */ + public AtomicBoolean getEnabledA() + { + return enabledA; + } + + /** + * + * + * @generated + */ + public void setEnabledA(AtomicBoolean newEnabledA) + { + AtomicBoolean oldEnabledA = enabledA; + enabledA = newEnabledA; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__ENABLED_A, oldEnabledA, enabledA)); + } + + /** + * + * + * @generated + */ + public BrickletJoystick getTinkerforgeDevice() + { + return tinkerforgeDevice; + } + + /** + * + * + * @generated + */ + public void setTinkerforgeDevice(BrickletJoystick newTinkerforgeDevice) + { + BrickletJoystick oldTinkerforgeDevice = tinkerforgeDevice; + tinkerforgeDevice = newTinkerforgeDevice; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__TINKERFORGE_DEVICE, oldTinkerforgeDevice, tinkerforgeDevice)); + } + + /** + * + * + * @generated + */ + public IPConnection getIpConnection() + { + return ipConnection; + } + + /** + * + * + * @generated + */ + public void setIpConnection(IPConnection newIpConnection) + { + IPConnection oldIpConnection = ipConnection; + ipConnection = newIpConnection; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__IP_CONNECTION, oldIpConnection, ipConnection)); + } + + /** + * + * + * @generated + */ + public String getConnectedUid() + { + return connectedUid; + } + + /** + * + * + * @generated + */ + public void setConnectedUid(String newConnectedUid) + { + String oldConnectedUid = connectedUid; + connectedUid = newConnectedUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__CONNECTED_UID, oldConnectedUid, connectedUid)); + } + + /** + * + * + * @generated + */ + public char getPosition() + { + return position; + } + + /** + * + * + * @generated + */ + public void setPosition(char newPosition) + { + char oldPosition = position; + position = newPosition; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__POSITION, oldPosition, position)); + } + + /** + * + * + * @generated + */ + public int getDeviceIdentifier() + { + return deviceIdentifier; + } + + /** + * + * + * @generated + */ + public void setDeviceIdentifier(int newDeviceIdentifier) + { + int oldDeviceIdentifier = deviceIdentifier; + deviceIdentifier = newDeviceIdentifier; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__DEVICE_IDENTIFIER, oldDeviceIdentifier, deviceIdentifier)); + } + + /** + * + * + * @generated + */ + public String getName() + { + return name; + } + + /** + * + * + * @generated + */ + public void setName(String newName) + { + String oldName = name; + name = newName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__NAME, oldName, name)); + } + + /** + * + * + * @generated + */ + public MBrickd getBrickd() + { + if (eContainerFeatureID() != ModelPackage.MBRICKLET_JOYSTICK__BRICKD) return null; + return (MBrickd)eContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetBrickd(MBrickd newBrickd, NotificationChain msgs) + { + msgs = eBasicSetContainer((InternalEObject)newBrickd, ModelPackage.MBRICKLET_JOYSTICK__BRICKD, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setBrickd(MBrickd newBrickd) + { + if (newBrickd != eInternalContainer() || (eContainerFeatureID() != ModelPackage.MBRICKLET_JOYSTICK__BRICKD && newBrickd != null)) + { + if (EcoreUtil.isAncestor(this, newBrickd)) + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + NotificationChain msgs = null; + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + if (newBrickd != null) + msgs = ((InternalEObject)newBrickd).eInverseAdd(this, ModelPackage.MBRICKD__MDEVICES, MBrickd.class, msgs); + msgs = basicSetBrickd(newBrickd, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__BRICKD, newBrickd, newBrickd)); + } + + /** + * + * + * @generated + */ + public EList getMsubdevices() + { + if (msubdevices == null) + { + msubdevices = new EObjectContainmentWithInverseEList(MSubDevice.class, this, ModelPackage.MBRICKLET_JOYSTICK__MSUBDEVICES, ModelPackage.MSUB_DEVICE__MBRICK); + } + return msubdevices; + } + + /** + * + * + * @generated + */ + public long getCallbackPeriod() + { + return callbackPeriod; + } + + /** + * + * + * @generated + */ + public void setCallbackPeriod(long newCallbackPeriod) + { + long oldCallbackPeriod = callbackPeriod; + callbackPeriod = newCallbackPeriod; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__CALLBACK_PERIOD, oldCallbackPeriod, callbackPeriod)); + } + + /** + * + * + * @generated + */ + public TFBaseConfiguration getTfConfig() + { + return tfConfig; + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetTfConfig(TFBaseConfiguration newTfConfig, NotificationChain msgs) + { + TFBaseConfiguration oldTfConfig = tfConfig; + tfConfig = newTfConfig; + if (eNotificationRequired()) + { + ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__TF_CONFIG, oldTfConfig, newTfConfig); + if (msgs == null) msgs = notification; else msgs.add(notification); + } + return msgs; + } + + /** + * + * + * @generated + */ + public void setTfConfig(TFBaseConfiguration newTfConfig) + { + if (newTfConfig != tfConfig) + { + NotificationChain msgs = null; + if (tfConfig != null) + msgs = ((InternalEObject)tfConfig).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ModelPackage.MBRICKLET_JOYSTICK__TF_CONFIG, null, msgs); + if (newTfConfig != null) + msgs = ((InternalEObject)newTfConfig).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ModelPackage.MBRICKLET_JOYSTICK__TF_CONFIG, null, msgs); + msgs = basicSetTfConfig(newTfConfig, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_JOYSTICK__TF_CONFIG, newTfConfig, newTfConfig)); + } + + /** + * + * + * @generated + */ + public String getDeviceType() + { + return deviceType; + } + + /** + * + * + * @generated NOT + */ + public void initSubDevices() + { + JoystickXPosition xPosition = ModelFactory.eINSTANCE.createJoystickXPosition(); + xPosition.setUid(getUid()); + String subIdX = "joystick_xposition"; + xPosition.setSubId(subIdX); + logger.debug("{} addSubDevice {}", LoggerConstants.TFINIT, subIdX); + xPosition.init(); + xPosition.setMbrick(this); + + JoystickYPosition yPosition = ModelFactory.eINSTANCE.createJoystickYPosition(); + yPosition.setUid(getUid()); + String subIdY = "joystick_yposition"; + yPosition.setSubId(subIdY); + logger.debug("{} addSubDevice {}", LoggerConstants.TFINIT, subIdY); + yPosition.init(); + yPosition.setMbrick(this); + + JoystickButton button = ModelFactory.eINSTANCE.createJoystickButton(); + button.setUid(getUid()); + String subIdButton = "joystick_button"; + button.setSubId(subIdButton); + logger.debug("{} addSubDevice {}", LoggerConstants.TFINIT, subIdButton); + button.init(); + button.setMbrick(this); + } + + /** + * + * + * @generated NOT + */ + public void init() + { + setEnabledA(new AtomicBoolean()); + logger = LoggerFactory.getLogger(MBrickletJoystickImpl.class); + } + + /** + * + * + * @generated NOT + */ + public void enable() + { + setCallbackPeriod(10); + if (tfConfig != null) { + logger.trace("got configuration"); + if (tfConfig.eIsSet(tfConfig.eClass().getEStructuralFeature("callbackPeriod"))) { + logger.trace("found callbackPeriod"); + setCallbackPeriod(tfConfig.getCallbackPeriod()); + } + } + logger.trace("callbackPeriod is {}", getCallbackPeriod()); + tinkerforgeDevice = new BrickletJoystick(getUid(), getIpConnection()); + } + + /** + * + * + * @generated NOT + */ + public void disable() + { + tinkerforgeDevice = null; + } + + /** + * + * + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_JOYSTICK__BRICKD: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetBrickd((MBrickd)otherEnd, msgs); + case ModelPackage.MBRICKLET_JOYSTICK__MSUBDEVICES: + return ((InternalEList)(InternalEList)getMsubdevices()).basicAdd(otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_JOYSTICK__BRICKD: + return basicSetBrickd(null, msgs); + case ModelPackage.MBRICKLET_JOYSTICK__MSUBDEVICES: + return ((InternalEList)getMsubdevices()).basicRemove(otherEnd, msgs); + case ModelPackage.MBRICKLET_JOYSTICK__TF_CONFIG: + return basicSetTfConfig(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) + { + switch (eContainerFeatureID()) + { + case ModelPackage.MBRICKLET_JOYSTICK__BRICKD: + return eInternalContainer().eInverseRemove(this, ModelPackage.MBRICKD__MDEVICES, MBrickd.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_JOYSTICK__LOGGER: + return getLogger(); + case ModelPackage.MBRICKLET_JOYSTICK__UID: + return getUid(); + case ModelPackage.MBRICKLET_JOYSTICK__POLL: + return isPoll(); + case ModelPackage.MBRICKLET_JOYSTICK__ENABLED_A: + return getEnabledA(); + case ModelPackage.MBRICKLET_JOYSTICK__TINKERFORGE_DEVICE: + return getTinkerforgeDevice(); + case ModelPackage.MBRICKLET_JOYSTICK__IP_CONNECTION: + return getIpConnection(); + case ModelPackage.MBRICKLET_JOYSTICK__CONNECTED_UID: + return getConnectedUid(); + case ModelPackage.MBRICKLET_JOYSTICK__POSITION: + return getPosition(); + case ModelPackage.MBRICKLET_JOYSTICK__DEVICE_IDENTIFIER: + return getDeviceIdentifier(); + case ModelPackage.MBRICKLET_JOYSTICK__NAME: + return getName(); + case ModelPackage.MBRICKLET_JOYSTICK__BRICKD: + return getBrickd(); + case ModelPackage.MBRICKLET_JOYSTICK__MSUBDEVICES: + return getMsubdevices(); + case ModelPackage.MBRICKLET_JOYSTICK__CALLBACK_PERIOD: + return getCallbackPeriod(); + case ModelPackage.MBRICKLET_JOYSTICK__TF_CONFIG: + return getTfConfig(); + case ModelPackage.MBRICKLET_JOYSTICK__DEVICE_TYPE: + return getDeviceType(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_JOYSTICK__LOGGER: + setLogger((Logger)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__UID: + setUid((String)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__POLL: + setPoll((Boolean)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__ENABLED_A: + setEnabledA((AtomicBoolean)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__TINKERFORGE_DEVICE: + setTinkerforgeDevice((BrickletJoystick)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__IP_CONNECTION: + setIpConnection((IPConnection)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__CONNECTED_UID: + setConnectedUid((String)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__POSITION: + setPosition((Character)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__DEVICE_IDENTIFIER: + setDeviceIdentifier((Integer)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__NAME: + setName((String)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__BRICKD: + setBrickd((MBrickd)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__MSUBDEVICES: + getMsubdevices().clear(); + getMsubdevices().addAll((Collection)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__CALLBACK_PERIOD: + setCallbackPeriod((Long)newValue); + return; + case ModelPackage.MBRICKLET_JOYSTICK__TF_CONFIG: + setTfConfig((TFBaseConfiguration)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_JOYSTICK__LOGGER: + setLogger(LOGGER_EDEFAULT); + return; + case ModelPackage.MBRICKLET_JOYSTICK__UID: + setUid(UID_EDEFAULT); + return; + case ModelPackage.MBRICKLET_JOYSTICK__POLL: + setPoll(POLL_EDEFAULT); + return; + case ModelPackage.MBRICKLET_JOYSTICK__ENABLED_A: + setEnabledA(ENABLED_A_EDEFAULT); + return; + case ModelPackage.MBRICKLET_JOYSTICK__TINKERFORGE_DEVICE: + setTinkerforgeDevice((BrickletJoystick)null); + return; + case ModelPackage.MBRICKLET_JOYSTICK__IP_CONNECTION: + setIpConnection(IP_CONNECTION_EDEFAULT); + return; + case ModelPackage.MBRICKLET_JOYSTICK__CONNECTED_UID: + setConnectedUid(CONNECTED_UID_EDEFAULT); + return; + case ModelPackage.MBRICKLET_JOYSTICK__POSITION: + setPosition(POSITION_EDEFAULT); + return; + case ModelPackage.MBRICKLET_JOYSTICK__DEVICE_IDENTIFIER: + setDeviceIdentifier(DEVICE_IDENTIFIER_EDEFAULT); + return; + case ModelPackage.MBRICKLET_JOYSTICK__NAME: + setName(NAME_EDEFAULT); + return; + case ModelPackage.MBRICKLET_JOYSTICK__BRICKD: + setBrickd((MBrickd)null); + return; + case ModelPackage.MBRICKLET_JOYSTICK__MSUBDEVICES: + getMsubdevices().clear(); + return; + case ModelPackage.MBRICKLET_JOYSTICK__CALLBACK_PERIOD: + setCallbackPeriod(CALLBACK_PERIOD_EDEFAULT); + return; + case ModelPackage.MBRICKLET_JOYSTICK__TF_CONFIG: + setTfConfig((TFBaseConfiguration)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_JOYSTICK__LOGGER: + return LOGGER_EDEFAULT == null ? logger != null : !LOGGER_EDEFAULT.equals(logger); + case ModelPackage.MBRICKLET_JOYSTICK__UID: + return UID_EDEFAULT == null ? uid != null : !UID_EDEFAULT.equals(uid); + case ModelPackage.MBRICKLET_JOYSTICK__POLL: + return poll != POLL_EDEFAULT; + case ModelPackage.MBRICKLET_JOYSTICK__ENABLED_A: + return ENABLED_A_EDEFAULT == null ? enabledA != null : !ENABLED_A_EDEFAULT.equals(enabledA); + case ModelPackage.MBRICKLET_JOYSTICK__TINKERFORGE_DEVICE: + return tinkerforgeDevice != null; + case ModelPackage.MBRICKLET_JOYSTICK__IP_CONNECTION: + return IP_CONNECTION_EDEFAULT == null ? ipConnection != null : !IP_CONNECTION_EDEFAULT.equals(ipConnection); + case ModelPackage.MBRICKLET_JOYSTICK__CONNECTED_UID: + return CONNECTED_UID_EDEFAULT == null ? connectedUid != null : !CONNECTED_UID_EDEFAULT.equals(connectedUid); + case ModelPackage.MBRICKLET_JOYSTICK__POSITION: + return position != POSITION_EDEFAULT; + case ModelPackage.MBRICKLET_JOYSTICK__DEVICE_IDENTIFIER: + return deviceIdentifier != DEVICE_IDENTIFIER_EDEFAULT; + case ModelPackage.MBRICKLET_JOYSTICK__NAME: + return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name); + case ModelPackage.MBRICKLET_JOYSTICK__BRICKD: + return getBrickd() != null; + case ModelPackage.MBRICKLET_JOYSTICK__MSUBDEVICES: + return msubdevices != null && !msubdevices.isEmpty(); + case ModelPackage.MBRICKLET_JOYSTICK__CALLBACK_PERIOD: + return callbackPeriod != CALLBACK_PERIOD_EDEFAULT; + case ModelPackage.MBRICKLET_JOYSTICK__TF_CONFIG: + return tfConfig != null; + case ModelPackage.MBRICKLET_JOYSTICK__DEVICE_TYPE: + return DEVICE_TYPE_EDEFAULT == null ? deviceType != null : !DEVICE_TYPE_EDEFAULT.equals(deviceType); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) + { + if (baseClass == MSubDeviceHolder.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICKLET_JOYSTICK__MSUBDEVICES: return ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES; + default: return -1; + } + } + if (baseClass == CallbackListener.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICKLET_JOYSTICK__CALLBACK_PERIOD: return ModelPackage.CALLBACK_LISTENER__CALLBACK_PERIOD; + default: return -1; + } + } + if (baseClass == MTFConfigConsumer.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICKLET_JOYSTICK__TF_CONFIG: return ModelPackage.MTF_CONFIG_CONSUMER__TF_CONFIG; + default: return -1; + } + } + return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) + { + if (baseClass == MSubDeviceHolder.class) + { + switch (baseFeatureID) + { + case ModelPackage.MSUB_DEVICE_HOLDER__MSUBDEVICES: return ModelPackage.MBRICKLET_JOYSTICK__MSUBDEVICES; + default: return -1; + } + } + if (baseClass == CallbackListener.class) + { + switch (baseFeatureID) + { + case ModelPackage.CALLBACK_LISTENER__CALLBACK_PERIOD: return ModelPackage.MBRICKLET_JOYSTICK__CALLBACK_PERIOD; + default: return -1; + } + } + if (baseClass == MTFConfigConsumer.class) + { + switch (baseFeatureID) + { + case ModelPackage.MTF_CONFIG_CONSUMER__TF_CONFIG: return ModelPackage.MBRICKLET_JOYSTICK__TF_CONFIG; + default: return -1; + } + } + return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedOperationID(int baseOperationID, Class baseClass) + { + if (baseClass == MSubDeviceHolder.class) + { + switch (baseOperationID) + { + case ModelPackage.MSUB_DEVICE_HOLDER___INIT_SUB_DEVICES: return ModelPackage.MBRICKLET_JOYSTICK___INIT_SUB_DEVICES; + default: return -1; + } + } + if (baseClass == CallbackListener.class) + { + switch (baseOperationID) + { + default: return -1; + } + } + if (baseClass == MTFConfigConsumer.class) + { + switch (baseOperationID) + { + default: return -1; + } + } + return super.eDerivedOperationID(baseOperationID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public Object eInvoke(int operationID, EList arguments) throws InvocationTargetException + { + switch (operationID) + { + case ModelPackage.MBRICKLET_JOYSTICK___INIT_SUB_DEVICES: + initSubDevices(); + return null; + case ModelPackage.MBRICKLET_JOYSTICK___INIT: + init(); + return null; + case ModelPackage.MBRICKLET_JOYSTICK___ENABLE: + enable(); + return null; + case ModelPackage.MBRICKLET_JOYSTICK___DISABLE: + disable(); + return null; + } + return super.eInvoke(operationID, arguments); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (logger: "); + result.append(logger); + result.append(", uid: "); + result.append(uid); + result.append(", poll: "); + result.append(poll); + result.append(", enabledA: "); + result.append(enabledA); + result.append(", tinkerforgeDevice: "); + result.append(tinkerforgeDevice); + result.append(", ipConnection: "); + result.append(ipConnection); + result.append(", connectedUid: "); + result.append(connectedUid); + result.append(", position: "); + result.append(position); + result.append(", deviceIdentifier: "); + result.append(deviceIdentifier); + result.append(", name: "); + result.append(name); + result.append(", callbackPeriod: "); + result.append(callbackPeriod); + result.append(", deviceType: "); + result.append(deviceType); + result.append(')'); + return result.toString(); + } + +} //MBrickletJoystickImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletLCD20x4Impl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletLCD20x4Impl.java index a73a3d50c97..e7bf15ae4d9 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletLCD20x4Impl.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletLCD20x4Impl.java @@ -845,6 +845,18 @@ public void init() { /** * * + * @generated + */ + public boolean clear() + { + // TODO: implement this method + // Ensure that you remove @generated or mark it @generated NOT + throw new UnsupportedOperationException(); + } + + /** + * + * * @generated NOT */ public void initSubDevices() @@ -1253,6 +1265,8 @@ public Object eInvoke(int operationID, EList arguments) case ModelPackage.MBRICKLET_LCD2_0X4___INIT: init(); return null; + case ModelPackage.MBRICKLET_LCD2_0X4___CLEAR: + return clear(); case ModelPackage.MBRICKLET_LCD2_0X4___INIT_SUB_DEVICES: initSubDevices(); return null; diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletLinearPotiImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletLinearPotiImpl.java new file mode 100644 index 00000000000..e4f891a53d9 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MBrickletLinearPotiImpl.java @@ -0,0 +1,1227 @@ +/** + */ +package org.openhab.binding.tinkerforge.internal.model.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.openhab.binding.tinkerforge.internal.LoggerConstants; +import org.openhab.binding.tinkerforge.internal.TinkerforgeErrorHandler; +import org.openhab.binding.tinkerforge.internal.model.CallbackListener; +import org.openhab.binding.tinkerforge.internal.model.MBrickd; +import org.openhab.binding.tinkerforge.internal.model.MBrickletLinearPoti; +import org.openhab.binding.tinkerforge.internal.model.MSensor; +import org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer; +import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration; +import org.openhab.binding.tinkerforge.internal.tools.Tools; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tinkerforge.BrickletLinearPoti; +import com.tinkerforge.IPConnection; +import com.tinkerforge.NotConnectedException; +import com.tinkerforge.TimeoutException; + +/** + * + * An implementation of the model object 'MBricklet Linear Poti'. + * + *

      + * The following features are implemented: + *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getLogger Logger}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getUid Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#isPoll Poll}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getEnabledA Enabled A}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getTinkerforgeDevice Tinkerforge Device}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getIpConnection Ip Connection}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getConnectedUid Connected Uid}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getPosition Position}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getDeviceIdentifier Device Identifier}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getName Name}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getBrickd Brickd}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getCallbackPeriod Callback Period}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getTfConfig Tf Config}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getSensorValue Sensor Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MBrickletLinearPotiImpl#getDeviceType Device Type}
      • + *
      + *

      + * + * @generated + */ +public class MBrickletLinearPotiImpl extends MinimalEObjectImpl.Container implements MBrickletLinearPoti +{ + /** + * The default value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected static final Logger LOGGER_EDEFAULT = null; + + /** + * The cached value of the '{@link #getLogger() Logger}' attribute. + * + * + * @see #getLogger() + * @generated + * @ordered + */ + protected Logger logger = LOGGER_EDEFAULT; + + /** + * The default value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected static final String UID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getUid() Uid}' attribute. + * + * + * @see #getUid() + * @generated + * @ordered + */ + protected String uid = UID_EDEFAULT; + + /** + * The default value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected static final boolean POLL_EDEFAULT = true; + + /** + * The cached value of the '{@link #isPoll() Poll}' attribute. + * + * + * @see #isPoll() + * @generated + * @ordered + */ + protected boolean poll = POLL_EDEFAULT; + + /** + * The default value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected static final AtomicBoolean ENABLED_A_EDEFAULT = null; + + /** + * The cached value of the '{@link #getEnabledA() Enabled A}' attribute. + * + * + * @see #getEnabledA() + * @generated + * @ordered + */ + protected AtomicBoolean enabledA = ENABLED_A_EDEFAULT; + + /** + * The cached value of the '{@link #getTinkerforgeDevice() Tinkerforge Device}' attribute. + * + * + * @see #getTinkerforgeDevice() + * @generated + * @ordered + */ + protected BrickletLinearPoti tinkerforgeDevice; + + /** + * The default value of the '{@link #getIpConnection() Ip Connection}' attribute. + * + * + * @see #getIpConnection() + * @generated + * @ordered + */ + protected static final IPConnection IP_CONNECTION_EDEFAULT = null; + + /** + * The cached value of the '{@link #getIpConnection() Ip Connection}' attribute. + * + * + * @see #getIpConnection() + * @generated + * @ordered + */ + protected IPConnection ipConnection = IP_CONNECTION_EDEFAULT; + + /** + * The default value of the '{@link #getConnectedUid() Connected Uid}' attribute. + * + * + * @see #getConnectedUid() + * @generated + * @ordered + */ + protected static final String CONNECTED_UID_EDEFAULT = null; + + /** + * The cached value of the '{@link #getConnectedUid() Connected Uid}' attribute. + * + * + * @see #getConnectedUid() + * @generated + * @ordered + */ + protected String connectedUid = CONNECTED_UID_EDEFAULT; + + /** + * The default value of the '{@link #getPosition() Position}' attribute. + * + * + * @see #getPosition() + * @generated + * @ordered + */ + protected static final char POSITION_EDEFAULT = '\u0000'; + + /** + * The cached value of the '{@link #getPosition() Position}' attribute. + * + * + * @see #getPosition() + * @generated + * @ordered + */ + protected char position = POSITION_EDEFAULT; + + /** + * The default value of the '{@link #getDeviceIdentifier() Device Identifier}' attribute. + * + * + * @see #getDeviceIdentifier() + * @generated + * @ordered + */ + protected static final int DEVICE_IDENTIFIER_EDEFAULT = 0; + + /** + * The cached value of the '{@link #getDeviceIdentifier() Device Identifier}' attribute. + * + * + * @see #getDeviceIdentifier() + * @generated + * @ordered + */ + protected int deviceIdentifier = DEVICE_IDENTIFIER_EDEFAULT; + + /** + * The default value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected static final String NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected String name = NAME_EDEFAULT; + + /** + * The default value of the '{@link #getCallbackPeriod() Callback Period}' attribute. + * + * + * @see #getCallbackPeriod() + * @generated + * @ordered + */ + protected static final long CALLBACK_PERIOD_EDEFAULT = 1000L; + + /** + * The cached value of the '{@link #getCallbackPeriod() Callback Period}' attribute. + * + * + * @see #getCallbackPeriod() + * @generated + * @ordered + */ + protected long callbackPeriod = CALLBACK_PERIOD_EDEFAULT; + + /** + * The cached value of the '{@link #getTfConfig() Tf Config}' containment reference. + * + * + * @see #getTfConfig() + * @generated + * @ordered + */ + protected TFBaseConfiguration tfConfig; + + /** + * The cached value of the '{@link #getSensorValue() Sensor Value}' attribute. + * + * + * @see #getSensorValue() + * @generated + * @ordered + */ + protected DecimalValue sensorValue; + + /** + * The default value of the '{@link #getDeviceType() Device Type}' attribute. + * + * + * @see #getDeviceType() + * @generated + * @ordered + */ + protected static final String DEVICE_TYPE_EDEFAULT = "bricklet_linear_poti"; + + /** + * The cached value of the '{@link #getDeviceType() Device Type}' attribute. + * + * + * @see #getDeviceType() + * @generated + * @ordered + */ + protected String deviceType = DEVICE_TYPE_EDEFAULT; + + private PositionListener listener; + + /** + * + * + * @generated + */ + protected MBrickletLinearPotiImpl() + { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.MBRICKLET_LINEAR_POTI; + } + + /** + * + * + * @generated + */ + public Logger getLogger() + { + return logger; + } + + /** + * + * + * @generated + */ + public void setLogger(Logger newLogger) + { + Logger oldLogger = logger; + logger = newLogger; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__LOGGER, oldLogger, logger)); + } + + /** + * + * + * @generated + */ + public String getUid() + { + return uid; + } + + /** + * + * + * @generated + */ + public void setUid(String newUid) + { + String oldUid = uid; + uid = newUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__UID, oldUid, uid)); + } + + /** + * + * + * @generated + */ + public boolean isPoll() + { + return poll; + } + + /** + * + * + * @generated + */ + public void setPoll(boolean newPoll) + { + boolean oldPoll = poll; + poll = newPoll; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__POLL, oldPoll, poll)); + } + + /** + * + * + * @generated + */ + public AtomicBoolean getEnabledA() + { + return enabledA; + } + + /** + * + * + * @generated + */ + public void setEnabledA(AtomicBoolean newEnabledA) + { + AtomicBoolean oldEnabledA = enabledA; + enabledA = newEnabledA; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__ENABLED_A, oldEnabledA, enabledA)); + } + + /** + * + * + * @generated + */ + public BrickletLinearPoti getTinkerforgeDevice() + { + return tinkerforgeDevice; + } + + /** + * + * + * @generated + */ + public void setTinkerforgeDevice(BrickletLinearPoti newTinkerforgeDevice) + { + BrickletLinearPoti oldTinkerforgeDevice = tinkerforgeDevice; + tinkerforgeDevice = newTinkerforgeDevice; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__TINKERFORGE_DEVICE, oldTinkerforgeDevice, tinkerforgeDevice)); + } + + /** + * + * + * @generated + */ + public IPConnection getIpConnection() + { + return ipConnection; + } + + /** + * + * + * @generated + */ + public void setIpConnection(IPConnection newIpConnection) + { + IPConnection oldIpConnection = ipConnection; + ipConnection = newIpConnection; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__IP_CONNECTION, oldIpConnection, ipConnection)); + } + + /** + * + * + * @generated + */ + public String getConnectedUid() + { + return connectedUid; + } + + /** + * + * + * @generated + */ + public void setConnectedUid(String newConnectedUid) + { + String oldConnectedUid = connectedUid; + connectedUid = newConnectedUid; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__CONNECTED_UID, oldConnectedUid, connectedUid)); + } + + /** + * + * + * @generated + */ + public char getPosition() + { + return position; + } + + /** + * + * + * @generated + */ + public void setPosition(char newPosition) + { + char oldPosition = position; + position = newPosition; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__POSITION, oldPosition, position)); + } + + /** + * + * + * @generated + */ + public int getDeviceIdentifier() + { + return deviceIdentifier; + } + + /** + * + * + * @generated + */ + public void setDeviceIdentifier(int newDeviceIdentifier) + { + int oldDeviceIdentifier = deviceIdentifier; + deviceIdentifier = newDeviceIdentifier; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__DEVICE_IDENTIFIER, oldDeviceIdentifier, deviceIdentifier)); + } + + /** + * + * + * @generated + */ + public String getName() + { + return name; + } + + /** + * + * + * @generated + */ + public void setName(String newName) + { + String oldName = name; + name = newName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__NAME, oldName, name)); + } + + /** + * + * + * @generated + */ + public MBrickd getBrickd() + { + if (eContainerFeatureID() != ModelPackage.MBRICKLET_LINEAR_POTI__BRICKD) return null; + return (MBrickd)eContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetBrickd(MBrickd newBrickd, NotificationChain msgs) + { + msgs = eBasicSetContainer((InternalEObject)newBrickd, ModelPackage.MBRICKLET_LINEAR_POTI__BRICKD, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setBrickd(MBrickd newBrickd) + { + if (newBrickd != eInternalContainer() || (eContainerFeatureID() != ModelPackage.MBRICKLET_LINEAR_POTI__BRICKD && newBrickd != null)) + { + if (EcoreUtil.isAncestor(this, newBrickd)) + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + NotificationChain msgs = null; + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + if (newBrickd != null) + msgs = ((InternalEObject)newBrickd).eInverseAdd(this, ModelPackage.MBRICKD__MDEVICES, MBrickd.class, msgs); + msgs = basicSetBrickd(newBrickd, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__BRICKD, newBrickd, newBrickd)); + } + + /** + * + * + * @generated + */ + public long getCallbackPeriod() + { + return callbackPeriod; + } + + /** + * + * + * @generated + */ + public void setCallbackPeriod(long newCallbackPeriod) + { + long oldCallbackPeriod = callbackPeriod; + callbackPeriod = newCallbackPeriod; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__CALLBACK_PERIOD, oldCallbackPeriod, callbackPeriod)); + } + + /** + * + * + * @generated + */ + public TFBaseConfiguration getTfConfig() + { + return tfConfig; + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetTfConfig(TFBaseConfiguration newTfConfig, NotificationChain msgs) + { + TFBaseConfiguration oldTfConfig = tfConfig; + tfConfig = newTfConfig; + if (eNotificationRequired()) + { + ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__TF_CONFIG, oldTfConfig, newTfConfig); + if (msgs == null) msgs = notification; else msgs.add(notification); + } + return msgs; + } + + /** + * + * + * @generated + */ + public void setTfConfig(TFBaseConfiguration newTfConfig) + { + if (newTfConfig != tfConfig) + { + NotificationChain msgs = null; + if (tfConfig != null) + msgs = ((InternalEObject)tfConfig).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ModelPackage.MBRICKLET_LINEAR_POTI__TF_CONFIG, null, msgs); + if (newTfConfig != null) + msgs = ((InternalEObject)newTfConfig).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ModelPackage.MBRICKLET_LINEAR_POTI__TF_CONFIG, null, msgs); + msgs = basicSetTfConfig(newTfConfig, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__TF_CONFIG, newTfConfig, newTfConfig)); + } + + /** + * + * + * @generated + */ + public DecimalValue getSensorValue() + { + return sensorValue; + } + + /** + * + * + * @generated + */ + public void setSensorValue(DecimalValue newSensorValue) + { + DecimalValue oldSensorValue = sensorValue; + sensorValue = newSensorValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MBRICKLET_LINEAR_POTI__SENSOR_VALUE, oldSensorValue, sensorValue)); + } + + /** + * + * + * @generated + */ + public String getDeviceType() + { + return deviceType; + } + + /** + * + * + * @generated NOT + */ + public void fetchSensorValue() + { + try { + int position = tinkerforgeDevice.getPosition(); + DecimalValue value = Tools.calculate(position); + setSensorValue(value); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + public void init() + { + setEnabledA(new AtomicBoolean()); + logger = LoggerFactory.getLogger(MBrickletLinearPotiImpl.class); + } + + /** + * + * + * @generated NOT + */ + public void enable() + { + setCallbackPeriod(10); + if (tfConfig != null) { + logger.trace("got configuration"); + if (tfConfig.eIsSet(tfConfig.eClass().getEStructuralFeature("callbackPeriod"))) { + logger.trace("found callbackPeriod"); + setCallbackPeriod(tfConfig.getCallbackPeriod()); + } + } + logger.trace("callbackPeriod is {}", getCallbackPeriod()); + tinkerforgeDevice = new BrickletLinearPoti(getUid(), getIpConnection()); + listener = new PositionListener(); + tinkerforgeDevice.addPositionListener(listener); + fetchSensorValue(); + try { + tinkerforgeDevice.setPositionCallbackPeriod(getCallbackPeriod()); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } + + /** + * + * + * @generated NOT + */ + private class PositionListener implements BrickletLinearPoti.PositionListener { + + @Override + public void position(int position) { + DecimalValue value = Tools.calculate(position); + logger.trace("{} got new value {}", LoggerConstants.TFMODELUPDATE, value); + logger.trace("{} setting new value {}", LoggerConstants.TFMODELUPDATE, value); + setSensorValue(value); + } + } + + /** + * + * + * @generated NOT + */ + public void disable() + { + if (listener != null) { + tinkerforgeDevice.removePositionListener(listener); + } + tinkerforgeDevice = null; + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_LINEAR_POTI__BRICKD: + if (eInternalContainer() != null) + msgs = eBasicRemoveFromContainer(msgs); + return basicSetBrickd((MBrickd)otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_LINEAR_POTI__BRICKD: + return basicSetBrickd(null, msgs); + case ModelPackage.MBRICKLET_LINEAR_POTI__TF_CONFIG: + return basicSetTfConfig(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) + { + switch (eContainerFeatureID()) + { + case ModelPackage.MBRICKLET_LINEAR_POTI__BRICKD: + return eInternalContainer().eInverseRemove(this, ModelPackage.MBRICKD__MDEVICES, MBrickd.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_LINEAR_POTI__LOGGER: + return getLogger(); + case ModelPackage.MBRICKLET_LINEAR_POTI__UID: + return getUid(); + case ModelPackage.MBRICKLET_LINEAR_POTI__POLL: + return isPoll(); + case ModelPackage.MBRICKLET_LINEAR_POTI__ENABLED_A: + return getEnabledA(); + case ModelPackage.MBRICKLET_LINEAR_POTI__TINKERFORGE_DEVICE: + return getTinkerforgeDevice(); + case ModelPackage.MBRICKLET_LINEAR_POTI__IP_CONNECTION: + return getIpConnection(); + case ModelPackage.MBRICKLET_LINEAR_POTI__CONNECTED_UID: + return getConnectedUid(); + case ModelPackage.MBRICKLET_LINEAR_POTI__POSITION: + return getPosition(); + case ModelPackage.MBRICKLET_LINEAR_POTI__DEVICE_IDENTIFIER: + return getDeviceIdentifier(); + case ModelPackage.MBRICKLET_LINEAR_POTI__NAME: + return getName(); + case ModelPackage.MBRICKLET_LINEAR_POTI__BRICKD: + return getBrickd(); + case ModelPackage.MBRICKLET_LINEAR_POTI__CALLBACK_PERIOD: + return getCallbackPeriod(); + case ModelPackage.MBRICKLET_LINEAR_POTI__TF_CONFIG: + return getTfConfig(); + case ModelPackage.MBRICKLET_LINEAR_POTI__SENSOR_VALUE: + return getSensorValue(); + case ModelPackage.MBRICKLET_LINEAR_POTI__DEVICE_TYPE: + return getDeviceType(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_LINEAR_POTI__LOGGER: + setLogger((Logger)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__UID: + setUid((String)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__POLL: + setPoll((Boolean)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__ENABLED_A: + setEnabledA((AtomicBoolean)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__TINKERFORGE_DEVICE: + setTinkerforgeDevice((BrickletLinearPoti)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__IP_CONNECTION: + setIpConnection((IPConnection)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__CONNECTED_UID: + setConnectedUid((String)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__POSITION: + setPosition((Character)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__DEVICE_IDENTIFIER: + setDeviceIdentifier((Integer)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__NAME: + setName((String)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__BRICKD: + setBrickd((MBrickd)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__CALLBACK_PERIOD: + setCallbackPeriod((Long)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__TF_CONFIG: + setTfConfig((TFBaseConfiguration)newValue); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__SENSOR_VALUE: + setSensorValue((DecimalValue)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_LINEAR_POTI__LOGGER: + setLogger(LOGGER_EDEFAULT); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__UID: + setUid(UID_EDEFAULT); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__POLL: + setPoll(POLL_EDEFAULT); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__ENABLED_A: + setEnabledA(ENABLED_A_EDEFAULT); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__TINKERFORGE_DEVICE: + setTinkerforgeDevice((BrickletLinearPoti)null); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__IP_CONNECTION: + setIpConnection(IP_CONNECTION_EDEFAULT); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__CONNECTED_UID: + setConnectedUid(CONNECTED_UID_EDEFAULT); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__POSITION: + setPosition(POSITION_EDEFAULT); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__DEVICE_IDENTIFIER: + setDeviceIdentifier(DEVICE_IDENTIFIER_EDEFAULT); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__NAME: + setName(NAME_EDEFAULT); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__BRICKD: + setBrickd((MBrickd)null); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__CALLBACK_PERIOD: + setCallbackPeriod(CALLBACK_PERIOD_EDEFAULT); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__TF_CONFIG: + setTfConfig((TFBaseConfiguration)null); + return; + case ModelPackage.MBRICKLET_LINEAR_POTI__SENSOR_VALUE: + setSensorValue((DecimalValue)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case ModelPackage.MBRICKLET_LINEAR_POTI__LOGGER: + return LOGGER_EDEFAULT == null ? logger != null : !LOGGER_EDEFAULT.equals(logger); + case ModelPackage.MBRICKLET_LINEAR_POTI__UID: + return UID_EDEFAULT == null ? uid != null : !UID_EDEFAULT.equals(uid); + case ModelPackage.MBRICKLET_LINEAR_POTI__POLL: + return poll != POLL_EDEFAULT; + case ModelPackage.MBRICKLET_LINEAR_POTI__ENABLED_A: + return ENABLED_A_EDEFAULT == null ? enabledA != null : !ENABLED_A_EDEFAULT.equals(enabledA); + case ModelPackage.MBRICKLET_LINEAR_POTI__TINKERFORGE_DEVICE: + return tinkerforgeDevice != null; + case ModelPackage.MBRICKLET_LINEAR_POTI__IP_CONNECTION: + return IP_CONNECTION_EDEFAULT == null ? ipConnection != null : !IP_CONNECTION_EDEFAULT.equals(ipConnection); + case ModelPackage.MBRICKLET_LINEAR_POTI__CONNECTED_UID: + return CONNECTED_UID_EDEFAULT == null ? connectedUid != null : !CONNECTED_UID_EDEFAULT.equals(connectedUid); + case ModelPackage.MBRICKLET_LINEAR_POTI__POSITION: + return position != POSITION_EDEFAULT; + case ModelPackage.MBRICKLET_LINEAR_POTI__DEVICE_IDENTIFIER: + return deviceIdentifier != DEVICE_IDENTIFIER_EDEFAULT; + case ModelPackage.MBRICKLET_LINEAR_POTI__NAME: + return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name); + case ModelPackage.MBRICKLET_LINEAR_POTI__BRICKD: + return getBrickd() != null; + case ModelPackage.MBRICKLET_LINEAR_POTI__CALLBACK_PERIOD: + return callbackPeriod != CALLBACK_PERIOD_EDEFAULT; + case ModelPackage.MBRICKLET_LINEAR_POTI__TF_CONFIG: + return tfConfig != null; + case ModelPackage.MBRICKLET_LINEAR_POTI__SENSOR_VALUE: + return sensorValue != null; + case ModelPackage.MBRICKLET_LINEAR_POTI__DEVICE_TYPE: + return DEVICE_TYPE_EDEFAULT == null ? deviceType != null : !DEVICE_TYPE_EDEFAULT.equals(deviceType); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) + { + if (baseClass == CallbackListener.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICKLET_LINEAR_POTI__CALLBACK_PERIOD: return ModelPackage.CALLBACK_LISTENER__CALLBACK_PERIOD; + default: return -1; + } + } + if (baseClass == MTFConfigConsumer.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICKLET_LINEAR_POTI__TF_CONFIG: return ModelPackage.MTF_CONFIG_CONSUMER__TF_CONFIG; + default: return -1; + } + } + if (baseClass == MSensor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MBRICKLET_LINEAR_POTI__SENSOR_VALUE: return ModelPackage.MSENSOR__SENSOR_VALUE; + default: return -1; + } + } + return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) + { + if (baseClass == CallbackListener.class) + { + switch (baseFeatureID) + { + case ModelPackage.CALLBACK_LISTENER__CALLBACK_PERIOD: return ModelPackage.MBRICKLET_LINEAR_POTI__CALLBACK_PERIOD; + default: return -1; + } + } + if (baseClass == MTFConfigConsumer.class) + { + switch (baseFeatureID) + { + case ModelPackage.MTF_CONFIG_CONSUMER__TF_CONFIG: return ModelPackage.MBRICKLET_LINEAR_POTI__TF_CONFIG; + default: return -1; + } + } + if (baseClass == MSensor.class) + { + switch (baseFeatureID) + { + case ModelPackage.MSENSOR__SENSOR_VALUE: return ModelPackage.MBRICKLET_LINEAR_POTI__SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedOperationID(int baseOperationID, Class baseClass) + { + if (baseClass == CallbackListener.class) + { + switch (baseOperationID) + { + default: return -1; + } + } + if (baseClass == MTFConfigConsumer.class) + { + switch (baseOperationID) + { + default: return -1; + } + } + if (baseClass == MSensor.class) + { + switch (baseOperationID) + { + case ModelPackage.MSENSOR___FETCH_SENSOR_VALUE: return ModelPackage.MBRICKLET_LINEAR_POTI___FETCH_SENSOR_VALUE; + default: return -1; + } + } + return super.eDerivedOperationID(baseOperationID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public Object eInvoke(int operationID, EList arguments) throws InvocationTargetException + { + switch (operationID) + { + case ModelPackage.MBRICKLET_LINEAR_POTI___FETCH_SENSOR_VALUE: + fetchSensorValue(); + return null; + case ModelPackage.MBRICKLET_LINEAR_POTI___INIT: + init(); + return null; + case ModelPackage.MBRICKLET_LINEAR_POTI___ENABLE: + enable(); + return null; + case ModelPackage.MBRICKLET_LINEAR_POTI___DISABLE: + disable(); + return null; + } + return super.eInvoke(operationID, arguments); + } + + /** + * + * + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (logger: "); + result.append(logger); + result.append(", uid: "); + result.append(uid); + result.append(", poll: "); + result.append(poll); + result.append(", enabledA: "); + result.append(enabledA); + result.append(", tinkerforgeDevice: "); + result.append(tinkerforgeDevice); + result.append(", ipConnection: "); + result.append(ipConnection); + result.append(", connectedUid: "); + result.append(connectedUid); + result.append(", position: "); + result.append(position); + result.append(", deviceIdentifier: "); + result.append(deviceIdentifier); + result.append(", name: "); + result.append(name); + result.append(", callbackPeriod: "); + result.append(callbackPeriod); + result.append(", sensorValue: "); + result.append(sensorValue); + result.append(", deviceType: "); + result.append(deviceType); + result.append(')'); + return result.toString(); + } + +} //MBrickletLinearPotiImpl diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MServoImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MServoImpl.java index 508283a88b8..4d652c30caa 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MServoImpl.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/MServoImpl.java @@ -9,6 +9,7 @@ package org.openhab.binding.tinkerforge.internal.model.impl; import java.lang.reflect.InvocationTargetException; +import java.math.BigDecimal; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.emf.common.notify.Notification; @@ -21,6 +22,10 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.openhab.binding.tinkerforge.internal.LoggerConstants; import org.openhab.binding.tinkerforge.internal.TinkerforgeErrorHandler; +import org.openhab.binding.tinkerforge.internal.config.DeviceOptions; +import org.openhab.binding.tinkerforge.internal.model.ConfigOptsDimmable; +import org.openhab.binding.tinkerforge.internal.model.ConfigOptsServo; +import org.openhab.binding.tinkerforge.internal.model.DimmableActor; import org.openhab.binding.tinkerforge.internal.model.MBaseDevice; import org.openhab.binding.tinkerforge.internal.model.MBrickServo; import org.openhab.binding.tinkerforge.internal.model.MServo; @@ -28,8 +33,19 @@ import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; import org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer; import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.model.MoveActor; +import org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor; +import org.openhab.binding.tinkerforge.internal.model.SetPointActor; +import org.openhab.binding.tinkerforge.internal.model.SwitchSensor; import org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration; +import org.openhab.binding.tinkerforge.internal.tools.Tools; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; +import org.openhab.binding.tinkerforge.internal.types.DirectionValue; import org.openhab.binding.tinkerforge.internal.types.OnOffValue; +import org.openhab.binding.tinkerforge.internal.types.PercentValue; +import org.openhab.core.library.types.IncreaseDecreaseType; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.UpDownType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,6 +63,7 @@ *

      * The following features are implemented: *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getSensorValue Sensor Value}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getSwitchState Switch State}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getLogger Logger}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getUid Uid}
      • @@ -54,16 +71,21 @@ *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getEnabledA Enabled A}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getSubId Sub Id}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getMbrick Mbrick}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getDirection Direction}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getTfConfig Tf Config}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getMinValue Min Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getMaxValue Max Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getPercentValue Percent Value}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getDeviceType Device Type}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getVelocity Velocity}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getAcceleration Acceleration}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getMaxPosition Max Position}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getMinPosition Min Position}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getPulseWidthMin Pulse Width Min}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getPulseWidthMax Pulse Width Max}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getPeriod Period}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getOutputVoltage Output Voltage}
      • - *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getServoCurrentPosition Servo Current Position}
      • - *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getServoDestinationPosition Servo Destination Position}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.MServoImpl#getTargetPosition Target Position}
      • *
      *

      * @@ -71,13 +93,21 @@ */ public class MServoImpl extends MinimalEObjectImpl.Container implements MServo { - private static final short OFF_POSITION = -9000; - private static final short ON_POSITION = 9000; -/** - * The default value of the '{@link #getSwitchState() Switch State}' attribute. + /** + * The cached value of the '{@link #getSensorValue() Sensor Value}' attribute. * * + * @see #getSensorValue() + * @generated + * @ordered + */ + protected DecimalValue sensorValue; + + /** + * The default value of the '{@link #getSwitchState() Switch State}' attribute. + * * @see #getSwitchState() * @generated * @ordered @@ -192,6 +222,26 @@ public class MServoImpl extends MinimalEObjectImpl.Container implements MServo */ protected String subId = SUB_ID_EDEFAULT; + /** + * The default value of the '{@link #getDirection() Direction}' attribute. + * + * + * @see #getDirection() + * @generated + * @ordered + */ + protected static final DirectionValue DIRECTION_EDEFAULT = null; + + /** + * The cached value of the '{@link #getDirection() Direction}' attribute. + * + * + * @see #getDirection() + * @generated + * @ordered + */ + protected DirectionValue direction = DIRECTION_EDEFAULT; + /** * The cached value of the '{@link #getTfConfig() Tf Config}' containment reference. * @@ -202,6 +252,60 @@ public class MServoImpl extends MinimalEObjectImpl.Container implements MServo */ protected TFServoConfiguration tfConfig; + /** + * The default value of the '{@link #getMinValue() Min Value}' attribute. + * + * + * @see #getMinValue() + * @generated + * @ordered + */ + protected static final BigDecimal MIN_VALUE_EDEFAULT = null; + /** + * The cached value of the '{@link #getMinValue() Min Value}' attribute. + * + * + * @see #getMinValue() + * @generated + * @ordered + */ + protected BigDecimal minValue = MIN_VALUE_EDEFAULT; + /** + * The default value of the '{@link #getMaxValue() Max Value}' attribute. + * + * + * @see #getMaxValue() + * @generated + * @ordered + */ + protected static final BigDecimal MAX_VALUE_EDEFAULT = null; + /** + * The cached value of the '{@link #getMaxValue() Max Value}' attribute. + * + * + * @see #getMaxValue() + * @generated + * @ordered + */ + protected BigDecimal maxValue = MAX_VALUE_EDEFAULT; + /** + * The default value of the '{@link #getPercentValue() Percent Value}' attribute. + * + * + * @see #getPercentValue() + * @generated + * @ordered + */ + protected static final PercentValue PERCENT_VALUE_EDEFAULT = null; + /** + * The cached value of the '{@link #getPercentValue() Percent Value}' attribute. + * + * + * @see #getPercentValue() + * @generated + * @ordered + */ + protected PercentValue percentValue = PERCENT_VALUE_EDEFAULT; /** * The default value of the '{@link #getDeviceType() Device Type}' attribute. * @@ -230,7 +334,7 @@ public class MServoImpl extends MinimalEObjectImpl.Container implements MServo * @generated * @ordered */ - protected static final int VELOCITY_EDEFAULT = 30000; + protected static final int VELOCITY_EDEFAULT = 65535; /** * The cached value of the '{@link #getVelocity() Velocity}' attribute. @@ -250,7 +354,7 @@ public class MServoImpl extends MinimalEObjectImpl.Container implements MServo * @generated * @ordered */ - protected static final int ACCELERATION_EDEFAULT = 30000; + protected static final int ACCELERATION_EDEFAULT = 65535; /** * The cached value of the '{@link #getAcceleration() Acceleration}' attribute. @@ -262,6 +366,46 @@ public class MServoImpl extends MinimalEObjectImpl.Container implements MServo */ protected int acceleration = ACCELERATION_EDEFAULT; + /** + * The default value of the '{@link #getMaxPosition() Max Position}' attribute. + * + * + * @see #getMaxPosition() + * @generated + * @ordered + */ + protected static final Short MAX_POSITION_EDEFAULT = new Short((short)9000); + + /** + * The cached value of the '{@link #getMaxPosition() Max Position}' attribute. + * + * + * @see #getMaxPosition() + * @generated + * @ordered + */ + protected Short maxPosition = MAX_POSITION_EDEFAULT; + + /** + * The default value of the '{@link #getMinPosition() Min Position}' attribute. + * + * + * @see #getMinPosition() + * @generated + * @ordered + */ + protected static final Short MIN_POSITION_EDEFAULT = new Short((short)-9000); + + /** + * The cached value of the '{@link #getMinPosition() Min Position}' attribute. + * + * + * @see #getMinPosition() + * @generated + * @ordered + */ + protected Short minPosition = MIN_POSITION_EDEFAULT; + /** * The default value of the '{@link #getPulseWidthMin() Pulse Width Min}' attribute. * @@ -343,55 +487,55 @@ public class MServoImpl extends MinimalEObjectImpl.Container implements MServo protected int outputVoltage = OUTPUT_VOLTAGE_EDEFAULT; /** - * The default value of the '{@link #getServoCurrentPosition() Servo Current Position}' attribute. + * The default value of the '{@link #getTargetPosition() Target Position}' attribute. * * - * @see #getServoCurrentPosition() + * @see #getTargetPosition() * @generated * @ordered */ - protected static final short SERVO_CURRENT_POSITION_EDEFAULT = 0; - + protected static final short TARGET_POSITION_EDEFAULT = 0; /** - * The cached value of the '{@link #getServoCurrentPosition() Servo Current Position}' attribute. + * The cached value of the '{@link #getTargetPosition() Target Position}' attribute. * * - * @see #getServoCurrentPosition() + * @see #getTargetPosition() * @generated * @ordered */ - protected short servoCurrentPosition = SERVO_CURRENT_POSITION_EDEFAULT; + protected short targetPosition = TARGET_POSITION_EDEFAULT; + private Short servoNum; + private PositionReachedListener listener; /** - * The default value of the '{@link #getServoDestinationPosition() Servo Destination Position}' attribute. * * - * @see #getServoDestinationPosition() * @generated - * @ordered */ - protected static final short SERVO_DESTINATION_POSITION_EDEFAULT = 0; + protected MServoImpl() + { + super(); + } /** - * The cached value of the '{@link #getServoDestinationPosition() Servo Destination Position}' attribute. * * - * @see #getServoDestinationPosition() * @generated - * @ordered */ - protected short servoDestinationPosition = SERVO_DESTINATION_POSITION_EDEFAULT; - - private Short servoNum; + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.MSERVO; + } /** * * * @generated */ - protected MServoImpl() + public DecimalValue getSensorValue() { - super(); + return sensorValue; } /** @@ -399,10 +543,12 @@ protected MServoImpl() * * @generated */ - @Override - protected EClass eStaticClass() + public void setSensorValue(DecimalValue newSensorValue) { - return ModelPackage.Literals.MSERVO; + DecimalValue oldSensorValue = sensorValue; + sensorValue = newSensorValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__SENSOR_VALUE, oldSensorValue, sensorValue)); } /** @@ -566,6 +712,52 @@ public void setAcceleration(int newAcceleration) eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__ACCELERATION, oldAcceleration, acceleration)); } + /** + * + * + * @generated + */ + public Short getMaxPosition() + { + return maxPosition; + } + + /** + * + * + * @generated + */ + public void setMaxPosition(Short newMaxPosition) + { + Short oldMaxPosition = maxPosition; + maxPosition = newMaxPosition; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__MAX_POSITION, oldMaxPosition, maxPosition)); + } + + /** + * + * + * @generated + */ + public Short getMinPosition() + { + return minPosition; + } + + /** + * + * + * @generated + */ + public void setMinPosition(Short newMinPosition) + { + Short oldMinPosition = minPosition; + minPosition = newMinPosition; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__MIN_POSITION, oldMinPosition, minPosition)); + } + /** * * @@ -663,9 +855,9 @@ public void setOutputVoltage(int newOutputVoltage) * * @generated */ - public short getServoCurrentPosition() + public short getTargetPosition() { - return servoCurrentPosition; + return targetPosition; } /** @@ -673,35 +865,62 @@ public short getServoCurrentPosition() * * @generated */ - public void setServoCurrentPosition(short newServoCurrentPosition) + public void setTargetPosition(short newTargetPosition) { - short oldServoCurrentPosition = servoCurrentPosition; - servoCurrentPosition = newServoCurrentPosition; + short oldTargetPosition = targetPosition; + targetPosition = newTargetPosition; if (eNotificationRequired()) - eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__SERVO_CURRENT_POSITION, oldServoCurrentPosition, servoCurrentPosition)); + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__TARGET_POSITION, oldTargetPosition, targetPosition)); } /** - * - * - * @generated + * + * + * @generated NOT */ - public short getServoDestinationPosition() + public void init() { + setEnabledA(new AtomicBoolean()); + logger = LoggerFactory.getLogger(MServoImpl.class); + logger.debug("init called on MServo: " + uid); + } + + /** + * + * + * @generated NOT + */ + public void setValue(BigDecimal newValue, DeviceOptions opts) { - return servoDestinationPosition; + setPoint(newValue.shortValue(), opts); } /** - * - * - * @generated + * + * + * @generated NOT */ - public void setServoDestinationPosition(short newServoDestinationPosition) + public void setValue(PercentType newPercentValue, DeviceOptions opts) { - short oldServoDestinationPosition = servoDestinationPosition; - servoDestinationPosition = newServoDestinationPosition; - if (eNotificationRequired()) - eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__SERVO_DESTINATION_POSITION, oldServoDestinationPosition, servoDestinationPosition)); + BigDecimal max = Tools.getBigDecimalOpt(ConfigOptsDimmable.MAX.toString(), opts); + if (max == null) { + logger.error("dimmer option max is missing, items configuration has to be fixed!"); + return; + } else { + logger.debug("max {}", max); + } + BigDecimal min = Tools.getBigDecimalOpt(ConfigOptsDimmable.MIN.toString(), opts); + logger.debug("min {}", min); + if (min == null) { + logger.error("dimmer option min is missing, items configuration has to be fixed!"); + return; + } + setPercentValue(new PercentValue(newPercentValue.toBigDecimal())); + BigDecimal abs = max.add(min.abs()); + Short newVelocity = + abs.divide(new BigDecimal(100)).multiply(newPercentValue.toBigDecimal()) + .subtract(min.abs()) + .shortValue(); + setPoint(newVelocity, opts); } /** @@ -709,12 +928,206 @@ public void setServoDestinationPosition(short newServoDestinationPosition) * * @generated NOT */ - public void init() { - setEnabledA(new AtomicBoolean()); - logger = LoggerFactory.getLogger(MServoImpl.class); - logger.debug("init called on MServo: " + uid); + public void dimm(IncreaseDecreaseType increaseDecrease, DeviceOptions opts) + { + logger.trace("dimmer increase increaseDecrease {} opts {}", increaseDecrease, opts); + if (opts == null) { + logger.error("options are missing"); + return; + } + if (increaseDecrease == null) { + logger.error("increaseDecrease may not be null!"); + return; + } + Short step = Tools.getShortOpt(ConfigOptsDimmable.STEP.toString(), opts); + if (step == null) { + logger.error("dimmer option step is missing, items configuration has to be fixed!"); + return; + } + Short newPosition = null; + if (increaseDecrease.equals(IncreaseDecreaseType.INCREASE)) { + newPosition = (short) (this.targetPosition + step); + } else if (increaseDecrease.equals(IncreaseDecreaseType.DECREASE)) { + newPosition = (short) (this.targetPosition - step); + } + logger.debug("new position {}", newPosition); + setPoint(newPosition, opts); + } + + /** + * + * + * @generated NOT + */ + public void move(UpDownType direction, DeviceOptions opts) + { + if (opts == null) { + logger.error("options are missing"); + return; + } + if (direction == null) { + logger.error("direction may not be null, items configuration has to be fixed!"); + return; + } + Short xposition = null; + + if (direction.equals(UpDownType.DOWN)) { + xposition = Tools.getShortOpt(ConfigOptsServo.RIGHTPOSITION.toString(), opts); + if (xposition == null) { + logger +.error("\"{}\" option missing or empty, items configuration has to be fixed!", + ConfigOptsServo.RIGHTPOSITION.toString()); + return; + } else { + setDirection(DirectionValue.RIGHT); + } + } else if (direction.equals(UpDownType.UP)) { + xposition = Tools.getShortOpt(ConfigOptsServo.LEFTPOSITION.toString(), opts); + if (xposition == null) { + logger.error("\"{}\" option missing or empty, items configuration has to be fixed!", + ConfigOptsServo.LEFTPOSITION.toString()); + return; + } else { + setDirection(DirectionValue.LEFT); + } + } + setPoint(xposition, opts); + } + + /** + * + * + * @generated NOT + */ + public void stop() + { + try { + // stop by setting current position value with setPosition on the tf servo device + getMbrick().getTinkerforgeDevice().setPosition(servoNum, getSensorValue().shortValue()); + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } } + /** + * + * + * @generated NOT + */ + public void moveon(DeviceOptions opts) + { + if (direction != null && direction != DirectionValue.UNDEF) { + UpDownType directiontmp = + this.direction == DirectionValue.LEFT ? UpDownType.UP : UpDownType.DOWN; + move(directiontmp, opts); + } else { + logger.warn("cannot moveon because direction is undefined"); + } + } + + /** + * + * + * @generated NOT + */ + private void setPoint(Short newPosition, DeviceOptions opts) { + Integer xacceleration = + Tools.getIntOpt(ConfigOptsServo.ACCELERATION.toString(), opts, this.acceleration); + if (xacceleration == null) { + logger.error("acceleration may not be null"); + return; + } + Integer xvelocity = Tools.getIntOpt(ConfigOptsServo.VELOCITY.toString(), opts, this.velocity); + if (xvelocity == null) { + logger.error("xvelocity may not be null"); + return; + } + if (newPosition == null) { + logger.error("position may not be null"); + return; + } + Short max = Tools.getShortOpt(ConfigOptsDimmable.MAX.toString(), opts, getMaxPosition()); + if (max == null) { + logger.error("option max is missing, items configuration has to be fixed!"); + return; + } else { + logger.debug("max {}", max); + } + Short min = Tools.getShortOpt(ConfigOptsDimmable.MIN.toString(), opts, getMinPosition()); + logger.debug("min {}", min); + if (min == null) { + logger.error("dimmer option min is missing, items configuration has to be fixed!"); + return; + } + if (newPosition > max) { + if (this.targetPosition < newPosition) { + logger.debug("setting value to max speed {}, which is lower then target speed {}", max, + newPosition); + newPosition = max; + } else { + logger.debug("max value already reached {}", max); + return; + } + } else if (newPosition < min) { + if (this.targetPosition > newPosition) { + logger.debug("setting velocity to min speed {}, which is higher then target speed {}", min, + newPosition); + newPosition = min; + } else { + logger.debug("min value already reached {}", min); + return; + } + } + setPoint(newPosition, xvelocity, xacceleration); + } + + /** + * + * + * @generated NOT + */ + public boolean setPoint(Short newPosition, int newVelocity, int newAccelleration) { + Short max = getMaxPosition(); + Short min = getMinPosition(); + if (newPosition > max) { + if (this.targetPosition < newPosition) { + logger.debug("setting value to max speed {}, which is lower then target speed {}", max, + newPosition); + newPosition = max; + } else { + logger.debug("max value already reached {}", max); + return true; + } + } else if (newPosition < min) { + if (this.targetPosition > newPosition) { + logger.debug("setting velocity to min speed {}, which is higher then target speed {}", min, + newPosition); + newPosition = min; + } else { + logger.debug("min value already reached {}", min); + return true; + } + } + try { + BrickServo tinkerBrickServo = getMbrick().getTinkerforgeDevice(); + tinkerBrickServo.setVelocity(servoNum, newVelocity); + tinkerBrickServo.setAcceleration(servoNum, newAccelleration); + tinkerBrickServo.setPosition(servoNum, newPosition); + setTargetPosition(newPosition); + return true; + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + return false; + } + + /** * * @@ -742,12 +1155,16 @@ public void enable() { BrickServo tinkerBrickServo = brick.getTinkerforgeDevice(); try { servoNum = Short.parseShort(String.valueOf(subId.charAt(subId.length() - 1))); - tinkerBrickServo.setVelocity(servoNum, velocity); - tinkerBrickServo.setAcceleration(servoNum, acceleration); + // tinkerBrickServo.setVelocity(servoNum, velocity); + // tinkerBrickServo.setAcceleration(servoNum, acceleration); tinkerBrickServo.setPulseWidth(servoNum, pulseWidthMin, pulseWidthMax); tinkerBrickServo.setPeriod(servoNum, period); tinkerBrickServo.setOutputVoltage(outputVoltage); - tinkerBrickServo.addPositionReachedListener(new PositionReachedListener()); + setTargetPosition(tinkerBrickServo.getPosition(servoNum)); // initialize target postion with + // current position value + listener = new PositionReachedListener(); + tinkerBrickServo.addPositionReachedListener(listener); + tinkerBrickServo.enablePositionReachedCallback(); tinkerBrickServo.enable(servoNum); fetchSwitchState(); } catch (NumberFormatException e) { @@ -767,7 +1184,11 @@ public void enable() { * @generated NOT */ @Override - public void disable() {} + public void disable() { + if (listener != null) { + getMbrick().getTinkerforgeDevice().removePositionReachedListener(listener); + } + } /** * @@ -775,15 +1196,25 @@ public void disable() {} * @generated NOT */ public void fetchSwitchState() { - OnOffValue value = OnOffValue.UNDEF; + fetchSensorValue(); + } + + /** + * + * + * @generated NOT + */ + public void fetchSensorValue() + { try { short position = getMbrick().getTinkerforgeDevice().getPosition(servoNum); - if (position == OFF_POSITION) { - value = OnOffValue.OFF; - } else if (position == ON_POSITION) { - value = OnOffValue.ON; - } - setSwitchState(value); + DecimalValue newValue = Tools.calculate(position); + setSensorValue(newValue); + + OnOffValue newSwitchState = newValue.onOffValue(0); + logger.trace("new switchstate {} new value {}", newSwitchState, newValue); + setSwitchState(newSwitchState); + } catch (TimeoutException e) { TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); } catch (NotConnectedException e) { @@ -800,8 +1231,15 @@ public void fetchSwitchState() { private class PositionReachedListener implements BrickServo.PositionReachedListener { @Override - public void positionReached(short servoNumPar, short position) { - if (servoNumPar == servoNum) setServoCurrentPosition(position); + public void positionReached(short servoNumPar, short newposition) { + DecimalValue newValue = Tools.calculate(newposition); + logger.trace("positionreachedlistener called servonum {} servonumpar {}, newpostion {}", + servoNum, servoNumPar, + newposition); + if (servoNumPar == servoNum) { + logger.trace("setting new value {}", newValue); + setSensorValue(newValue); + } } } @@ -811,31 +1249,21 @@ public void positionReached(short servoNumPar, short position) { * @generated NOT */ @Override - public void turnSwitch(OnOffValue state) { + public void turnSwitch(OnOffValue state, DeviceOptions opts) { logger.debug("setSwitchState called"); - try { - - if (state == OnOffValue.OFF) { - logger.debug("setSwitchState off"); - setServoDestinationPosition(OFF_POSITION); - getMbrick().getTinkerforgeDevice().setPosition(servoNum, OFF_POSITION); - } else if (state == OnOffValue.ON) { - logger.debug("setSwitchState off"); - - setServoDestinationPosition(ON_POSITION); - MBrickServo mbrick = getMbrick(); - mbrick.getTinkerforgeDevice().setPosition(servoNum, ON_POSITION); - } else { - logger.error("{} unkown switchstate {}", LoggerConstants.TFMODELUPDATE, state); + Short position = null; + if (state == OnOffValue.OFF) { + position = 0; + } else if (state == OnOffValue.ON) { + position = Tools.getShortOpt(ConfigOptsServo.POSITION.toString(), opts); + if (position == null) { + logger.error("{} option is missing", ConfigOptsServo.POSITION.toString().toLowerCase()); + return; } - switchState = state == null ? OnOffValue.UNDEF : state; - setSwitchState(switchState); - } catch (TimeoutException e) { - TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); - } catch (NotConnectedException e) { - TinkerforgeErrorHandler.handleError(this, - TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } else { + logger.error("{} unkown switchstate {}", LoggerConstants.TFMODELUPDATE, state); } + setPoint(position, opts); } /** @@ -906,6 +1334,29 @@ else if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__MBRICK, newMbrick, newMbrick)); } + /** + * + * + * @generated + */ + public DirectionValue getDirection() + { + return direction; + } + +/** + * + * + * @generated + */ + public void setDirection(DirectionValue newDirection) + { + DirectionValue oldDirection = direction; + direction = newDirection; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__DIRECTION, oldDirection, direction)); + } + /** * * @@ -933,7 +1384,7 @@ public NotificationChain basicSetTfConfig(TFServoConfiguration newTfConfig, Noti return msgs; } -/** + /** * * * @generated @@ -954,11 +1405,80 @@ else if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__TF_CONFIG, newTfConfig, newTfConfig)); } +/** + * + * + * @generated + */ + public BigDecimal getMinValue() + { + return minValue; + } + + /** + * + * + * @generated + */ + public void setMinValue(BigDecimal newMinValue) + { + BigDecimal oldMinValue = minValue; + minValue = newMinValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__MIN_VALUE, oldMinValue, minValue)); + } + + /** + * + * + * @generated + */ + public BigDecimal getMaxValue() + { + return maxValue; + } + + /** + * + * + * @generated + */ + public void setMaxValue(BigDecimal newMaxValue) + { + BigDecimal oldMaxValue = maxValue; + maxValue = newMaxValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__MAX_VALUE, oldMaxValue, maxValue)); + } + /** * * * @generated */ + public PercentValue getPercentValue() + { + return percentValue; + } + + /** + * + * + * @generated + */ + public void setPercentValue(PercentValue newPercentValue) + { + PercentValue oldPercentValue = percentValue; + percentValue = newPercentValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.MSERVO__PERCENT_VALUE, oldPercentValue, percentValue)); + } + +/** + * + * + * @generated + */ public String getDeviceType() { return deviceType; @@ -1026,6 +1546,8 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { + case ModelPackage.MSERVO__SENSOR_VALUE: + return getSensorValue(); case ModelPackage.MSERVO__SWITCH_STATE: return getSwitchState(); case ModelPackage.MSERVO__LOGGER: @@ -1040,14 +1562,26 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) return getSubId(); case ModelPackage.MSERVO__MBRICK: return getMbrick(); + case ModelPackage.MSERVO__DIRECTION: + return getDirection(); case ModelPackage.MSERVO__TF_CONFIG: return getTfConfig(); + case ModelPackage.MSERVO__MIN_VALUE: + return getMinValue(); + case ModelPackage.MSERVO__MAX_VALUE: + return getMaxValue(); + case ModelPackage.MSERVO__PERCENT_VALUE: + return getPercentValue(); case ModelPackage.MSERVO__DEVICE_TYPE: return getDeviceType(); case ModelPackage.MSERVO__VELOCITY: return getVelocity(); case ModelPackage.MSERVO__ACCELERATION: return getAcceleration(); + case ModelPackage.MSERVO__MAX_POSITION: + return getMaxPosition(); + case ModelPackage.MSERVO__MIN_POSITION: + return getMinPosition(); case ModelPackage.MSERVO__PULSE_WIDTH_MIN: return getPulseWidthMin(); case ModelPackage.MSERVO__PULSE_WIDTH_MAX: @@ -1056,10 +1590,8 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) return getPeriod(); case ModelPackage.MSERVO__OUTPUT_VOLTAGE: return getOutputVoltage(); - case ModelPackage.MSERVO__SERVO_CURRENT_POSITION: - return getServoCurrentPosition(); - case ModelPackage.MSERVO__SERVO_DESTINATION_POSITION: - return getServoDestinationPosition(); + case ModelPackage.MSERVO__TARGET_POSITION: + return getTargetPosition(); } return super.eGet(featureID, resolve, coreType); } @@ -1074,6 +1606,9 @@ public void eSet(int featureID, Object newValue) { switch (featureID) { + case ModelPackage.MSERVO__SENSOR_VALUE: + setSensorValue((DecimalValue)newValue); + return; case ModelPackage.MSERVO__SWITCH_STATE: setSwitchState((OnOffValue)newValue); return; @@ -1095,15 +1630,33 @@ public void eSet(int featureID, Object newValue) case ModelPackage.MSERVO__MBRICK: setMbrick((MBrickServo)newValue); return; + case ModelPackage.MSERVO__DIRECTION: + setDirection((DirectionValue)newValue); + return; case ModelPackage.MSERVO__TF_CONFIG: setTfConfig((TFServoConfiguration)newValue); return; + case ModelPackage.MSERVO__MIN_VALUE: + setMinValue((BigDecimal)newValue); + return; + case ModelPackage.MSERVO__MAX_VALUE: + setMaxValue((BigDecimal)newValue); + return; + case ModelPackage.MSERVO__PERCENT_VALUE: + setPercentValue((PercentValue)newValue); + return; case ModelPackage.MSERVO__VELOCITY: setVelocity((Integer)newValue); return; case ModelPackage.MSERVO__ACCELERATION: setAcceleration((Integer)newValue); return; + case ModelPackage.MSERVO__MAX_POSITION: + setMaxPosition((Short)newValue); + return; + case ModelPackage.MSERVO__MIN_POSITION: + setMinPosition((Short)newValue); + return; case ModelPackage.MSERVO__PULSE_WIDTH_MIN: setPulseWidthMin((Integer)newValue); return; @@ -1116,11 +1669,8 @@ public void eSet(int featureID, Object newValue) case ModelPackage.MSERVO__OUTPUT_VOLTAGE: setOutputVoltage((Integer)newValue); return; - case ModelPackage.MSERVO__SERVO_CURRENT_POSITION: - setServoCurrentPosition((Short)newValue); - return; - case ModelPackage.MSERVO__SERVO_DESTINATION_POSITION: - setServoDestinationPosition((Short)newValue); + case ModelPackage.MSERVO__TARGET_POSITION: + setTargetPosition((Short)newValue); return; } super.eSet(featureID, newValue); @@ -1136,6 +1686,9 @@ public void eUnset(int featureID) { switch (featureID) { + case ModelPackage.MSERVO__SENSOR_VALUE: + setSensorValue((DecimalValue)null); + return; case ModelPackage.MSERVO__SWITCH_STATE: setSwitchState(SWITCH_STATE_EDEFAULT); return; @@ -1157,15 +1710,33 @@ public void eUnset(int featureID) case ModelPackage.MSERVO__MBRICK: setMbrick((MBrickServo)null); return; + case ModelPackage.MSERVO__DIRECTION: + setDirection(DIRECTION_EDEFAULT); + return; case ModelPackage.MSERVO__TF_CONFIG: setTfConfig((TFServoConfiguration)null); return; + case ModelPackage.MSERVO__MIN_VALUE: + setMinValue(MIN_VALUE_EDEFAULT); + return; + case ModelPackage.MSERVO__MAX_VALUE: + setMaxValue(MAX_VALUE_EDEFAULT); + return; + case ModelPackage.MSERVO__PERCENT_VALUE: + setPercentValue(PERCENT_VALUE_EDEFAULT); + return; case ModelPackage.MSERVO__VELOCITY: setVelocity(VELOCITY_EDEFAULT); return; case ModelPackage.MSERVO__ACCELERATION: setAcceleration(ACCELERATION_EDEFAULT); return; + case ModelPackage.MSERVO__MAX_POSITION: + setMaxPosition(MAX_POSITION_EDEFAULT); + return; + case ModelPackage.MSERVO__MIN_POSITION: + setMinPosition(MIN_POSITION_EDEFAULT); + return; case ModelPackage.MSERVO__PULSE_WIDTH_MIN: setPulseWidthMin(PULSE_WIDTH_MIN_EDEFAULT); return; @@ -1178,11 +1749,8 @@ public void eUnset(int featureID) case ModelPackage.MSERVO__OUTPUT_VOLTAGE: setOutputVoltage(OUTPUT_VOLTAGE_EDEFAULT); return; - case ModelPackage.MSERVO__SERVO_CURRENT_POSITION: - setServoCurrentPosition(SERVO_CURRENT_POSITION_EDEFAULT); - return; - case ModelPackage.MSERVO__SERVO_DESTINATION_POSITION: - setServoDestinationPosition(SERVO_DESTINATION_POSITION_EDEFAULT); + case ModelPackage.MSERVO__TARGET_POSITION: + setTargetPosition(TARGET_POSITION_EDEFAULT); return; } super.eUnset(featureID); @@ -1198,6 +1766,8 @@ public boolean eIsSet(int featureID) { switch (featureID) { + case ModelPackage.MSERVO__SENSOR_VALUE: + return sensorValue != null; case ModelPackage.MSERVO__SWITCH_STATE: return SWITCH_STATE_EDEFAULT == null ? switchState != null : !SWITCH_STATE_EDEFAULT.equals(switchState); case ModelPackage.MSERVO__LOGGER: @@ -1212,14 +1782,26 @@ public boolean eIsSet(int featureID) return SUB_ID_EDEFAULT == null ? subId != null : !SUB_ID_EDEFAULT.equals(subId); case ModelPackage.MSERVO__MBRICK: return getMbrick() != null; + case ModelPackage.MSERVO__DIRECTION: + return DIRECTION_EDEFAULT == null ? direction != null : !DIRECTION_EDEFAULT.equals(direction); case ModelPackage.MSERVO__TF_CONFIG: return tfConfig != null; + case ModelPackage.MSERVO__MIN_VALUE: + return MIN_VALUE_EDEFAULT == null ? minValue != null : !MIN_VALUE_EDEFAULT.equals(minValue); + case ModelPackage.MSERVO__MAX_VALUE: + return MAX_VALUE_EDEFAULT == null ? maxValue != null : !MAX_VALUE_EDEFAULT.equals(maxValue); + case ModelPackage.MSERVO__PERCENT_VALUE: + return PERCENT_VALUE_EDEFAULT == null ? percentValue != null : !PERCENT_VALUE_EDEFAULT.equals(percentValue); case ModelPackage.MSERVO__DEVICE_TYPE: return DEVICE_TYPE_EDEFAULT == null ? deviceType != null : !DEVICE_TYPE_EDEFAULT.equals(deviceType); case ModelPackage.MSERVO__VELOCITY: return velocity != VELOCITY_EDEFAULT; case ModelPackage.MSERVO__ACCELERATION: return acceleration != ACCELERATION_EDEFAULT; + case ModelPackage.MSERVO__MAX_POSITION: + return MAX_POSITION_EDEFAULT == null ? maxPosition != null : !MAX_POSITION_EDEFAULT.equals(maxPosition); + case ModelPackage.MSERVO__MIN_POSITION: + return MIN_POSITION_EDEFAULT == null ? minPosition != null : !MIN_POSITION_EDEFAULT.equals(minPosition); case ModelPackage.MSERVO__PULSE_WIDTH_MIN: return pulseWidthMin != PULSE_WIDTH_MIN_EDEFAULT; case ModelPackage.MSERVO__PULSE_WIDTH_MAX: @@ -1228,10 +1810,8 @@ public boolean eIsSet(int featureID) return period != PERIOD_EDEFAULT; case ModelPackage.MSERVO__OUTPUT_VOLTAGE: return outputVoltage != OUTPUT_VOLTAGE_EDEFAULT; - case ModelPackage.MSERVO__SERVO_CURRENT_POSITION: - return servoCurrentPosition != SERVO_CURRENT_POSITION_EDEFAULT; - case ModelPackage.MSERVO__SERVO_DESTINATION_POSITION: - return servoDestinationPosition != SERVO_DESTINATION_POSITION_EDEFAULT; + case ModelPackage.MSERVO__TARGET_POSITION: + return targetPosition != TARGET_POSITION_EDEFAULT; } return super.eIsSet(featureID); } @@ -1244,6 +1824,21 @@ public boolean eIsSet(int featureID) @Override public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) { + if (baseClass == SwitchSensor.class) + { + switch (derivedFeatureID) + { + default: return -1; + } + } + if (baseClass == ProgrammableSwitchActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MSERVO__SWITCH_STATE: return ModelPackage.PROGRAMMABLE_SWITCH_ACTOR__SWITCH_STATE; + default: return -1; + } + } if (baseClass == MBaseDevice.class) { switch (derivedFeatureID) @@ -1264,6 +1859,14 @@ public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) default: return -1; } } + if (baseClass == MoveActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MSERVO__DIRECTION: return ModelPackage.MOVE_ACTOR__DIRECTION; + default: return -1; + } + } if (baseClass == MTFConfigConsumer.class) { switch (derivedFeatureID) @@ -1272,6 +1875,23 @@ public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) default: return -1; } } + if (baseClass == DimmableActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MSERVO__MIN_VALUE: return ModelPackage.DIMMABLE_ACTOR__MIN_VALUE; + case ModelPackage.MSERVO__MAX_VALUE: return ModelPackage.DIMMABLE_ACTOR__MAX_VALUE; + default: return -1; + } + } + if (baseClass == SetPointActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.MSERVO__PERCENT_VALUE: return ModelPackage.SET_POINT_ACTOR__PERCENT_VALUE; + default: return -1; + } + } return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); } @@ -1283,6 +1903,21 @@ public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) @Override public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) { + if (baseClass == SwitchSensor.class) + { + switch (baseFeatureID) + { + default: return -1; + } + } + if (baseClass == ProgrammableSwitchActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.PROGRAMMABLE_SWITCH_ACTOR__SWITCH_STATE: return ModelPackage.MSERVO__SWITCH_STATE; + default: return -1; + } + } if (baseClass == MBaseDevice.class) { switch (baseFeatureID) @@ -1303,6 +1938,14 @@ public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) default: return -1; } } + if (baseClass == MoveActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.MOVE_ACTOR__DIRECTION: return ModelPackage.MSERVO__DIRECTION; + default: return -1; + } + } if (baseClass == MTFConfigConsumer.class) { switch (baseFeatureID) @@ -1311,6 +1954,23 @@ public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) default: return -1; } } + if (baseClass == DimmableActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.DIMMABLE_ACTOR__MIN_VALUE: return ModelPackage.MSERVO__MIN_VALUE; + case ModelPackage.DIMMABLE_ACTOR__MAX_VALUE: return ModelPackage.MSERVO__MAX_VALUE; + default: return -1; + } + } + if (baseClass == SetPointActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.SET_POINT_ACTOR__PERCENT_VALUE: return ModelPackage.MSERVO__PERCENT_VALUE; + default: return -1; + } + } return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); } @@ -1322,6 +1982,22 @@ public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) @Override public int eDerivedOperationID(int baseOperationID, Class baseClass) { + if (baseClass == SwitchSensor.class) + { + switch (baseOperationID) + { + case ModelPackage.SWITCH_SENSOR___FETCH_SWITCH_STATE: return ModelPackage.MSERVO___FETCH_SWITCH_STATE; + default: return -1; + } + } + if (baseClass == ProgrammableSwitchActor.class) + { + switch (baseOperationID) + { + case ModelPackage.PROGRAMMABLE_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE_DEVICEOPTIONS: return ModelPackage.MSERVO___TURN_SWITCH__ONOFFVALUE_DEVICEOPTIONS; + default: return -1; + } + } if (baseClass == MBaseDevice.class) { switch (baseOperationID) @@ -1339,6 +2015,16 @@ public int eDerivedOperationID(int baseOperationID, Class baseClass) default: return -1; } } + if (baseClass == MoveActor.class) + { + switch (baseOperationID) + { + case ModelPackage.MOVE_ACTOR___MOVE__UPDOWNTYPE_DEVICEOPTIONS: return ModelPackage.MSERVO___MOVE__UPDOWNTYPE_DEVICEOPTIONS; + case ModelPackage.MOVE_ACTOR___STOP: return ModelPackage.MSERVO___STOP; + case ModelPackage.MOVE_ACTOR___MOVEON__DEVICEOPTIONS: return ModelPackage.MSERVO___MOVEON__DEVICEOPTIONS; + default: return -1; + } + } if (baseClass == MTFConfigConsumer.class) { switch (baseOperationID) @@ -1346,6 +2032,23 @@ public int eDerivedOperationID(int baseOperationID, Class baseClass) default: return -1; } } + if (baseClass == DimmableActor.class) + { + switch (baseOperationID) + { + case ModelPackage.DIMMABLE_ACTOR___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS: return ModelPackage.MSERVO___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS; + default: return -1; + } + } + if (baseClass == SetPointActor.class) + { + switch (baseOperationID) + { + case ModelPackage.SET_POINT_ACTOR___SET_VALUE__BIGDECIMAL_DEVICEOPTIONS: return ModelPackage.MSERVO___SET_VALUE__BIGDECIMAL_DEVICEOPTIONS; + case ModelPackage.SET_POINT_ACTOR___SET_VALUE__PERCENTTYPE_DEVICEOPTIONS: return ModelPackage.MSERVO___SET_VALUE__PERCENTTYPE_DEVICEOPTIONS; + default: return -1; + } + } return super.eDerivedOperationID(baseOperationID, baseClass); } @@ -1362,18 +2065,41 @@ public Object eInvoke(int operationID, EList arguments) throws InvocationTarg case ModelPackage.MSERVO___INIT: init(); return null; + case ModelPackage.MSERVO___SET_POINT__SHORT_INT_INT: + return setPoint((Short)arguments.get(0), (Integer)arguments.get(1), (Integer)arguments.get(2)); + case ModelPackage.MSERVO___SET_VALUE__BIGDECIMAL_DEVICEOPTIONS: + setValue((BigDecimal)arguments.get(0), (DeviceOptions)arguments.get(1)); + return null; + case ModelPackage.MSERVO___SET_VALUE__PERCENTTYPE_DEVICEOPTIONS: + setValue((PercentType)arguments.get(0), (DeviceOptions)arguments.get(1)); + return null; + case ModelPackage.MSERVO___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS: + dimm((IncreaseDecreaseType)arguments.get(0), (DeviceOptions)arguments.get(1)); + return null; + case ModelPackage.MSERVO___MOVE__UPDOWNTYPE_DEVICEOPTIONS: + move((UpDownType)arguments.get(0), (DeviceOptions)arguments.get(1)); + return null; + case ModelPackage.MSERVO___STOP: + stop(); + return null; + case ModelPackage.MSERVO___MOVEON__DEVICEOPTIONS: + moveon((DeviceOptions)arguments.get(0)); + return null; case ModelPackage.MSERVO___ENABLE: enable(); return null; case ModelPackage.MSERVO___DISABLE: disable(); return null; - case ModelPackage.MSERVO___TURN_SWITCH__ONOFFVALUE: - turnSwitch((OnOffValue)arguments.get(0)); + case ModelPackage.MSERVO___TURN_SWITCH__ONOFFVALUE_DEVICEOPTIONS: + turnSwitch((OnOffValue)arguments.get(0), (DeviceOptions)arguments.get(1)); return null; case ModelPackage.MSERVO___FETCH_SWITCH_STATE: fetchSwitchState(); return null; + case ModelPackage.MSERVO___FETCH_SENSOR_VALUE: + fetchSensorValue(); + return null; } return super.eInvoke(operationID, arguments); } @@ -1389,7 +2115,9 @@ public String toString() if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); - result.append(" (switchState: "); + result.append(" (sensorValue: "); + result.append(sensorValue); + result.append(", switchState: "); result.append(switchState); result.append(", logger: "); result.append(logger); @@ -1401,12 +2129,24 @@ public String toString() result.append(enabledA); result.append(", subId: "); result.append(subId); + result.append(", direction: "); + result.append(direction); + result.append(", minValue: "); + result.append(minValue); + result.append(", maxValue: "); + result.append(maxValue); + result.append(", percentValue: "); + result.append(percentValue); result.append(", deviceType: "); result.append(deviceType); result.append(", velocity: "); result.append(velocity); result.append(", acceleration: "); result.append(acceleration); + result.append(", maxPosition: "); + result.append(maxPosition); + result.append(", minPosition: "); + result.append(minPosition); result.append(", pulseWidthMin: "); result.append(pulseWidthMin); result.append(", pulseWidthMax: "); @@ -1415,10 +2155,8 @@ public String toString() result.append(period); result.append(", outputVoltage: "); result.append(outputVoltage); - result.append(", servoCurrentPosition: "); - result.append(servoCurrentPosition); - result.append(", servoDestinationPosition: "); - result.append(servoDestinationPosition); + result.append(", targetPosition: "); + result.append(targetPosition); result.append(')'); return result.toString(); } diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/ModelFactoryImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/ModelFactoryImpl.java index c09918c9422..6149fb039d4 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/ModelFactoryImpl.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/ModelFactoryImpl.java @@ -65,10 +65,15 @@ import org.openhab.binding.tinkerforge.internal.model.TFNullConfiguration; import org.openhab.binding.tinkerforge.internal.model.TFServoConfiguration; import org.openhab.binding.tinkerforge.internal.types.DecimalValue; +import org.openhab.binding.tinkerforge.internal.types.DirectionValue; import org.openhab.binding.tinkerforge.internal.types.HighLowValue; import org.openhab.binding.tinkerforge.internal.types.OnOffValue; +import org.openhab.binding.tinkerforge.internal.types.PercentValue; import org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue; import org.openhab.core.library.types.HSBType; +import org.openhab.core.library.types.IncreaseDecreaseType; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.UpDownType; import org.slf4j.Logger; import com.tinkerforge.BrickDC; @@ -77,6 +82,7 @@ import com.tinkerforge.BrickletBarometer; import com.tinkerforge.BrickletDistanceIR; import com.tinkerforge.BrickletDistanceUS; +import com.tinkerforge.BrickletDualButton; import com.tinkerforge.BrickletDualRelay; import com.tinkerforge.BrickletHallEffect; import com.tinkerforge.BrickletHumidity; @@ -85,8 +91,10 @@ import com.tinkerforge.BrickletIndustrialDigitalIn4; import com.tinkerforge.BrickletIndustrialDigitalOut4; import com.tinkerforge.BrickletIndustrialQuadRelay; +import com.tinkerforge.BrickletJoystick; import com.tinkerforge.BrickletLCD20x4; import com.tinkerforge.BrickletLEDStrip; +import com.tinkerforge.BrickletLinearPoti; import com.tinkerforge.BrickletMoisture; import com.tinkerforge.BrickletMotionDetector; import com.tinkerforge.BrickletMultiTouch; @@ -155,6 +163,16 @@ public EObject create(EClass eClass) { case ModelPackage.ECOSYSTEM: return createEcosystem(); case ModelPackage.MBRICKD: return createMBrickd(); + case ModelPackage.MBRICKLET_DUAL_BUTTON: return createMBrickletDualButton(); + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON: return createDualButtonLeftButton(); + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON: return createDualButtonRightButton(); + case ModelPackage.DUAL_BUTTON_LEFT_LED: return createDualButtonLeftLed(); + case ModelPackage.DUAL_BUTTON_RIGHT_LED: return createDualButtonRightLed(); + case ModelPackage.MBRICKLET_LINEAR_POTI: return createMBrickletLinearPoti(); + case ModelPackage.MBRICKLET_JOYSTICK: return createMBrickletJoystick(); + case ModelPackage.JOYSTICK_XPOSITION: return createJoystickXPosition(); + case ModelPackage.JOYSTICK_YPOSITION: return createJoystickYPosition(); + case ModelPackage.JOYSTICK_BUTTON: return createJoystickButton(); case ModelPackage.MBRICK_SERVO: return createMBrickServo(); case ModelPackage.MSERVO: return createMServo(); case ModelPackage.MBRICK_DC: return createMBrickDC(); @@ -224,6 +242,7 @@ public EObject create(EClass eClass) case ModelPackage.REMOTE_SWITCH_CCONFIGURATION: return createRemoteSwitchCConfiguration(); case ModelPackage.MULTI_TOUCH_DEVICE_CONFIGURATION: return createMultiTouchDeviceConfiguration(); case ModelPackage.BRICKLET_MULTI_TOUCH_CONFIGURATION: return createBrickletMultiTouchConfiguration(); + case ModelPackage.DIMMABLE_CONFIGURATION: return createDimmableConfiguration(); default: throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); } @@ -239,8 +258,6 @@ public Object createFromString(EDataType eDataType, String initialValue) { switch (eDataType.getClassifierID()) { - case ModelPackage.DC_DRIVE_MODE: - return createDCDriveModeFromString(eDataType, initialValue); case ModelPackage.NO_SUB_IDS: return createNoSubIdsFromString(eDataType, initialValue); case ModelPackage.INDUSTRIAL_DIGITAL_IN_SUB_IDS: @@ -267,6 +284,18 @@ public Object createFromString(EDataType eDataType, String initialValue) return createTemperatureIRSubIdsFromString(eDataType, initialValue); case ModelPackage.VOLTAGE_CURRENT_SUB_IDS: return createVoltageCurrentSubIdsFromString(eDataType, initialValue); + case ModelPackage.CONFIG_OPTS_MOVE: + return createConfigOptsMoveFromString(eDataType, initialValue); + case ModelPackage.CONFIG_OPTS_DIMMABLE: + return createConfigOptsDimmableFromString(eDataType, initialValue); + case ModelPackage.CONFIG_OPTS_SET_POINT: + return createConfigOptsSetPointFromString(eDataType, initialValue); + case ModelPackage.CONFIG_OPTS_SWITCH_SPEED: + return createConfigOptsSwitchSpeedFromString(eDataType, initialValue); + case ModelPackage.DC_DRIVE_MODE: + return createDCDriveModeFromString(eDataType, initialValue); + case ModelPackage.CONFIG_OPTS_SERVO: + return createConfigOptsServoFromString(eDataType, initialValue); case ModelPackage.MIP_CONNECTION: return createMIPConnectionFromString(eDataType, initialValue); case ModelPackage.MTINKER_DEVICE: @@ -337,10 +366,26 @@ public Object createFromString(EDataType eDataType, String initialValue) return createTinkerBrickletSegmentDisplay4x7FromString(eDataType, initialValue); case ModelPackage.TINKER_BRICKLET_LED_STRIP: return createTinkerBrickletLEDStripFromString(eDataType, initialValue); + case ModelPackage.BRICKLET_JOYSTICK: + return createBrickletJoystickFromString(eDataType, initialValue); + case ModelPackage.TINKER_BRICKLET_LINEAR_POTI: + return createTinkerBrickletLinearPotiFromString(eDataType, initialValue); + case ModelPackage.TINKER_BRICKLET_DUAL_BUTTON: + return createTinkerBrickletDualButtonFromString(eDataType, initialValue); case ModelPackage.HSB_TYPE: return createHSBTypeFromString(eDataType, initialValue); + case ModelPackage.UP_DOWN_TYPE: + return createUpDownTypeFromString(eDataType, initialValue); + case ModelPackage.PERCENT_VALUE: + return createPercentValueFromString(eDataType, initialValue); case ModelPackage.DEVICE_OPTIONS: return createDeviceOptionsFromString(eDataType, initialValue); + case ModelPackage.PERCENT_TYPE: + return createPercentTypeFromString(eDataType, initialValue); + case ModelPackage.INCREASE_DECREASE_TYPE: + return createIncreaseDecreaseTypeFromString(eDataType, initialValue); + case ModelPackage.DIRECTION_VALUE: + return createDirectionValueFromString(eDataType, initialValue); case ModelPackage.ENUM: return createEnumFromString(eDataType, initialValue); default: @@ -358,8 +403,6 @@ public String convertToString(EDataType eDataType, Object instanceValue) { switch (eDataType.getClassifierID()) { - case ModelPackage.DC_DRIVE_MODE: - return convertDCDriveModeToString(eDataType, instanceValue); case ModelPackage.NO_SUB_IDS: return convertNoSubIdsToString(eDataType, instanceValue); case ModelPackage.INDUSTRIAL_DIGITAL_IN_SUB_IDS: @@ -386,6 +429,18 @@ public String convertToString(EDataType eDataType, Object instanceValue) return convertTemperatureIRSubIdsToString(eDataType, instanceValue); case ModelPackage.VOLTAGE_CURRENT_SUB_IDS: return convertVoltageCurrentSubIdsToString(eDataType, instanceValue); + case ModelPackage.CONFIG_OPTS_MOVE: + return convertConfigOptsMoveToString(eDataType, instanceValue); + case ModelPackage.CONFIG_OPTS_DIMMABLE: + return convertConfigOptsDimmableToString(eDataType, instanceValue); + case ModelPackage.CONFIG_OPTS_SET_POINT: + return convertConfigOptsSetPointToString(eDataType, instanceValue); + case ModelPackage.CONFIG_OPTS_SWITCH_SPEED: + return convertConfigOptsSwitchSpeedToString(eDataType, instanceValue); + case ModelPackage.DC_DRIVE_MODE: + return convertDCDriveModeToString(eDataType, instanceValue); + case ModelPackage.CONFIG_OPTS_SERVO: + return convertConfigOptsServoToString(eDataType, instanceValue); case ModelPackage.MIP_CONNECTION: return convertMIPConnectionToString(eDataType, instanceValue); case ModelPackage.MTINKER_DEVICE: @@ -456,10 +511,26 @@ public String convertToString(EDataType eDataType, Object instanceValue) return convertTinkerBrickletSegmentDisplay4x7ToString(eDataType, instanceValue); case ModelPackage.TINKER_BRICKLET_LED_STRIP: return convertTinkerBrickletLEDStripToString(eDataType, instanceValue); + case ModelPackage.BRICKLET_JOYSTICK: + return convertBrickletJoystickToString(eDataType, instanceValue); + case ModelPackage.TINKER_BRICKLET_LINEAR_POTI: + return convertTinkerBrickletLinearPotiToString(eDataType, instanceValue); + case ModelPackage.TINKER_BRICKLET_DUAL_BUTTON: + return convertTinkerBrickletDualButtonToString(eDataType, instanceValue); case ModelPackage.HSB_TYPE: return convertHSBTypeToString(eDataType, instanceValue); + case ModelPackage.UP_DOWN_TYPE: + return convertUpDownTypeToString(eDataType, instanceValue); + case ModelPackage.PERCENT_VALUE: + return convertPercentValueToString(eDataType, instanceValue); case ModelPackage.DEVICE_OPTIONS: return convertDeviceOptionsToString(eDataType, instanceValue); + case ModelPackage.PERCENT_TYPE: + return convertPercentTypeToString(eDataType, instanceValue); + case ModelPackage.INCREASE_DECREASE_TYPE: + return convertIncreaseDecreaseTypeToString(eDataType, instanceValue); + case ModelPackage.DIRECTION_VALUE: + return convertDirectionValueToString(eDataType, instanceValue); case ModelPackage.ENUM: return convertEnumToString(eDataType, instanceValue); default: @@ -523,6 +594,116 @@ public MBrickd createMBrickd() return mBrickd; } + /** + * + * + * @generated + */ + public MBrickletDualButton createMBrickletDualButton() + { + MBrickletDualButtonImpl mBrickletDualButton = new MBrickletDualButtonImpl(); + return mBrickletDualButton; + } + + /** + * + * + * @generated + */ + public DualButtonLeftButton createDualButtonLeftButton() + { + DualButtonLeftButtonImpl dualButtonLeftButton = new DualButtonLeftButtonImpl(); + return dualButtonLeftButton; + } + + /** + * + * + * @generated + */ + public DualButtonRightButton createDualButtonRightButton() + { + DualButtonRightButtonImpl dualButtonRightButton = new DualButtonRightButtonImpl(); + return dualButtonRightButton; + } + + /** + * + * + * @generated + */ + public DualButtonLeftLed createDualButtonLeftLed() + { + DualButtonLeftLedImpl dualButtonLeftLed = new DualButtonLeftLedImpl(); + return dualButtonLeftLed; + } + + /** + * + * + * @generated + */ + public DualButtonRightLed createDualButtonRightLed() + { + DualButtonRightLedImpl dualButtonRightLed = new DualButtonRightLedImpl(); + return dualButtonRightLed; + } + + /** + * + * + * @generated + */ + public MBrickletLinearPoti createMBrickletLinearPoti() + { + MBrickletLinearPotiImpl mBrickletLinearPoti = new MBrickletLinearPotiImpl(); + return mBrickletLinearPoti; + } + + /** + * + * + * @generated + */ + public MBrickletJoystick createMBrickletJoystick() + { + MBrickletJoystickImpl mBrickletJoystick = new MBrickletJoystickImpl(); + return mBrickletJoystick; + } + + /** + * + * + * @generated + */ + public JoystickXPosition createJoystickXPosition() + { + JoystickXPositionImpl joystickXPosition = new JoystickXPositionImpl(); + return joystickXPosition; + } + + /** + * + * + * @generated + */ + public JoystickYPosition createJoystickYPosition() + { + JoystickYPositionImpl joystickYPosition = new JoystickYPositionImpl(); + return joystickYPosition; + } + + /** + * + * + * @generated + */ + public JoystickButton createJoystickButton() + { + JoystickButtonImpl joystickButton = new JoystickButtonImpl(); + return joystickButton; + } + /** * * @@ -963,6 +1144,17 @@ public BrickletMultiTouchConfiguration createBrickletMultiTouchConfiguration() return brickletMultiTouchConfiguration; } + /** + * + * + * @generated + */ + public DimmableConfiguration createDimmableConfiguration() + { + DimmableConfigurationImpl dimmableConfiguration = new DimmableConfigurationImpl(); + return dimmableConfiguration; + } + /** * * @@ -1331,6 +1523,28 @@ public String convertDCDriveModeToString(EDataType eDataType, Object instanceVal return instanceValue == null ? null : instanceValue.toString(); } + /** + * + * + * @generated + */ + public ConfigOptsServo createConfigOptsServoFromString(EDataType eDataType, String initialValue) + { + ConfigOptsServo result = ConfigOptsServo.get(initialValue); + if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'"); + return result; + } + + /** + * + * + * @generated + */ + public String convertConfigOptsServoToString(EDataType eDataType, Object instanceValue) + { + return instanceValue == null ? null : instanceValue.toString(); + } + /** * * @@ -1617,6 +1831,94 @@ public String convertVoltageCurrentSubIdsToString(EDataType eDataType, Object in return instanceValue == null ? null : instanceValue.toString(); } + /** + * + * + * @generated + */ + public ConfigOptsMove createConfigOptsMoveFromString(EDataType eDataType, String initialValue) + { + ConfigOptsMove result = ConfigOptsMove.get(initialValue); + if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'"); + return result; + } + + /** + * + * + * @generated + */ + public String convertConfigOptsMoveToString(EDataType eDataType, Object instanceValue) + { + return instanceValue == null ? null : instanceValue.toString(); + } + + /** + * + * + * @generated + */ + public ConfigOptsDimmable createConfigOptsDimmableFromString(EDataType eDataType, String initialValue) + { + ConfigOptsDimmable result = ConfigOptsDimmable.get(initialValue); + if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'"); + return result; + } + + /** + * + * + * @generated + */ + public String convertConfigOptsDimmableToString(EDataType eDataType, Object instanceValue) + { + return instanceValue == null ? null : instanceValue.toString(); + } + + /** + * + * + * @generated + */ + public ConfigOptsSetPoint createConfigOptsSetPointFromString(EDataType eDataType, String initialValue) + { + ConfigOptsSetPoint result = ConfigOptsSetPoint.get(initialValue); + if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'"); + return result; + } + + /** + * + * + * @generated + */ + public String convertConfigOptsSetPointToString(EDataType eDataType, Object instanceValue) + { + return instanceValue == null ? null : instanceValue.toString(); + } + + /** + * + * + * @generated + */ + public ConfigOptsSwitchSpeed createConfigOptsSwitchSpeedFromString(EDataType eDataType, String initialValue) + { + ConfigOptsSwitchSpeed result = ConfigOptsSwitchSpeed.get(initialValue); + if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'"); + return result; + } + + /** + * + * + * @generated + */ + public String convertConfigOptsSwitchSpeedToString(EDataType eDataType, Object instanceValue) + { + return instanceValue == null ? null : instanceValue.toString(); + } + /** * * @@ -2177,6 +2479,66 @@ public String convertTinkerBrickletLEDStripToString(EDataType eDataType, Object return super.convertToString(eDataType, instanceValue); } + /** + * + * + * @generated + */ + public BrickletJoystick createBrickletJoystickFromString(EDataType eDataType, String initialValue) + { + return (BrickletJoystick)super.createFromString(eDataType, initialValue); + } + + /** + * + * + * @generated + */ + public String convertBrickletJoystickToString(EDataType eDataType, Object instanceValue) + { + return super.convertToString(eDataType, instanceValue); + } + + /** + * + * + * @generated + */ + public BrickletLinearPoti createTinkerBrickletLinearPotiFromString(EDataType eDataType, String initialValue) + { + return (BrickletLinearPoti)super.createFromString(eDataType, initialValue); + } + + /** + * + * + * @generated + */ + public String convertTinkerBrickletLinearPotiToString(EDataType eDataType, Object instanceValue) + { + return super.convertToString(eDataType, instanceValue); + } + + /** + * + * + * @generated + */ + public BrickletDualButton createTinkerBrickletDualButtonFromString(EDataType eDataType, String initialValue) + { + return (BrickletDualButton)super.createFromString(eDataType, initialValue); + } + + /** + * + * + * @generated + */ + public String convertTinkerBrickletDualButtonToString(EDataType eDataType, Object instanceValue) + { + return super.convertToString(eDataType, instanceValue); + } + /** * * @@ -2197,6 +2559,46 @@ public String convertHSBTypeToString(EDataType eDataType, Object instanceValue) return super.convertToString(eDataType, instanceValue); } + /** + * + * + * @generated + */ + public UpDownType createUpDownTypeFromString(EDataType eDataType, String initialValue) + { + return (UpDownType)super.createFromString(eDataType, initialValue); + } + + /** + * + * + * @generated + */ + public String convertUpDownTypeToString(EDataType eDataType, Object instanceValue) + { + return super.convertToString(eDataType, instanceValue); + } + + /** + * + * + * @generated + */ + public PercentValue createPercentValueFromString(EDataType eDataType, String initialValue) + { + return (PercentValue)super.createFromString(eDataType, initialValue); + } + + /** + * + * + * @generated + */ + public String convertPercentValueToString(EDataType eDataType, Object instanceValue) + { + return super.convertToString(eDataType, instanceValue); + } + /** * * @@ -2217,6 +2619,66 @@ public String convertDeviceOptionsToString(EDataType eDataType, Object instanceV return super.convertToString(eDataType, instanceValue); } + /** + * + * + * @generated + */ + public PercentType createPercentTypeFromString(EDataType eDataType, String initialValue) + { + return (PercentType)super.createFromString(eDataType, initialValue); + } + + /** + * + * + * @generated + */ + public String convertPercentTypeToString(EDataType eDataType, Object instanceValue) + { + return super.convertToString(eDataType, instanceValue); + } + + /** + * + * + * @generated + */ + public IncreaseDecreaseType createIncreaseDecreaseTypeFromString(EDataType eDataType, String initialValue) + { + return (IncreaseDecreaseType)super.createFromString(eDataType, initialValue); + } + + /** + * + * + * @generated + */ + public String convertIncreaseDecreaseTypeToString(EDataType eDataType, Object instanceValue) + { + return super.convertToString(eDataType, instanceValue); + } + + /** + * + * + * @generated + */ + public DirectionValue createDirectionValueFromString(EDataType eDataType, String initialValue) + { + return (DirectionValue)super.createFromString(eDataType, initialValue); + } + + /** + * + * + * @generated + */ + public String convertDirectionValueToString(EDataType eDataType, Object instanceValue) + { + return super.convertToString(eDataType, instanceValue); + } + /** * * diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/ModelPackageImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/ModelPackageImpl.java index 8a930f42dca..632fdf4550c 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/ModelPackageImpl.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/ModelPackageImpl.java @@ -30,6 +30,11 @@ import org.openhab.binding.tinkerforge.internal.model.BrickletRemoteSwitchConfiguration; import org.openhab.binding.tinkerforge.internal.model.CallbackListener; import org.openhab.binding.tinkerforge.internal.model.ColorActor; +import org.openhab.binding.tinkerforge.internal.model.ConfigOptsDimmable; +import org.openhab.binding.tinkerforge.internal.model.ConfigOptsMove; +import org.openhab.binding.tinkerforge.internal.model.ConfigOptsServo; +import org.openhab.binding.tinkerforge.internal.model.ConfigOptsSetPoint; +import org.openhab.binding.tinkerforge.internal.model.ConfigOptsSwitchSpeed; import org.openhab.binding.tinkerforge.internal.model.DCDriveMode; import org.openhab.binding.tinkerforge.internal.model.DigitalActor; import org.openhab.binding.tinkerforge.internal.model.DigitalActorDigitalOut4; @@ -37,6 +42,14 @@ import org.openhab.binding.tinkerforge.internal.model.DigitalActorIO4; import org.openhab.binding.tinkerforge.internal.model.DigitalSensor; import org.openhab.binding.tinkerforge.internal.model.DigitalSensorIO4; +import org.openhab.binding.tinkerforge.internal.model.DimmableActor; +import org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration; +import org.openhab.binding.tinkerforge.internal.model.DualButtonDevice; +import org.openhab.binding.tinkerforge.internal.model.DualButtonLeftButton; +import org.openhab.binding.tinkerforge.internal.model.DualButtonLeftLed; +import org.openhab.binding.tinkerforge.internal.model.DualButtonRightButton; +import org.openhab.binding.tinkerforge.internal.model.DualButtonRightLed; +import org.openhab.binding.tinkerforge.internal.model.Direction; import org.openhab.binding.tinkerforge.internal.model.DualRelaySubIds; import org.openhab.binding.tinkerforge.internal.model.Ecosystem; import org.openhab.binding.tinkerforge.internal.model.Electrode; @@ -48,6 +61,10 @@ import org.openhab.binding.tinkerforge.internal.model.IndustrialDigitalInSubIDs; import org.openhab.binding.tinkerforge.internal.model.IndustrialQuadRelayIDs; import org.openhab.binding.tinkerforge.internal.model.InterruptListener; +import org.openhab.binding.tinkerforge.internal.model.JoystickButton; +import org.openhab.binding.tinkerforge.internal.model.JoystickDevice; +import org.openhab.binding.tinkerforge.internal.model.JoystickXPosition; +import org.openhab.binding.tinkerforge.internal.model.JoystickYPosition; import org.openhab.binding.tinkerforge.internal.model.LCDBacklightSubIds; import org.openhab.binding.tinkerforge.internal.model.LCDButtonSubIds; import org.openhab.binding.tinkerforge.internal.model.MActor; @@ -60,14 +77,17 @@ import org.openhab.binding.tinkerforge.internal.model.MBrickletBarometer; import org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceIR; import org.openhab.binding.tinkerforge.internal.model.MBrickletDistanceUS; +import org.openhab.binding.tinkerforge.internal.model.MBrickletDualButton; import org.openhab.binding.tinkerforge.internal.model.MBrickletHallEffect; import org.openhab.binding.tinkerforge.internal.model.MBrickletHumidity; import org.openhab.binding.tinkerforge.internal.model.MBrickletIO16; import org.openhab.binding.tinkerforge.internal.model.MBrickletIO4; import org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalIn4; import org.openhab.binding.tinkerforge.internal.model.MBrickletIndustrialDigitalOut4; +import org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick; import org.openhab.binding.tinkerforge.internal.model.MBrickletLCD20x4; import org.openhab.binding.tinkerforge.internal.model.MBrickletLEDStrip; +import org.openhab.binding.tinkerforge.internal.model.MBrickletLinearPoti; import org.openhab.binding.tinkerforge.internal.model.MBrickletMoisture; import org.openhab.binding.tinkerforge.internal.model.MBrickletMotionDetector; import org.openhab.binding.tinkerforge.internal.model.MBrickletMultiTouch; @@ -99,6 +119,7 @@ import org.openhab.binding.tinkerforge.internal.model.MTextActor; import org.openhab.binding.tinkerforge.internal.model.ModelFactory; import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.model.MoveActor; import org.openhab.binding.tinkerforge.internal.model.MultiTouchDevice; import org.openhab.binding.tinkerforge.internal.model.MultiTouchDeviceConfiguration; import org.openhab.binding.tinkerforge.internal.model.MultiTouchSubIds; @@ -108,6 +129,8 @@ import org.openhab.binding.tinkerforge.internal.model.OHTFDevice; import org.openhab.binding.tinkerforge.internal.model.OHTFSubDeviceAdminDevice; import org.openhab.binding.tinkerforge.internal.model.ObjectTemperature; +import org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor; +import org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitch; import org.openhab.binding.tinkerforge.internal.model.Proximity; import org.openhab.binding.tinkerforge.internal.model.RemoteSwitch; import org.openhab.binding.tinkerforge.internal.model.RemoteSwitchA; @@ -117,7 +140,9 @@ import org.openhab.binding.tinkerforge.internal.model.RemoteSwitchC; import org.openhab.binding.tinkerforge.internal.model.RemoteSwitchCConfiguration; import org.openhab.binding.tinkerforge.internal.model.ServoSubIDs; +import org.openhab.binding.tinkerforge.internal.model.SetPointActor; import org.openhab.binding.tinkerforge.internal.model.SubDeviceAdmin; +import org.openhab.binding.tinkerforge.internal.model.SwitchSensor; import org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration; import org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration; import org.openhab.binding.tinkerforge.internal.model.TFConfig; @@ -134,13 +159,19 @@ import org.openhab.binding.tinkerforge.internal.model.VCDeviceCurrent; import org.openhab.binding.tinkerforge.internal.model.VCDevicePower; import org.openhab.binding.tinkerforge.internal.model.VCDeviceVoltage; +import org.openhab.binding.tinkerforge.internal.model.ValueActor; import org.openhab.binding.tinkerforge.internal.model.VoltageCurrentDevice; import org.openhab.binding.tinkerforge.internal.model.VoltageCurrentSubIds; import org.openhab.binding.tinkerforge.internal.types.DecimalValue; +import org.openhab.binding.tinkerforge.internal.types.DirectionValue; import org.openhab.binding.tinkerforge.internal.types.HighLowValue; import org.openhab.binding.tinkerforge.internal.types.OnOffValue; +import org.openhab.binding.tinkerforge.internal.types.PercentValue; import org.openhab.binding.tinkerforge.internal.types.TinkerforgeValue; import org.openhab.core.library.types.HSBType; +import org.openhab.core.library.types.IncreaseDecreaseType; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.UpDownType; import org.slf4j.Logger; import com.tinkerforge.BrickDC; @@ -149,6 +180,7 @@ import com.tinkerforge.BrickletBarometer; import com.tinkerforge.BrickletDistanceIR; import com.tinkerforge.BrickletDistanceUS; +import com.tinkerforge.BrickletDualButton; import com.tinkerforge.BrickletDualRelay; import com.tinkerforge.BrickletHallEffect; import com.tinkerforge.BrickletHumidity; @@ -157,8 +189,10 @@ import com.tinkerforge.BrickletIndustrialDigitalIn4; import com.tinkerforge.BrickletIndustrialDigitalOut4; import com.tinkerforge.BrickletIndustrialQuadRelay; +import com.tinkerforge.BrickletJoystick; import com.tinkerforge.BrickletLCD20x4; import com.tinkerforge.BrickletLEDStrip; +import com.tinkerforge.BrickletLinearPoti; import com.tinkerforge.BrickletMoisture; import com.tinkerforge.BrickletMotionDetector; import com.tinkerforge.BrickletMultiTouch; @@ -349,6 +383,111 @@ public class ModelPackageImpl extends EPackageImpl implements ModelPackage */ private EClass colorActorEClass = null; + /** + * + * + * @generated + */ + private EClass moveActorEClass = null; + + /** + * + * + * @generated + */ + private EClass dimmableActorEClass = null; + + /** + * + * + * @generated + */ + private EClass setPointActorEClass = null; + + /** + * + * + * @generated + */ + private EClass mBrickletDualButtonEClass = null; + + /** + * + * + * @generated + */ + private EClass dualButtonDeviceEClass = null; + + /** + * + * + * @generated + */ + private EClass dualButtonLeftButtonEClass = null; + + /** + * + * + * @generated + */ + private EClass dualButtonRightButtonEClass = null; + + /** + * + * + * @generated + */ + private EClass dualButtonLeftLedEClass = null; + + /** + * + * + * @generated + */ + private EClass dualButtonRightLedEClass = null; + + /** + * + * + * @generated + */ + private EClass mBrickletLinearPotiEClass = null; + + /** + * + * + * @generated + */ + private EClass mBrickletJoystickEClass = null; + + /** + * + * + * @generated + */ + private EClass joystickDeviceEClass = null; + + /** + * + * + * @generated + */ + private EClass joystickXPositionEClass = null; + + /** + * + * + * @generated + */ + private EClass joystickYPositionEClass = null; + + /** + * + * + * @generated + */ + private EClass joystickButtonEClass = null; + /** * * @@ -377,6 +516,13 @@ public class ModelPackageImpl extends EPackageImpl implements ModelPackage */ private EClass mActorEClass = null; + /** + * + * + * @generated + */ + private EClass switchSensorEClass = null; + /** * * @@ -384,6 +530,13 @@ public class ModelPackageImpl extends EPackageImpl implements ModelPackage */ private EClass mSwitchActorEClass = null; + /** + * + * + * @generated + */ + private EClass programmableSwitchActorEClass = null; + /** * * @@ -622,6 +775,13 @@ public class ModelPackageImpl extends EPackageImpl implements ModelPackage */ private EClass brickletMultiTouchConfigurationEClass = null; + /** + * + * + * @generated + */ + private EClass dimmableConfigurationEClass = null; + /** * * @@ -860,6 +1020,13 @@ public class ModelPackageImpl extends EPackageImpl implements ModelPackage */ private EEnum dcDriveModeEEnum = null; + /** + * + * + * @generated + */ + private EEnum configOptsServoEEnum = null; + /** * * @@ -951,6 +1118,34 @@ public class ModelPackageImpl extends EPackageImpl implements ModelPackage */ private EEnum voltageCurrentSubIdsEEnum = null; + /** + * + * + * @generated + */ + private EEnum configOptsMoveEEnum = null; + + /** + * + * + * @generated + */ + private EEnum configOptsDimmableEEnum = null; + + /** + * + * + * @generated + */ + private EEnum configOptsSetPointEEnum = null; + + /** + * + * + * @generated + */ + private EEnum configOptsSwitchSpeedEEnum = null; + /** * * @@ -1147,6 +1342,27 @@ public class ModelPackageImpl extends EPackageImpl implements ModelPackage */ private EDataType tinkerBrickletLEDStripEDataType = null; + /** + * + * + * @generated + */ + private EDataType brickletJoystickEDataType = null; + + /** + * + * + * @generated + */ + private EDataType tinkerBrickletLinearPotiEDataType = null; + + /** + * + * + * @generated + */ + private EDataType tinkerBrickletDualButtonEDataType = null; + /** * * @@ -1154,6 +1370,20 @@ public class ModelPackageImpl extends EPackageImpl implements ModelPackage */ private EDataType hsbTypeEDataType = null; + /** + * + * + * @generated + */ + private EDataType upDownTypeEDataType = null; + + /** + * + * + * @generated + */ + private EDataType percentValueEDataType = null; + /** * * @@ -1161,6 +1391,27 @@ public class ModelPackageImpl extends EPackageImpl implements ModelPackage */ private EDataType deviceOptionsEDataType = null; + /** + * + * + * @generated + */ + private EDataType percentTypeEDataType = null; + + /** + * + * + * @generated + */ + private EDataType increaseDecreaseTypeEDataType = null; + + /** + * + * + * @generated + */ + private EDataType directionValueEDataType = null; + /** * * @@ -1800,7 +2051,337 @@ public EAttribute getMDevice_TinkerforgeDevice() */ public EAttribute getMDevice_IpConnection() { - return (EAttribute)mDeviceEClass.getEStructuralFeatures().get(1); + return (EAttribute)mDeviceEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EAttribute getMDevice_ConnectedUid() + { + return (EAttribute)mDeviceEClass.getEStructuralFeatures().get(2); + } + + /** + * + * + * @generated + */ + public EAttribute getMDevice_Position() + { + return (EAttribute)mDeviceEClass.getEStructuralFeatures().get(3); + } + + /** + * + * + * @generated + */ + public EAttribute getMDevice_DeviceIdentifier() + { + return (EAttribute)mDeviceEClass.getEStructuralFeatures().get(4); + } + + /** + * + * + * @generated + */ + public EAttribute getMDevice_Name() + { + return (EAttribute)mDeviceEClass.getEStructuralFeatures().get(5); + } + + /** + * + * + * @generated + */ + public EReference getMDevice_Brickd() + { + return (EReference)mDeviceEClass.getEStructuralFeatures().get(6); + } + + /** + * + * + * @generated + */ + public EClass getMSubDeviceHolder() + { + return mSubDeviceHolderEClass; + } + + /** + * + * + * @generated + */ + public EReference getMSubDeviceHolder_Msubdevices() + { + return (EReference)mSubDeviceHolderEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EOperation getMSubDeviceHolder__InitSubDevices() + { + return mSubDeviceHolderEClass.getEOperations().get(0); + } + + /** + * + * + * @generated + */ + public EClass getMBrickServo() + { + return mBrickServoEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getMBrickServo_DeviceType() + { + return (EAttribute)mBrickServoEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EOperation getMBrickServo__Init() + { + return mBrickServoEClass.getEOperations().get(0); + } + + /** + * + * + * @generated + */ + public EClass getTFBrickDCConfiguration() + { + return tfBrickDCConfigurationEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getTFBrickDCConfiguration_Velocity() + { + return (EAttribute)tfBrickDCConfigurationEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getTFBrickDCConfiguration_Acceleration() + { + return (EAttribute)tfBrickDCConfigurationEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EAttribute getTFBrickDCConfiguration_PwmFrequency() + { + return (EAttribute)tfBrickDCConfigurationEClass.getEStructuralFeatures().get(2); + } + + /** + * + * + * @generated + */ + public EAttribute getTFBrickDCConfiguration_DriveMode() + { + return (EAttribute)tfBrickDCConfigurationEClass.getEStructuralFeatures().get(3); + } + + /** + * + * + * @generated + */ + public EClass getMBrickDC() + { + return mBrickDCEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getMBrickDC_Threshold() + { + return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EAttribute getMBrickDC_MaxVelocity() + { + return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(2); + } + + /** + * + * + * @generated + */ + public EAttribute getMBrickDC_MinVelocity() + { + return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(3); + } + + /** + * + * + * @generated + */ + public EAttribute getMBrickDC_DeviceType() + { + return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getMBrickDC_Velocity() + { + return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(4); + } + + /** + * + * + * @generated + */ + public EAttribute getMBrickDC_Targetvelocity() + { + return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(5); + } + + /** + * + * + * @generated + */ + public EAttribute getMBrickDC_CurrentVelocity() + { + return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(6); + } + + /** + * + * + * @generated + */ + public EAttribute getMBrickDC_Acceleration() + { + return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(7); + } + + /** + * + * + * @generated + */ + public EAttribute getMBrickDC_PwmFrequency() + { + return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(8); + } + + /** + * + * + * @generated + */ + public EAttribute getMBrickDC_DriveMode() + { + return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(9); + } + + /** + * + * + * @generated + */ + public EOperation getMBrickDC__Init() + { + return mBrickDCEClass.getEOperations().get(0); + } + + /** + * + * + * @generated + */ + public EOperation getMBrickDC__SetSpeed__Short_int_String() + { + return mBrickDCEClass.getEOperations().get(1); + } + + /** + * + * + * @generated + */ + public EClass getMDualRelayBricklet() + { + return mDualRelayBrickletEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getMDualRelayBricklet_DeviceType() + { + return (EAttribute)mDualRelayBrickletEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getMIndustrialQuadRelayBricklet() + { + return mIndustrialQuadRelayBrickletEClass; + } + + /** + * + * + * @generated + */ + public EClass getMIndustrialQuadRelay() + { + return mIndustrialQuadRelayEClass; } /** @@ -1808,9 +2389,9 @@ public EAttribute getMDevice_IpConnection() * * @generated */ - public EAttribute getMDevice_ConnectedUid() + public EAttribute getMIndustrialQuadRelay_DeviceType() { - return (EAttribute)mDeviceEClass.getEStructuralFeatures().get(2); + return (EAttribute)mIndustrialQuadRelayEClass.getEStructuralFeatures().get(0); } /** @@ -1818,9 +2399,9 @@ public EAttribute getMDevice_ConnectedUid() * * @generated */ - public EAttribute getMDevice_Position() + public EClass getMBrickletIndustrialDigitalIn4() { - return (EAttribute)mDeviceEClass.getEStructuralFeatures().get(3); + return mBrickletIndustrialDigitalIn4EClass; } /** @@ -1828,9 +2409,9 @@ public EAttribute getMDevice_Position() * * @generated */ - public EAttribute getMDevice_DeviceIdentifier() + public EAttribute getMBrickletIndustrialDigitalIn4_DeviceType() { - return (EAttribute)mDeviceEClass.getEStructuralFeatures().get(4); + return (EAttribute)mBrickletIndustrialDigitalIn4EClass.getEStructuralFeatures().get(0); } /** @@ -1838,9 +2419,9 @@ public EAttribute getMDevice_DeviceIdentifier() * * @generated */ - public EAttribute getMDevice_Name() + public EClass getMIndustrialDigitalIn() { - return (EAttribute)mDeviceEClass.getEStructuralFeatures().get(5); + return mIndustrialDigitalInEClass; } /** @@ -1848,9 +2429,9 @@ public EAttribute getMDevice_Name() * * @generated */ - public EReference getMDevice_Brickd() + public EClass getMBrickletIndustrialDigitalOut4() { - return (EReference)mDeviceEClass.getEStructuralFeatures().get(6); + return mBrickletIndustrialDigitalOut4EClass; } /** @@ -1858,9 +2439,9 @@ public EReference getMDevice_Brickd() * * @generated */ - public EClass getMSubDeviceHolder() + public EClass getDigitalActorDigitalOut4() { - return mSubDeviceHolderEClass; + return digitalActorDigitalOut4EClass; } /** @@ -1868,9 +2449,9 @@ public EClass getMSubDeviceHolder() * * @generated */ - public EReference getMSubDeviceHolder_Msubdevices() + public EAttribute getDigitalActorDigitalOut4_Pin() { - return (EReference)mSubDeviceHolderEClass.getEStructuralFeatures().get(0); + return (EAttribute)digitalActorDigitalOut4EClass.getEStructuralFeatures().get(0); } /** @@ -1878,9 +2459,9 @@ public EReference getMSubDeviceHolder_Msubdevices() * * @generated */ - public EOperation getMSubDeviceHolder__InitSubDevices() + public EClass getDigitalActor() { - return mSubDeviceHolderEClass.getEOperations().get(0); + return digitalActorEClass; } /** @@ -1888,9 +2469,9 @@ public EOperation getMSubDeviceHolder__InitSubDevices() * * @generated */ - public EClass getMBrickServo() + public EAttribute getDigitalActor_DigitalState() { - return mBrickServoEClass; + return (EAttribute)digitalActorEClass.getEStructuralFeatures().get(0); } /** @@ -1898,9 +2479,9 @@ public EClass getMBrickServo() * * @generated */ - public EAttribute getMBrickServo_DeviceType() + public EOperation getDigitalActor__TurnDigital__HighLowValue() { - return (EAttribute)mBrickServoEClass.getEStructuralFeatures().get(0); + return digitalActorEClass.getEOperations().get(0); } /** @@ -1908,9 +2489,9 @@ public EAttribute getMBrickServo_DeviceType() * * @generated */ - public EOperation getMBrickServo__Init() + public EOperation getDigitalActor__FetchDigitalValue() { - return mBrickServoEClass.getEOperations().get(0); + return digitalActorEClass.getEOperations().get(1); } /** @@ -1918,9 +2499,9 @@ public EOperation getMBrickServo__Init() * * @generated */ - public EClass getTFBrickDCConfiguration() + public EClass getNumberActor() { - return tfBrickDCConfigurationEClass; + return numberActorEClass; } /** @@ -1928,9 +2509,9 @@ public EClass getTFBrickDCConfiguration() * * @generated */ - public EAttribute getTFBrickDCConfiguration_Velocity() + public EOperation getNumberActor__SetNumber__BigDecimal() { - return (EAttribute)tfBrickDCConfigurationEClass.getEStructuralFeatures().get(0); + return numberActorEClass.getEOperations().get(0); } /** @@ -1938,9 +2519,9 @@ public EAttribute getTFBrickDCConfiguration_Velocity() * * @generated */ - public EAttribute getTFBrickDCConfiguration_Acceleration() + public EClass getColorActor() { - return (EAttribute)tfBrickDCConfigurationEClass.getEStructuralFeatures().get(1); + return colorActorEClass; } /** @@ -1948,9 +2529,9 @@ public EAttribute getTFBrickDCConfiguration_Acceleration() * * @generated */ - public EAttribute getTFBrickDCConfiguration_PwmFrequency() + public EOperation getColorActor__SetColor__HSBType_DeviceOptions() { - return (EAttribute)tfBrickDCConfigurationEClass.getEStructuralFeatures().get(2); + return colorActorEClass.getEOperations().get(0); } /** @@ -1958,9 +2539,9 @@ public EAttribute getTFBrickDCConfiguration_PwmFrequency() * * @generated */ - public EAttribute getTFBrickDCConfiguration_DriveMode() + public EClass getMoveActor() { - return (EAttribute)tfBrickDCConfigurationEClass.getEStructuralFeatures().get(3); + return moveActorEClass; } /** @@ -1968,9 +2549,9 @@ public EAttribute getTFBrickDCConfiguration_DriveMode() * * @generated */ - public EAttribute getTFBrickDCConfiguration_SwitchOnVelocity() + public EAttribute getMoveActor_Direction() { - return (EAttribute)tfBrickDCConfigurationEClass.getEStructuralFeatures().get(4); + return (EAttribute)moveActorEClass.getEStructuralFeatures().get(0); } /** @@ -1978,9 +2559,9 @@ public EAttribute getTFBrickDCConfiguration_SwitchOnVelocity() * * @generated */ - public EClass getMBrickDC() + public EOperation getMoveActor__Move__UpDownType_DeviceOptions() { - return mBrickDCEClass; + return moveActorEClass.getEOperations().get(0); } /** @@ -1988,9 +2569,9 @@ public EClass getMBrickDC() * * @generated */ - public EAttribute getMBrickDC_DeviceType() + public EOperation getMoveActor__Stop() { - return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(0); + return moveActorEClass.getEOperations().get(1); } /** @@ -1998,9 +2579,9 @@ public EAttribute getMBrickDC_DeviceType() * * @generated */ - public EAttribute getMBrickDC_Velocity() + public EOperation getMoveActor__Moveon__DeviceOptions() { - return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(1); + return moveActorEClass.getEOperations().get(2); } /** @@ -2008,9 +2589,9 @@ public EAttribute getMBrickDC_Velocity() * * @generated */ - public EAttribute getMBrickDC_CurrentVelocity() + public EClass getDimmableActor() { - return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(2); + return dimmableActorEClass; } /** @@ -2018,9 +2599,9 @@ public EAttribute getMBrickDC_CurrentVelocity() * * @generated */ - public EAttribute getMBrickDC_Acceleration() + public EAttribute getDimmableActor_MinValue() { - return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(3); + return (EAttribute)dimmableActorEClass.getEStructuralFeatures().get(0); } /** @@ -2028,9 +2609,9 @@ public EAttribute getMBrickDC_Acceleration() * * @generated */ - public EAttribute getMBrickDC_PwmFrequency() + public EAttribute getDimmableActor_MaxValue() { - return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(4); + return (EAttribute)dimmableActorEClass.getEStructuralFeatures().get(1); } /** @@ -2038,9 +2619,9 @@ public EAttribute getMBrickDC_PwmFrequency() * * @generated */ - public EAttribute getMBrickDC_DriveMode() + public EOperation getDimmableActor__Dimm__IncreaseDecreaseType_DeviceOptions() { - return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(5); + return dimmableActorEClass.getEOperations().get(0); } /** @@ -2048,9 +2629,9 @@ public EAttribute getMBrickDC_DriveMode() * * @generated */ - public EAttribute getMBrickDC_SwitchOnVelocity() + public EClass getSetPointActor() { - return (EAttribute)mBrickDCEClass.getEStructuralFeatures().get(6); + return setPointActorEClass; } /** @@ -2058,9 +2639,9 @@ public EAttribute getMBrickDC_SwitchOnVelocity() * * @generated */ - public EOperation getMBrickDC__Init() + public EAttribute getSetPointActor_PercentValue() { - return mBrickDCEClass.getEOperations().get(0); + return (EAttribute)setPointActorEClass.getEStructuralFeatures().get(0); } /** @@ -2068,9 +2649,9 @@ public EOperation getMBrickDC__Init() * * @generated */ - public EClass getMDualRelayBricklet() + public EOperation getSetPointActor__SetValue__BigDecimal_DeviceOptions() { - return mDualRelayBrickletEClass; + return setPointActorEClass.getEOperations().get(0); } /** @@ -2078,9 +2659,9 @@ public EClass getMDualRelayBricklet() * * @generated */ - public EAttribute getMDualRelayBricklet_DeviceType() + public EOperation getSetPointActor__SetValue__PercentType_DeviceOptions() { - return (EAttribute)mDualRelayBrickletEClass.getEStructuralFeatures().get(0); + return setPointActorEClass.getEOperations().get(1); } /** @@ -2088,9 +2669,9 @@ public EAttribute getMDualRelayBricklet_DeviceType() * * @generated */ - public EClass getMIndustrialQuadRelayBricklet() + public EClass getMBrickletDualButton() { - return mIndustrialQuadRelayBrickletEClass; + return mBrickletDualButtonEClass; } /** @@ -2098,9 +2679,9 @@ public EClass getMIndustrialQuadRelayBricklet() * * @generated */ - public EClass getMIndustrialQuadRelay() + public EClass getDualButtonDevice() { - return mIndustrialQuadRelayEClass; + return dualButtonDeviceEClass; } /** @@ -2108,9 +2689,9 @@ public EClass getMIndustrialQuadRelay() * * @generated */ - public EAttribute getMIndustrialQuadRelay_DeviceType() + public EClass getDualButtonLeftButton() { - return (EAttribute)mIndustrialQuadRelayEClass.getEStructuralFeatures().get(0); + return dualButtonLeftButtonEClass; } /** @@ -2118,9 +2699,9 @@ public EAttribute getMIndustrialQuadRelay_DeviceType() * * @generated */ - public EClass getMBrickletIndustrialDigitalIn4() + public EClass getDualButtonRightButton() { - return mBrickletIndustrialDigitalIn4EClass; + return dualButtonRightButtonEClass; } /** @@ -2128,9 +2709,9 @@ public EClass getMBrickletIndustrialDigitalIn4() * * @generated */ - public EAttribute getMBrickletIndustrialDigitalIn4_DeviceType() + public EClass getDualButtonLeftLed() { - return (EAttribute)mBrickletIndustrialDigitalIn4EClass.getEStructuralFeatures().get(0); + return dualButtonLeftLedEClass; } /** @@ -2138,9 +2719,9 @@ public EAttribute getMBrickletIndustrialDigitalIn4_DeviceType() * * @generated */ - public EClass getMIndustrialDigitalIn() + public EClass getDualButtonRightLed() { - return mIndustrialDigitalInEClass; + return dualButtonRightLedEClass; } /** @@ -2148,9 +2729,9 @@ public EClass getMIndustrialDigitalIn() * * @generated */ - public EClass getMBrickletIndustrialDigitalOut4() + public EClass getMBrickletLinearPoti() { - return mBrickletIndustrialDigitalOut4EClass; + return mBrickletLinearPotiEClass; } /** @@ -2158,9 +2739,9 @@ public EClass getMBrickletIndustrialDigitalOut4() * * @generated */ - public EClass getDigitalActorDigitalOut4() + public EAttribute getMBrickletLinearPoti_DeviceType() { - return digitalActorDigitalOut4EClass; + return (EAttribute)mBrickletLinearPotiEClass.getEStructuralFeatures().get(0); } /** @@ -2168,9 +2749,9 @@ public EClass getDigitalActorDigitalOut4() * * @generated */ - public EAttribute getDigitalActorDigitalOut4_Pin() + public EClass getMBrickletJoystick() { - return (EAttribute)digitalActorDigitalOut4EClass.getEStructuralFeatures().get(0); + return mBrickletJoystickEClass; } /** @@ -2178,9 +2759,9 @@ public EAttribute getDigitalActorDigitalOut4_Pin() * * @generated */ - public EClass getDigitalActor() + public EAttribute getMBrickletJoystick_DeviceType() { - return digitalActorEClass; + return (EAttribute)mBrickletJoystickEClass.getEStructuralFeatures().get(0); } /** @@ -2188,9 +2769,9 @@ public EClass getDigitalActor() * * @generated */ - public EAttribute getDigitalActor_DigitalState() + public EClass getJoystickDevice() { - return (EAttribute)digitalActorEClass.getEStructuralFeatures().get(0); + return joystickDeviceEClass; } /** @@ -2198,9 +2779,9 @@ public EAttribute getDigitalActor_DigitalState() * * @generated */ - public EOperation getDigitalActor__TurnDigital__HighLowValue() + public EClass getJoystickXPosition() { - return digitalActorEClass.getEOperations().get(0); + return joystickXPositionEClass; } /** @@ -2208,9 +2789,9 @@ public EOperation getDigitalActor__TurnDigital__HighLowValue() * * @generated */ - public EOperation getDigitalActor__FetchDigitalValue() + public EAttribute getJoystickXPosition_DeviceType() { - return digitalActorEClass.getEOperations().get(1); + return (EAttribute)joystickXPositionEClass.getEStructuralFeatures().get(0); } /** @@ -2218,9 +2799,9 @@ public EOperation getDigitalActor__FetchDigitalValue() * * @generated */ - public EClass getNumberActor() + public EClass getJoystickYPosition() { - return numberActorEClass; + return joystickYPositionEClass; } /** @@ -2228,9 +2809,9 @@ public EClass getNumberActor() * * @generated */ - public EOperation getNumberActor__SetNumber__BigDecimal() + public EAttribute getJoystickYPosition_DeviceType() { - return numberActorEClass.getEOperations().get(0); + return (EAttribute)joystickYPositionEClass.getEStructuralFeatures().get(0); } /** @@ -2238,9 +2819,9 @@ public EOperation getNumberActor__SetNumber__BigDecimal() * * @generated */ - public EClass getColorActor() + public EClass getJoystickButton() { - return colorActorEClass; + return joystickButtonEClass; } /** @@ -2248,9 +2829,9 @@ public EClass getColorActor() * * @generated */ - public EOperation getColorActor__SetColor__HSBType_DeviceOptions() + public EAttribute getJoystickButton_DeviceType() { - return colorActorEClass.getEOperations().get(0); + return (EAttribute)joystickButtonEClass.getEStructuralFeatures().get(0); } /** @@ -2363,6 +2944,26 @@ public EClass getMActor() return mActorEClass; } + /** + * + * + * @generated + */ + public EClass getSwitchSensor() + { + return switchSensorEClass; + } + + /** + * + * + * @generated + */ + public EOperation getSwitchSensor__FetchSwitchState() + { + return switchSensorEClass.getEOperations().get(0); + } + /** * * @@ -2398,9 +2999,29 @@ public EOperation getMSwitchActor__TurnSwitch__OnOffValue() * * @generated */ - public EOperation getMSwitchActor__FetchSwitchState() + public EClass getProgrammableSwitchActor() + { + return programmableSwitchActorEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getProgrammableSwitchActor_SwitchState() { - return mSwitchActorEClass.getEOperations().get(1); + return (EAttribute)programmableSwitchActorEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EOperation getProgrammableSwitchActor__TurnSwitch__OnOffValue_DeviceOptions() + { + return programmableSwitchActorEClass.getEOperations().get(0); } /** @@ -3113,6 +3734,16 @@ public EAttribute getRemoteSwitchB_Repeats() return (EAttribute)remoteSwitchBEClass.getEStructuralFeatures().get(3); } + /** + * + * + * @generated + */ + public EAttribute getRemoteSwitchB_TargetDimmvalue() + { + return (EAttribute)remoteSwitchBEClass.getEStructuralFeatures().get(4); + } + /** * * @@ -3463,6 +4094,36 @@ public EAttribute getBrickletMultiTouchConfiguration_Sensitivity() return (EAttribute)brickletMultiTouchConfigurationEClass.getEStructuralFeatures().get(1); } + /** + * + * + * @generated + */ + public EClass getDimmableConfiguration() + { + return dimmableConfigurationEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getDimmableConfiguration_MinValue() + { + return (EAttribute)dimmableConfigurationEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getDimmableConfiguration_MaxValue() + { + return (EAttribute)dimmableConfigurationEClass.getEStructuralFeatures().get(1); + } + /** * * @@ -3508,7 +4169,7 @@ public EAttribute getMServo_Acceleration() * * @generated */ - public EAttribute getMServo_PulseWidthMin() + public EAttribute getMServo_MaxPosition() { return (EAttribute)mServoEClass.getEStructuralFeatures().get(3); } @@ -3518,7 +4179,7 @@ public EAttribute getMServo_PulseWidthMin() * * @generated */ - public EAttribute getMServo_PulseWidthMax() + public EAttribute getMServo_MinPosition() { return (EAttribute)mServoEClass.getEStructuralFeatures().get(4); } @@ -3528,7 +4189,7 @@ public EAttribute getMServo_PulseWidthMax() * * @generated */ - public EAttribute getMServo_Period() + public EAttribute getMServo_PulseWidthMin() { return (EAttribute)mServoEClass.getEStructuralFeatures().get(5); } @@ -3538,7 +4199,7 @@ public EAttribute getMServo_Period() * * @generated */ - public EAttribute getMServo_OutputVoltage() + public EAttribute getMServo_PulseWidthMax() { return (EAttribute)mServoEClass.getEStructuralFeatures().get(6); } @@ -3548,7 +4209,7 @@ public EAttribute getMServo_OutputVoltage() * * @generated */ - public EAttribute getMServo_ServoCurrentPosition() + public EAttribute getMServo_Period() { return (EAttribute)mServoEClass.getEStructuralFeatures().get(7); } @@ -3558,11 +4219,21 @@ public EAttribute getMServo_ServoCurrentPosition() * * @generated */ - public EAttribute getMServo_ServoDestinationPosition() + public EAttribute getMServo_OutputVoltage() { return (EAttribute)mServoEClass.getEStructuralFeatures().get(8); } + /** + * + * + * @generated + */ + public EAttribute getMServo_TargetPosition() + { + return (EAttribute)mServoEClass.getEStructuralFeatures().get(9); + } + /** * * @@ -3573,6 +4244,16 @@ public EOperation getMServo__Init() return mServoEClass.getEOperations().get(0); } + /** + * + * + * @generated + */ + public EOperation getMServo__SetPoint__Short_int_int() + { + return mServoEClass.getEOperations().get(1); + } + /** * * @@ -4473,6 +5154,16 @@ public EOperation getMBrickletLCD20x4__Init() return mBrickletLCD20x4EClass.getEOperations().get(0); } + /** + * + * + * @generated + */ + public EOperation getMBrickletLCD20x4__Clear() + { + return mBrickletLCD20x4EClass.getEOperations().get(1); + } + /** * * @@ -4593,6 +5284,16 @@ public EEnum getDCDriveMode() return dcDriveModeEEnum; } + /** + * + * + * @generated + */ + public EEnum getConfigOptsServo() + { + return configOptsServoEEnum; + } + /** * * @@ -4723,6 +5424,46 @@ public EEnum getVoltageCurrentSubIds() return voltageCurrentSubIdsEEnum; } + /** + * + * + * @generated + */ + public EEnum getConfigOptsMove() + { + return configOptsMoveEEnum; + } + + /** + * + * + * @generated + */ + public EEnum getConfigOptsDimmable() + { + return configOptsDimmableEEnum; + } + + /** + * + * + * @generated + */ + public EEnum getConfigOptsSetPoint() + { + return configOptsSetPointEEnum; + } + + /** + * + * + * @generated + */ + public EEnum getConfigOptsSwitchSpeed() + { + return configOptsSwitchSpeedEEnum; + } + /** * * @@ -5003,6 +5744,36 @@ public EDataType getTinkerBrickletLEDStrip() return tinkerBrickletLEDStripEDataType; } + /** + * + * + * @generated + */ + public EDataType getBrickletJoystick() + { + return brickletJoystickEDataType; + } + + /** + * + * + * @generated + */ + public EDataType getTinkerBrickletLinearPoti() + { + return tinkerBrickletLinearPotiEDataType; + } + + /** + * + * + * @generated + */ + public EDataType getTinkerBrickletDualButton() + { + return tinkerBrickletDualButtonEDataType; + } + /** * * @@ -5013,6 +5784,26 @@ public EDataType getHSBType() return hsbTypeEDataType; } + /** + * + * + * @generated + */ + public EDataType getUpDownType() + { + return upDownTypeEDataType; + } + + /** + * + * + * @generated + */ + public EDataType getPercentValue() + { + return percentValueEDataType; + } + /** * * @@ -5023,6 +5814,36 @@ public EDataType getDeviceOptions() return deviceOptionsEDataType; } + /** + * + * + * @generated + */ + public EDataType getPercentType() + { + return percentTypeEDataType; + } + + /** + * + * + * @generated + */ + public EDataType getIncreaseDecreaseType() + { + return increaseDecreaseTypeEDataType; + } + + /** + * + * + * @generated + */ + public EDataType getDirectionValue() + { + return directionValueEDataType; + } + /** * * @@ -5157,10 +5978,16 @@ public void createPackageContents() mActorEClass = createEClass(MACTOR); + switchSensorEClass = createEClass(SWITCH_SENSOR); + createEOperation(switchSensorEClass, SWITCH_SENSOR___FETCH_SWITCH_STATE); + mSwitchActorEClass = createEClass(MSWITCH_ACTOR); createEAttribute(mSwitchActorEClass, MSWITCH_ACTOR__SWITCH_STATE); createEOperation(mSwitchActorEClass, MSWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE); - createEOperation(mSwitchActorEClass, MSWITCH_ACTOR___FETCH_SWITCH_STATE); + + programmableSwitchActorEClass = createEClass(PROGRAMMABLE_SWITCH_ACTOR); + createEAttribute(programmableSwitchActorEClass, PROGRAMMABLE_SWITCH_ACTOR__SWITCH_STATE); + createEOperation(programmableSwitchActorEClass, PROGRAMMABLE_SWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE_DEVICEOPTIONS); mOutSwitchActorEClass = createEClass(MOUT_SWITCH_ACTOR); @@ -5190,6 +6017,62 @@ public void createPackageContents() mlcdSubDeviceEClass = createEClass(MLCD_SUB_DEVICE); + digitalActorEClass = createEClass(DIGITAL_ACTOR); + createEAttribute(digitalActorEClass, DIGITAL_ACTOR__DIGITAL_STATE); + createEOperation(digitalActorEClass, DIGITAL_ACTOR___TURN_DIGITAL__HIGHLOWVALUE); + createEOperation(digitalActorEClass, DIGITAL_ACTOR___FETCH_DIGITAL_VALUE); + + numberActorEClass = createEClass(NUMBER_ACTOR); + createEOperation(numberActorEClass, NUMBER_ACTOR___SET_NUMBER__BIGDECIMAL); + + colorActorEClass = createEClass(COLOR_ACTOR); + createEOperation(colorActorEClass, COLOR_ACTOR___SET_COLOR__HSBTYPE_DEVICEOPTIONS); + + moveActorEClass = createEClass(MOVE_ACTOR); + createEAttribute(moveActorEClass, MOVE_ACTOR__DIRECTION); + createEOperation(moveActorEClass, MOVE_ACTOR___MOVE__UPDOWNTYPE_DEVICEOPTIONS); + createEOperation(moveActorEClass, MOVE_ACTOR___STOP); + createEOperation(moveActorEClass, MOVE_ACTOR___MOVEON__DEVICEOPTIONS); + + dimmableActorEClass = createEClass(DIMMABLE_ACTOR); + createEAttribute(dimmableActorEClass, DIMMABLE_ACTOR__MIN_VALUE); + createEAttribute(dimmableActorEClass, DIMMABLE_ACTOR__MAX_VALUE); + createEOperation(dimmableActorEClass, DIMMABLE_ACTOR___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS); + + setPointActorEClass = createEClass(SET_POINT_ACTOR); + createEAttribute(setPointActorEClass, SET_POINT_ACTOR__PERCENT_VALUE); + createEOperation(setPointActorEClass, SET_POINT_ACTOR___SET_VALUE__BIGDECIMAL_DEVICEOPTIONS); + createEOperation(setPointActorEClass, SET_POINT_ACTOR___SET_VALUE__PERCENTTYPE_DEVICEOPTIONS); + + mBrickletDualButtonEClass = createEClass(MBRICKLET_DUAL_BUTTON); + + dualButtonDeviceEClass = createEClass(DUAL_BUTTON_DEVICE); + + dualButtonLeftButtonEClass = createEClass(DUAL_BUTTON_LEFT_BUTTON); + + dualButtonRightButtonEClass = createEClass(DUAL_BUTTON_RIGHT_BUTTON); + + dualButtonLeftLedEClass = createEClass(DUAL_BUTTON_LEFT_LED); + + dualButtonRightLedEClass = createEClass(DUAL_BUTTON_RIGHT_LED); + + mBrickletLinearPotiEClass = createEClass(MBRICKLET_LINEAR_POTI); + createEAttribute(mBrickletLinearPotiEClass, MBRICKLET_LINEAR_POTI__DEVICE_TYPE); + + mBrickletJoystickEClass = createEClass(MBRICKLET_JOYSTICK); + createEAttribute(mBrickletJoystickEClass, MBRICKLET_JOYSTICK__DEVICE_TYPE); + + joystickDeviceEClass = createEClass(JOYSTICK_DEVICE); + + joystickXPositionEClass = createEClass(JOYSTICK_XPOSITION); + createEAttribute(joystickXPositionEClass, JOYSTICK_XPOSITION__DEVICE_TYPE); + + joystickYPositionEClass = createEClass(JOYSTICK_YPOSITION); + createEAttribute(joystickYPositionEClass, JOYSTICK_YPOSITION__DEVICE_TYPE); + + joystickButtonEClass = createEClass(JOYSTICK_BUTTON); + createEAttribute(joystickButtonEClass, JOYSTICK_BUTTON__DEVICE_TYPE); + mBrickServoEClass = createEClass(MBRICK_SERVO); createEAttribute(mBrickServoEClass, MBRICK_SERVO__DEVICE_TYPE); createEOperation(mBrickServoEClass, MBRICK_SERVO___INIT); @@ -5198,23 +6081,29 @@ public void createPackageContents() createEAttribute(mServoEClass, MSERVO__DEVICE_TYPE); createEAttribute(mServoEClass, MSERVO__VELOCITY); createEAttribute(mServoEClass, MSERVO__ACCELERATION); + createEAttribute(mServoEClass, MSERVO__MAX_POSITION); + createEAttribute(mServoEClass, MSERVO__MIN_POSITION); createEAttribute(mServoEClass, MSERVO__PULSE_WIDTH_MIN); createEAttribute(mServoEClass, MSERVO__PULSE_WIDTH_MAX); createEAttribute(mServoEClass, MSERVO__PERIOD); createEAttribute(mServoEClass, MSERVO__OUTPUT_VOLTAGE); - createEAttribute(mServoEClass, MSERVO__SERVO_CURRENT_POSITION); - createEAttribute(mServoEClass, MSERVO__SERVO_DESTINATION_POSITION); + createEAttribute(mServoEClass, MSERVO__TARGET_POSITION); createEOperation(mServoEClass, MSERVO___INIT); + createEOperation(mServoEClass, MSERVO___SET_POINT__SHORT_INT_INT); mBrickDCEClass = createEClass(MBRICK_DC); createEAttribute(mBrickDCEClass, MBRICK_DC__DEVICE_TYPE); + createEAttribute(mBrickDCEClass, MBRICK_DC__THRESHOLD); + createEAttribute(mBrickDCEClass, MBRICK_DC__MAX_VELOCITY); + createEAttribute(mBrickDCEClass, MBRICK_DC__MIN_VELOCITY); createEAttribute(mBrickDCEClass, MBRICK_DC__VELOCITY); + createEAttribute(mBrickDCEClass, MBRICK_DC__TARGETVELOCITY); createEAttribute(mBrickDCEClass, MBRICK_DC__CURRENT_VELOCITY); createEAttribute(mBrickDCEClass, MBRICK_DC__ACCELERATION); createEAttribute(mBrickDCEClass, MBRICK_DC__PWM_FREQUENCY); createEAttribute(mBrickDCEClass, MBRICK_DC__DRIVE_MODE); - createEAttribute(mBrickDCEClass, MBRICK_DC__SWITCH_ON_VELOCITY); createEOperation(mBrickDCEClass, MBRICK_DC___INIT); + createEOperation(mBrickDCEClass, MBRICK_DC___SET_SPEED__SHORT_INT_STRING); mDualRelayBrickletEClass = createEClass(MDUAL_RELAY_BRICKLET); createEAttribute(mDualRelayBrickletEClass, MDUAL_RELAY_BRICKLET__DEVICE_TYPE); @@ -5234,19 +6123,8 @@ public void createPackageContents() digitalActorDigitalOut4EClass = createEClass(DIGITAL_ACTOR_DIGITAL_OUT4); createEAttribute(digitalActorDigitalOut4EClass, DIGITAL_ACTOR_DIGITAL_OUT4__PIN); - digitalActorEClass = createEClass(DIGITAL_ACTOR); - createEAttribute(digitalActorEClass, DIGITAL_ACTOR__DIGITAL_STATE); - createEOperation(digitalActorEClass, DIGITAL_ACTOR___TURN_DIGITAL__HIGHLOWVALUE); - createEOperation(digitalActorEClass, DIGITAL_ACTOR___FETCH_DIGITAL_VALUE); - - numberActorEClass = createEClass(NUMBER_ACTOR); - createEOperation(numberActorEClass, NUMBER_ACTOR___SET_NUMBER__BIGDECIMAL); - mBrickletSegmentDisplay4x7EClass = createEClass(MBRICKLET_SEGMENT_DISPLAY4X7); - colorActorEClass = createEClass(COLOR_ACTOR); - createEOperation(colorActorEClass, COLOR_ACTOR___SET_COLOR__HSBTYPE_DEVICEOPTIONS); - mBrickletLEDStripEClass = createEClass(MBRICKLET_LED_STRIP); digitalActorIO16EClass = createEClass(DIGITAL_ACTOR_IO16); @@ -5330,6 +6208,7 @@ public void createPackageContents() createEAttribute(remoteSwitchBEClass, REMOTE_SWITCH_B__ADDRESS); createEAttribute(remoteSwitchBEClass, REMOTE_SWITCH_B__UNIT); createEAttribute(remoteSwitchBEClass, REMOTE_SWITCH_B__REPEATS); + createEAttribute(remoteSwitchBEClass, REMOTE_SWITCH_B__TARGET_DIMMVALUE); remoteSwitchCEClass = createEClass(REMOTE_SWITCH_C); createEAttribute(remoteSwitchCEClass, REMOTE_SWITCH_C__DEVICE_TYPE); @@ -5426,6 +6305,7 @@ public void createPackageContents() createEAttribute(mBrickletLCD20x4EClass, MBRICKLET_LCD2_0X4__DISPLAY_ERRORS); createEAttribute(mBrickletLCD20x4EClass, MBRICKLET_LCD2_0X4__ERROR_PREFIX); createEOperation(mBrickletLCD20x4EClass, MBRICKLET_LCD2_0X4___INIT); + createEOperation(mBrickletLCD20x4EClass, MBRICKLET_LCD2_0X4___CLEAR); mlcd20x4BacklightEClass = createEClass(MLCD2_0X4_BACKLIGHT); createEAttribute(mlcd20x4BacklightEClass, MLCD2_0X4_BACKLIGHT__DEVICE_TYPE); @@ -5478,7 +6358,6 @@ public void createPackageContents() createEAttribute(tfBrickDCConfigurationEClass, TF_BRICK_DC_CONFIGURATION__ACCELERATION); createEAttribute(tfBrickDCConfigurationEClass, TF_BRICK_DC_CONFIGURATION__PWM_FREQUENCY); createEAttribute(tfBrickDCConfigurationEClass, TF_BRICK_DC_CONFIGURATION__DRIVE_MODE); - createEAttribute(tfBrickDCConfigurationEClass, TF_BRICK_DC_CONFIGURATION__SWITCH_ON_VELOCITY); tfioActorConfigurationEClass = createEClass(TFIO_ACTOR_CONFIGURATION); createEAttribute(tfioActorConfigurationEClass, TFIO_ACTOR_CONFIGURATION__DEFAULT_STATE); @@ -5526,8 +6405,11 @@ public void createPackageContents() createEAttribute(brickletMultiTouchConfigurationEClass, BRICKLET_MULTI_TOUCH_CONFIGURATION__RECALIBRATE); createEAttribute(brickletMultiTouchConfigurationEClass, BRICKLET_MULTI_TOUCH_CONFIGURATION__SENSITIVITY); + dimmableConfigurationEClass = createEClass(DIMMABLE_CONFIGURATION); + createEAttribute(dimmableConfigurationEClass, DIMMABLE_CONFIGURATION__MIN_VALUE); + createEAttribute(dimmableConfigurationEClass, DIMMABLE_CONFIGURATION__MAX_VALUE); + // Create enums - dcDriveModeEEnum = createEEnum(DC_DRIVE_MODE); noSubIdsEEnum = createEEnum(NO_SUB_IDS); industrialDigitalInSubIDsEEnum = createEEnum(INDUSTRIAL_DIGITAL_IN_SUB_IDS); industrialQuadRelayIDsEEnum = createEEnum(INDUSTRIAL_QUAD_RELAY_IDS); @@ -5541,6 +6423,12 @@ public void createPackageContents() multiTouchSubIdsEEnum = createEEnum(MULTI_TOUCH_SUB_IDS); temperatureIRSubIdsEEnum = createEEnum(TEMPERATURE_IR_SUB_IDS); voltageCurrentSubIdsEEnum = createEEnum(VOLTAGE_CURRENT_SUB_IDS); + configOptsMoveEEnum = createEEnum(CONFIG_OPTS_MOVE); + configOptsDimmableEEnum = createEEnum(CONFIG_OPTS_DIMMABLE); + configOptsSetPointEEnum = createEEnum(CONFIG_OPTS_SET_POINT); + configOptsSwitchSpeedEEnum = createEEnum(CONFIG_OPTS_SWITCH_SPEED); + dcDriveModeEEnum = createEEnum(DC_DRIVE_MODE); + configOptsServoEEnum = createEEnum(CONFIG_OPTS_SERVO); // Create data types mipConnectionEDataType = createEDataType(MIP_CONNECTION); @@ -5578,8 +6466,16 @@ public void createPackageContents() tinkerBrickletHallEffectEDataType = createEDataType(TINKER_BRICKLET_HALL_EFFECT); tinkerBrickletSegmentDisplay4x7EDataType = createEDataType(TINKER_BRICKLET_SEGMENT_DISPLAY4X7); tinkerBrickletLEDStripEDataType = createEDataType(TINKER_BRICKLET_LED_STRIP); + brickletJoystickEDataType = createEDataType(BRICKLET_JOYSTICK); + tinkerBrickletLinearPotiEDataType = createEDataType(TINKER_BRICKLET_LINEAR_POTI); + tinkerBrickletDualButtonEDataType = createEDataType(TINKER_BRICKLET_DUAL_BUTTON); hsbTypeEDataType = createEDataType(HSB_TYPE); + upDownTypeEDataType = createEDataType(UP_DOWN_TYPE); + percentValueEDataType = createEDataType(PERCENT_VALUE); deviceOptionsEDataType = createEDataType(DEVICE_OPTIONS); + percentTypeEDataType = createEDataType(PERCENT_TYPE); + increaseDecreaseTypeEDataType = createEDataType(INCREASE_DECREASE_TYPE); + directionValueEDataType = createEDataType(DIRECTION_VALUE); enumEDataType = createEDataType(ENUM); } @@ -5616,6 +6512,8 @@ public void initializePackageContents() ETypeParameter mSubDeviceHolderEClass_S = addETypeParameter(mSubDeviceHolderEClass, "S"); ETypeParameter mSubDeviceEClass_B = addETypeParameter(mSubDeviceEClass, "B"); ETypeParameter mSensorEClass_DeviceValue = addETypeParameter(mSensorEClass, "DeviceValue"); + ETypeParameter dimmableActorEClass_TC = addETypeParameter(dimmableActorEClass, "TC"); + ETypeParameter setPointActorEClass_C = addETypeParameter(setPointActorEClass, "C"); ETypeParameter ohtfDeviceEClass_TFC = addETypeParameter(ohtfDeviceEClass, "TFC"); ETypeParameter ohtfDeviceEClass_IDS = addETypeParameter(ohtfDeviceEClass, "IDS"); ETypeParameter ohtfSubDeviceAdminDeviceEClass_TFC = addETypeParameter(ohtfSubDeviceAdminDeviceEClass, "TFC"); @@ -5634,6 +6532,10 @@ public void initializePackageContents() mSubDeviceEClass_B.getEBounds().add(g1); g1 = createEGenericType(this.getMTinkerforgeValue()); mSensorEClass_DeviceValue.getEBounds().add(g1); + g1 = createEGenericType(this.getDimmableConfiguration()); + dimmableActorEClass_TC.getEBounds().add(g1); + g1 = createEGenericType(this.getDimmableConfiguration()); + setPointActorEClass_C.getEBounds().add(g1); g1 = createEGenericType(this.getTFConfig()); ohtfDeviceEClass_TFC.getEBounds().add(g1); g1 = createEGenericType(this.getEnum()); @@ -5645,6 +6547,8 @@ public void initializePackageContents() // Add supertypes to classes mDeviceEClass.getESuperTypes().add(this.getMBaseDevice()); + mSwitchActorEClass.getESuperTypes().add(this.getSwitchSensor()); + programmableSwitchActorEClass.getESuperTypes().add(this.getSwitchSensor()); mOutSwitchActorEClass.getESuperTypes().add(this.getMSwitchActor()); mInSwitchActorEClass.getESuperTypes().add(this.getMSwitchActor()); g1 = createEGenericType(this.getMSubDevice()); @@ -5658,6 +6562,92 @@ public void initializePackageContents() g2 = createEGenericType(this.getMBrickletLCD20x4()); g1.getETypeArguments().add(g2); mlcdSubDeviceEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMTFConfigConsumer()); + g2 = createEGenericType(dimmableActorEClass_TC); + g1.getETypeArguments().add(g2); + dimmableActorEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getDimmableActor()); + g2 = createEGenericType(setPointActorEClass_C); + g1.getETypeArguments().add(g2); + setPointActorEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMDevice()); + g2 = createEGenericType(this.getTinkerBrickletDualButton()); + g1.getETypeArguments().add(g2); + mBrickletDualButtonEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMSubDeviceHolder()); + g2 = createEGenericType(this.getDualButtonDevice()); + g1.getETypeArguments().add(g2); + mBrickletDualButtonEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMSubDevice()); + g2 = createEGenericType(this.getMBrickletDualButton()); + g1.getETypeArguments().add(g2); + dualButtonDeviceEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getDualButtonDevice()); + dualButtonLeftButtonEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMSensor()); + g2 = createEGenericType(this.getDigitalValue()); + g1.getETypeArguments().add(g2); + dualButtonLeftButtonEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getDualButtonDevice()); + dualButtonRightButtonEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMSensor()); + g2 = createEGenericType(this.getDigitalValue()); + g1.getETypeArguments().add(g2); + dualButtonRightButtonEClass.getEGenericSuperTypes().add(g1); + dualButtonLeftLedEClass.getESuperTypes().add(this.getDualButtonDevice()); + dualButtonLeftLedEClass.getESuperTypes().add(this.getDigitalActor()); + dualButtonRightLedEClass.getESuperTypes().add(this.getDualButtonDevice()); + dualButtonRightLedEClass.getESuperTypes().add(this.getDigitalActor()); + g1 = createEGenericType(this.getMDevice()); + g2 = createEGenericType(this.getTinkerBrickletLinearPoti()); + g1.getETypeArguments().add(g2); + mBrickletLinearPotiEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getCallbackListener()); + mBrickletLinearPotiEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMTFConfigConsumer()); + g2 = createEGenericType(this.getTFBaseConfiguration()); + g1.getETypeArguments().add(g2); + mBrickletLinearPotiEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMSensor()); + g2 = createEGenericType(this.getMDecimalValue()); + g1.getETypeArguments().add(g2); + mBrickletLinearPotiEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMDevice()); + g2 = createEGenericType(this.getBrickletJoystick()); + g1.getETypeArguments().add(g2); + mBrickletJoystickEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMSubDeviceHolder()); + g2 = createEGenericType(this.getJoystickDevice()); + g1.getETypeArguments().add(g2); + mBrickletJoystickEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getCallbackListener()); + mBrickletJoystickEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMTFConfigConsumer()); + g2 = createEGenericType(this.getTFBaseConfiguration()); + g1.getETypeArguments().add(g2); + mBrickletJoystickEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMSubDevice()); + g2 = createEGenericType(this.getMBrickletJoystick()); + g1.getETypeArguments().add(g2); + joystickDeviceEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getJoystickDevice()); + joystickXPositionEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMSensor()); + g2 = createEGenericType(this.getMDecimalValue()); + g1.getETypeArguments().add(g2); + joystickXPositionEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getJoystickDevice()); + joystickYPositionEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMSensor()); + g2 = createEGenericType(this.getMDecimalValue()); + g1.getETypeArguments().add(g2); + joystickYPositionEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getJoystickDevice()); + joystickButtonEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMSensor()); + g2 = createEGenericType(this.getDigitalValue()); + g1.getETypeArguments().add(g2); + joystickButtonEClass.getEGenericSuperTypes().add(g1); g1 = createEGenericType(this.getMDevice()); g2 = createEGenericType(this.getMTinkerBrickServo()); g1.getETypeArguments().add(g2); @@ -5666,26 +6656,40 @@ public void initializePackageContents() g2 = createEGenericType(this.getMServo()); g1.getETypeArguments().add(g2); mBrickServoEClass.getEGenericSuperTypes().add(g1); - g1 = createEGenericType(this.getMInSwitchActor()); + g1 = createEGenericType(this.getMSensor()); + g2 = createEGenericType(this.getMDecimalValue()); + g1.getETypeArguments().add(g2); + mServoEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getProgrammableSwitchActor()); mServoEClass.getEGenericSuperTypes().add(g1); g1 = createEGenericType(this.getMSubDevice()); g2 = createEGenericType(this.getMBrickServo()); g1.getETypeArguments().add(g2); mServoEClass.getEGenericSuperTypes().add(g1); - g1 = createEGenericType(this.getMTFConfigConsumer()); + g1 = createEGenericType(this.getMoveActor()); + mServoEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getSetPointActor()); g2 = createEGenericType(this.getTFServoConfiguration()); g1.getETypeArguments().add(g2); mServoEClass.getEGenericSuperTypes().add(g1); - g1 = createEGenericType(this.getMInSwitchActor()); + g1 = createEGenericType(this.getMSensor()); + g2 = createEGenericType(this.getMDecimalValue()); + g1.getETypeArguments().add(g2); + mBrickDCEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getProgrammableSwitchActor()); mBrickDCEClass.getEGenericSuperTypes().add(g1); g1 = createEGenericType(this.getMDevice()); g2 = createEGenericType(this.getMTinkerBrickDC()); g1.getETypeArguments().add(g2); mBrickDCEClass.getEGenericSuperTypes().add(g1); - g1 = createEGenericType(this.getMTFConfigConsumer()); + g1 = createEGenericType(this.getMoveActor()); + mBrickDCEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getSetPointActor()); g2 = createEGenericType(this.getTFBrickDCConfiguration()); g1.getETypeArguments().add(g2); mBrickDCEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getCallbackListener()); + mBrickDCEClass.getEGenericSuperTypes().add(g1); g1 = createEGenericType(this.getMDevice()); g2 = createEGenericType(this.getMTinkerBrickletDualRelay()); g1.getETypeArguments().add(g2); @@ -5906,9 +6910,13 @@ public void initializePackageContents() g2 = createEGenericType(this.getRemoteSwitchAConfiguration()); g1.getETypeArguments().add(g2); remoteSwitchAEClass.getEGenericSuperTypes().add(g1); + g1 = createEGenericType(this.getMSensor()); + g2 = createEGenericType(this.getMDecimalValue()); + g1.getETypeArguments().add(g2); + remoteSwitchBEClass.getEGenericSuperTypes().add(g1); g1 = createEGenericType(this.getRemoteSwitch()); remoteSwitchBEClass.getEGenericSuperTypes().add(g1); - g1 = createEGenericType(this.getMTFConfigConsumer()); + g1 = createEGenericType(this.getDimmableActor()); g2 = createEGenericType(this.getRemoteSwitchBConfiguration()); g1.getETypeArguments().add(g2); remoteSwitchBEClass.getEGenericSuperTypes().add(g1); @@ -6136,17 +7144,19 @@ public void initializePackageContents() tfMoistureBrickletConfigurationEClass.getESuperTypes().add(this.getTFBaseConfiguration()); tfDistanceUSBrickletConfigurationEClass.getESuperTypes().add(this.getTFBaseConfiguration()); tfVoltageCurrentConfigurationEClass.getESuperTypes().add(this.getTFConfig()); - tfBrickDCConfigurationEClass.getESuperTypes().add(this.getTFConfig()); + tfBrickDCConfigurationEClass.getESuperTypes().add(this.getDimmableConfiguration()); + tfBrickDCConfigurationEClass.getESuperTypes().add(this.getTFBaseConfiguration()); tfioActorConfigurationEClass.getESuperTypes().add(this.getTFConfig()); tfInterruptListenerConfigurationEClass.getESuperTypes().add(this.getTFConfig()); tfioSensorConfigurationEClass.getESuperTypes().add(this.getTFConfig()); - tfServoConfigurationEClass.getESuperTypes().add(this.getTFConfig()); + tfServoConfigurationEClass.getESuperTypes().add(this.getDimmableConfiguration()); brickletRemoteSwitchConfigurationEClass.getESuperTypes().add(this.getTFConfig()); remoteSwitchAConfigurationEClass.getESuperTypes().add(this.getTFConfig()); - remoteSwitchBConfigurationEClass.getESuperTypes().add(this.getTFConfig()); + remoteSwitchBConfigurationEClass.getESuperTypes().add(this.getDimmableConfiguration()); remoteSwitchCConfigurationEClass.getESuperTypes().add(this.getTFConfig()); multiTouchDeviceConfigurationEClass.getESuperTypes().add(this.getTFConfig()); brickletMultiTouchConfigurationEClass.getESuperTypes().add(this.getTFConfig()); + dimmableConfigurationEClass.getESuperTypes().add(this.getTFConfig()); // Initialize classes, features, and operations; add parameters initEClass(ecosystemEClass, Ecosystem.class, "Ecosystem", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); @@ -6235,13 +7245,22 @@ public void initializePackageContents() initEClass(mActorEClass, MActor.class, "MActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEClass(switchSensorEClass, SwitchSensor.class, "SwitchSensor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEOperation(getSwitchSensor__FetchSwitchState(), null, "fetchSwitchState", 0, 1, !IS_UNIQUE, IS_ORDERED); + initEClass(mSwitchActorEClass, MSwitchActor.class, "MSwitchActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getMSwitchActor_SwitchState(), this.getSwitchState(), "switchState", null, 0, 1, MSwitchActor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); op = initEOperation(getMSwitchActor__TurnSwitch__OnOffValue(), null, "turnSwitch", 0, 1, !IS_UNIQUE, IS_ORDERED); addEParameter(op, this.getSwitchState(), "state", 0, 1, !IS_UNIQUE, IS_ORDERED); - initEOperation(getMSwitchActor__FetchSwitchState(), null, "fetchSwitchState", 0, 1, !IS_UNIQUE, IS_ORDERED); + initEClass(programmableSwitchActorEClass, ProgrammableSwitchActor.class, "ProgrammableSwitchActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getProgrammableSwitchActor_SwitchState(), this.getSwitchState(), "switchState", null, 0, 1, ProgrammableSwitchActor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + op = initEOperation(getProgrammableSwitchActor__TurnSwitch__OnOffValue_DeviceOptions(), null, "turnSwitch", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getSwitchState(), "state", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getDeviceOptions(), "opts", 0, 1, !IS_UNIQUE, IS_ORDERED); initEClass(mOutSwitchActorEClass, MOutSwitchActor.class, "MOutSwitchActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); @@ -6274,6 +7293,85 @@ public void initializePackageContents() initEClass(mlcdSubDeviceEClass, MLCDSubDevice.class, "MLCDSubDevice", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEClass(digitalActorEClass, DigitalActor.class, "DigitalActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getDigitalActor_DigitalState(), this.getDigitalValue(), "digitalState", null, 0, 1, DigitalActor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + op = initEOperation(getDigitalActor__TurnDigital__HighLowValue(), null, "turnDigital", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getDigitalValue(), "digitalState", 0, 1, !IS_UNIQUE, IS_ORDERED); + + initEOperation(getDigitalActor__FetchDigitalValue(), null, "fetchDigitalValue", 0, 1, !IS_UNIQUE, IS_ORDERED); + + initEClass(numberActorEClass, NumberActor.class, "NumberActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + op = initEOperation(getNumberActor__SetNumber__BigDecimal(), null, "setNumber", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, theEcorePackage.getEBigDecimal(), "value", 0, 1, !IS_UNIQUE, IS_ORDERED); + + initEClass(colorActorEClass, ColorActor.class, "ColorActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + op = initEOperation(getColorActor__SetColor__HSBType_DeviceOptions(), null, "setColor", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getHSBType(), "color", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getDeviceOptions(), "opts", 0, 1, !IS_UNIQUE, IS_ORDERED); + + initEClass(moveActorEClass, MoveActor.class, "MoveActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getMoveActor_Direction(), this.getDirectionValue(), "direction", null, 0, 1, MoveActor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + op = initEOperation(getMoveActor__Move__UpDownType_DeviceOptions(), null, "move", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getUpDownType(), "direction", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getDeviceOptions(), "opts", 0, 1, !IS_UNIQUE, IS_ORDERED); + + initEOperation(getMoveActor__Stop(), null, "stop", 0, 1, !IS_UNIQUE, IS_ORDERED); + + op = initEOperation(getMoveActor__Moveon__DeviceOptions(), null, "moveon", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getDeviceOptions(), "opts", 0, 1, !IS_UNIQUE, IS_ORDERED); + + initEClass(dimmableActorEClass, DimmableActor.class, "DimmableActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getDimmableActor_MinValue(), theEcorePackage.getEBigDecimal(), "minValue", null, 0, 1, DimmableActor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getDimmableActor_MaxValue(), theEcorePackage.getEBigDecimal(), "maxValue", null, 0, 1, DimmableActor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + op = initEOperation(getDimmableActor__Dimm__IncreaseDecreaseType_DeviceOptions(), null, "dimm", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getIncreaseDecreaseType(), "increaseDecrease", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getDeviceOptions(), "opts", 0, 1, !IS_UNIQUE, IS_ORDERED); + + initEClass(setPointActorEClass, SetPointActor.class, "SetPointActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getSetPointActor_PercentValue(), this.getPercentValue(), "percentValue", null, 0, 1, SetPointActor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + op = initEOperation(getSetPointActor__SetValue__BigDecimal_DeviceOptions(), null, "setValue", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, theEcorePackage.getEBigDecimal(), "newValue", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getDeviceOptions(), "opts", 0, 1, !IS_UNIQUE, IS_ORDERED); + + op = initEOperation(getSetPointActor__SetValue__PercentType_DeviceOptions(), null, "setValue", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getPercentType(), "newValue", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, this.getDeviceOptions(), "opts", 0, 1, !IS_UNIQUE, IS_ORDERED); + + initEClass(mBrickletDualButtonEClass, MBrickletDualButton.class, "MBrickletDualButton", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(dualButtonDeviceEClass, DualButtonDevice.class, "DualButtonDevice", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(dualButtonLeftButtonEClass, DualButtonLeftButton.class, "DualButtonLeftButton", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(dualButtonRightButtonEClass, DualButtonRightButton.class, "DualButtonRightButton", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(dualButtonLeftLedEClass, DualButtonLeftLed.class, "DualButtonLeftLed", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(dualButtonRightLedEClass, DualButtonRightLed.class, "DualButtonRightLed", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(mBrickletLinearPotiEClass, MBrickletLinearPoti.class, "MBrickletLinearPoti", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getMBrickletLinearPoti_DeviceType(), theEcorePackage.getEString(), "deviceType", "bricklet_linear_poti", 0, 1, MBrickletLinearPoti.class, !IS_TRANSIENT, !IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(mBrickletJoystickEClass, MBrickletJoystick.class, "MBrickletJoystick", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getMBrickletJoystick_DeviceType(), theEcorePackage.getEString(), "deviceType", "bricklet_joystick", 0, 1, MBrickletJoystick.class, !IS_TRANSIENT, !IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(joystickDeviceEClass, JoystickDevice.class, "JoystickDevice", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(joystickXPositionEClass, JoystickXPosition.class, "JoystickXPosition", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getJoystickXPosition_DeviceType(), theEcorePackage.getEString(), "deviceType", "joystick_xposition", 0, 1, JoystickXPosition.class, !IS_TRANSIENT, !IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(joystickYPositionEClass, JoystickYPosition.class, "JoystickYPosition", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getJoystickYPosition_DeviceType(), theEcorePackage.getEString(), "deviceType", "joystick_yposition", 0, 1, JoystickYPosition.class, !IS_TRANSIENT, !IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(joystickButtonEClass, JoystickButton.class, "JoystickButton", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getJoystickButton_DeviceType(), theEcorePackage.getEString(), "deviceType", "joystick_button", 0, 1, JoystickButton.class, !IS_TRANSIENT, !IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEClass(mBrickServoEClass, MBrickServo.class, "MBrickServo", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getMBrickServo_DeviceType(), theEcorePackage.getEString(), "deviceType", "brick_servo", 0, 1, MBrickServo.class, !IS_TRANSIENT, !IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); @@ -6281,28 +7379,42 @@ public void initializePackageContents() initEClass(mServoEClass, MServo.class, "MServo", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getMServo_DeviceType(), theEcorePackage.getEString(), "deviceType", "servo", 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - initEAttribute(getMServo_Velocity(), theEcorePackage.getEInt(), "velocity", "30000", 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - initEAttribute(getMServo_Acceleration(), theEcorePackage.getEInt(), "acceleration", "30000", 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getMServo_Velocity(), theEcorePackage.getEInt(), "velocity", "65535", 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getMServo_Acceleration(), theEcorePackage.getEInt(), "acceleration", "65535", 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getMServo_MaxPosition(), theEcorePackage.getEShortObject(), "maxPosition", "9000", 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getMServo_MinPosition(), theEcorePackage.getEShortObject(), "minPosition", "-9000", 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getMServo_PulseWidthMin(), theEcorePackage.getEInt(), "pulseWidthMin", "1000", 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getMServo_PulseWidthMax(), theEcorePackage.getEInt(), "pulseWidthMax", "2000", 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getMServo_Period(), theEcorePackage.getEInt(), "period", "19500", 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getMServo_OutputVoltage(), theEcorePackage.getEInt(), "outputVoltage", "5000", 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - initEAttribute(getMServo_ServoCurrentPosition(), theEcorePackage.getEShort(), "servoCurrentPosition", null, 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - initEAttribute(getMServo_ServoDestinationPosition(), theEcorePackage.getEShort(), "servoDestinationPosition", null, 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getMServo_TargetPosition(), theEcorePackage.getEShort(), "targetPosition", null, 0, 1, MServo.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEOperation(getMServo__Init(), null, "init", 0, 1, !IS_UNIQUE, IS_ORDERED); + op = initEOperation(getMServo__SetPoint__Short_int_int(), theEcorePackage.getEBoolean(), "setPoint", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, theEcorePackage.getEShortObject(), "position", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, theEcorePackage.getEInt(), "velocity", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, theEcorePackage.getEInt(), "acceleration", 0, 1, !IS_UNIQUE, IS_ORDERED); + initEClass(mBrickDCEClass, MBrickDC.class, "MBrickDC", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getMBrickDC_DeviceType(), theEcorePackage.getEString(), "deviceType", "brick_dc", 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getMBrickDC_Threshold(), theEcorePackage.getEBigDecimal(), "threshold", "10", 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getMBrickDC_MaxVelocity(), theEcorePackage.getEShortObject(), "maxVelocity", "32767", 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getMBrickDC_MinVelocity(), theEcorePackage.getEShortObject(), "minVelocity", "-32767", 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getMBrickDC_Velocity(), theEcorePackage.getEShort(), "velocity", null, 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getMBrickDC_Targetvelocity(), theEcorePackage.getEShort(), "targetvelocity", "0", 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getMBrickDC_CurrentVelocity(), theEcorePackage.getEShort(), "currentVelocity", null, 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getMBrickDC_Acceleration(), theEcorePackage.getEInt(), "acceleration", "10000", 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getMBrickDC_PwmFrequency(), theEcorePackage.getEInt(), "pwmFrequency", "15000", 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - initEAttribute(getMBrickDC_DriveMode(), this.getDCDriveMode(), "driveMode", "Break", 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - initEAttribute(getMBrickDC_SwitchOnVelocity(), theEcorePackage.getEShort(), "switchOnVelocity", "10000", 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getMBrickDC_DriveMode(), this.getDCDriveMode(), "driveMode", "BRAKE", 0, 1, MBrickDC.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEOperation(getMBrickDC__Init(), null, "init", 0, 1, !IS_UNIQUE, IS_ORDERED); + op = initEOperation(getMBrickDC__SetSpeed__Short_int_String(), theEcorePackage.getEBoolean(), "setSpeed", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, theEcorePackage.getEShortObject(), "velocity", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, theEcorePackage.getEInt(), "acceleration", 0, 1, !IS_UNIQUE, IS_ORDERED); + addEParameter(op, theEcorePackage.getEString(), "drivemode", 0, 1, !IS_UNIQUE, IS_ORDERED); + initEClass(mDualRelayBrickletEClass, MDualRelayBricklet.class, "MDualRelayBricklet", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getMDualRelayBricklet_DeviceType(), theEcorePackage.getEString(), "deviceType", "bricklet_dual_relay", 0, 1, MDualRelayBricklet.class, !IS_TRANSIENT, !IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); @@ -6321,27 +7433,8 @@ public void initializePackageContents() initEClass(digitalActorDigitalOut4EClass, DigitalActorDigitalOut4.class, "DigitalActorDigitalOut4", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getDigitalActorDigitalOut4_Pin(), theEcorePackage.getEInt(), "pin", null, 0, 1, DigitalActorDigitalOut4.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - initEClass(digitalActorEClass, DigitalActor.class, "DigitalActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); - initEAttribute(getDigitalActor_DigitalState(), this.getDigitalValue(), "digitalState", null, 0, 1, DigitalActor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - - op = initEOperation(getDigitalActor__TurnDigital__HighLowValue(), null, "turnDigital", 0, 1, !IS_UNIQUE, IS_ORDERED); - addEParameter(op, this.getDigitalValue(), "digitalState", 0, 1, !IS_UNIQUE, IS_ORDERED); - - initEOperation(getDigitalActor__FetchDigitalValue(), null, "fetchDigitalValue", 0, 1, !IS_UNIQUE, IS_ORDERED); - - initEClass(numberActorEClass, NumberActor.class, "NumberActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); - - op = initEOperation(getNumberActor__SetNumber__BigDecimal(), null, "setNumber", 0, 1, !IS_UNIQUE, IS_ORDERED); - addEParameter(op, theEcorePackage.getEBigDecimal(), "value", 0, 1, !IS_UNIQUE, IS_ORDERED); - initEClass(mBrickletSegmentDisplay4x7EClass, MBrickletSegmentDisplay4x7.class, "MBrickletSegmentDisplay4x7", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); - initEClass(colorActorEClass, ColorActor.class, "ColorActor", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); - - op = initEOperation(getColorActor__SetColor__HSBType_DeviceOptions(), null, "setColor", 0, 1, !IS_UNIQUE, IS_ORDERED); - addEParameter(op, this.getHSBType(), "color", 0, 1, !IS_UNIQUE, IS_ORDERED); - addEParameter(op, this.getDeviceOptions(), "opts", 0, 1, !IS_UNIQUE, IS_ORDERED); - initEClass(mBrickletLEDStripEClass, MBrickletLEDStrip.class, "MBrickletLEDStrip", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEClass(digitalActorIO16EClass, DigitalActorIO16.class, "DigitalActorIO16", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); @@ -6433,6 +7526,7 @@ public void initializePackageContents() initEAttribute(getRemoteSwitchB_Address(), theEcorePackage.getELongObject(), "address", null, 0, 1, RemoteSwitchB.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getRemoteSwitchB_Unit(), theEcorePackage.getEShortObject(), "unit", null, 0, 1, RemoteSwitchB.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getRemoteSwitchB_Repeats(), theEcorePackage.getEShortObject(), "repeats", null, 0, 1, RemoteSwitchB.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getRemoteSwitchB_TargetDimmvalue(), theEcorePackage.getEShortObject(), "targetDimmvalue", "0", 0, 1, RemoteSwitchB.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEClass(remoteSwitchCEClass, RemoteSwitchC.class, "RemoteSwitchC", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getRemoteSwitchC_DeviceType(), theEcorePackage.getEString(), "deviceType", "remote_switch_c", 0, 1, RemoteSwitchC.class, !IS_TRANSIENT, !IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); @@ -6540,6 +7634,8 @@ public void initializePackageContents() initEOperation(getMBrickletLCD20x4__Init(), null, "init", 0, 1, !IS_UNIQUE, IS_ORDERED); + initEOperation(getMBrickletLCD20x4__Clear(), theEcorePackage.getEBoolean(), "clear", 0, 1, !IS_UNIQUE, IS_ORDERED); + initEClass(mlcd20x4BacklightEClass, MLCD20x4Backlight.class, "MLCD20x4Backlight", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getMLCD20x4Backlight_DeviceType(), theEcorePackage.getEString(), "deviceType", "backlight", 0, 1, MLCD20x4Backlight.class, !IS_TRANSIENT, !IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); @@ -6618,8 +7714,7 @@ public void initializePackageContents() initEAttribute(getTFBrickDCConfiguration_Velocity(), theEcorePackage.getEShort(), "velocity", null, 0, 1, TFBrickDCConfiguration.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getTFBrickDCConfiguration_Acceleration(), theEcorePackage.getEInt(), "acceleration", null, 0, 1, TFBrickDCConfiguration.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getTFBrickDCConfiguration_PwmFrequency(), theEcorePackage.getEInt(), "pwmFrequency", null, 0, 1, TFBrickDCConfiguration.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - initEAttribute(getTFBrickDCConfiguration_DriveMode(), theEcorePackage.getEInt(), "driveMode", null, 0, 1, TFBrickDCConfiguration.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - initEAttribute(getTFBrickDCConfiguration_SwitchOnVelocity(), theEcorePackage.getEShort(), "switchOnVelocity", null, 0, 1, TFBrickDCConfiguration.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getTFBrickDCConfiguration_DriveMode(), theEcorePackage.getEString(), "driveMode", null, 0, 1, TFBrickDCConfiguration.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEClass(tfioActorConfigurationEClass, TFIOActorConfiguration.class, "TFIOActorConfiguration", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getTFIOActorConfiguration_DefaultState(), theEcorePackage.getEString(), "defaultState", null, 0, 1, TFIOActorConfiguration.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); @@ -6667,11 +7762,11 @@ public void initializePackageContents() initEAttribute(getBrickletMultiTouchConfiguration_Recalibrate(), theEcorePackage.getEBooleanObject(), "recalibrate", null, 0, 1, BrickletMultiTouchConfiguration.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getBrickletMultiTouchConfiguration_Sensitivity(), theEcorePackage.getEShortObject(), "sensitivity", null, 0, 1, BrickletMultiTouchConfiguration.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - // Initialize enums and add enum literals - initEEnum(dcDriveModeEEnum, DCDriveMode.class, "DCDriveMode"); - addEEnumLiteral(dcDriveModeEEnum, DCDriveMode.BRAKE); - addEEnumLiteral(dcDriveModeEEnum, DCDriveMode.COAST); + initEClass(dimmableConfigurationEClass, DimmableConfiguration.class, "DimmableConfiguration", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getDimmableConfiguration_MinValue(), theEcorePackage.getEBigDecimal(), "minValue", null, 0, 1, DimmableConfiguration.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getDimmableConfiguration_MaxValue(), theEcorePackage.getEBigDecimal(), "maxValue", null, 0, 1, DimmableConfiguration.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + // Initialize enums and add enum literals initEEnum(noSubIdsEEnum, NoSubIds.class, "NoSubIds"); initEEnum(industrialDigitalInSubIDsEEnum, IndustrialDigitalInSubIDs.class, "IndustrialDigitalInSubIDs"); @@ -6779,6 +7874,39 @@ public void initializePackageContents() addEEnumLiteral(voltageCurrentSubIdsEEnum, VoltageCurrentSubIds.VOLTAGECURRENT_CURRENT); addEEnumLiteral(voltageCurrentSubIdsEEnum, VoltageCurrentSubIds.VOLTAGECURRENT_POWER); + initEEnum(configOptsMoveEEnum, ConfigOptsMove.class, "ConfigOptsMove"); + addEEnumLiteral(configOptsMoveEEnum, ConfigOptsMove.RIGHTSPEED); + addEEnumLiteral(configOptsMoveEEnum, ConfigOptsMove.LEFTSPEED); + addEEnumLiteral(configOptsMoveEEnum, ConfigOptsMove.ACCELERATION); + addEEnumLiteral(configOptsMoveEEnum, ConfigOptsMove.DRIVEMODE); + addEEnumLiteral(configOptsMoveEEnum, ConfigOptsMove.PWM); + + initEEnum(configOptsDimmableEEnum, ConfigOptsDimmable.class, "ConfigOptsDimmable"); + addEEnumLiteral(configOptsDimmableEEnum, ConfigOptsDimmable.MAX); + addEEnumLiteral(configOptsDimmableEEnum, ConfigOptsDimmable.MIN); + addEEnumLiteral(configOptsDimmableEEnum, ConfigOptsDimmable.STEP); + + initEEnum(configOptsSetPointEEnum, ConfigOptsSetPoint.class, "ConfigOptsSetPoint"); + addEEnumLiteral(configOptsSetPointEEnum, ConfigOptsSetPoint.MAX); + addEEnumLiteral(configOptsSetPointEEnum, ConfigOptsSetPoint.MIN); + + initEEnum(configOptsSwitchSpeedEEnum, ConfigOptsSwitchSpeed.class, "ConfigOptsSwitchSpeed"); + addEEnumLiteral(configOptsSwitchSpeedEEnum, ConfigOptsSwitchSpeed.SPEED); + + initEEnum(dcDriveModeEEnum, DCDriveMode.class, "DCDriveMode"); + addEEnumLiteral(dcDriveModeEEnum, DCDriveMode.BRAKE); + addEEnumLiteral(dcDriveModeEEnum, DCDriveMode.COAST); + + initEEnum(configOptsServoEEnum, ConfigOptsServo.class, "ConfigOptsServo"); + addEEnumLiteral(configOptsServoEEnum, ConfigOptsServo.VELOCITY); + addEEnumLiteral(configOptsServoEEnum, ConfigOptsServo.ACCELERATION); + addEEnumLiteral(configOptsServoEEnum, ConfigOptsServo.PULSEWIDTHMIN); + addEEnumLiteral(configOptsServoEEnum, ConfigOptsServo.PULSEWIDTHMAX); + addEEnumLiteral(configOptsServoEEnum, ConfigOptsServo.PERIOD); + addEEnumLiteral(configOptsServoEEnum, ConfigOptsServo.POSITION); + addEEnumLiteral(configOptsServoEEnum, ConfigOptsServo.LEFTPOSITION); + addEEnumLiteral(configOptsServoEEnum, ConfigOptsServo.RIGHTPOSITION); + // Initialize data types initEDataType(mipConnectionEDataType, IPConnection.class, "MIPConnection", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); initEDataType(mTinkerDeviceEDataType, Device.class, "MTinkerDevice", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); @@ -6815,8 +7943,16 @@ public void initializePackageContents() initEDataType(tinkerBrickletHallEffectEDataType, BrickletHallEffect.class, "TinkerBrickletHallEffect", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); initEDataType(tinkerBrickletSegmentDisplay4x7EDataType, BrickletSegmentDisplay4x7.class, "TinkerBrickletSegmentDisplay4x7", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); initEDataType(tinkerBrickletLEDStripEDataType, BrickletLEDStrip.class, "TinkerBrickletLEDStrip", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(brickletJoystickEDataType, BrickletJoystick.class, "BrickletJoystick", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(tinkerBrickletLinearPotiEDataType, BrickletLinearPoti.class, "TinkerBrickletLinearPoti", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(tinkerBrickletDualButtonEDataType, BrickletDualButton.class, "TinkerBrickletDualButton", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); initEDataType(hsbTypeEDataType, HSBType.class, "HSBType", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(upDownTypeEDataType, UpDownType.class, "UpDownType", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(percentValueEDataType, PercentValue.class, "PercentValue", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); initEDataType(deviceOptionsEDataType, DeviceOptions.class, "DeviceOptions", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(percentTypeEDataType, PercentType.class, "PercentType", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(increaseDecreaseTypeEDataType, IncreaseDecreaseType.class, "IncreaseDecreaseType", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(directionValueEDataType, DirectionValue.class, "DirectionValue", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); initEDataType(enumEDataType, Enum.class, "Enum", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); // Create resource diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/RemoteSwitchBConfigurationImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/RemoteSwitchBConfigurationImpl.java index 42d6e489053..f06a0f69846 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/RemoteSwitchBConfigurationImpl.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/RemoteSwitchBConfigurationImpl.java @@ -35,7 +35,7 @@ * * @generated */ -public class RemoteSwitchBConfigurationImpl extends MinimalEObjectImpl.Container implements RemoteSwitchBConfiguration +public class RemoteSwitchBConfigurationImpl extends DimmableConfigurationImpl implements RemoteSwitchBConfiguration { /** * The default value of the '{@link #getAddress() Address}' attribute. diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/RemoteSwitchBImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/RemoteSwitchBImpl.java index 35d081cb170..0d8d38ad984 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/RemoteSwitchBImpl.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/RemoteSwitchBImpl.java @@ -9,6 +9,7 @@ package org.openhab.binding.tinkerforge.internal.model.impl; import java.lang.reflect.InvocationTargetException; +import java.math.BigDecimal; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.emf.common.notify.Notification; @@ -21,15 +22,25 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.openhab.binding.tinkerforge.internal.LoggerConstants; import org.openhab.binding.tinkerforge.internal.TinkerforgeErrorHandler; +import org.openhab.binding.tinkerforge.internal.config.DeviceOptions; +import org.openhab.binding.tinkerforge.internal.model.ConfigOptsDimmable; +import org.openhab.binding.tinkerforge.internal.model.DimmableActor; import org.openhab.binding.tinkerforge.internal.model.MBaseDevice; import org.openhab.binding.tinkerforge.internal.model.MBrickletRemoteSwitch; +import org.openhab.binding.tinkerforge.internal.model.MInSwitchActor; import org.openhab.binding.tinkerforge.internal.model.MSubDevice; import org.openhab.binding.tinkerforge.internal.model.MSubDeviceHolder; +import org.openhab.binding.tinkerforge.internal.model.MSwitchActor; import org.openhab.binding.tinkerforge.internal.model.MTFConfigConsumer; import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.model.RemoteSwitch; import org.openhab.binding.tinkerforge.internal.model.RemoteSwitchB; import org.openhab.binding.tinkerforge.internal.model.RemoteSwitchBConfiguration; +import org.openhab.binding.tinkerforge.internal.model.SwitchSensor; +import org.openhab.binding.tinkerforge.internal.tools.Tools; +import org.openhab.binding.tinkerforge.internal.types.DecimalValue; import org.openhab.binding.tinkerforge.internal.types.OnOffValue; +import org.openhab.core.library.types.IncreaseDecreaseType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,6 +58,7 @@ *

      * The following features are implemented: *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getSensorValue Sensor Value}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getSwitchState Switch State}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getLogger Logger}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getUid Uid}
      • @@ -55,10 +67,13 @@ *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getSubId Sub Id}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getMbrick Mbrick}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getTfConfig Tf Config}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getMinValue Min Value}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getMaxValue Max Value}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getDeviceType Device Type}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getAddress Address}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getUnit Unit}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getRepeats Repeats}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.RemoteSwitchBImpl#getTargetDimmvalue Target Dimmvalue}
      • *
      *

      * @@ -66,6 +81,16 @@ */ public class RemoteSwitchBImpl extends MinimalEObjectImpl.Container implements RemoteSwitchB { + /** + * The cached value of the '{@link #getSensorValue() Sensor Value}' attribute. + * + * + * @see #getSensorValue() + * @generated + * @ordered + */ + protected DecimalValue sensorValue; + /** * The default value of the '{@link #getSwitchState() Switch State}' attribute. * @@ -196,6 +221,46 @@ public class RemoteSwitchBImpl extends MinimalEObjectImpl.Container implements R */ protected RemoteSwitchBConfiguration tfConfig; + /** + * The default value of the '{@link #getMinValue() Min Value}' attribute. + * + * + * @see #getMinValue() + * @generated + * @ordered + */ + protected static final BigDecimal MIN_VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getMinValue() Min Value}' attribute. + * + * + * @see #getMinValue() + * @generated + * @ordered + */ + protected BigDecimal minValue = MIN_VALUE_EDEFAULT; + + /** + * The default value of the '{@link #getMaxValue() Max Value}' attribute. + * + * + * @see #getMaxValue() + * @generated + * @ordered + */ + protected static final BigDecimal MAX_VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getMaxValue() Max Value}' attribute. + * + * + * @see #getMaxValue() + * @generated + * @ordered + */ + protected BigDecimal maxValue = MAX_VALUE_EDEFAULT; + /** * The default value of the '{@link #getDeviceType() Device Type}' attribute. * @@ -276,6 +341,26 @@ public class RemoteSwitchBImpl extends MinimalEObjectImpl.Container implements R */ protected Short repeats = REPEATS_EDEFAULT; + /** + * The default value of the '{@link #getTargetDimmvalue() Target Dimmvalue}' attribute. + * + * + * @see #getTargetDimmvalue() + * @generated + * @ordered + */ + protected static final Short TARGET_DIMMVALUE_EDEFAULT = new Short((short)0); + + /** + * The cached value of the '{@link #getTargetDimmvalue() Target Dimmvalue}' attribute. + * + * + * @see #getTargetDimmvalue() + * @generated + * @ordered + */ + protected Short targetDimmvalue = TARGET_DIMMVALUE_EDEFAULT; + /** * * @@ -297,6 +382,29 @@ protected EClass eStaticClass() return ModelPackage.Literals.REMOTE_SWITCH_B; } + /** + * + * + * @generated + */ + public DecimalValue getSensorValue() + { + return sensorValue; + } + + /** + * + * + * @generated + */ + public void setSensorValue(DecimalValue newSensorValue) + { + DecimalValue oldSensorValue = sensorValue; + sensorValue = newSensorValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.REMOTE_SWITCH_B__SENSOR_VALUE, oldSensorValue, sensorValue)); + } + /** * * @@ -559,6 +667,30 @@ public void setRepeats(Short newRepeats) eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.REMOTE_SWITCH_B__REPEATS, oldRepeats, repeats)); } + /** + * + * + * @generated + */ + public Short getTargetDimmvalue() + { + return targetDimmvalue; + } + + /** + * + * + * @generated + */ + public void setTargetDimmvalue(Short newTargetDimmvalue) + { + Short oldTargetDimmvalue = targetDimmvalue; + targetDimmvalue = newTargetDimmvalue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.REMOTE_SWITCH_B__TARGET_DIMMVALUE, oldTargetDimmvalue, targetDimmvalue)); + } + + /** * * @@ -607,6 +739,52 @@ else if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.REMOTE_SWITCH_B__TF_CONFIG, newTfConfig, newTfConfig)); } + /** + * + * + * @generated + */ + public BigDecimal getMinValue() + { + return minValue; + } + + /** + * + * + * @generated + */ + public void setMinValue(BigDecimal newMinValue) + { + BigDecimal oldMinValue = minValue; + minValue = newMinValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.REMOTE_SWITCH_B__MIN_VALUE, oldMinValue, minValue)); + } + + /** + * + * + * @generated + */ + public BigDecimal getMaxValue() + { + return maxValue; + } + + /** + * + * + * @generated + */ + public void setMaxValue(BigDecimal newMaxValue) + { + BigDecimal oldMaxValue = maxValue; + maxValue = newMaxValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.REMOTE_SWITCH_B__MAX_VALUE, oldMaxValue, maxValue)); + } + /** * * @@ -696,6 +874,81 @@ public void turnSwitch(OnOffValue state) } } + /** + * + * + * @generated NOT + */ + public void dimm(IncreaseDecreaseType increaseDecrease, DeviceOptions opts) { + logger.trace("dimmer increase increaseDecrease {} opts {}", increaseDecrease, opts); + if (opts == null) { + logger.error("options are missing"); + return; + } + if (increaseDecrease == null) { + logger.error("increaseDecrease may not be null!"); + return; + } + Short step = Tools.getShortOpt(ConfigOptsDimmable.STEP.toString(), opts); + if (step == null) { + logger.error("dimmer option step is missing, items configuration has to be fixed!"); + return; + } + Short max = Tools.getShortOpt(ConfigOptsDimmable.MAX.toString(), opts); + if (max == null) { + max = 15; + } + logger.debug("max {}", max); + + Short min = Tools.getShortOpt(ConfigOptsDimmable.MIN.toString(), opts); + if (min == null) { + min = 0; + } + logger.debug("min {}", min); + Short newDimmValue = null; + if (increaseDecrease.equals(IncreaseDecreaseType.INCREASE)) { + newDimmValue = (short) (this.targetDimmvalue + step); + } else if (increaseDecrease.equals(IncreaseDecreaseType.DECREASE)) { + newDimmValue = (short) (this.targetDimmvalue - step); + } + if (newDimmValue > max) { + if (targetDimmvalue < max) { + newDimmValue = max; + } else { + logger.trace("max dim value already reached"); + return; + } + } else if (newDimmValue < min) { + if (targetDimmvalue > min) { + newDimmValue = min; + } else { + logger.trace("min dim value already reached"); + return; + } + } + OnOffValue state = newDimmValue == 0 ? OnOffValue.OFF : OnOffValue.ON; + logger.debug("newDimmValue {}", newDimmValue); + if (getAddress() != null && getUnit() != null) { + try { + if (getRepeats() != null) { + getMbrick().getTinkerforgeDevice().setRepeats(getRepeats()); + } + getMbrick().getTinkerforgeDevice().dimSocketB(getAddress(), getUnit(), newDimmValue); + setSwitchState(state); + setSensorValue(new DecimalValue(newDimmValue)); + targetDimmvalue = newDimmValue; + } catch (TimeoutException e) { + TinkerforgeErrorHandler.handleError(this, TinkerforgeErrorHandler.TF_TIMEOUT_EXCEPTION, e); + } catch (NotConnectedException e) { + TinkerforgeErrorHandler.handleError(this, + TinkerforgeErrorHandler.TF_NOT_CONNECTION_EXCEPTION, e); + } + } else { + logger.error("{} missing configuration for subid {} device will not switch", + LoggerConstants.TFINITSUB, getSubId()); + } + } + /** * * @@ -703,6 +956,16 @@ public void turnSwitch(OnOffValue state) */ public void fetchSwitchState() {} + /** + * + * + * @generated NOT + */ + public void fetchSensorValue() + { + setSensorValue(new DecimalValue(this.targetDimmvalue)); + } + /** * * @@ -765,6 +1028,8 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { + case ModelPackage.REMOTE_SWITCH_B__SENSOR_VALUE: + return getSensorValue(); case ModelPackage.REMOTE_SWITCH_B__SWITCH_STATE: return getSwitchState(); case ModelPackage.REMOTE_SWITCH_B__LOGGER: @@ -781,6 +1046,10 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) return getMbrick(); case ModelPackage.REMOTE_SWITCH_B__TF_CONFIG: return getTfConfig(); + case ModelPackage.REMOTE_SWITCH_B__MIN_VALUE: + return getMinValue(); + case ModelPackage.REMOTE_SWITCH_B__MAX_VALUE: + return getMaxValue(); case ModelPackage.REMOTE_SWITCH_B__DEVICE_TYPE: return getDeviceType(); case ModelPackage.REMOTE_SWITCH_B__ADDRESS: @@ -789,6 +1058,8 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) return getUnit(); case ModelPackage.REMOTE_SWITCH_B__REPEATS: return getRepeats(); + case ModelPackage.REMOTE_SWITCH_B__TARGET_DIMMVALUE: + return getTargetDimmvalue(); } return super.eGet(featureID, resolve, coreType); } @@ -803,6 +1074,9 @@ public void eSet(int featureID, Object newValue) { switch (featureID) { + case ModelPackage.REMOTE_SWITCH_B__SENSOR_VALUE: + setSensorValue((DecimalValue)newValue); + return; case ModelPackage.REMOTE_SWITCH_B__SWITCH_STATE: setSwitchState((OnOffValue)newValue); return; @@ -827,6 +1101,12 @@ public void eSet(int featureID, Object newValue) case ModelPackage.REMOTE_SWITCH_B__TF_CONFIG: setTfConfig((RemoteSwitchBConfiguration)newValue); return; + case ModelPackage.REMOTE_SWITCH_B__MIN_VALUE: + setMinValue((BigDecimal)newValue); + return; + case ModelPackage.REMOTE_SWITCH_B__MAX_VALUE: + setMaxValue((BigDecimal)newValue); + return; case ModelPackage.REMOTE_SWITCH_B__ADDRESS: setAddress((Long)newValue); return; @@ -836,6 +1116,9 @@ public void eSet(int featureID, Object newValue) case ModelPackage.REMOTE_SWITCH_B__REPEATS: setRepeats((Short)newValue); return; + case ModelPackage.REMOTE_SWITCH_B__TARGET_DIMMVALUE: + setTargetDimmvalue((Short)newValue); + return; } super.eSet(featureID, newValue); } @@ -850,6 +1133,9 @@ public void eUnset(int featureID) { switch (featureID) { + case ModelPackage.REMOTE_SWITCH_B__SENSOR_VALUE: + setSensorValue((DecimalValue)null); + return; case ModelPackage.REMOTE_SWITCH_B__SWITCH_STATE: setSwitchState(SWITCH_STATE_EDEFAULT); return; @@ -874,6 +1160,12 @@ public void eUnset(int featureID) case ModelPackage.REMOTE_SWITCH_B__TF_CONFIG: setTfConfig((RemoteSwitchBConfiguration)null); return; + case ModelPackage.REMOTE_SWITCH_B__MIN_VALUE: + setMinValue(MIN_VALUE_EDEFAULT); + return; + case ModelPackage.REMOTE_SWITCH_B__MAX_VALUE: + setMaxValue(MAX_VALUE_EDEFAULT); + return; case ModelPackage.REMOTE_SWITCH_B__ADDRESS: setAddress(ADDRESS_EDEFAULT); return; @@ -883,6 +1175,9 @@ public void eUnset(int featureID) case ModelPackage.REMOTE_SWITCH_B__REPEATS: setRepeats(REPEATS_EDEFAULT); return; + case ModelPackage.REMOTE_SWITCH_B__TARGET_DIMMVALUE: + setTargetDimmvalue(TARGET_DIMMVALUE_EDEFAULT); + return; } super.eUnset(featureID); } @@ -897,6 +1192,8 @@ public boolean eIsSet(int featureID) { switch (featureID) { + case ModelPackage.REMOTE_SWITCH_B__SENSOR_VALUE: + return sensorValue != null; case ModelPackage.REMOTE_SWITCH_B__SWITCH_STATE: return SWITCH_STATE_EDEFAULT == null ? switchState != null : !SWITCH_STATE_EDEFAULT.equals(switchState); case ModelPackage.REMOTE_SWITCH_B__LOGGER: @@ -913,6 +1210,10 @@ public boolean eIsSet(int featureID) return getMbrick() != null; case ModelPackage.REMOTE_SWITCH_B__TF_CONFIG: return tfConfig != null; + case ModelPackage.REMOTE_SWITCH_B__MIN_VALUE: + return MIN_VALUE_EDEFAULT == null ? minValue != null : !MIN_VALUE_EDEFAULT.equals(minValue); + case ModelPackage.REMOTE_SWITCH_B__MAX_VALUE: + return MAX_VALUE_EDEFAULT == null ? maxValue != null : !MAX_VALUE_EDEFAULT.equals(maxValue); case ModelPackage.REMOTE_SWITCH_B__DEVICE_TYPE: return DEVICE_TYPE_EDEFAULT == null ? deviceType != null : !DEVICE_TYPE_EDEFAULT.equals(deviceType); case ModelPackage.REMOTE_SWITCH_B__ADDRESS: @@ -921,6 +1222,8 @@ public boolean eIsSet(int featureID) return UNIT_EDEFAULT == null ? unit != null : !UNIT_EDEFAULT.equals(unit); case ModelPackage.REMOTE_SWITCH_B__REPEATS: return REPEATS_EDEFAULT == null ? repeats != null : !REPEATS_EDEFAULT.equals(repeats); + case ModelPackage.REMOTE_SWITCH_B__TARGET_DIMMVALUE: + return TARGET_DIMMVALUE_EDEFAULT == null ? targetDimmvalue != null : !TARGET_DIMMVALUE_EDEFAULT.equals(targetDimmvalue); } return super.eIsSet(featureID); } @@ -933,6 +1236,28 @@ public boolean eIsSet(int featureID) @Override public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) { + if (baseClass == SwitchSensor.class) + { + switch (derivedFeatureID) + { + default: return -1; + } + } + if (baseClass == MSwitchActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.REMOTE_SWITCH_B__SWITCH_STATE: return ModelPackage.MSWITCH_ACTOR__SWITCH_STATE; + default: return -1; + } + } + if (baseClass == MInSwitchActor.class) + { + switch (derivedFeatureID) + { + default: return -1; + } + } if (baseClass == MBaseDevice.class) { switch (derivedFeatureID) @@ -953,6 +1278,13 @@ public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) default: return -1; } } + if (baseClass == RemoteSwitch.class) + { + switch (derivedFeatureID) + { + default: return -1; + } + } if (baseClass == MTFConfigConsumer.class) { switch (derivedFeatureID) @@ -961,6 +1293,15 @@ public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) default: return -1; } } + if (baseClass == DimmableActor.class) + { + switch (derivedFeatureID) + { + case ModelPackage.REMOTE_SWITCH_B__MIN_VALUE: return ModelPackage.DIMMABLE_ACTOR__MIN_VALUE; + case ModelPackage.REMOTE_SWITCH_B__MAX_VALUE: return ModelPackage.DIMMABLE_ACTOR__MAX_VALUE; + default: return -1; + } + } return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); } @@ -972,6 +1313,28 @@ public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) @Override public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) { + if (baseClass == SwitchSensor.class) + { + switch (baseFeatureID) + { + default: return -1; + } + } + if (baseClass == MSwitchActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.MSWITCH_ACTOR__SWITCH_STATE: return ModelPackage.REMOTE_SWITCH_B__SWITCH_STATE; + default: return -1; + } + } + if (baseClass == MInSwitchActor.class) + { + switch (baseFeatureID) + { + default: return -1; + } + } if (baseClass == MBaseDevice.class) { switch (baseFeatureID) @@ -992,6 +1355,13 @@ public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) default: return -1; } } + if (baseClass == RemoteSwitch.class) + { + switch (baseFeatureID) + { + default: return -1; + } + } if (baseClass == MTFConfigConsumer.class) { switch (baseFeatureID) @@ -1000,6 +1370,15 @@ public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) default: return -1; } } + if (baseClass == DimmableActor.class) + { + switch (baseFeatureID) + { + case ModelPackage.DIMMABLE_ACTOR__MIN_VALUE: return ModelPackage.REMOTE_SWITCH_B__MIN_VALUE; + case ModelPackage.DIMMABLE_ACTOR__MAX_VALUE: return ModelPackage.REMOTE_SWITCH_B__MAX_VALUE; + default: return -1; + } + } return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); } @@ -1011,6 +1390,29 @@ public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) @Override public int eDerivedOperationID(int baseOperationID, Class baseClass) { + if (baseClass == SwitchSensor.class) + { + switch (baseOperationID) + { + case ModelPackage.SWITCH_SENSOR___FETCH_SWITCH_STATE: return ModelPackage.REMOTE_SWITCH_B___FETCH_SWITCH_STATE; + default: return -1; + } + } + if (baseClass == MSwitchActor.class) + { + switch (baseOperationID) + { + case ModelPackage.MSWITCH_ACTOR___TURN_SWITCH__ONOFFVALUE: return ModelPackage.REMOTE_SWITCH_B___TURN_SWITCH__ONOFFVALUE; + default: return -1; + } + } + if (baseClass == MInSwitchActor.class) + { + switch (baseOperationID) + { + default: return -1; + } + } if (baseClass == MBaseDevice.class) { switch (baseOperationID) @@ -1028,6 +1430,13 @@ public int eDerivedOperationID(int baseOperationID, Class baseClass) default: return -1; } } + if (baseClass == RemoteSwitch.class) + { + switch (baseOperationID) + { + default: return -1; + } + } if (baseClass == MTFConfigConsumer.class) { switch (baseOperationID) @@ -1035,6 +1444,14 @@ public int eDerivedOperationID(int baseOperationID, Class baseClass) default: return -1; } } + if (baseClass == DimmableActor.class) + { + switch (baseOperationID) + { + case ModelPackage.DIMMABLE_ACTOR___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS: return ModelPackage.REMOTE_SWITCH_B___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS; + default: return -1; + } + } return super.eDerivedOperationID(baseOperationID, baseClass); } @@ -1048,6 +1465,9 @@ public Object eInvoke(int operationID, EList arguments) throws InvocationTarg { switch (operationID) { + case ModelPackage.REMOTE_SWITCH_B___DIMM__INCREASEDECREASETYPE_DEVICEOPTIONS: + dimm((IncreaseDecreaseType)arguments.get(0), (DeviceOptions)arguments.get(1)); + return null; case ModelPackage.REMOTE_SWITCH_B___INIT: init(); return null; @@ -1063,6 +1483,9 @@ public Object eInvoke(int operationID, EList arguments) throws InvocationTarg case ModelPackage.REMOTE_SWITCH_B___FETCH_SWITCH_STATE: fetchSwitchState(); return null; + case ModelPackage.REMOTE_SWITCH_B___FETCH_SENSOR_VALUE: + fetchSensorValue(); + return null; } return super.eInvoke(operationID, arguments); } @@ -1078,7 +1501,9 @@ public String toString() if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); - result.append(" (switchState: "); + result.append(" (sensorValue: "); + result.append(sensorValue); + result.append(", switchState: "); result.append(switchState); result.append(", logger: "); result.append(logger); @@ -1090,6 +1515,10 @@ public String toString() result.append(enabledA); result.append(", subId: "); result.append(subId); + result.append(", minValue: "); + result.append(minValue); + result.append(", maxValue: "); + result.append(maxValue); result.append(", deviceType: "); result.append(deviceType); result.append(", address: "); @@ -1098,6 +1527,8 @@ public String toString() result.append(unit); result.append(", repeats: "); result.append(repeats); + result.append(", targetDimmvalue: "); + result.append(targetDimmvalue); result.append(')'); return result.toString(); } diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/TFBrickDCConfigurationImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/TFBrickDCConfigurationImpl.java index 4669b2c91f2..4b234df0e81 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/TFBrickDCConfigurationImpl.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/TFBrickDCConfigurationImpl.java @@ -8,11 +8,13 @@ */ package org.openhab.binding.tinkerforge.internal.model.impl; +import java.math.BigDecimal; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.impl.ENotificationImpl; import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; import org.openhab.binding.tinkerforge.internal.model.ModelPackage; +import org.openhab.binding.tinkerforge.internal.model.TFBaseConfiguration; import org.openhab.binding.tinkerforge.internal.model.TFBrickDCConfiguration; /** @@ -25,18 +27,59 @@ *

      * The following features are implemented: *

        + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl#getThreshold Threshold}
      • + *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl#getCallbackPeriod Callback Period}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl#getVelocity Velocity}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl#getAcceleration Acceleration}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl#getPwmFrequency Pwm Frequency}
      • *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl#getDriveMode Drive Mode}
      • - *
      • {@link org.openhab.binding.tinkerforge.internal.model.impl.TFBrickDCConfigurationImpl#getSwitchOnVelocity Switch On Velocity}
      • *
      *

      * * @generated */ -public class TFBrickDCConfigurationImpl extends MinimalEObjectImpl.Container implements TFBrickDCConfiguration +public class TFBrickDCConfigurationImpl extends DimmableConfigurationImpl implements TFBrickDCConfiguration { + /** + * The default value of the '{@link #getThreshold() Threshold}' attribute. + * + * + * @see #getThreshold() + * @generated + * @ordered + */ + protected static final BigDecimal THRESHOLD_EDEFAULT = null; + + /** + * The cached value of the '{@link #getThreshold() Threshold}' attribute. + * + * + * @see #getThreshold() + * @generated + * @ordered + */ + protected BigDecimal threshold = THRESHOLD_EDEFAULT; + + /** + * The default value of the '{@link #getCallbackPeriod() Callback Period}' attribute. + * + * + * @see #getCallbackPeriod() + * @generated + * @ordered + */ + protected static final int CALLBACK_PERIOD_EDEFAULT = 0; + + /** + * The cached value of the '{@link #getCallbackPeriod() Callback Period}' attribute. + * + * + * @see #getCallbackPeriod() + * @generated + * @ordered + */ + protected int callbackPeriod = CALLBACK_PERIOD_EDEFAULT; + /** * The default value of the '{@link #getVelocity() Velocity}' attribute. * @@ -105,7 +148,7 @@ public class TFBrickDCConfigurationImpl extends MinimalEObjectImpl.Container imp * @generated * @ordered */ - protected static final int DRIVE_MODE_EDEFAULT = 0; + protected static final String DRIVE_MODE_EDEFAULT = null; /** * The cached value of the '{@link #getDriveMode() Drive Mode}' attribute. @@ -115,36 +158,37 @@ public class TFBrickDCConfigurationImpl extends MinimalEObjectImpl.Container imp * @generated * @ordered */ - protected int driveMode = DRIVE_MODE_EDEFAULT; + protected String driveMode = DRIVE_MODE_EDEFAULT; /** - * The default value of the '{@link #getSwitchOnVelocity() Switch On Velocity}' attribute. * * - * @see #getSwitchOnVelocity() * @generated - * @ordered */ - protected static final short SWITCH_ON_VELOCITY_EDEFAULT = 0; + protected TFBrickDCConfigurationImpl() + { + super(); + } /** - * The cached value of the '{@link #getSwitchOnVelocity() Switch On Velocity}' attribute. * * - * @see #getSwitchOnVelocity() * @generated - * @ordered */ - protected short switchOnVelocity = SWITCH_ON_VELOCITY_EDEFAULT; + @Override + protected EClass eStaticClass() + { + return ModelPackage.Literals.TF_BRICK_DC_CONFIGURATION; + } /** * * * @generated */ - protected TFBrickDCConfigurationImpl() + public BigDecimal getThreshold() { - super(); + return threshold; } /** @@ -152,10 +196,35 @@ protected TFBrickDCConfigurationImpl() * * @generated */ - @Override - protected EClass eStaticClass() + public void setThreshold(BigDecimal newThreshold) { - return ModelPackage.Literals.TF_BRICK_DC_CONFIGURATION; + BigDecimal oldThreshold = threshold; + threshold = newThreshold; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.TF_BRICK_DC_CONFIGURATION__THRESHOLD, oldThreshold, threshold)); + } + + /** + * + * + * @generated + */ + public int getCallbackPeriod() + { + return callbackPeriod; + } + + /** + * + * + * @generated + */ + public void setCallbackPeriod(int newCallbackPeriod) + { + int oldCallbackPeriod = callbackPeriod; + callbackPeriod = newCallbackPeriod; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.TF_BRICK_DC_CONFIGURATION__CALLBACK_PERIOD, oldCallbackPeriod, callbackPeriod)); } /** @@ -232,7 +301,7 @@ public void setPwmFrequency(int newPwmFrequency) * * @generated */ - public int getDriveMode() + public String getDriveMode() { return driveMode; } @@ -242,37 +311,14 @@ public int getDriveMode() * * @generated */ - public void setDriveMode(int newDriveMode) + public void setDriveMode(String newDriveMode) { - int oldDriveMode = driveMode; + String oldDriveMode = driveMode; driveMode = newDriveMode; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.TF_BRICK_DC_CONFIGURATION__DRIVE_MODE, oldDriveMode, driveMode)); } - /** - * - * - * @generated - */ - public short getSwitchOnVelocity() - { - return switchOnVelocity; - } - - /** - * - * - * @generated - */ - public void setSwitchOnVelocity(short newSwitchOnVelocity) - { - short oldSwitchOnVelocity = switchOnVelocity; - switchOnVelocity = newSwitchOnVelocity; - if (eNotificationRequired()) - eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.TF_BRICK_DC_CONFIGURATION__SWITCH_ON_VELOCITY, oldSwitchOnVelocity, switchOnVelocity)); - } - /** * * @@ -283,6 +329,10 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { + case ModelPackage.TF_BRICK_DC_CONFIGURATION__THRESHOLD: + return getThreshold(); + case ModelPackage.TF_BRICK_DC_CONFIGURATION__CALLBACK_PERIOD: + return getCallbackPeriod(); case ModelPackage.TF_BRICK_DC_CONFIGURATION__VELOCITY: return getVelocity(); case ModelPackage.TF_BRICK_DC_CONFIGURATION__ACCELERATION: @@ -291,8 +341,6 @@ public Object eGet(int featureID, boolean resolve, boolean coreType) return getPwmFrequency(); case ModelPackage.TF_BRICK_DC_CONFIGURATION__DRIVE_MODE: return getDriveMode(); - case ModelPackage.TF_BRICK_DC_CONFIGURATION__SWITCH_ON_VELOCITY: - return getSwitchOnVelocity(); } return super.eGet(featureID, resolve, coreType); } @@ -307,6 +355,12 @@ public void eSet(int featureID, Object newValue) { switch (featureID) { + case ModelPackage.TF_BRICK_DC_CONFIGURATION__THRESHOLD: + setThreshold((BigDecimal)newValue); + return; + case ModelPackage.TF_BRICK_DC_CONFIGURATION__CALLBACK_PERIOD: + setCallbackPeriod((Integer)newValue); + return; case ModelPackage.TF_BRICK_DC_CONFIGURATION__VELOCITY: setVelocity((Short)newValue); return; @@ -317,10 +371,7 @@ public void eSet(int featureID, Object newValue) setPwmFrequency((Integer)newValue); return; case ModelPackage.TF_BRICK_DC_CONFIGURATION__DRIVE_MODE: - setDriveMode((Integer)newValue); - return; - case ModelPackage.TF_BRICK_DC_CONFIGURATION__SWITCH_ON_VELOCITY: - setSwitchOnVelocity((Short)newValue); + setDriveMode((String)newValue); return; } super.eSet(featureID, newValue); @@ -336,6 +387,12 @@ public void eUnset(int featureID) { switch (featureID) { + case ModelPackage.TF_BRICK_DC_CONFIGURATION__THRESHOLD: + setThreshold(THRESHOLD_EDEFAULT); + return; + case ModelPackage.TF_BRICK_DC_CONFIGURATION__CALLBACK_PERIOD: + setCallbackPeriod(CALLBACK_PERIOD_EDEFAULT); + return; case ModelPackage.TF_BRICK_DC_CONFIGURATION__VELOCITY: setVelocity(VELOCITY_EDEFAULT); return; @@ -348,9 +405,6 @@ public void eUnset(int featureID) case ModelPackage.TF_BRICK_DC_CONFIGURATION__DRIVE_MODE: setDriveMode(DRIVE_MODE_EDEFAULT); return; - case ModelPackage.TF_BRICK_DC_CONFIGURATION__SWITCH_ON_VELOCITY: - setSwitchOnVelocity(SWITCH_ON_VELOCITY_EDEFAULT); - return; } super.eUnset(featureID); } @@ -365,6 +419,10 @@ public boolean eIsSet(int featureID) { switch (featureID) { + case ModelPackage.TF_BRICK_DC_CONFIGURATION__THRESHOLD: + return THRESHOLD_EDEFAULT == null ? threshold != null : !THRESHOLD_EDEFAULT.equals(threshold); + case ModelPackage.TF_BRICK_DC_CONFIGURATION__CALLBACK_PERIOD: + return callbackPeriod != CALLBACK_PERIOD_EDEFAULT; case ModelPackage.TF_BRICK_DC_CONFIGURATION__VELOCITY: return velocity != VELOCITY_EDEFAULT; case ModelPackage.TF_BRICK_DC_CONFIGURATION__ACCELERATION: @@ -372,13 +430,51 @@ public boolean eIsSet(int featureID) case ModelPackage.TF_BRICK_DC_CONFIGURATION__PWM_FREQUENCY: return pwmFrequency != PWM_FREQUENCY_EDEFAULT; case ModelPackage.TF_BRICK_DC_CONFIGURATION__DRIVE_MODE: - return driveMode != DRIVE_MODE_EDEFAULT; - case ModelPackage.TF_BRICK_DC_CONFIGURATION__SWITCH_ON_VELOCITY: - return switchOnVelocity != SWITCH_ON_VELOCITY_EDEFAULT; + return DRIVE_MODE_EDEFAULT == null ? driveMode != null : !DRIVE_MODE_EDEFAULT.equals(driveMode); } return super.eIsSet(featureID); } + /** + * + * + * @generated + */ + @Override + public int eBaseStructuralFeatureID(int derivedFeatureID, Class baseClass) + { + if (baseClass == TFBaseConfiguration.class) + { + switch (derivedFeatureID) + { + case ModelPackage.TF_BRICK_DC_CONFIGURATION__THRESHOLD: return ModelPackage.TF_BASE_CONFIGURATION__THRESHOLD; + case ModelPackage.TF_BRICK_DC_CONFIGURATION__CALLBACK_PERIOD: return ModelPackage.TF_BASE_CONFIGURATION__CALLBACK_PERIOD; + default: return -1; + } + } + return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); + } + + /** + * + * + * @generated + */ + @Override + public int eDerivedStructuralFeatureID(int baseFeatureID, Class baseClass) + { + if (baseClass == TFBaseConfiguration.class) + { + switch (baseFeatureID) + { + case ModelPackage.TF_BASE_CONFIGURATION__THRESHOLD: return ModelPackage.TF_BRICK_DC_CONFIGURATION__THRESHOLD; + case ModelPackage.TF_BASE_CONFIGURATION__CALLBACK_PERIOD: return ModelPackage.TF_BRICK_DC_CONFIGURATION__CALLBACK_PERIOD; + default: return -1; + } + } + return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); + } + /** * * @@ -390,7 +486,11 @@ public String toString() if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); - result.append(" (velocity: "); + result.append(" (threshold: "); + result.append(threshold); + result.append(", callbackPeriod: "); + result.append(callbackPeriod); + result.append(", velocity: "); result.append(velocity); result.append(", acceleration: "); result.append(acceleration); @@ -398,8 +498,6 @@ public String toString() result.append(pwmFrequency); result.append(", driveMode: "); result.append(driveMode); - result.append(", switchOnVelocity: "); - result.append(switchOnVelocity); result.append(')'); return result.toString(); } diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/TFServoConfigurationImpl.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/TFServoConfigurationImpl.java index 680ce230a1f..ba03956f51b 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/TFServoConfigurationImpl.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/impl/TFServoConfigurationImpl.java @@ -40,7 +40,7 @@ * * @generated */ -public class TFServoConfigurationImpl extends MinimalEObjectImpl.Container implements TFServoConfiguration +public class TFServoConfigurationImpl extends DimmableConfigurationImpl implements TFServoConfiguration { /** * The default value of the '{@link #getVelocity() Velocity}' attribute. diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/util/ModelAdapterFactory.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/util/ModelAdapterFactory.java index 95683effa49..7cb91f3c8cc 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/util/ModelAdapterFactory.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/util/ModelAdapterFactory.java @@ -172,11 +172,21 @@ public Adapter caseMActor(MActor object) return createMActorAdapter(); } @Override + public Adapter caseSwitchSensor(SwitchSensor object) + { + return createSwitchSensorAdapter(); + } + @Override public Adapter caseMSwitchActor(MSwitchActor object) { return createMSwitchActorAdapter(); } @Override + public Adapter caseProgrammableSwitchActor(ProgrammableSwitchActor object) + { + return createProgrammableSwitchActorAdapter(); + } + @Override public Adapter caseMOutSwitchActor(MOutSwitchActor object) { return createMOutSwitchActorAdapter(); @@ -227,6 +237,96 @@ public Adapter caseMLCDSubDevice(MLCDSubDevice object) return createMLCDSubDeviceAdapter(); } @Override + public Adapter caseDigitalActor(DigitalActor object) + { + return createDigitalActorAdapter(); + } + @Override + public Adapter caseNumberActor(NumberActor object) + { + return createNumberActorAdapter(); + } + @Override + public Adapter caseColorActor(ColorActor object) + { + return createColorActorAdapter(); + } + @Override + public Adapter caseMoveActor(MoveActor object) + { + return createMoveActorAdapter(); + } + @Override + public Adapter caseDimmableActor(DimmableActor object) + { + return createDimmableActorAdapter(); + } + @Override + public Adapter caseSetPointActor(SetPointActor object) + { + return createSetPointActorAdapter(); + } + @Override + public Adapter caseMBrickletDualButton(MBrickletDualButton object) + { + return createMBrickletDualButtonAdapter(); + } + @Override + public Adapter caseDualButtonDevice(DualButtonDevice object) + { + return createDualButtonDeviceAdapter(); + } + @Override + public Adapter caseDualButtonLeftButton(DualButtonLeftButton object) + { + return createDualButtonLeftButtonAdapter(); + } + @Override + public Adapter caseDualButtonRightButton(DualButtonRightButton object) + { + return createDualButtonRightButtonAdapter(); + } + @Override + public Adapter caseDualButtonLeftLed(DualButtonLeftLed object) + { + return createDualButtonLeftLedAdapter(); + } + @Override + public Adapter caseDualButtonRightLed(DualButtonRightLed object) + { + return createDualButtonRightLedAdapter(); + } + @Override + public Adapter caseMBrickletLinearPoti(MBrickletLinearPoti object) + { + return createMBrickletLinearPotiAdapter(); + } + @Override + public Adapter caseMBrickletJoystick(MBrickletJoystick object) + { + return createMBrickletJoystickAdapter(); + } + @Override + public Adapter caseJoystickDevice(JoystickDevice object) + { + return createJoystickDeviceAdapter(); + } + @Override + public Adapter caseJoystickXPosition(JoystickXPosition object) + { + return createJoystickXPositionAdapter(); + } + @Override + public Adapter caseJoystickYPosition(JoystickYPosition object) + { + return createJoystickYPositionAdapter(); + } + @Override + public Adapter caseJoystickButton(JoystickButton object) + { + return createJoystickButtonAdapter(); + } + @Override public Adapter caseMBrickServo(MBrickServo object) { return createMBrickServoAdapter(); @@ -277,26 +377,11 @@ public Adapter caseDigitalActorDigitalOut4(DigitalActorDigitalOut4 object) return createDigitalActorDigitalOut4Adapter(); } @Override - public Adapter caseDigitalActor(DigitalActor object) - { - return createDigitalActorAdapter(); - } - @Override - public Adapter caseNumberActor(NumberActor object) - { - return createNumberActorAdapter(); - } - @Override public Adapter caseMBrickletSegmentDisplay4x7(MBrickletSegmentDisplay4x7 object) { return createMBrickletSegmentDisplay4x7Adapter(); } @Override - public Adapter caseColorActor(ColorActor object) - { - return createColorActorAdapter(); - } - @Override public Adapter caseMBrickletLEDStrip(MBrickletLEDStrip object) { return createMBrickletLEDStripAdapter(); @@ -612,6 +697,11 @@ public Adapter caseBrickletMultiTouchConfiguration(BrickletMultiTouchConfigurati return createBrickletMultiTouchConfigurationAdapter(); } @Override + public Adapter caseDimmableConfiguration(DimmableConfiguration object) + { + return createDimmableConfigurationAdapter(); + } + @Override public Adapter defaultCase(EObject object) { return createEObjectAdapter(); @@ -993,6 +1083,231 @@ public Adapter createColorActorAdapter() return null; } + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.MoveActor Move Actor}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.MoveActor + * @generated + */ + public Adapter createMoveActorAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.DimmableActor Dimmable Actor}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.DimmableActor + * @generated + */ + public Adapter createDimmableActorAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.SetPointActor Set Point Actor}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.SetPointActor + * @generated + */ + public Adapter createSetPointActorAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletDualButton MBricklet Dual Button}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletDualButton + * @generated + */ + public Adapter createMBrickletDualButtonAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonDevice Dual Button Device}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonDevice + * @generated + */ + public Adapter createDualButtonDeviceAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonLeftButton Dual Button Left Button}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonLeftButton + * @generated + */ + public Adapter createDualButtonLeftButtonAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonRightButton Dual Button Right Button}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonRightButton + * @generated + */ + public Adapter createDualButtonRightButtonAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonLeftLed Dual Button Left Led}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonLeftLed + * @generated + */ + public Adapter createDualButtonLeftLedAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.DualButtonRightLed Dual Button Right Led}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.DualButtonRightLed + * @generated + */ + public Adapter createDualButtonRightLedAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLinearPoti MBricklet Linear Poti}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletLinearPoti + * @generated + */ + public Adapter createMBrickletLinearPotiAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick MBricklet Joystick}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.MBrickletJoystick + * @generated + */ + public Adapter createMBrickletJoystickAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.JoystickDevice Joystick Device}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.JoystickDevice + * @generated + */ + public Adapter createJoystickDeviceAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.JoystickXPosition Joystick XPosition}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.JoystickXPosition + * @generated + */ + public Adapter createJoystickXPositionAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.JoystickYPosition Joystick YPosition}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.JoystickYPosition + * @generated + */ + public Adapter createJoystickYPositionAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.JoystickButton Joystick Button}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.JoystickButton + * @generated + */ + public Adapter createJoystickButtonAdapter() + { + return null; + } + /** * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.MBrickletLEDStrip MBricklet LED Strip}'. * @@ -1053,6 +1368,21 @@ public Adapter createMActorAdapter() return null; } + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.SwitchSensor Switch Sensor}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.SwitchSensor + * @generated + */ + public Adapter createSwitchSensorAdapter() + { + return null; + } + /** * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.MSwitchActor MSwitch Actor}'. * @@ -1068,6 +1398,21 @@ public Adapter createMSwitchActorAdapter() return null; } + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor Programmable Switch Actor}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.ProgrammableSwitchActor + * @generated + */ + public Adapter createProgrammableSwitchActorAdapter() + { + return null; + } + /** * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.MOutSwitchActor MOut Switch Actor}'. * @@ -1578,6 +1923,21 @@ public Adapter createBrickletMultiTouchConfigurationAdapter() return null; } + /** + * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration Dimmable Configuration}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.openhab.binding.tinkerforge.internal.model.DimmableConfiguration + * @generated + */ + public Adapter createDimmableConfigurationAdapter() + { + return null; + } + /** * Creates a new adapter for an object of class '{@link org.openhab.binding.tinkerforge.internal.model.MServo MServo}'. * diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/util/ModelSwitch.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/util/ModelSwitch.java index 0469baf4d8a..743a17d9565 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/util/ModelSwitch.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/model/util/ModelSwitch.java @@ -187,10 +187,26 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = defaultCase(theEObject); return result; } + case ModelPackage.SWITCH_SENSOR: + { + SwitchSensor switchSensor = (SwitchSensor)theEObject; + T result = caseSwitchSensor(switchSensor); + if (result == null) result = defaultCase(theEObject); + return result; + } case ModelPackage.MSWITCH_ACTOR: { MSwitchActor mSwitchActor = (MSwitchActor)theEObject; T result = caseMSwitchActor(mSwitchActor); + if (result == null) result = caseSwitchSensor(mSwitchActor); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.PROGRAMMABLE_SWITCH_ACTOR: + { + ProgrammableSwitchActor programmableSwitchActor = (ProgrammableSwitchActor)theEObject; + T result = caseProgrammableSwitchActor(programmableSwitchActor); + if (result == null) result = caseSwitchSensor(programmableSwitchActor); if (result == null) result = defaultCase(theEObject); return result; } @@ -199,6 +215,7 @@ protected T doSwitch(int classifierID, EObject theEObject) MOutSwitchActor mOutSwitchActor = (MOutSwitchActor)theEObject; T result = caseMOutSwitchActor(mOutSwitchActor); if (result == null) result = caseMSwitchActor(mOutSwitchActor); + if (result == null) result = caseSwitchSensor(mOutSwitchActor); if (result == null) result = defaultCase(theEObject); return result; } @@ -207,6 +224,7 @@ protected T doSwitch(int classifierID, EObject theEObject) MInSwitchActor mInSwitchActor = (MInSwitchActor)theEObject; T result = caseMInSwitchActor(mInSwitchActor); if (result == null) result = caseMSwitchActor(mInSwitchActor); + if (result == null) result = caseSwitchSensor(mInSwitchActor); if (result == null) result = defaultCase(theEObject); return result; } @@ -272,6 +290,180 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = defaultCase(theEObject); return result; } + case ModelPackage.DIGITAL_ACTOR: + { + DigitalActor digitalActor = (DigitalActor)theEObject; + T result = caseDigitalActor(digitalActor); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.NUMBER_ACTOR: + { + NumberActor numberActor = (NumberActor)theEObject; + T result = caseNumberActor(numberActor); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.COLOR_ACTOR: + { + ColorActor colorActor = (ColorActor)theEObject; + T result = caseColorActor(colorActor); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.MOVE_ACTOR: + { + MoveActor moveActor = (MoveActor)theEObject; + T result = caseMoveActor(moveActor); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.DIMMABLE_ACTOR: + { + DimmableActor dimmableActor = (DimmableActor)theEObject; + T result = caseDimmableActor(dimmableActor); + if (result == null) result = caseMTFConfigConsumer(dimmableActor); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.SET_POINT_ACTOR: + { + SetPointActor setPointActor = (SetPointActor)theEObject; + T result = caseSetPointActor(setPointActor); + if (result == null) result = caseDimmableActor(setPointActor); + if (result == null) result = caseMTFConfigConsumer(setPointActor); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.MBRICKLET_DUAL_BUTTON: + { + MBrickletDualButton mBrickletDualButton = (MBrickletDualButton)theEObject; + T result = caseMBrickletDualButton(mBrickletDualButton); + if (result == null) result = caseMDevice(mBrickletDualButton); + if (result == null) result = caseMSubDeviceHolder(mBrickletDualButton); + if (result == null) result = caseMBaseDevice(mBrickletDualButton); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.DUAL_BUTTON_DEVICE: + { + DualButtonDevice dualButtonDevice = (DualButtonDevice)theEObject; + T result = caseDualButtonDevice(dualButtonDevice); + if (result == null) result = caseMSubDevice(dualButtonDevice); + if (result == null) result = caseMBaseDevice(dualButtonDevice); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.DUAL_BUTTON_LEFT_BUTTON: + { + DualButtonLeftButton dualButtonLeftButton = (DualButtonLeftButton)theEObject; + T result = caseDualButtonLeftButton(dualButtonLeftButton); + if (result == null) result = caseDualButtonDevice(dualButtonLeftButton); + if (result == null) result = caseMSensor(dualButtonLeftButton); + if (result == null) result = caseMSubDevice(dualButtonLeftButton); + if (result == null) result = caseMBaseDevice(dualButtonLeftButton); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.DUAL_BUTTON_RIGHT_BUTTON: + { + DualButtonRightButton dualButtonRightButton = (DualButtonRightButton)theEObject; + T result = caseDualButtonRightButton(dualButtonRightButton); + if (result == null) result = caseDualButtonDevice(dualButtonRightButton); + if (result == null) result = caseMSensor(dualButtonRightButton); + if (result == null) result = caseMSubDevice(dualButtonRightButton); + if (result == null) result = caseMBaseDevice(dualButtonRightButton); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.DUAL_BUTTON_LEFT_LED: + { + DualButtonLeftLed dualButtonLeftLed = (DualButtonLeftLed)theEObject; + T result = caseDualButtonLeftLed(dualButtonLeftLed); + if (result == null) result = caseDualButtonDevice(dualButtonLeftLed); + if (result == null) result = caseDigitalActor(dualButtonLeftLed); + if (result == null) result = caseMSubDevice(dualButtonLeftLed); + if (result == null) result = caseMBaseDevice(dualButtonLeftLed); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.DUAL_BUTTON_RIGHT_LED: + { + DualButtonRightLed dualButtonRightLed = (DualButtonRightLed)theEObject; + T result = caseDualButtonRightLed(dualButtonRightLed); + if (result == null) result = caseDualButtonDevice(dualButtonRightLed); + if (result == null) result = caseDigitalActor(dualButtonRightLed); + if (result == null) result = caseMSubDevice(dualButtonRightLed); + if (result == null) result = caseMBaseDevice(dualButtonRightLed); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.MBRICKLET_LINEAR_POTI: + { + MBrickletLinearPoti mBrickletLinearPoti = (MBrickletLinearPoti)theEObject; + T result = caseMBrickletLinearPoti(mBrickletLinearPoti); + if (result == null) result = caseMDevice(mBrickletLinearPoti); + if (result == null) result = caseCallbackListener(mBrickletLinearPoti); + if (result == null) result = caseMTFConfigConsumer(mBrickletLinearPoti); + if (result == null) result = caseMSensor(mBrickletLinearPoti); + if (result == null) result = caseMBaseDevice(mBrickletLinearPoti); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.MBRICKLET_JOYSTICK: + { + MBrickletJoystick mBrickletJoystick = (MBrickletJoystick)theEObject; + T result = caseMBrickletJoystick(mBrickletJoystick); + if (result == null) result = caseMDevice(mBrickletJoystick); + if (result == null) result = caseMSubDeviceHolder(mBrickletJoystick); + if (result == null) result = caseCallbackListener(mBrickletJoystick); + if (result == null) result = caseMTFConfigConsumer(mBrickletJoystick); + if (result == null) result = caseMBaseDevice(mBrickletJoystick); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.JOYSTICK_DEVICE: + { + JoystickDevice joystickDevice = (JoystickDevice)theEObject; + T result = caseJoystickDevice(joystickDevice); + if (result == null) result = caseMSubDevice(joystickDevice); + if (result == null) result = caseMBaseDevice(joystickDevice); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.JOYSTICK_XPOSITION: + { + JoystickXPosition joystickXPosition = (JoystickXPosition)theEObject; + T result = caseJoystickXPosition(joystickXPosition); + if (result == null) result = caseJoystickDevice(joystickXPosition); + if (result == null) result = caseMSensor(joystickXPosition); + if (result == null) result = caseMSubDevice(joystickXPosition); + if (result == null) result = caseMBaseDevice(joystickXPosition); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.JOYSTICK_YPOSITION: + { + JoystickYPosition joystickYPosition = (JoystickYPosition)theEObject; + T result = caseJoystickYPosition(joystickYPosition); + if (result == null) result = caseJoystickDevice(joystickYPosition); + if (result == null) result = caseMSensor(joystickYPosition); + if (result == null) result = caseMSubDevice(joystickYPosition); + if (result == null) result = caseMBaseDevice(joystickYPosition); + if (result == null) result = defaultCase(theEObject); + return result; + } + case ModelPackage.JOYSTICK_BUTTON: + { + JoystickButton joystickButton = (JoystickButton)theEObject; + T result = caseJoystickButton(joystickButton); + if (result == null) result = caseJoystickDevice(joystickButton); + if (result == null) result = caseMSensor(joystickButton); + if (result == null) result = caseMSubDevice(joystickButton); + if (result == null) result = caseMBaseDevice(joystickButton); + if (result == null) result = defaultCase(theEObject); + return result; + } case ModelPackage.MBRICK_SERVO: { MBrickServo mBrickServo = (MBrickServo)theEObject; @@ -286,11 +478,15 @@ protected T doSwitch(int classifierID, EObject theEObject) { MServo mServo = (MServo)theEObject; T result = caseMServo(mServo); - if (result == null) result = caseMInSwitchActor(mServo); + if (result == null) result = caseMSensor(mServo); + if (result == null) result = caseProgrammableSwitchActor(mServo); if (result == null) result = caseMSubDevice(mServo); - if (result == null) result = caseMTFConfigConsumer(mServo); - if (result == null) result = caseMSwitchActor(mServo); + if (result == null) result = caseMoveActor(mServo); + if (result == null) result = caseSetPointActor(mServo); + if (result == null) result = caseSwitchSensor(mServo); if (result == null) result = caseMBaseDevice(mServo); + if (result == null) result = caseDimmableActor(mServo); + if (result == null) result = caseMTFConfigConsumer(mServo); if (result == null) result = defaultCase(theEObject); return result; } @@ -298,11 +494,16 @@ protected T doSwitch(int classifierID, EObject theEObject) { MBrickDC mBrickDC = (MBrickDC)theEObject; T result = caseMBrickDC(mBrickDC); - if (result == null) result = caseMInSwitchActor(mBrickDC); + if (result == null) result = caseMSensor(mBrickDC); + if (result == null) result = caseProgrammableSwitchActor(mBrickDC); if (result == null) result = caseMDevice(mBrickDC); - if (result == null) result = caseMTFConfigConsumer(mBrickDC); - if (result == null) result = caseMSwitchActor(mBrickDC); + if (result == null) result = caseMoveActor(mBrickDC); + if (result == null) result = caseSetPointActor(mBrickDC); + if (result == null) result = caseCallbackListener(mBrickDC); + if (result == null) result = caseSwitchSensor(mBrickDC); if (result == null) result = caseMBaseDevice(mBrickDC); + if (result == null) result = caseDimmableActor(mBrickDC); + if (result == null) result = caseMTFConfigConsumer(mBrickDC); if (result == null) result = defaultCase(theEObject); return result; } @@ -334,6 +535,7 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = caseMSubDevice(mIndustrialQuadRelay); if (result == null) result = caseMSwitchActor(mIndustrialQuadRelay); if (result == null) result = caseMBaseDevice(mIndustrialQuadRelay); + if (result == null) result = caseSwitchSensor(mIndustrialQuadRelay); if (result == null) result = defaultCase(theEObject); return result; } @@ -379,20 +581,6 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = defaultCase(theEObject); return result; } - case ModelPackage.DIGITAL_ACTOR: - { - DigitalActor digitalActor = (DigitalActor)theEObject; - T result = caseDigitalActor(digitalActor); - if (result == null) result = defaultCase(theEObject); - return result; - } - case ModelPackage.NUMBER_ACTOR: - { - NumberActor numberActor = (NumberActor)theEObject; - T result = caseNumberActor(numberActor); - if (result == null) result = defaultCase(theEObject); - return result; - } case ModelPackage.MBRICKLET_SEGMENT_DISPLAY4X7: { MBrickletSegmentDisplay4x7 mBrickletSegmentDisplay4x7 = (MBrickletSegmentDisplay4x7)theEObject; @@ -403,13 +591,6 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = defaultCase(theEObject); return result; } - case ModelPackage.COLOR_ACTOR: - { - ColorActor colorActor = (ColorActor)theEObject; - T result = caseColorActor(colorActor); - if (result == null) result = defaultCase(theEObject); - return result; - } case ModelPackage.MBRICKLET_LED_STRIP: { MBrickletLEDStrip mBrickletLEDStrip = (MBrickletLEDStrip)theEObject; @@ -582,6 +763,7 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = caseMSubDevice(mDualRelay); if (result == null) result = caseMSwitchActor(mDualRelay); if (result == null) result = caseMBaseDevice(mDualRelay); + if (result == null) result = caseSwitchSensor(mDualRelay); if (result == null) result = defaultCase(theEObject); return result; } @@ -605,6 +787,7 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = caseMSubDevice(remoteSwitch); if (result == null) result = caseMSwitchActor(remoteSwitch); if (result == null) result = caseMBaseDevice(remoteSwitch); + if (result == null) result = caseSwitchSensor(remoteSwitch); if (result == null) result = defaultCase(theEObject); return result; } @@ -618,6 +801,7 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = caseMSubDevice(remoteSwitchA); if (result == null) result = caseMSwitchActor(remoteSwitchA); if (result == null) result = caseMBaseDevice(remoteSwitchA); + if (result == null) result = caseSwitchSensor(remoteSwitchA); if (result == null) result = defaultCase(theEObject); return result; } @@ -625,12 +809,15 @@ protected T doSwitch(int classifierID, EObject theEObject) { RemoteSwitchB remoteSwitchB = (RemoteSwitchB)theEObject; T result = caseRemoteSwitchB(remoteSwitchB); + if (result == null) result = caseMSensor(remoteSwitchB); if (result == null) result = caseRemoteSwitch(remoteSwitchB); - if (result == null) result = caseMTFConfigConsumer(remoteSwitchB); + if (result == null) result = caseDimmableActor(remoteSwitchB); if (result == null) result = caseMInSwitchActor(remoteSwitchB); if (result == null) result = caseMSubDevice(remoteSwitchB); + if (result == null) result = caseMTFConfigConsumer(remoteSwitchB); if (result == null) result = caseMSwitchActor(remoteSwitchB); if (result == null) result = caseMBaseDevice(remoteSwitchB); + if (result == null) result = caseSwitchSensor(remoteSwitchB); if (result == null) result = defaultCase(theEObject); return result; } @@ -644,6 +831,7 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = caseMSubDevice(remoteSwitchC); if (result == null) result = caseMSwitchActor(remoteSwitchC); if (result == null) result = caseMBaseDevice(remoteSwitchC); + if (result == null) result = caseSwitchSensor(remoteSwitchC); if (result == null) result = defaultCase(theEObject); return result; } @@ -892,6 +1080,7 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = caseMLCDSubDevice(mlcd20x4Backlight); if (result == null) result = caseMSwitchActor(mlcd20x4Backlight); if (result == null) result = caseMSubDevice(mlcd20x4Backlight); + if (result == null) result = caseSwitchSensor(mlcd20x4Backlight); if (result == null) result = caseMBaseDevice(mlcd20x4Backlight); if (result == null) result = defaultCase(theEObject); return result; @@ -905,6 +1094,7 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = caseCallbackListener(mlcd20x4Button); if (result == null) result = caseMSwitchActor(mlcd20x4Button); if (result == null) result = caseMSubDevice(mlcd20x4Button); + if (result == null) result = caseSwitchSensor(mlcd20x4Button); if (result == null) result = caseMBaseDevice(mlcd20x4Button); if (result == null) result = defaultCase(theEObject); return result; @@ -993,6 +1183,8 @@ protected T doSwitch(int classifierID, EObject theEObject) { TFBrickDCConfiguration tfBrickDCConfiguration = (TFBrickDCConfiguration)theEObject; T result = caseTFBrickDCConfiguration(tfBrickDCConfiguration); + if (result == null) result = caseDimmableConfiguration(tfBrickDCConfiguration); + if (result == null) result = caseTFBaseConfiguration(tfBrickDCConfiguration); if (result == null) result = caseTFConfig(tfBrickDCConfiguration); if (result == null) result = defaultCase(theEObject); return result; @@ -1025,6 +1217,7 @@ protected T doSwitch(int classifierID, EObject theEObject) { TFServoConfiguration tfServoConfiguration = (TFServoConfiguration)theEObject; T result = caseTFServoConfiguration(tfServoConfiguration); + if (result == null) result = caseDimmableConfiguration(tfServoConfiguration); if (result == null) result = caseTFConfig(tfServoConfiguration); if (result == null) result = defaultCase(theEObject); return result; @@ -1049,6 +1242,7 @@ protected T doSwitch(int classifierID, EObject theEObject) { RemoteSwitchBConfiguration remoteSwitchBConfiguration = (RemoteSwitchBConfiguration)theEObject; T result = caseRemoteSwitchBConfiguration(remoteSwitchBConfiguration); + if (result == null) result = caseDimmableConfiguration(remoteSwitchBConfiguration); if (result == null) result = caseTFConfig(remoteSwitchBConfiguration); if (result == null) result = defaultCase(theEObject); return result; @@ -1077,6 +1271,14 @@ protected T doSwitch(int classifierID, EObject theEObject) if (result == null) result = defaultCase(theEObject); return result; } + case ModelPackage.DIMMABLE_CONFIGURATION: + { + DimmableConfiguration dimmableConfiguration = (DimmableConfiguration)theEObject; + T result = caseDimmableConfiguration(dimmableConfiguration); + if (result == null) result = caseTFConfig(dimmableConfiguration); + if (result == null) result = defaultCase(theEObject); + return result; + } default: return defaultCase(theEObject); } } @@ -1467,6 +1669,246 @@ public T caseColorActor(ColorActor object) return null; } + /** + * Returns the result of interpreting the object as an instance of 'Move Actor'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Move Actor'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseMoveActor(MoveActor object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'Dimmable Actor'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Dimmable Actor'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseDimmableActor(DimmableActor object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'Set Point Actor'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Set Point Actor'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseSetPointActor(SetPointActor object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'MBricklet Dual Button'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'MBricklet Dual Button'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseMBrickletDualButton(MBrickletDualButton object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'Dual Button Device'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Dual Button Device'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseDualButtonDevice(DualButtonDevice object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'Dual Button Left Button'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Dual Button Left Button'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseDualButtonLeftButton(DualButtonLeftButton object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'Dual Button Right Button'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Dual Button Right Button'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseDualButtonRightButton(DualButtonRightButton object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'Dual Button Left Led'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Dual Button Left Led'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseDualButtonLeftLed(DualButtonLeftLed object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'Dual Button Right Led'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Dual Button Right Led'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseDualButtonRightLed(DualButtonRightLed object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'MBricklet Linear Poti'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'MBricklet Linear Poti'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseMBrickletLinearPoti(MBrickletLinearPoti object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'MBricklet Joystick'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'MBricklet Joystick'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseMBrickletJoystick(MBrickletJoystick object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'Joystick Device'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Joystick Device'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseJoystickDevice(JoystickDevice object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'Joystick XPosition'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Joystick XPosition'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseJoystickXPosition(JoystickXPosition object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'Joystick YPosition'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Joystick YPosition'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseJoystickYPosition(JoystickYPosition object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of 'Joystick Button'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Joystick Button'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseJoystickButton(JoystickButton object) + { + return null; + } + /** * Returns the result of interpreting the object as an instance of 'MBricklet LED Strip'. * @@ -1531,6 +1973,22 @@ public T caseMActor(MActor object) return null; } + /** + * Returns the result of interpreting the object as an instance of 'Switch Sensor'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Switch Sensor'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseSwitchSensor(SwitchSensor object) + { + return null; + } + /** * Returns the result of interpreting the object as an instance of 'MSwitch Actor'. * @@ -1547,6 +2005,22 @@ public T caseMSwitchActor(MSwitchActor object) return null; } + /** + * Returns the result of interpreting the object as an instance of 'Programmable Switch Actor'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Programmable Switch Actor'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseProgrammableSwitchActor(ProgrammableSwitchActor object) + { + return null; + } + /** * Returns the result of interpreting the object as an instance of 'MOut Switch Actor'. * @@ -2091,6 +2565,22 @@ public T caseBrickletMultiTouchConfiguration(BrickletMultiTouchConfiguration obj return null; } + /** + * Returns the result of interpreting the object as an instance of 'Dimmable Configuration'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Dimmable Configuration'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseDimmableConfiguration(DimmableConfiguration object) + { + return null; + } + /** * Returns the result of interpreting the object as an instance of 'MServo'. * diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/tools/Tools.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/tools/Tools.java index ea5ead7352d..05f5e016f86 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/tools/Tools.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/tools/Tools.java @@ -10,6 +10,7 @@ import java.math.BigDecimal; +import org.openhab.binding.tinkerforge.internal.config.DeviceOptions; import org.openhab.binding.tinkerforge.internal.types.DecimalValue; public class Tools { @@ -18,6 +19,12 @@ public static DecimalValue calculate(int value){ BigDecimal bvalue = new BigDecimal(String.valueOf(value)); return new DecimalValue(bvalue); + } + + public static DecimalValue calculate(short value) { + BigDecimal bvalue = new BigDecimal(String.valueOf(value)); + return new DecimalValue(bvalue); + } public static DecimalValue calculate10(short value){ return calculate(value, BigDecimal.TEN); @@ -44,4 +51,68 @@ public static DecimalValue calculate(int value, BigDecimal devider){ BigDecimal bvalue = new BigDecimal(String.valueOf(value)).divide(devider); return new DecimalValue(bvalue); } + + public static BigDecimal getBigDecimalOpt(String key, DeviceOptions opts){ + return getBigDecimalOpt(key, opts, null); + } + + public static BigDecimal getBigDecimalOpt(String key, DeviceOptions opts, + BigDecimal bigdecimaldefault) { + if (opts.containsKey(key.toLowerCase())) { + BigDecimal value = new BigDecimal(opts.getOption(key.toLowerCase())); + return value; + } + return bigdecimaldefault; + } + + public static Short getShortOpt(String key, DeviceOptions opts) throws NumberFormatException { + return getShortOpt(key, opts, null); + } + + public static Short getShortOpt(String key, DeviceOptions opts, Short shortdefault) + throws NumberFormatException { + if (opts.containsKey(key.toLowerCase())) { + short value = Short.parseShort(opts.getOption(key.toLowerCase())); + return value; + } + return shortdefault; + } + + public static Long getLongOpt(String key, DeviceOptions opts) throws NumberFormatException { + return getLongOpt(key, opts, null); + } + + public static Long getLongOpt(String key, DeviceOptions opts, Long shortdefault) + throws NumberFormatException { + if (opts.containsKey(key.toLowerCase())) { + long value = Long.parseLong(opts.getOption(key.toLowerCase())); + return value; + } + return shortdefault; + } + + + public static Integer getIntOpt(String key, DeviceOptions opts) throws NumberFormatException { + return getIntOpt(key, opts, null); + } + + public static Integer getIntOpt(String key, DeviceOptions opts, Integer intdefault) + throws NumberFormatException { + if (opts.containsKey(key.toLowerCase())) { + int value = Integer.valueOf(opts.getOption(key.toLowerCase())); + return value; + } + return intdefault; + } + + public static String getStringOpt(String key, DeviceOptions opts) { + return getStringOpt(key, opts, null); + } + + public static String getStringOpt(String key, DeviceOptions opts, String stringdefault) { + if (opts.containsKey(key.toLowerCase())) { + return opts.getOption(key.toLowerCase()); + } + return stringdefault; + } } diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/DecimalValue.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/DecimalValue.java index 233cf9bf7e9..5383b557b6d 100644 --- a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/DecimalValue.java +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/DecimalValue.java @@ -11,122 +11,127 @@ import java.math.BigDecimal; /** - * The decimal value uses a BigDecimal internally and thus can be used for - * integers, longs and floating point numbers alike (inspired by - * {@link org.openhab.core.library.types.DecimalType}). + * The decimal value uses a BigDecimal internally and thus can be used for integers, longs and + * floating point numbers alike (inspired by {@link org.openhab.core.library.types.DecimalType}). * * @author Theo Weiss * @since 1.4.0 */ public class DecimalValue extends Number implements TinkerforgeValue, Comparable { - private static final long serialVersionUID = -165912774170068480L; + private static final long serialVersionUID = -165912774170068480L; - final static public DecimalValue ZERO = new DecimalValue(0); + final static public DecimalValue ZERO = new DecimalValue(0); - protected BigDecimal value; + protected BigDecimal value; - public DecimalValue() { - this.value = BigDecimal.ZERO; - } + public DecimalValue() { + this.value = BigDecimal.ZERO; + } - public DecimalValue(BigDecimal value) { - this.value = value; - } + public DecimalValue(BigDecimal value) { + this.value = value; + } - public DecimalValue(long value) { - this.value = new BigDecimal(value); + public DecimalValue(long value) { + this.value = new BigDecimal(value); } - public DecimalValue(double value) { - this.value = new BigDecimal(value); - } + public DecimalValue(double value) { + this.value = new BigDecimal(value); + } - public DecimalValue(String value) { - this.value = new BigDecimal(value); - } + public DecimalValue(String value) { + this.value = new BigDecimal(value); + } - public String toString() { - return value.toPlainString(); - } + public String toString() { + return value.toPlainString(); + } - public static DecimalValue valueOf(String value) { - return new DecimalValue(value); + public static DecimalValue valueOf(String value) { + return new DecimalValue(value); } - public static DecimalValue valueOf(BigDecimal value) { - return new DecimalValue(value); + public static DecimalValue valueOf(BigDecimal value) { + return new DecimalValue(value); } - @Override - public int intValue() { - return value.intValue(); - } + @Override + public int intValue() { + return value.intValue(); + } - @Override - public long longValue() { - return value.longValue(); - } + @Override + public long longValue() { + return value.longValue(); + } - @Override - public float floatValue() { - return value.floatValue(); - } + @Override + public float floatValue() { + return value.floatValue(); + } - @Override - public double doubleValue() { - return value.doubleValue(); - } + @Override + public double doubleValue() { + return value.doubleValue(); + } - public BigDecimal bigDecimalValue() { - return value; - } - - @Override - public int compareTo(DecimalValue o) { - return value.compareTo(o.toBigDecimal()); + public BigDecimal bigDecimalValue() { + return value; } - /* - * Compare two values taking a threshold into account. - * - * If the absolute difference between the values is less then - * threshold 0 is returned elsewhere the values are compared - * using the compareTo function of BigDecimal. - */ - public int compareTo(DecimalValue o, BigDecimal threshold) { + public OnOffValue onOffValue(int scale) { + BigDecimal scaledvalue = value.setScale(0, BigDecimal.ROUND_UP); + return scaledvalue.compareTo(BigDecimal.ZERO) == 0 ? OnOffValue.OFF : OnOffValue.ON; + } + + @Override + public int compareTo(DecimalValue o) { + return value.compareTo(o.toBigDecimal()); + } + + /* + * Compare two values taking a threshold into account. + * + * If the absolute difference between the values is less then threshold 0 is returned elsewhere + * the values are compared using the compareTo function of BigDecimal. + */ + public int compareTo(DecimalValue o, BigDecimal threshold) { + if (o == null) { + return 1; + } else if (threshold == null) { + return value.compareTo(o.toBigDecimal().abs()); + } else if (o != null && threshold != null) { BigDecimal difference = value.subtract(o.toBigDecimal()).abs(); - if (difference.compareTo(threshold) < 0){ + if (difference.compareTo(threshold) < 0) { return 0; } - return value.compareTo(o.toBigDecimal()); + return value.compareTo(o.toBigDecimal().abs()); } + return 0; + } - private BigDecimal toBigDecimal() { - return value; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - DecimalValue other = (DecimalValue) obj; - if (value == null) { - if (other.value != null) - return false; - } else if (!value.equals(other.value)) - return false; - return true; - } + private BigDecimal toBigDecimal() { + return value; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + DecimalValue other = (DecimalValue) obj; + if (value == null) { + if (other.value != null) return false; + } else if (!value.equals(other.value)) return false; + return true; + } } diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/DirectionValue.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/DirectionValue.java new file mode 100644 index 00000000000..0f76859b3dd --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/DirectionValue.java @@ -0,0 +1,5 @@ +package org.openhab.binding.tinkerforge.internal.types; + +public enum DirectionValue implements TinkerforgeValue { + UNDEF, LEFT, RIGHT +} diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/PercentValue.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/PercentValue.java new file mode 100644 index 00000000000..ce8a488793a --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/PercentValue.java @@ -0,0 +1,18 @@ +package org.openhab.binding.tinkerforge.internal.types; + +import java.math.BigDecimal; + +import org.openhab.core.library.types.PercentType; + +public class PercentValue extends PercentType implements TinkerforgeValue { + + public PercentValue(BigDecimal bigDecimal) { + super(bigDecimal); + } + + /** + * + */ + private static final long serialVersionUID = 8087283524157935305L; + +} diff --git a/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/UpDownValue.java b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/UpDownValue.java new file mode 100644 index 00000000000..6a9ac09e2b3 --- /dev/null +++ b/bundles/binding/org.openhab.binding.tinkerforge/src/main/java/org/openhab/binding/tinkerforge/internal/types/UpDownValue.java @@ -0,0 +1,5 @@ +package org.openhab.binding.tinkerforge.internal.types; + +public enum UpDownValue implements TinkerforgeValue { + UP, DOWN +} diff --git a/bundles/binding/org.openhab.binding.urtsi/.classpath b/bundles/binding/org.openhab.binding.urtsi/.classpath index fca1d70c3e1..c75d087d3cc 100644 --- a/bundles/binding/org.openhab.binding.urtsi/.classpath +++ b/bundles/binding/org.openhab.binding.urtsi/.classpath @@ -1,9 +1,8 @@ - - - - - - - - - + + + + + + + + diff --git a/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/UrtsiBindingProvider.java b/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/UrtsiBindingProvider.java index 1f9063d8d68..85b84e7f758 100644 --- a/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/UrtsiBindingProvider.java +++ b/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/UrtsiBindingProvider.java @@ -1,25 +1,24 @@ -/** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.urtsi; - -import org.openhab.binding.urtsi.internal.UrtsiDevice; -import org.openhab.core.autoupdate.AutoUpdateBindingProvider; - -/** - * @author Oliver Libutzki - * @since 1.3.0 - * - */ -public interface UrtsiBindingProvider extends AutoUpdateBindingProvider { - - String getDeviceId(String itemName); - - int getChannel (String itemName); - int getAddress (String itemName); -} +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.urtsi; + +import org.openhab.core.autoupdate.AutoUpdateBindingProvider; + +/** + * @author Oliver Libutzki + * @since 1.3.0 + * + */ +public interface UrtsiBindingProvider extends AutoUpdateBindingProvider { + + String getDeviceId(String itemName); + + int getChannel (String itemName); + int getAddress (String itemName); +} diff --git a/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiBinding.java b/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiBinding.java index 803d40608ce..15d1a066ae4 100644 --- a/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiBinding.java +++ b/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiBinding.java @@ -1,222 +1,265 @@ -/** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.urtsi.internal; - -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.openhab.binding.urtsi.UrtsiBindingProvider; -import org.openhab.core.binding.AbstractBinding; -import org.openhab.core.library.types.StopMoveType; -import org.openhab.core.library.types.UpDownType; -import org.openhab.core.types.Command; -import org.openhab.core.types.State; -import org.openhab.core.types.Type; -import org.openhab.model.item.binding.BindingConfigParseException; -import org.osgi.service.cm.ConfigurationException; -import org.osgi.service.cm.ManagedService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Main implementation of the Somfy URTSI II Binding. This binding is - * responsible for delegating the received commands and updates to the - * {@link UrtsiDevice}. - * - * @author Oliver Libutzki - * @since 1.3.0 - * - */ -public class UrtsiBinding extends AbstractBinding - implements ManagedService { - - private final static Logger logger = LoggerFactory - .getLogger(UrtsiBinding.class); - - private final static String COMMAND_UP = "U"; - private final static String COMMAND_DOWN = "D"; - private final static String COMMAND_STOP = "S"; - - private final static Pattern EXTRACT_URTSI_CONFIG_PATTERN = Pattern - .compile("^(.*?)\\.(port)$"); - - /** - * Maps the device id to a URTSI device. This is needed if you use multiple - * ports for multiple urtsi devices. - */ - private final Map idToDeviceMap = new HashMap(); - - /** - * The method determines the appropriate - * {@link org.openhab.core.binding.BindingProvider} and uses it to get the - * corresponding URTSI device and channel. Bases on the given type a command - * is send to the device. - * - * @param itemName - * name of the item - * @param type - * Type of the command or status update - * @return Returns true, if the command has been executed successfully. - * Returns false otherwise. - * @throws BindingConfigParseException - */ - private boolean sendToUrtsi(String itemName, Type type) { - UrtsiBindingProvider provider = null; - if (!providers.isEmpty()) { - provider = providers.iterator().next(); - } - if (provider == null) { - if (logger.isErrorEnabled()) { - logger.error("doesn't find matching binding provider [itemName={}, type={}]", itemName, type); - } - return false; - } - String urtsiDeviceId = provider.getDeviceId(itemName); - UrtsiDevice urtsiDevice = idToDeviceMap.get(urtsiDeviceId); - - if (urtsiDevice == null) { - if (logger.isErrorEnabled()) { - logger.error("No serial port has been configured for urtsi device id '" + urtsiDeviceId +"'"); - } - return false; - } - - int channel = provider.getChannel(itemName); - int address = provider.getAddress(itemName); - - if (urtsiDevice != null) { - if (logger.isDebugEnabled()) { - logger.debug("Send to URTSI for item: " + itemName + "; Type: " + type); - } - String actionKey = null; - if (type instanceof UpDownType) { - switch ((UpDownType)type) { - case UP : - actionKey = COMMAND_UP; - break; - case - DOWN : actionKey = COMMAND_DOWN; - break; - } - } else if (type instanceof StopMoveType) { - switch ((StopMoveType)type) { - case STOP : - actionKey = COMMAND_STOP; - break; - default: - break; - } - } - - - if (logger.isDebugEnabled()) { - logger.debug("Action key: " + actionKey); - } - if (actionKey != null) { - String channelString = String.format("%02d", channel); - String addressString = String.format("%02d", address); - String command = addressString + channelString + actionKey; - boolean executedSuccessfully = urtsiDevice.writeString(command); - if (!executedSuccessfully) { - if (logger.isErrorEnabled()) { - logger.error("Command has not been processed [itemName={}, command={}]", itemName, command); - } - } - return executedSuccessfully; - } - } - return false; - } - - /** - * The method delegates the received command to the URTSI device and updates - * the item's state, if the command has been executed successfully. - */ - protected void internalReceiveCommand(String itemName, Command command) { - if (logger.isDebugEnabled()) { - logger.debug("Received command for " + itemName + "! Command: " + command); - } - boolean executedSuccessfully = sendToUrtsi(itemName, command); - if (executedSuccessfully && command instanceof State) { - eventPublisher.postUpdate(itemName, (State)command); - } - } - - /** - * The method delegates the received state-update to the URTSI device. - */ - protected void internalReceiveUpdate(String itemName, State newState) { - if (logger.isDebugEnabled()) { - logger.debug("Received update for " + itemName + "! New state: " + newState); - } - sendToUrtsi(itemName, newState); - } - - /** - * Parses the global configuration file. - * Expected values: - * urtsi..port= - */ - public void updated(Dictionary config) throws ConfigurationException { - - if (config != null) { - Enumeration keys = config.keys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - logger.debug("Processing key '" + key + "'"); - // the config-key enumeration contains additional keys that we - // don't want to process here ... - if (key != "service.pid") { - - Matcher matcher = EXTRACT_URTSI_CONFIG_PATTERN.matcher(key); - if (!matcher.matches()) { - logger.debug("given config key '" - + key - + "' does not follow the expected pattern '.port'"); - } else { - matcher.reset(); - matcher.find(); - - String deviceId = matcher.group(1); - UrtsiDevice urtsiDevice = idToDeviceMap.get(deviceId); - if (urtsiDevice == null) { - String configKey = matcher.group(2); - String value = (String)config.get(key); - String port = null; - if ("port".equals(configKey)) { - port = value; - } else { - throw new ConfigurationException(configKey, "the given config key '" + configKey + "' is unknown"); - } - urtsiDevice = new UrtsiDevice(port); - try { - System.setProperty("gnu.io.rxtx.SerialPorts", port); - urtsiDevice.initialize(); - } catch (InitializationException e) { - throw new ConfigurationException(configKey, - "Could not open serial port " + port + ": " - + e.getMessage()); - } catch (Throwable e) { - throw new ConfigurationException(configKey, - "Could not open serial port " + port + ": " - + e.getMessage()); - } - idToDeviceMap.put(deviceId, urtsiDevice); - } - } - } - } - } - } - -} +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.urtsi.internal; + +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.openhab.binding.urtsi.UrtsiBindingProvider; +import org.openhab.core.binding.AbstractBinding; +import org.openhab.core.library.types.StopMoveType; +import org.openhab.core.library.types.UpDownType; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.core.types.Type; +import org.openhab.model.item.binding.BindingConfigParseException; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.collect.Sets; + +/** + * Main implementation of the Somfy URTSI II Binding. This binding is + * responsible for delegating the received commands and updates to the + * {@link UrtsiDevice}. + * + * @author Oliver Libutzki + * @since 1.3.0 + * + */ +public class UrtsiBinding extends AbstractBinding + implements ManagedService { + + private static final String GNU_IO_RXTX_SERIAL_PORTS = "gnu.io.rxtx.SerialPorts"; + + private final static Logger logger = LoggerFactory + .getLogger(UrtsiBinding.class); + + private final static String COMMAND_UP = "U"; + private final static String COMMAND_DOWN = "D"; + private final static String COMMAND_STOP = "S"; + + private final static String CONFIG_PORT = "port"; + private final static String CONFIG_INTERVAL = "interval"; + + private final static Pattern EXTRACT_URTSI_CONFIG_PATTERN = Pattern + .compile("^(.*?)\\.(" + CONFIG_PORT + "|" + CONFIG_INTERVAL + ")$"); + + /** + * Maps the device id to a URTSI device. This is needed if you use multiple + * ports for multiple urtsi devices. + */ + private final Map idToDeviceMap = new HashMap(); + + /** + * The method determines the appropriate + * {@link org.openhab.core.binding.BindingProvider} and uses it to get the + * corresponding URTSI device and channel. Bases on the given type a command + * is send to the device. + * + * @param itemName + * name of the item + * @param type + * Type of the command or status update + * @return Returns true, if the command has been executed successfully. + * Returns false otherwise. + * @throws BindingConfigParseException + */ + private boolean sendToUrtsi(String itemName, Type type) { + UrtsiBindingProvider provider = null; + if (!providers.isEmpty()) { + provider = providers.iterator().next(); + } + if (provider == null) { + if (logger.isErrorEnabled()) { + logger.error("doesn't find matching binding provider [itemName={}, type={}]", itemName, type); + } + return false; + } + String urtsiDeviceId = provider.getDeviceId(itemName); + UrtsiDevice urtsiDevice = idToDeviceMap.get(urtsiDeviceId); + + if (urtsiDevice == null) { + if (logger.isErrorEnabled()) { + logger.error("No serial port has been configured for urtsi device id '" + urtsiDeviceId +"'"); + } + return false; + } + + int channel = provider.getChannel(itemName); + int address = provider.getAddress(itemName); + + if (urtsiDevice != null) { + if (logger.isDebugEnabled()) { + logger.debug("Send to URTSI for item: " + itemName + "; Type: " + type); + } + String actionKey = null; + if (type instanceof UpDownType) { + switch ((UpDownType)type) { + case UP : + actionKey = COMMAND_UP; + break; + case + DOWN : actionKey = COMMAND_DOWN; + break; + } + } else if (type instanceof StopMoveType) { + switch ((StopMoveType)type) { + case STOP : + actionKey = COMMAND_STOP; + break; + default: + break; + } + } + + + if (logger.isDebugEnabled()) { + logger.debug("Action key: " + actionKey); + } + if (actionKey != null) { + String channelString = String.format("%02d", channel); + String addressString = String.format("%02d", address); + String command = addressString + channelString + actionKey; + boolean executedSuccessfully = urtsiDevice.writeString(command); + if (!executedSuccessfully) { + if (logger.isErrorEnabled()) { + logger.error("Command has not been processed [itemName={}, command={}]", itemName, command); + } + } + return executedSuccessfully; + } + } + return false; + } + + /** + * The method delegates the received command to the URTSI device and updates + * the item's state, if the command has been executed successfully. + */ + protected void internalReceiveCommand(String itemName, Command command) { + if (logger.isDebugEnabled()) { + logger.debug("Received command for " + itemName + "! Command: " + command); + } + boolean executedSuccessfully = sendToUrtsi(itemName, command); + if (executedSuccessfully && command instanceof State) { + eventPublisher.postUpdate(itemName, (State)command); + } + } + + /** + * With openHAB 1.7.0 the state-update is not passed to the URTSI device anymore as this let to multiple actions in the past. + * + */ + protected void internalReceiveUpdate(String itemName, State newState) { + if (logger.isDebugEnabled()) { + logger.debug("Received update for " + itemName + "! New state: " + newState); + } + } + + /** + * Parses the global configuration file. + * Expected values: + * urtsi..port= + * urtsi..interval= (optional, default: 100) + */ + public void updated(Dictionary config) throws ConfigurationException { + + if (config != null) { + Map errorMessages = new LinkedHashMap(); + Enumeration keys = config.keys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + logger.debug("Processing key '" + key + "'"); + // the config-key enumeration contains additional keys that we + // don't want to process here ... + if (key != "service.pid") { + + Matcher matcher = EXTRACT_URTSI_CONFIG_PATTERN.matcher(key); + if (!matcher.matches()) { + logger.debug("given config key '" + + key + + "' does not follow the expected pattern '.port'"); + } else { + matcher.reset(); + matcher.find(); + + String deviceId = matcher.group(1); + UrtsiDevice urtsiDevice = idToDeviceMap.get(deviceId); + if (urtsiDevice == null) { + urtsiDevice = new UrtsiDevice(); + idToDeviceMap.put(deviceId, urtsiDevice); + } + String configKey = matcher.group(2); + String value = (String)config.get(key); + if (CONFIG_PORT.equals(configKey)) { + urtsiDevice.setPort(value); + } else if (CONFIG_INTERVAL.equals(configKey)) { + urtsiDevice.setInterval(Integer.valueOf(value)); + } else { + errorMessages.put(configKey, "the given config key '" + configKey + "' is unknown"); + } + } + } + } + + for (Iterator> deviceIterator = idToDeviceMap.entrySet().iterator(); deviceIterator.hasNext();) { + Entry deviceEntry = deviceIterator.next(); + UrtsiDevice urtsiDevice = deviceEntry.getValue(); + try { + String serialPortsProperty = System.getProperty(GNU_IO_RXTX_SERIAL_PORTS); + Set serialPorts = null; + if (serialPortsProperty != null) { + serialPorts = Sets.newHashSet(Splitter.on(":").split(serialPortsProperty)); + } else { + serialPorts = new HashSet(); + } + if (serialPorts.add(urtsiDevice.getPort())) { + logger.debug("Added {} to the {} system property.", urtsiDevice.getPort(), GNU_IO_RXTX_SERIAL_PORTS ); + } + System.setProperty(GNU_IO_RXTX_SERIAL_PORTS, Joiner.on(":").join(serialPorts)); + urtsiDevice.initialize(); + } catch (Throwable e) { + deviceIterator.remove(); + errorMessages.put(deviceEntry.getKey(), e.getMessage()); + } + } + + if (!errorMessages.isEmpty()) { + StringBuilder errorMessageStringBuilder = new StringBuilder("The following errors occurred:\r\n"); + for (Iterator> errorMessageIterator = errorMessages.entrySet().iterator(); errorMessageIterator + .hasNext();) { + Entry errorMessageEntry = errorMessageIterator.next(); + errorMessageStringBuilder.append(errorMessageEntry.getKey()).append(": ").append(errorMessageEntry.getValue()); + if (errorMessageIterator.hasNext()) { + errorMessageStringBuilder.append("\r\n"); + } + } + logger.error(errorMessageStringBuilder.toString()); + Entry firstErrorMessageEntry = errorMessages.entrySet().iterator().next(); + throw new ConfigurationException(firstErrorMessageEntry.getKey(), firstErrorMessageEntry.getValue()); + } + + } + } + +} diff --git a/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiDevice.xtend b/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiDevice.xtend index e9b58294b88..3ae097103fc 100644 --- a/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiDevice.xtend +++ b/bundles/binding/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiDevice.xtend @@ -1,184 +1,194 @@ -package org.openhab.binding.urtsi.internal - -import gnu.io.CommPortIdentifier -import gnu.io.PortInUseException -import gnu.io.SerialPort -import gnu.io.SerialPortEvent -import gnu.io.UnsupportedCommOperationException -import java.io.IOException -import java.io.InputStream -import java.io.OutputStream -import java.util.List -import org.apache.commons.io.IOUtils -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import static org.openhab.binding.urtsi.internal.ArrayHelper.* -import static org.openhab.binding.urtsi.internal.UrtsiDevice.* - -/** - * Implementation of the device. This class is responsible for communicating to the hardware which is connected via a serial port. - * It completely encapsulates the serial communication and just provides a writeString method which returns true, if the message has been transmitted successfully. - * @author Oliver Libutzki - * @since 1.3.0 - * - */ -class UrtsiDevice { - - static val Logger logger = LoggerFactory::getLogger(typeof(UrtsiDevice)) - - static val int baud = 9600 - static val int databits = SerialPort::DATABITS_8 - static val int stopbit = SerialPort::STOPBITS_1 - static val int parity = SerialPort::PARITY_NONE - - // Serial communication fields - String port - - CommPortIdentifier portId - SerialPort serialPort - OutputStream outputStream - InputStream inputStream - - DedicatedThreadExecutor threadExecutor = new DedicatedThreadExecutor - - public new(String port) { - this.port = port - } - - /** - * Initialize this device and open the serial port - * - * @throws InitializationException - * if port can not be opened - */ - def void initialize() throws InitializationException { - // parse ports and if the default port is found, initialized the reader - var portList = CommPortIdentifier::portIdentifiers - while (portList.hasMoreElements) { - val id = portList.nextElement() as CommPortIdentifier - if (id.portType == CommPortIdentifier::PORT_SERIAL) { - if (id.name.equals(port)) { - logger.debug("Serial port '{}' has been found.", port) - portId = id - } - } - } - if (portId != null) { - // initialize serial port - try { - serialPort = portId.open("openHAB", 2000) as SerialPort - } catch (PortInUseException e) { - throw new InitializationException(e) - } - - try { - // set port parameters - serialPort.setSerialPortParams(baud, databits, stopbit, parity) - } catch (UnsupportedCommOperationException e) { - throw new InitializationException(e) - } - - try { - inputStream = serialPort.inputStream - } catch (IOException e) { - throw new InitializationException(e) - } - - try { - // get the output stream - outputStream = serialPort.outputStream - } catch (IOException e) { - throw new InitializationException(e) - } - } else { - val sb = new StringBuilder() - portList = CommPortIdentifier::portIdentifiers - while (portList.hasMoreElements()) { - val id = portList.nextElement() as CommPortIdentifier - if (id.portType == CommPortIdentifier::PORT_SERIAL) { - sb.append(id.name + "\n"); - } - } - throw new InitializationException("Serial port '" + port - + "' could not be found. Available ports are:\n" - + sb.toString()); - } - } - - - /** - * Sends a string to the serial port of this device. - * The execution of the msg is executed in a dedicated Thread, so it's guaranteed that the device doesn't get multiple messages concurrently. - * - * @param msg - * the string to send - * @return Returns true, if the message has been transmitted successfully, otherwise false. - */ - def boolean writeString(String msg) { - logger.debug("Writing '{}' to serial port {}", newArrayList( msg, port )) - val future = - threadExecutor.execute( [ - try { - val List listenerResult = newArrayList - serialPort.addEventListener[event | - switch (event.eventType) { - case SerialPortEvent::DATA_AVAILABLE: { - // we get here if data has been received - val sb = new StringBuilder() - val readBuffer = getByteArray(20) - try { - do { - // read data from serial device - while (inputStream.available > 0) { - val bytes = inputStream.read(readBuffer) - sb.append(new String(readBuffer, 0, bytes)) - } - try { - // add wait states around reading the stream, so that interrupted transmissions are merged - Thread::sleep(100) - } catch (InterruptedException e) { - // ignore interruption - } - } while (inputStream.available > 0) - val result = sb.toString - if (result == msg) { - listenerResult.add(true) - } - - } catch (IOException e) { - logger.debug("Error receiving data on serial port {}: {}", newArrayList( port, e.message )) - } - } - } - - ] - serialPort.notifyOnDataAvailable(true) - outputStream.write(msg.bytes) - outputStream.flush() - val timeout = System::currentTimeMillis + 1000 - while (listenerResult.empty && System::currentTimeMillis < timeout) { - // Waiting for response - Thread::sleep(100) - } - return !listenerResult.empty - } catch (IOException e) { - logger.error("Error writing '{}' to serial port {}: {}", - newArrayList ( msg, port, e.getMessage() )) - } finally { - serialPort.removeEventListener() - } - ]) - future.get - } - - /** - * Close this serial device - */ - def void close() { - serialPort.removeEventListener - IOUtils::closeQuietly(outputStream) - IOUtils::closeQuietly(inputStream) - serialPort.close - } +package org.openhab.binding.urtsi.internal + +import gnu.io.CommPortIdentifier +import gnu.io.PortInUseException +import gnu.io.SerialPort +import gnu.io.SerialPortEvent +import gnu.io.UnsupportedCommOperationException +import java.io.IOException +import java.io.InputStream +import java.io.OutputStream +import java.util.List +import org.apache.commons.io.IOUtils +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import static org.openhab.binding.urtsi.internal.ArrayHelper.* +import static org.openhab.binding.urtsi.internal.UrtsiDevice.* + +/** + * Implementation of the device. This class is responsible for communicating to the hardware which is connected via a serial port. + * It completely encapsulates the serial communication and just provides a writeString method which returns true, if the message has been transmitted successfully. + * @author Oliver Libutzki + * @since 1.3.0 + * + */ +class UrtsiDevice { + + static val Logger logger = LoggerFactory::getLogger(typeof(UrtsiDevice)) + + static val int baud = 9600 + static val int databits = SerialPort::DATABITS_8 + static val int stopbit = SerialPort::STOPBITS_1 + static val int parity = SerialPort::PARITY_NONE + + // Serial communication fields + @Property + String port + + @Property + int interval = 100 + + long lastCommandTime = 0 + + CommPortIdentifier portId + SerialPort serialPort + OutputStream outputStream + InputStream inputStream + + DedicatedThreadExecutor threadExecutor = new DedicatedThreadExecutor + + public new() { + } + + /** + * Initialize this device and open the serial port + * + * @throws InitializationException + * if port can not be opened + */ + def void initialize() throws InitializationException { + // parse ports and if the default port is found, initialized the reader + var portList = CommPortIdentifier::portIdentifiers + while (portList.hasMoreElements) { + val id = portList.nextElement() as CommPortIdentifier + if (id.portType == CommPortIdentifier::PORT_SERIAL) { + if (id.name.equals(port)) { + logger.debug("Serial port '{}' has been found.", port) + portId = id + } + } + } + if (portId != null) { + // initialize serial port + try { + serialPort = portId.open("openHAB", 2000) as SerialPort + } catch (PortInUseException e) { + throw new InitializationException(e) + } + + try { + // set port parameters + serialPort.setSerialPortParams(baud, databits, stopbit, parity) + } catch (UnsupportedCommOperationException e) { + throw new InitializationException(e) + } + + try { + inputStream = serialPort.inputStream + } catch (IOException e) { + throw new InitializationException(e) + } + + try { + // get the output stream + outputStream = serialPort.outputStream + } catch (IOException e) { + throw new InitializationException(e) + } + } else { + val sb = new StringBuilder() + portList = CommPortIdentifier::portIdentifiers + while (portList.hasMoreElements()) { + val id = portList.nextElement() as CommPortIdentifier + if (id.portType == CommPortIdentifier::PORT_SERIAL) { + sb.append(id.name + "\n"); + } + } + throw new InitializationException("Serial port '" + port + + "' could not be found. Available ports are:\n" + + sb.toString()); + } + } + + + /** + * Sends a string to the serial port of this device. + * The execution of the msg is executed in a dedicated Thread, so it's guaranteed that the device doesn't get multiple messages concurrently. + * + * @param msg + * the string to send + * @return Returns true, if the message has been transmitted successfully, otherwise false. + */ + def boolean writeString(String msg) { + logger.debug("Writing '{}' to serial port {}", msg, port ) + val future = + threadExecutor.execute( [ + val earliestNextExecution = lastCommandTime + interval + while ( earliestNextExecution > System::currentTimeMillis) { + Thread::sleep(100) + } + try { + val List listenerResult = newArrayList + serialPort.addEventListener[event | + switch (event.eventType) { + case SerialPortEvent::DATA_AVAILABLE: { + // we get here if data has been received + val sb = new StringBuilder() + val readBuffer = getByteArray(20) + try { + do { + // read data from serial device + while (inputStream.available > 0) { + val bytes = inputStream.read(readBuffer) + sb.append(new String(readBuffer, 0, bytes)) + } + try { + // add wait states around reading the stream, so that interrupted transmissions are merged + Thread::sleep(100) + } catch (InterruptedException e) { + // ignore interruption + } + } while (inputStream.available > 0) + val result = sb.toString + if (result == msg) { + listenerResult.add(true) + } + + } catch (IOException e) { + logger.debug("Error receiving data on serial port {}: {}", newArrayList( port, e.message )) + } + } + } + + ] + serialPort.notifyOnDataAvailable(true) + outputStream.write(msg.bytes) + outputStream.flush() + lastCommandTime = System::currentTimeMillis + val timeout = lastCommandTime + 1000 + while (listenerResult.empty && System::currentTimeMillis < timeout) { + // Waiting for response + Thread::sleep(100) + } + return !listenerResult.empty + } catch (IOException e) { + logger.error("Error writing '{}' to serial port {}: {}", + newArrayList ( msg, port, e.getMessage() )) + } finally { + serialPort.removeEventListener() + } + ]) + future.get + } + + /** + * Close this serial device + */ + def void close() { + serialPort.removeEventListener + IOUtils::closeQuietly(outputStream) + IOUtils::closeQuietly(inputStream) + serialPort.close + } } \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.wago/.classpath b/bundles/binding/org.openhab.binding.wago/.classpath index f88c2bd789f..fc32b9b49d1 100644 --- a/bundles/binding/org.openhab.binding.wago/.classpath +++ b/bundles/binding/org.openhab.binding.wago/.classpath @@ -4,7 +4,6 @@ - - + diff --git a/bundles/binding/org.openhab.binding.weather/.classpath b/bundles/binding/org.openhab.binding.weather/.classpath index 5970cc9f19c..be45340687b 100644 --- a/bundles/binding/org.openhab.binding.weather/.classpath +++ b/bundles/binding/org.openhab.binding.weather/.classpath @@ -4,7 +4,6 @@ - diff --git a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/bus/BindingConfigParser.java b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/bus/BindingConfigParser.java index 7a6673bbae9..1a8ed493f38 100644 --- a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/bus/BindingConfigParser.java +++ b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/bus/BindingConfigParser.java @@ -31,7 +31,7 @@ *
        * Number  Temperature    "Temperature [%.2f °C]"        {weather="locationId=home, type=temperature, property=current"} 
        * Number  Temperature_F  "Temperature [%.2f °F]"        {weather="locationId=home, type=temperature, property=current, unit=fahrenheit"} 
      - * Number  Humidity       "Humidity [%.0f %]"            {weather="locationId=home, type=athmosphere, property=humidity"}
      + * Number  Humidity       "Humidity [%.0f %]"            {weather="locationId=home, type=atmosphere, property=humidity"}
        * Number  Rain           "Rain [%.2f mm]"               {weather="locationId=home, type=precipitation, property=rain"}
        * 
        * Number  Temperature    "Temperature [%.0f °C]"        {weather="locationId=home, type=precipitation, property=rain, roundingMode=ceiling, scale=0"}
      @@ -76,6 +76,8 @@ public WeatherBindingConfig parse(Item item, String bindingConfig) throws Bindin
       			throw new BindingConfigParseException("Invalid binding: " + bindingConfig);
       		}
       
      +		helper.type = StringUtils.replace(helper.type, "athmosphere", "atmosphere");
      +		
       		WeatherBindingConfig weatherConfig = null;
       		if (helper.isForecast()) {
       			Integer forecast = parseInteger(helper.forecast, bindingConfig);
      diff --git a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/bus/WeatherPublisher.java b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/bus/WeatherPublisher.java
      index 0e2abb7bdc3..0701723edb1 100644
      --- a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/bus/WeatherPublisher.java
      +++ b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/bus/WeatherPublisher.java
      @@ -166,7 +166,11 @@ private Weather getInstance(Weather weather, WeatherBindingConfig bindingConfig)
       	 * Returns true, if the cached value is equal to the new value.
       	 */
       	private boolean equalsCachedValue(Object value, String itemName) {
      -		int cachedValueHashCode = ObjectUtils.hashCode(itemCache.get(itemName));
      +		Object cachedValue = itemCache.get(itemName);
      +		if (cachedValue == null && value != null) {
      +			return false;
      +		}
      +		int cachedValueHashCode = ObjectUtils.hashCode(cachedValue);
       		int valueHashCode = ObjectUtils.hashCode(value);
       		return cachedValueHashCode == valueHashCode;
       	}
      diff --git a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/model/Athmosphere.java b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/model/Atmosphere.java
      similarity index 98%
      rename from bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/model/Athmosphere.java
      rename to bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/model/Atmosphere.java
      index 4e570ef815d..da30ad735f6 100644
      --- a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/model/Athmosphere.java
      +++ b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/model/Atmosphere.java
      @@ -15,12 +15,12 @@
       import org.openhab.binding.weather.internal.converter.ConverterType;
       
       /**
      - * Common provider model for athmosphere data.
      + * Common provider model for atmosphere data.
        * 
        * @author Gerhard Riegler
        * @since 1.6.0
        */
      -public class Athmosphere {
      +public class Atmosphere {
       
       	@ProviderMappings({
       			@Provider(name = ProviderName.WUNDERGROUND, property = "current_observation.relative_humidity", converter = ConverterType.PERCENT_INTEGER),
      diff --git a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/model/Weather.java b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/model/Weather.java
      index 0fd155b55c3..470945ac0d1 100644
      --- a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/model/Weather.java
      +++ b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/model/Weather.java
      @@ -29,7 +29,7 @@ public class Weather {
       	public static final String VIRTUAL_TEMP_MINMAX = "temperature.minMax";
       	private static final String[] VIRTUAL_PROPERTIES = new String[] { VIRTUAL_TEMP_MINMAX };
       
      -	private Athmosphere athmosphere = new Athmosphere();
      +	private Atmosphere atmosphere = new Atmosphere();
       	private Clouds clouds = new Clouds();
       	private Condition condition = new Condition();
       	private Precipitation precipitation = new Precipitation();
      @@ -71,10 +71,10 @@ public Weather(ProviderName provider) {
       	}
       
       	/**
      -	 * Returns athmosphere data.
      +	 * Returns atmosphere data.
       	 */
      -	public Athmosphere getAthmosphere() {
      -		return athmosphere;
      +	public Atmosphere getAtmosphere() {
      +		return atmosphere;
       	}
       
       	/**
      @@ -170,7 +170,7 @@ public String toString() {
       		if (this instanceof org.openhab.binding.weather.internal.model.Forecast) {
       			tsb.append("day", ((org.openhab.binding.weather.internal.model.Forecast) this).getDay());
       		}
      -		tsb.append(temperature).append(athmosphere).append(clouds).append(condition).append(precipitation).append(wind)
      +		tsb.append(temperature).append(atmosphere).append(clouds).append(condition).append(precipitation).append(wind)
       				.append(error);
       
       		return tsb.toString();
      diff --git a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/parser/AbstractWeatherParser.java b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/parser/AbstractWeatherParser.java
      index 717038e1e90..884390cb8c7 100644
      --- a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/parser/AbstractWeatherParser.java
      +++ b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/parser/AbstractWeatherParser.java
      @@ -15,7 +15,7 @@
       import org.openhab.binding.weather.internal.converter.Converter;
       import org.openhab.binding.weather.internal.metadata.MetadataHandler;
       import org.openhab.binding.weather.internal.metadata.ProviderMappingInfo;
      -import org.openhab.binding.weather.internal.model.Athmosphere;
      +import org.openhab.binding.weather.internal.model.Atmosphere;
       import org.openhab.binding.weather.internal.model.Forecast;
       import org.openhab.binding.weather.internal.model.Precipitation;
       import org.openhab.binding.weather.internal.model.ProviderName;
      @@ -130,9 +130,9 @@ public void postProcessEach(Weather weather) throws Exception {
       			temp.setCurrent(null);
       		}
       
      -		Athmosphere athm = weather.getAthmosphere();
      -		if (temp.getFeel() == null && temp.getCurrent() != null && athm.getHumidity() != null) {
      -			Double humidex = UnitUtils.getHumidex(temp.getCurrent(), athm.getHumidity());
      +		Atmosphere atm = weather.getAtmosphere();
      +		if (temp.getFeel() == null && temp.getCurrent() != null && atm.getHumidity() != null) {
      +			Double humidex = UnitUtils.getHumidex(temp.getCurrent(), atm.getHumidity());
       			temp.setFeel(humidex);
       		}
       
      @@ -153,11 +153,11 @@ public void postProcessEach(Weather weather) throws Exception {
       			precip.setRain(null);
       		}
       
      -		if (precip.getSnow() != null && precip.getSnow() == 0.0) {
      -			precip.setSnow(null);
      +		if (precip.getSnow() == null) {
      +			precip.setSnow(0.0);
       		}
      -		if (precip.getRain() != null && precip.getRain() == 0.0) {
      -			precip.setRain(null);
      +		if (precip.getRain() == null) {
      +			precip.setRain(0.0);
       		}
       
       		CommonIdHandler.getInstance().setCommonId(weather);
      @@ -168,16 +168,16 @@ public void postProcessEach(Weather weather) throws Exception {
       	 */
       	@Override
       	public void postProcess(Weather weather) throws Exception {
      -		Double currentPressure = weather.getAthmosphere().getPressure();
      +		Double currentPressure = weather.getAtmosphere().getPressure();
       		if (currentPressure != null && weather.getForecast().size() > 0) {
      -			Double fcPressure = weather.getForecast().get(0).getAthmosphere().getPressure();
      +			Double fcPressure = weather.getForecast().get(0).getAtmosphere().getPressure();
       			if (fcPressure != null) {
       				if (fcPressure > currentPressure) {
      -					weather.getAthmosphere().setPressureTrend("up");
      +					weather.getAtmosphere().setPressureTrend("up");
       				} else if (fcPressure < currentPressure) {
      -					weather.getAthmosphere().setPressureTrend("down");
      +					weather.getAtmosphere().setPressureTrend("down");
       				} else {
      -					weather.getAthmosphere().setPressureTrend("equal");
      +					weather.getAtmosphere().setPressureTrend("equal");
       				}
       			}
       		}
      diff --git a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/utils/UnitUtils.java b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/utils/UnitUtils.java
      index 0c0d0c48832..e1bc09d8861 100644
      --- a/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/utils/UnitUtils.java
      +++ b/bundles/binding/org.openhab.binding.weather/src/main/java/org/openhab/binding/weather/internal/utils/UnitUtils.java
      @@ -151,7 +151,7 @@ public static Double convertUnit(Double value, WeatherBindingConfig bindingConfi
       			case MPH:
       				return kmhToMph(value);
       			case INCHES:
      -				if ("athmosphere.pressure".equals(bindingConfig.getWeatherProperty())) {
      +				if ("atmosphere.pressure".equals(bindingConfig.getWeatherProperty())) {
       					return millibarToInches(value);
       				} else if ("precipitation.snow".equals(bindingConfig.getWeatherProperty())) {
       					return millimetersToInches(centimeterToMillimeter(value));
      diff --git a/bundles/binding/org.openhab.binding.zwave/.classpath b/bundles/binding/org.openhab.binding.zwave/.classpath
      index b92c9186e05..d2a42a66eca 100644
      --- a/bundles/binding/org.openhab.binding.zwave/.classpath
      +++ b/bundles/binding/org.openhab.binding.zwave/.classpath
      @@ -4,7 +4,6 @@
       	
       	
       	
      -	
       	
       	
       
      diff --git a/bundles/binding/org.openhab.binding.zwave/META-INF/MANIFEST.MF b/bundles/binding/org.openhab.binding.zwave/META-INF/MANIFEST.MF
      index 297f62d5057..33b235c691e 100644
      --- a/bundles/binding/org.openhab.binding.zwave/META-INF/MANIFEST.MF
      +++ b/bundles/binding/org.openhab.binding.zwave/META-INF/MANIFEST.MF
      @@ -24,7 +24,12 @@ Import-Package: gnu.io,
        org.osgi.service.cm,
        org.osgi.service.component,
        org.osgi.service.event,
      - org.slf4j
      + org.slf4j,
      + javax.security.auth,
      + javax.xml.namespace,
      + javax.xml.stream,
      + javax.xml.transform,
      + javax.xml.transform.stream
       Export-Package: org.openhab.binding.zwave,org.openhab.binding.zwave.in
        ternal.config
       Bundle-DocURL: http://www.openhab.org
      diff --git a/bundles/binding/org.openhab.binding.zwave/database/aeon/4in1ms.xml b/bundles/binding/org.openhab.binding.zwave/database/aeon/4in1ms.xml
      index 4ccacd670a5..7441c3ca213 100644
      --- a/bundles/binding/org.openhab.binding.zwave/database/aeon/4in1ms.xml
      +++ b/bundles/binding/org.openhab.binding.zwave/database/aeon/4in1ms.xml
      @@ -20,6 +20,7 @@
       			list
       			0
       			1
      +			true
       			
       			
       			
      @@ -48,6 +49,7 @@
       			list
       			0
       			1
      +			true
       			
       			
       			
      @@ -96,6 +98,7 @@
       			list
       			1
       			1
      +			true
       			
       			
       				1
      diff --git a/bundles/binding/org.openhab.binding.zwave/database/aeon/4in1ms_g5.xml b/bundles/binding/org.openhab.binding.zwave/database/aeon/4in1ms_g5.xml
      new file mode 100644
      index 00000000000..c95b9535b25
      --- /dev/null
      +++ b/bundles/binding/org.openhab.binding.zwave/database/aeon/4in1ms_g5.xml
      @@ -0,0 +1,179 @@
      +
      +
      +	4in1MS
      +	
      +	
      +	
      +		0x20
      +		0x30
      +		0x31
      +		0x70
      +		0x72
      +		0x80
      +		0x84
      +		0x85
      +		0x86
      +	
      +	
      +		
      +			1
      +			list
      +			0
      +			1
      +			true
      +			
      +			
      +			
      +				0
      +				
      +				
      +			
      +			
      +				1
      +				
      +				
      +			
      +			
      +				2
      +				
      +				
      +			
      +			
      +				3
      +				
      +				
      +			
      +		
      +		
      +			2
      +			list
      +			0
      +			1
      +			true
      +			
      +			
      +			
      +				0
      +				
      +				
      +			
      +			
      +				1
      +				
      +				
      +			
      +		
      +		
      +			3
      +			short
      +			1
      +			15300
      +			240
      +			2
      +			
      +			
      +			How long should the device associated to multi sensor keep state On before sending it Off command (if the value is bigger than 255, the value would be rounded to next integer in minutes)
      +			Wie lang soll das assozierte Gerät eingeschaltet bleiben bevor es wieder ausgeschaltet wird (wenn der Wert grösser als 255 ist, wird der Wert in Minuten gerundet
      +		
      +		
      +			4
      +			list
      +			1
      +			1
      +			
      +			
      +			
      +				0
      +				
      +				
      +			
      +			
      +				1
      +				
      +				
      +			
      +		
      +		
      +			101
      +			int
      +			0
      +			4
      +			
      +			
      +			The value is a combination number made up of the sum of the values for the individual sensors and battery.
      +							The sensors have the values: Temperature=32, Humidity=64, Lightlevel=128, Battery=1.
      +							Therefore if you want all sensors and the battery sending regular reports, set the parameter to 225 (32 + 64 + 128 + 1).
      +			Der Wert ist die Summe der Werte der einzelnen Sensoren und der Batterie
      +							Die Sensoren haben folgende Werte: Temperatur=32, Feuchtigkeit=64, Helligkeit=128, Batterie=1.
      +							Wenn also alle Sensoren und der Batteriestand berichtet werden soll, setzen sie den Parameter auf 225 (32 + 64 + 128 + 1).
      +		
      +		
      +			102
      +			int
      +			0
      +			4
      +			
      +			
      +			The value is a combination number made up of the sum of the values for the individual sensors and battery.
      +							The sensors have the values: Temperature=32, Humidity=64, Lightlevel=128, Battery=1.
      +							Therefore if you want all sensors and the battery sending regular reports, set the parameter to 225 (32 + 64 + 128 + 1).
      +			Der Wert ist die Summe der Werte der einzelnen Sensoren und der Batterie
      +							Die Sensoren haben folgende Werte: Temperatur=32, Feuchtigkeit=64, Helligkeit=128, Batterie=1.
      +							Wenn also alle Sensoren und der Batteriestand berichtet werden soll, setzen sie den Parameter auf 225 (32 + 64 + 128 + 1).
      +		
      +		
      +			103
      +			int
      +			0
      +			4
      +			
      +			
      +			The value is a combination number made up of the sum of the values for the individual sensors and battery.
      +							The sensors have the values: Temperature=32, Humidity=64, Lightlevel=128, Battery=1.
      +							Therefore if you want all sensors and the battery sending regular reports, set the parameter to 225 (32 + 64 + 128 + 1).
      +			Der Wert ist die Summe der Werte der einzelnen Sensoren und der Batterie
      +							Die Sensoren haben folgende Werte: Temperatur=32, Feuchtigkeit=64, Helligkeit=128, Batterie=1.
      +							Wenn also alle Sensoren und der Batteriestand berichtet werden soll, setzen sie den Parameter auf 225 (32 + 64 + 128 + 1).
      +		
      +		
      +			111
      +			int
      +			1
      +			2678400
      +			720
      +			4
      +			
      +			
      +		
      +		
      +			112
      +			int
      +			1
      +			2678400
      +			720
      +			4
      +			
      +			
      +		
      +		
      +			113
      +			int
      +			1
      +			2678400
      +			720
      +			4
      +			
      +			
      +		
      +	
      +	
      +		
      +			1
      +			5
      +			true
      +			
      +			
      +		
      +	
      +
      +
      diff --git a/bundles/binding/org.openhab.binding.zwave/database/aeon/doorsensor.xml b/bundles/binding/org.openhab.binding.zwave/database/aeon/doorsensor.xml
      index 247a083e9c6..b16b24a6dac 100644
      --- a/bundles/binding/org.openhab.binding.zwave/database/aeon/doorsensor.xml
      +++ b/bundles/binding/org.openhab.binding.zwave/database/aeon/doorsensor.xml
      @@ -66,9 +66,9 @@
                       
                       
                               121
      -                        byte
      -                        256
      -                        1
      +                        int
      +                        4
      +                        4
                               
       						
       						0	   ->  	Battery report
      diff --git a/bundles/binding/org.openhab.binding.zwave/database/aeon/dsa38.xml b/bundles/binding/org.openhab.binding.zwave/database/aeon/dsa38.xml new file mode 100644 index 00000000000..a52f01ca0eb --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/aeon/dsa38.xml @@ -0,0 +1,44 @@ + + + OneButtonKeyFob + + + 0x20 + 0x25 + 0x27 + 0x2b + 0x32 + 0x70 + 0x72 + 0x84 + 0x85 + 0x86 + + + + + 250 + list + 0 + 1 + + 0 + + + + 1 + + + + Defines the switching mode of Button 1 + + + + + + 1 + 5 + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/aeon/dsc24.xml b/bundles/binding/org.openhab.binding.zwave/database/aeon/dsc24.xml index ce700e69228..1ae008299e1 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/aeon/dsc24.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/aeon/dsc24.xml @@ -20,6 +20,7 @@ list 0 1 + true 0 diff --git a/bundles/binding/org.openhab.binding.zwave/database/aeon/keyfobg1.xml b/bundles/binding/org.openhab.binding.zwave/database/aeon/keyfobg1.xml new file mode 100644 index 00000000000..42cb7f30a79 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/aeon/keyfobg1.xml @@ -0,0 +1,48 @@ + + + KeyFobG5 + + + 0x20 + 0x59 + 0x5a + 0x5e + 0x70 + 0x72 + 0x73 + 0x80 + 0x84 + 0x85 + 0x86 + 0x2b + 0x26 + + + + + 250 + list + 0 + 1 + + 0 + + + + 1 + + + + Defines the Use Mode setting of the fob + + + + + + 1 + 5 + true + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/aeon/msd2e.xml b/bundles/binding/org.openhab.binding.zwave/database/aeon/msd2e.xml index c4d3d18a678..cbb6003f410 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/aeon/msd2e.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/aeon/msd2e.xml @@ -39,6 +39,7 @@ 65535 0 2 + true This is a double byte value. The LSB defines the total time the device need to blink. The value if set in seconds. The MSB defines the on/off interval of the blinking. The unit is 0.1 s. @@ -69,13 +70,14 @@ list 0 1 + true Parameter to Enable/Disable CRC16 encapsulation Parameter to Enable/Disable CRC16 encapsulation 0 - + diff --git a/bundles/binding/org.openhab.binding.zwave/database/aeon/smart_strip.xml b/bundles/binding/org.openhab.binding.zwave/database/aeon/smart_strip.xml new file mode 100644 index 00000000000..288e2e4645c --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/aeon/smart_strip.xml @@ -0,0 +1,277 @@ + + + HEM + + + 0x20 + 0x31 + 0x32 + 0x60 + 0x70 + 0x72 + 0x80 + 0x84 + 0x85 + 0x86 + + + + 1 + 5 + + + + + + 1 + integer + 2 + 240 + 0 + 32000 + + + + + 4 + byte + 0 + 16 + 1 + 1 + + Enable selective reporting only when power change reaches +a certain threshold or percentage set in 4-11 below. This is +used to reduce network traffic. + + + + 5 + byte + 25 + 0 + 60000 + 2 + + Threshold change in wattage to induce a automatic report (Whole HEM). (Valid values 0-60000) + + + 6 + byte + 25 + 0 + 60000 + 2 + + Threshold change in wattage to induce a automatic report (Socket 1). (Valid values 0-60000) + + + 7 + byte + 25 + 0 + 60000 + 2 + + Threshold change in wattage to induce a automatic report (Socket 2). (Valid values 0-60000) + + + 8 + byte + 25 + 0 + 60000 + 2 + + Threshold change in wattage to induce a automatic report (Socket 3). (Valid values 0-60000) + + + 9 + byte + 25 + 0 + 60000 + 2 + + Threshold change in wattage to induce a automatic report (Socket 4). (Valid values 0-60000) + + + 10 + byte + 25 + 0 + 60000 + 2 + + Threshold change in wattage to induce a automatic report (Socket 5). (Valid values 0-60000) + + + 11 + byte + 25 + 0 + 60000 + 2 + + Threshold change in wattage to induce a automatic report (Socket 6). (Valid values 0-60000) + + + + 12 + byte + 5 + 0 + 100 + 1 + + Percentage change in wattage to induce a automatic report (Whole HEM). (Valid values 0-100) + + + 13 + byte + 5 + 0 + 100 + 1 + + Percentage change in wattage to induce a automatic report (Socket 1). (Valid values 0-100) + + + 14 + byte + 5 + 0 + 100 + 1 + + Percentage change in wattage to induce a automatic report (Socket 2). (Valid values 0-100) + + + 15 + byte + 5 + 0 + 100 + 1 + + Percentage change in wattage to induce a automatic report (Socket 3). (Valid values 0-100) + + + 16 + byte + 5 + 0 + 100 + 1 + + Percentage change in wattage to induce a automatic report (Socket 4). (Valid values 0-100) + + + 17 + byte + 5 + 0 + 100 + 1 + + Percentage change in wattage to induce a automatic report (Socket 5). (Valid values 0-100) + + + 16 + byte + 5 + 0 + 100 + 1 + + Percentage change in wattage to induce a automatic report (Socket 6). (Valid values 0-100) + + + + 80 + list + 8 + 4 + + + 0 + + + + 1 + + + + 2 + + + Status of load changed,send group 1 associate nodes Hail CC or Basic report CC. + + + + 90 + int + 0 + 4 + + true + + + + + 101 + int + 8 + 4 + + + + + 102 + int + 8 + 4 + + + + + 101 + int + 8 + 4 + + + + + + 111 + int + 1 + 2678400 + 720 + 4 + + + + + 112 + int + 1 + 2678400 + 720 + 4 + + + + + 113 + int + 1 + 2678400 + 720 + 4 + + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/aeon/zw089.xml b/bundles/binding/org.openhab.binding.zwave/database/aeon/zw089.xml new file mode 100644 index 00000000000..9ac8d0c352e --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/aeon/zw089.xml @@ -0,0 +1,127 @@ + + + ZW089 + + + 0x20 + 0x30 + 0x70 + 0x72 + 0x80 + 0x84 + 0x85 + 0x86 + + + + + 1 + list + 0 + 1 + + 0 + + + + 1 + + + + + + + 3 + list + 0 + 1 + + 0 + + + + 1 + + + + + + + 101 + list + 0 + 1 + + 0 + + + + 1 + + + + parameter defines, if battery check function is possible, when battery is below warning voltage + + + 111 + long + 112 + 4 + 0 + 65535 + + Minimum battery low check Interval time is 4 minutes (240 seconds) + + + 121 + long + 256 + 4 + 0 + 65535 + + Flag values for which reports to send when the magnet switch is triggered + + + 252 + list + 0 + 1 + + 0 + + + + 1 + + + + Lock or Unlock other configuration set function + + + 255 + constant + 0 + 2 + + 0 + + + + Reset to the default configuration + + + + + + 1 + 5 + + + + 2 + 5 + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/brk/zcombo.xml b/bundles/binding/org.openhab.binding.zwave/database/brk/zcombo.xml new file mode 100644 index 00000000000..0e105848b55 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/brk/zcombo.xml @@ -0,0 +1,43 @@ + + + ZCOMBO + + + 0x20 + 0x80 + 0x70 + 0x85 + 0x71 + 0x72 + 0x86 + + + + + 1 + list + 0 + 1 + + + 0 + + + + 1 + + + Causes the device to send double alarm messages + + + + + + 1 + 5 + true + + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/brk/zsmoke.xml b/bundles/binding/org.openhab.binding.zwave/database/brk/zsmoke.xml new file mode 100644 index 00000000000..04045e4759e --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/brk/zsmoke.xml @@ -0,0 +1,43 @@ + + + ZSMOKE + + + 0x20 + 0x80 + 0x70 + 0x85 + 0x71 + 0x72 + 0x86 + + + + + 1 + list + 0 + 1 + + + 0 + + + + 1 + + + Causes the device to send double alarm messages + + + + + + 1 + 5 + true + + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/danfoss/lcz_251.xml b/bundles/binding/org.openhab.binding.zwave/database/danfoss/lcz_251.xml index 55e953d85bd..f98dfa1b14c 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/danfoss/lcz_251.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/danfoss/lcz_251.xml @@ -22,6 +22,7 @@ 1 + true diff --git a/bundles/binding/org.openhab.binding.zwave/database/dragontech/pa100.xml b/bundles/binding/org.openhab.binding.zwave/database/dragontech/pa100.xml new file mode 100644 index 00000000000..be16d00246a --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/dragontech/pa100.xml @@ -0,0 +1,51 @@ + + + PA-100 + + + 0x20 + 0x25 + 0x27 + 0x59 + 0x5a + 0x5e + 0x70 + 0x72 + 0x73 + 0x7a + 0x85 + 0x86 + + + + + 3 + list + 0 + 1 + + Controls LED behavior when switch state is on/off + + 0 + + + + 1 + + + + 2 + + + + + + + + 1 + 5 + + true + + + \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.zwave/database/dragontech/wd100.xml b/bundles/binding/org.openhab.binding.zwave/database/dragontech/wd100.xml new file mode 100644 index 00000000000..aaccc86c8df --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/dragontech/wd100.xml @@ -0,0 +1,63 @@ + + + WD-100 + + + 0x20 + 0x26 + 0x27 + 0x2b + 0x59 + 0x5a + 0x5e + 0x70 + 0x72 + 0x73 + 0x7a + 0x85 + 0x86 + + + + + 4 + list + 0 + 1 + + Controls the on/off orientation of the rocker switch + + 0 + + + + 1 + + + + + 9 + byte + 1 + 1 + + Indicates the number of levels (1-99) to change dimming each step + + + 10 + byte + 3 + + The number of tens of milliseconds (1-255) to delay on each dimming step. + + + + + + 1 + 5 + + true + + + \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.zwave/database/dragontech/ws100.xml b/bundles/binding/org.openhab.binding.zwave/database/dragontech/ws100.xml new file mode 100644 index 00000000000..374a219987a --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/dragontech/ws100.xml @@ -0,0 +1,68 @@ + + + WS-100 + + + 0x20 + 0x25 + 0x27 + 0x2b + 0x59 + 0x5a + 0x5e + 0x70 + 0x72 + 0x73 + 0x7a + 0x85 + 0x86 + + + + + 3 + list + 0 + 1 + + Controls LED behavior when switch state is on/off + + 0 + + + + 1 + + + + 2 + + + + + 4 + list + 0 + 1 + + Controls the on/off orientation of the rocker switch + + 0 + + + + 1 + + + + + + + + 1 + 5 + + true + + + \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.zwave/database/everspring/hsp02.xml b/bundles/binding/org.openhab.binding.zwave/database/everspring/hsp02.xml new file mode 100644 index 00000000000..d49cacd3ca5 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/everspring/hsp02.xml @@ -0,0 +1,99 @@ + + + HSP02 + + + 0x20 + 0x30 + 0x70 + 0x71 + 0x72 + 0x80 + 0x84 + 0x85 + 0x86 + + + + 1 + byte + 0 + 99 + 99 + 1 + + + Value to be sent with a BASIC SET command + Wert der bei einem BASIC SET gesendet wird + + + 2 + list + 1 + 1 + + + 1 + + + + 2 + + + + 3 + + + + + 3 + byte + 1 + 10 + 6 + 1 + + + + 4 + byte + 5 + 3600 + 180 + 1 + + + + 5 + byte + 1 + 100 + 10 + 1 + + Value for what LUX level will arm the detection sensor + + + 6 + byte + 5 + 3600 + 15 + 1 + + + + + + 1 + 1 + + + + 2 + 5 + + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/everspring/se812.xml b/bundles/binding/org.openhab.binding.zwave/database/everspring/se812.xml new file mode 100644 index 00000000000..6d18c3041c0 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/everspring/se812.xml @@ -0,0 +1,25 @@ + + + SE812 + + + 0x20 + 0x25 + 0x71 + 0x85 + 0x80 + 0x72 + 0x86 + + + + + + 1 + 5 + + true + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/everspring/st815.xml b/bundles/binding/org.openhab.binding.zwave/database/everspring/st815.xml new file mode 100644 index 00000000000..9682d1010ae --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/everspring/st815.xml @@ -0,0 +1,98 @@ + + + ST814 + + + 0x20 + 0x31 + 0x70 + 0x72 + 0x80 + 0x84 + 0x85 + 0x86 + + + + 1 + byte + 0 + 99 + 99 + 1 + + Set to 0 to disable]]> + + + + 2 + short + 0 + 1000 + 300 + 2 + + Set to 0 to disable.]]> + + + + 3 + short + 0 + 1000 + 500 + 2 + + Set to 0 to disable.]]> + + + + 4 + short + 0 + 480 + 0 + 2 + + Set to 0 to disable.]]> + + + + 5 + short + 0 + 1439 + 0 + 2 + + Set to 0 to Disable]]> + + + + 6 + short + 0 + 1000 + 0 + 2 + + Set to 0 to Disable]]> + + + + + + + 1 + 1 + + true + + + 2 + 3 + + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/evolve/ltm-5.xml b/bundles/binding/org.openhab.binding.zwave/database/evolve/ltm-5.xml new file mode 100644 index 00000000000..bf1deb36680 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/evolve/ltm-5.xml @@ -0,0 +1,159 @@ + + + LTM-5 + + + + 0x20 + + + 0x26 + + + 0x27 + + + 0x2b + + + 0x2c + + + 0x70 + + + 0x72 + + + 0x73 + + + 0x85 + + + 0x86 + + + + + 1 + list + 1 + 1 + + Dimmers controlled by this switch will start dimming from their current level. + + 0 + + + + 1 + + + + + 3 + list + 1 + 1 + + In night-light mode the LED on the switch will turn ON when the switch is turned OFF. + + 0 + + + + 1 + + + + + 4 + list + 0 + 1 + + Change the top of the switch to OFF and the bottom of the switch to ON. + + 0 + + + + 1 + + + + + 5 + list + 1 + 1 + + The dimmer will start dimming from its current level. + + 0 + + + + 1 + + + + + 19 + list + 2 + 1 + + Flicker LED while transmitting. + + 0 + + + + 1 + + + + 2 + + + + + 20 + byte + 2 + 1 + 255 + 1 + + How often, in minutes, to poll to keep synchronized with group. + + + 21 + list + 0 + 1 + + Poll only the first node in Group 1. + + 0 + + + + 1 + + + + + + + + 1 + 5 + + Nodes in this group are turned ON/OFF by tapping the paddle or dimmed/brightened by holding the paddle. The LED will indicate the status of this group. + true + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgd211-19.xml b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgd211-19.xml new file mode 100644 index 00000000000..8bbc521ba44 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgd211-19.xml @@ -0,0 +1,345 @@ + + + FGD211 + + + 0x20 + 0x26 + 0x27 + 0x70 + 0x72 + 0x73 + 0x85 + 0x86 + 0x8e + + + + 1 + list + 255 + 1 + + + 0 + + + + 1 + + + + 2 + + + + -1 + + + Activate/Deactive ALL ON/OFF + + + + 6 + list + 0 + 1 + + + 0 + + + + 1 + + + + 2 + + + Activate/Deactivate association sending for group + 1 - Also see param #16 + + + + 7 + list + 1 + 1 + + + 0 + + + + 1 + + + Key no.2 is not represented by any physical device - only + devices in the association list. + This functionality prevents of lack of reaction on pressing key no.2 + through polling devices + from association list one by one and checking their actual statuses. + + + + 8 + byte + 1 + 99 + 1 + 1 + + + + + + 9 + byte + 1 + 255 + 5 + 1 + + Options for changing parameter 1-255 (10ms - 2,5s) + + + + 10 + byte + 0 + 255 + 1 + 1 + + Options for changing parameter 1-255 (10ms - 2,5s) - 0: this value disables the smooth change in light intensity. NOTE: value 0 is required for inductive and capacitive devices unsuitable for dimming (e.g. fluorescent lamps, motors, etc...) + + + + 11 + byte + 1 + 99 + 1 + 1 + + Options for changing parameter 1-99 + + + + 12 + byte + 2 + 99 + 2 + 1 + + Options for changing parameter 2-99 + + + + 13 + byte + 0 + 1 + + Options for changing parameter 1-98 + + + + 14 + list + 0 + 1 + + + 0 + + + + 1 + + + Binary inputs type configuration + + + + 15 + list + 0 + 1 + + + 0 + + + + 1 + + + Double-click set lighting at 100% + + + + 16 + list + 1 + 1 + + + 0 + + + + 1 + + + Saving state before power failure + + + + 17 + list + 0 + 1 + + + 0 + + + + 1 + + + The function of 3-way switch provides the option to double key no. 1. The dimmer may control two bi-stable push-buttons or an infinite number of mono-stable push-buttons. (default value 0) + + + + 18 + list + 0 + 1 + + + 0 + + + + 1 + + + The dimmer communicate the level to the associated devices. (default value 0) + + + + 19 + list + 0 + 1 + + + 0 + + + + 1 + + + This function allow user to change [On-Off] bi-stable keys (parameter no. 14) (default value 0) + + + + 20 + byte + 100 + 170 + 110 + 1 + + + WARNING: Wrong setting of the function may cause incorrect operation of the Dimmer.]]> + + + + 30 + list + 3 + 1 + + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + + + + 39 + short + 600 + 2 + + Amount of time (ms) the device keeps on flashing after receipt of Alarm Frame + + + + 40 + short + 99 + 1 + + Available settings: from 1 to 99. Parameter’s value changes depending on the dimming level. + + + + 41 + list + 0 + 1 + + + 0 + + + + 1 + + + The device offers the possibility of sending commands compatible with Command class scene activation. Information is sent to devices assigned to association group no. 3. Controllers such as Home Center 2 are able to interpret such commands and based on these commands they activate scenes, to which specific scene IDs have been assigned. The user may expand the functionality of the button connected to inputs S1 and S2 by distinguishing the actions of keys connected to those inputs. For example: double click would activate the scene “goodnight” and triple click would activate the scene “morning”. + + + + + + 1 + 5 + + + + 2 + 5 + + + + 3 + 1 + + true + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgfs101.xml b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgfs101.xml index 2590fca897b..7e151451d06 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgfs101.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgfs101.xml @@ -26,7 +26,7 @@ 0 2 - Additional delay after an alarm has ceased. The parameter allows you to specify additional time, after which the alarm is cancelled once its violation has ceased. +
      2 @@ -36,21 +36,21 @@ 0 - + 1 - + 2 - + 3 - + - parameter allows for LED indicator and acoustic alarm deactivation in case of flooding detection + @@ -67,7 +67,7 @@ -127
      - parameter determines a type of command frame sent by the Sensor in case flooding has been detected or cancelled + @@ -79,7 +79,7 @@ 1 -In the case of alarm frames the alarm priority is specified. Possible parameter settings: (1 � 99) and 255. Value of 255 makes it possible to activate the device when using the Dimmer module it means activating the device and setting it to the previous stored condition, e.g. when Dimmer is set to 30%, then deactivated, and then reactivated using command 255, it will automatically be set to the previous condition, i.e. 30%.]]> +In the case of alarm frames the alarm priority is specified. Possible parameter settings: (1-99) and 255. Value of 255 makes it possible to activate the device when using the Dimmer module it means activating the device and setting it to the previous stored condition, e.g. when Dimmer is set to 30%, then deactivated, and then reactivated using command 255, it will automatically be set to the previous condition, i.e. 30%.]]> @@ -89,11 +89,11 @@ In the case of alarm frames the alarm priority is specified. Possible parameter 1 0 - + 1 - + @@ -107,7 +107,7 @@ In the case of alarm frames the alarm priority is specified. Possible parameter 300 2 - Interval between successive readings of temperature from all sensors connected to the device in seconds. Note: taking temperature readings from the sensor does not result in sending a temperature condition report to the central hub. + Interval between successive readings of temperature from all sensors connected to the device in seconds.
      NOTE: taking temperature readings from the sensor does not result in sending a temperature condition report to the central hub.
      @@ -118,13 +118,15 @@ In the case of alarm frames the alarm priority is specified. Possible parameter 50 2 - + + 13 list 0 1 + 0 @@ -141,9 +143,148 @@ In the case of alarm frames the alarm priority is specified. Possible parameter 3 - NOTE: If the broadcast mode of information transmission is activated for a given channel, then transmission of information in singlecast mode to devices assigned to the association group of this channel is deactivated.]]> + + + 50 + byte + -10000 + 10000 + 1500 + 2 + + NOTE: The main controller does not interpret negative numbers as decimals. That’s why read value may be different than entered. Negative numbers are coded in U2 standard.]]> + + + + 51 + byte + -10000 + 10000 + 3500 + 2 + + + + + + 61 + byte + 0 + 16777215 + 255 + 4 + + NOTE: A main controller interprets colours as a sum of it component colours value. Each colours value is a number from 0 to 255. Eg: Indicated colour = 65536 * RED value + 256 * GREEN value + BLUE value]]> + + + + 62 + byte + 0 + 16777215 + 16711680 + 4 + + NOTE: A main controller interprets colours as a sum of it component colours value. Each colours value is a number from 0 to 255. Eg: Indicated colour = 65536 * RED value + 256 * GREEN value + BLUE value]]> + + + + 63 + list + 2 + 1 + + + 0 + + + + 1 + + + + 2 + + + + + + + 73 + byte + -10000 + 10000 + 0 + 2 + + + + + + 74 + list + 2 + 1 + + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + + + + 75 + byte + 0 + 65535 + 0 + 2 + + NOTE: The parameter is ignored when Parameter 2 is set to 0]]> + + + + 76 + byte + 0 + 65535 + 0 + 2 + + NOTE: In case a time period set in this parameter is shorter than the one specified in parameter 75, the device will not quiet the alarm, it will remain active]]> + + + + 77 + list + 0 + 1 + + + 0 + + + + 1 + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgk101.xml b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgk101.xml index e8e2d041496..4f2079765c4 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgk101.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgk101.xml @@ -171,7 +171,9 @@ are always sent.]]> - + 12 byte diff --git a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgms001.xml b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgms001.xml index 3024b6b47a9..83b6939f80b 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgms001.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgms001.xml @@ -4,6 +4,10 @@ 0x30 + + 0x31 + false + 0x84 0x85 0x80 @@ -14,7 +18,6 @@ 0x70 0x8e 0x7a - 0x31 0x9c diff --git a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgrgbw.xml b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgrgbw.xml index 30f53b927c8..b1688dddab6 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgrgbw.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgrgbw.xml @@ -6,7 +6,33 @@ 0x60 0x20 0x86 - 0x26 + + + 0x26 + 1 + false + + + 0x26 + 2 + false + + + 0x26 + 3 + false + + + 0x26 + 4 + false + + + 0x26 + 5 + false + + 0x27 0x72 0x70 @@ -15,6 +41,9 @@ 0x73 0x7a 0x85 + + 0x33 + diff --git a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgrm222.xml b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgrm222.xml index 45cb6151728..b9d8819c0aa 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgrm222.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgrm222.xml @@ -15,6 +15,10 @@ 0x85 0x86 0x9a + + 0x91 + true + diff --git a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgsd002.xml b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgsd002.xml new file mode 100644 index 00000000000..731e7728f59 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgsd002.xml @@ -0,0 +1,298 @@ + + + FGSD002 + + + 0x20 + 0x31 + 0x70 + 0x74 + 0x7A + 0x84 + 0x85 + 0x8E + 0x9c + + + + + 1 + list + 2 + 1 + + There are 3 levels of sensitivity to smoke presence. Level 1 means the highest sensitivity. Rising the parameter value lowers the sensitivity to smoke presence. + + 1 + + + + 2 + + + + 3 + + + + + + 2 + list + 0 + 1 + + This parameter allows to activate excess temperature and/or enclosure opening notifications sent to the main controller + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + + + 3 + list + 0 + 1 + + This parameter allows to activate visual indications but does not apply to major alarms, such as FIRE, TROUBLE and LOW BATTERY ALARM. + + 0 + + + + 1 + + + + 2 + + + + 4 + + + + 3 + + + + 5 + + + + 6 + + + + 7 + + + + + + 4 + list + 0 + 1 + + This parameter allows to activate sound signals but does not apply to major alarms, such as FIRE, TROUBLE and LOW BATTERY ALARM. + + 0 + + + + 1 + + + + 2 + + + + 4 + + + + 3 + + + + 5 + + + + 6 + + + + 7 + + + + + + 10 + list + 0 + 1 + + This parameter defines which frames will be sent in the 2-nd Association Group (FIRE ALARM). The values of BASIC ON and BASIC OFF frames may be defined as described in further parameters. + + 0 + + + + 1 + + + + 2 + + + + + + 11 + byte + 1 + 255 + 255 + 1 + + BASIC ON frame is sent in case of smoke presence detection and FIRE ALARM triggering. Its value is defined by the parameter. Available settings: 0-99, 255. 0 - turn off the device. 1-99 - set the device to 1-99%. 255 - set the last status + + + + 12 + byte + 1 + 255 + 255 + 1 + + BASIC OFF frame is sent in case of FIRE ALARM cancellation. Its value is defined by the parameter. Available settings: 0-99, 255. 0 - turn off the device. 1-99 - set the device to 1-99%. 255 - set the last status + + + + 13 + list + 0 + 1 + + A value other than 0 means that alarms are being sent in broadcast mode, i.e. to all devices within a Fibaro Smoke Sensor’s range + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + + + 20 + byte + 0 + 8640 + 1 + 2 + + Time interval between consecutive temperature reports. Report is sent when new temperature value is different from the one previously reported - according to the set hysteresis (parameter 21). Temperature reports can be also sent as a result of polling. Available settings: 0, 1-8640 (multiply by 10 seconds) [10s-24h]. 0 – reports inactive. 1-8640 - [10s-24h] + + + + 21 + byte + 1 + 100 + 10 + 1 + + The temperature report will only be sent if there is a difference in temperature value from the previous value reported, defined in this parameter (hysteresis). Temperature reports can be also sent as a result of polling. Available settings: 1 – 100 (in 0,1o C steps) 1-100 - (multiply by 0,1) [0,1oC - 10oC] + + + + 30 + byte + 1 + 100 + 55 + 1 + + Temperature value measured by the built-in temperature sensor above which the excess temperature notification is sent (visual indication/sound/Z-Wave report). Available settings: 1 - 100 (1oC - 100oC) + + + + 31 + byte + 1 + 8640 + 1 + 2 + + Time interval of signaling (visual indication/sound) excess temperature level.Available settings: 1-8640 (multiply by 10 seconds) [10s-24h] 1-8640 - [10s-24h] + + + + 32 + byte + 1 + 8640 + 180 + 2 + + Time interval of signaling (visual indication/sound) lack of Z-Wave range. Available settings: 1-8640 (multiply by 10 seconds) [10s-24h]. 1-8640 - [10s-24h] + + + + + + 1 + 1 + + true + + + 2 + 5 + + + + 3 + 5 + + + + 4 + 5 + + + + 5 + 5 + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgss101.xml b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgss101.xml index 126a1eb50cf..6a7256c1b4a 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgss101.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/fibaro/fgss101.xml @@ -99,9 +99,9 @@ In the case of alarm frames the alarm priority is specified. Possible parameter 12 byte 0 - 1000 - 50 - 2 + 100 + 20 + 1 diff --git a/bundles/binding/org.openhab.binding.zwave/database/fortrezz/mimolite.xml b/bundles/binding/org.openhab.binding.zwave/database/fortrezz/mimolite.xml index 285706bfc97..f0b4393645d 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/fortrezz/mimolite.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/fortrezz/mimolite.xml @@ -1,17 +1,37 @@ iTemp - + - 0x91 - 0x86 - 0x71 - 0x30 - 0x31 - 0x35 - 0x70 - 0x85 - 0x25 + + 0x91 + + + 0x86 + + + 0x71 + + + 0x30 + + + 0x31 + + + 0x35 + + + 0x70 + + + 0x85 + + + 0x25 + @@ -33,16 +53,192 @@ - 4 - 2 - - - - - 5 - 2 - - - + 4 + 2 + + + + + 5 + 2 + + + + + + + 1 + list + 0 + 1 + + + 0 + + + + + + 2 + list + 0 + 1 + + + 0 + + + + + + 3 + list + 0 + 1 + + + 0 + + + + 1 + + + + + + 4 + list + 187 + 0 + 255 + 1 + + + 187 + + + + + + 5 + list + 171 + 0 + 255 + 1 + + + 171 + + + + + + 6 + list + 255 + 0 + 255 + 1 + + + 255 + + + + + + 7 + list + 254 + 0 + 255 + 1 + + + 254 + + + + + + 8 + list + 3 + 1 + + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + + + 9 + list + 3 + 0 + 255 + 1 + + + 0 + + + + 3 + + + + + + 10 + list + 0 + 1 + + + 0 + + + + + + 11 + list + 0 + 0 + 255 + 1 + + + 0 + + + + 5 + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/ge/ZW4201.xml b/bundles/binding/org.openhab.binding.zwave/database/ge/45604.xml similarity index 100% rename from bundles/binding/org.openhab.binding.zwave/database/ge/ZW4201.xml rename to bundles/binding/org.openhab.binding.zwave/database/ge/45604.xml diff --git a/bundles/binding/org.openhab.binding.zwave/database/horstmann/hrt4-zw.xml b/bundles/binding/org.openhab.binding.zwave/database/horstmann/hrt4-zw.xml index 0f18ae02ac4..e940f8a3885 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/horstmann/hrt4-zw.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/horstmann/hrt4-zw.xml @@ -27,7 +27,7 @@
      - -1 + 255 @@ -44,7 +44,7 @@
      - -1 + 255 @@ -64,26 +64,31 @@ 1 4 + true 2 4 + true 3 4 + true 4 4 + true 5 4 + true diff --git a/bundles/binding/org.openhab.binding.zwave/database/horstmann/scsc17.xml b/bundles/binding/org.openhab.binding.zwave/database/horstmann/scsc17.xml new file mode 100644 index 00000000000..a364cfa3ef6 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/horstmann/scsc17.xml @@ -0,0 +1,80 @@ + + + SCSC17 + + + 0x80 + 0x40 + 0x42 + 0x44 + 0x84 + 0x85 + 0x72 + 0x86 + 0x70 + 0x31 + 0x72 + 0x25 + + + + 1 + list + 0 + 1 + + + 0 + + + + 255 + + + + + + + 2 + byte + 5 + 1 + + + + + + 3 + byte + 5 + 1 + + + + + + 4 + byte + 5 + 1 + + 1 0.1 ̊C / ̊F - 50 0.1 ̊C / ̊F]]> + + + + + + + 1 + 1 + true + + + + 2 + 4 + + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/innovus/smartdimmer.xml b/bundles/binding/org.openhab.binding.zwave/database/innovus/smartdimmer.xml index 9f3873e312c..01f777b575b 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/innovus/smartdimmer.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/innovus/smartdimmer.xml @@ -46,7 +46,7 @@ list 1 1 - + 0 @@ -55,7 +55,7 @@ 1 - B&O IR support is disabled if 0 otherwise enabled. + B&O IR support is disabled if 0 otherwise enabled. diff --git a/bundles/binding/org.openhab.binding.zwave/database/intermatic/ha20.xml b/bundles/binding/org.openhab.binding.zwave/database/intermatic/ha20.xml new file mode 100644 index 00000000000..31b8ba7fa9b --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/intermatic/ha20.xml @@ -0,0 +1,18 @@ + + + HA-20 + + + + + + + + + 1 + 4 + true + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/leviton/vrcz4-m0z.xml b/bundles/binding/org.openhab.binding.zwave/database/leviton/vrcz4-m0z.xml new file mode 100644 index 00000000000..8d50ea6459a --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/leviton/vrcz4-m0z.xml @@ -0,0 +1,43 @@ + + + VRCZ4-M0Z + + + 0x82 + 0x85 + 0x86 + 0x2D + 0x91 + 0x72 + 0x73 + 0x77 + 0x7C + + + + + + + + 1 + 232 + + + + 2 + 232 + + + + 3 + 232 + + + + 4 + 232 + + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/linear/lb60z-1.xml b/bundles/binding/org.openhab.binding.zwave/database/linear/lb60z-1.xml new file mode 100644 index 00000000000..f120d1c3739 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/linear/lb60z-1.xml @@ -0,0 +1,69 @@ + + + LB60Z-1 + + + + 0x20 + + + 0x26 + + + 0x27 + + + 0x59 + + + 0x5A + + + 0x5E + + + 0x70 + + + 0x72 + + + 0x73 + + + 0x7A + + + 0x85 + + + 0x86 + + + + + 1 + list + 0 + 1 + + By default, the LB60Z-1 bulb will go to full brightness when turned on. To have the bulb turn on to the last dim level setting, set parameter 1 to 1. + + 0 + + + + 1 + + + + + + + 1 + 5 + + true + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/philio/pan11_1.xml b/bundles/binding/org.openhab.binding.zwave/database/philio/pan11_1.xml new file mode 100644 index 00000000000..2fa15b62d05 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/philio/pan11_1.xml @@ -0,0 +1,74 @@ + + + PAN11-1 + + + 0x20 + 0x25 + 0x86 + 0x27 + 0x72 + 0x70 + 0x32 + 0x85 + + + + 1 + short + 720 + 2 + + + If the setting is configured for 1 hour (value = 720), + the device will report its instant power consumption every 1 hour to Z-Wave Controller. + Unit: 5 seconds + Wenn diese Einstellung auf 1 Stunde steht (Wert = 720), + sendet das Gerät denn aktuellen Stromverbrauch jede Stunde an den Z-Wave Controller. + Einheit: 5 Sekunden + + + 2 + short + 6 + 2 + + + If the setting is configured for 1 hour (value = 6), + the device will report its total power consumption every 1 hour to Z-Wave Controller. + Unit: 10 minutes + Wenn diese Einstellung auf 1 Stunde steht (Wert = 6), + sendet das Gerät denn gesamthaften Stromverbrauch jede Stunde an den Z-Wave Controller. + Einheit: 10 Minuten + + + 3 + short + 3000 + 2 + + + If threshold of wattage is reached, a meter report will be generated + Wenn der Watt-Schwellwert überschritten wird, wird automatisch ein Strommessbericht generiert. + + + 4 + short + 10000 + 2 + + + If threshold of kWh is reached, a Meter Report will be generated + Wenn der kWH Schwellwert überschritten wird, wird automatisch ein Strommessbericht generiert. + + + + + 1 + 1 + true + + When the power consumption of load vary over 5%, the PAN11 will send a Meter Report. When "on" or "off" state has been changed, it will send Binary Switch Report. + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/philio/pst02.xml b/bundles/binding/org.openhab.binding.zwave/database/philio/pst02.xml new file mode 100644 index 00000000000..aff6729237f --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/philio/pst02.xml @@ -0,0 +1,240 @@ + + + PST02 + + + 0x20 + 0x30 + 0x31 + 0x59 + 0x5A + 0x5E + 0x70 + 0x71 + 0x72 + 0x73 + 0x7A + 0x80 + 0x84 + 0x85 + 0x86 + 0x8F + 0x98 + 0xEF + + + + 2 + byte + -1 + -1 + 100 + 1 + + +
      • -1 = 0xFF(-1) turns on the light. (Default)
      • +
      • 0 = Turn off the light.
      • +
      • 1 - 100 = For dimmers 1 to 100 means the light strength.
      ]]>
      +
      + + 3 + byte + 70 + 0 + 99 + 1 + + +
      • 0 = Disable the PIR motion detection.
      • +
      • 1 - 99 = 1 means the lowest sensitivity, 99 means the highest sensitivity
      + High sensitivity means detection over a longer distance, but if there is more noise signal in the environment, it may lead to false triggers.]]>
      +
      + + 4 + byte + 100 + 0 + 100 + 1 + + +
      • 0 = Turn off illumination detected function and never turn on the light.
      • +
      • 1 - 99 = Illumination threshold; 1 means darkest, 99 means brightest.
      • +
      • 100 = Turn off illumination detected function and always turn on the light.
      ]]>
      +
      + + 5 + byte + 0 + 0 + 127 + 1 + + +
      • Bit 0: Reserved.
      • +
      • Bit 1: 1 means enable test mode; 0 means normal mode. Notice: Ignored if DIP Switch is not set to Customer Mode.
      • +
      • Bit 2: Disable the door/window function. 1: Disable, 0: Enable
      • +
      • Bit 3: Set the temperature scale. 0: Fahrenheit, 1:Celsius
      • +
      • Bit 4: Disable illumination report after event triggered. 1: Disable, 0: Enable
      • +
      • Bit 5: Disable temperature report after event triggered. 1: Disable, 0: Enable
      • +
      • Bit 6: Reserved.
      • +
      • Bit 7: Disable the back key release into test mode. 1: Disable, 0: Enable
      ]]>
      +
      + + 6 + byte + 4 + 0 + 127 + 1 + + +
      • Bit 0: Disable magnetic integrate illumination to turn on the lighting nodes in the association group 2. 1: Disable, 0: Enable
      • +
      • Bit 1: Disable PIR integrate Illumination to turn on the lighting nodes in the association group 2. 1: Disable, 0: Enable
      • +
      • Bit 2: Disable magnetic integrate PIR to turn on the lighting nodes in the association group 2. 1: Disable, 0: Enable (Default is Disable)
      • +
      • Bit 3: Used when Bit 2 is 0 (Enable). Are the device is installed in the same room with the light? 0: In the same room (Default), 1: In the different room. Notice: If this bit is 1 then it is recommended to also set Bit 1 to 1.
      • +
      • Bit 4: Disable delay 5 seconds to turn off the light, when door/window closed. 1: Disable, 0: Enable
      • +
      • Bit 5: Disable auto turn off the light, after door/window opened to turn on the light. 1: Disable, 0: Enable. Notice: Ignored when Bit 2 is set to 0.
      • +
      • Bit 6: Reserved.
      • +
      • Bit 7: Reserved.
      ]]>
      +
      + + 7 + byte + 4 + 0 + 127 + 1 + + +
      • Bit 0: Reserved.
      • +
      • Bit 1: Enable sending motion OFF report. 0: Disable, 1: Enable. Note: Depends on the Bit4, 0: Report Notification CC, Type: 0x07, Event: 0xFE 1: Sensor Binary Report, Type: 0x0C, Value: 0x00
      • +
      • Bit 2: Enable PIR super sensitivity mode. 0: Disable, 1: Enable
      • +
      • Bit 3: Enable don't send out BASIC OFF after door closed. 1: Disable, 0: Enable
      • +
      • Bit 4: Notification Type, 0: Using Notification Report. 1: Using Sensor Binary Report.
      • +
      • Bit 5: Disable Multi CC in auto report. 1: Disable, 0: Enable
      • +
      • Bit 6: Disable to report battery state when the device triggered. 1: Disable, 0: Enable
      • +
      • Bit 7: Reserved.
      ]]>
      +
      + + 8 + byte + 3 + 1 + 127 + 1 + + +
      • 1 - 127 = Number of ticks. 8 seconds per tick, default value is 3 (24 seconds).
      ]]>
      +
      + + 9 + byte + 4 + 0 + 127 + 1 + + +
      • 0 = Never send turn off light command.
      • +
      • 1 - 127 = Number of ticks. 8 seconds per tick, default value is 4 (32 seconds).
      ]]>
      +
      + + 10 + byte + 12 + 0 + 127 + 1 + + +
      • 0 = Turn off auto report battery.
      • +
      • 1-127 = Number of ticks. The default value is 12. The tick time can be set by configuration No. 20.
      ]]>
      +
      + + 11 + byte + 12 + 0 + 127 + 1 + + +
      • 0 = Turn off auto report door/window state.
      • +
      • 1-127 = Number of ticks. The default value is 12. The tick time can be set by configuration No. 20.
      ]]>
      +
      + + 12 + byte + 12 + 1 + 127 + 1 + + +
    • 0 = Turn off auto report illumination.
    • +
    • 1-127 = Number of ticks. The default value is 12. The tick time can be set by configuration No. 20.
    • ]]>
      +
      + + 13 + byte + 12 + 1 + 127 + 1 + + +
      • 0 = Turn off auto report temperature.
      • +
      • 1-127 = Number of ticks. The default value is 12. The tick time can be set by configuration No. 20.
      ]]>
      +
      + + 20 + byte + 30 + 0 + 255 + 1 + + +
      • 0 = Turn off all auto report functions.
      • +
      • 1-255 = Interval time for each tick. Default is 30.
      ]]>
      +
      + + 21 + byte + 1 + 0 + 127 + 1 + + +
      • 0 = Turn off this function.
      • +
      • 1-127 = Degrees Fahrenheit.
      ]]>
      +
      + + 22 + byte + 1 + 0 + 99 + 1 + + +
      • 0 = Turn off this function.
      • +
      • 1-99 = Percentage.
      ]]>
      +
      +
      + + + 1 + 8 + true + + + + 2 + 8 + + + +
      diff --git a/bundles/binding/org.openhab.binding.zwave/database/popp/123665.xml b/bundles/binding/org.openhab.binding.zwave/database/popp/123665.xml new file mode 100644 index 00000000000..4b57d923e30 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/popp/123665.xml @@ -0,0 +1,119 @@ + + + 123665 + + + + 0x20 + + + 0x25 + + + 0x27 + + + 0x32 + + + 0x70 + + + 0x72 + + + 0x73 + + + 0x85 + + + 0x86 + + + 0x8e + + + + + 1 + integer + 720 + 2 + + If the setting is configured for 1hour (set value + =720), the device will report its instant power consumption every 1 + hour to Z-Wave Controller. (in seconds) + + + + 2 + integer + 6 + 2 + + if the setting is configured for 1hour (set value + =6), the device will report its Accumulated Power Consumption (KW/h) + every hour (in seconds) + + + + 4 + integer + 10000 + 2 + + This is a warning when the KWh of load over the + preset threshold value, if the Accumulated Power Consumption exceeds + the setting value the device will send a warning alarm command to + the controller. + + + + 5 + list + 1 + 1 + + + 0 + + + + 1 + + + + 2 + + + + + + + 11 + list + 1 + 1 + + + 0 + + + + 1 + + + + + + + + + 1 + 5 + + true + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/products.xml b/bundles/binding/org.openhab.binding.zwave/database/products.xml index 084418e13e7..66349dff659 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/products.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/products.xml @@ -33,6 +33,15 @@ linear/pd300z-2.xml + + + 4754 + 3038 + + LB60Z-1 + + linear/lb60z-1.xml + 0150 @@ -89,6 +98,14 @@ 0005 Intermatic + + + 0001 + 0003 + + HA-01 + + 0002 @@ -153,6 +170,15 @@ CA-9000 + + + 4841 + 0020 + + HA-20 + + intermatic/ha20.xml + 0059 @@ -190,10 +216,28 @@ ASR-ZW + + + 0004 + 0001 + + SCSC17 + + horstmann/scsc17.xml + 0060 Everspring + + + 0001 + 0003 + + HSP02 + + everspring/hsp02.xml + 0003 @@ -259,6 +303,15 @@ everspring/st814.xml + + + 0007 + 0001 + + ST815 + + everspring/st815.xml + 000D @@ -270,6 +323,10 @@ everspring/sf812.xml + + 0202 + 0001 + 0002 0001 @@ -290,6 +347,7 @@ SE812 + everspring/se812.xml @@ -301,6 +359,19 @@ everspring/st812.xml + + 0113 + Evolve + + + 5457 + 3033 + + LTM-5 + + evolve/ltm-5.xml + + 0063 GE @@ -507,6 +578,15 @@ 0086 Aeon Labs + + + 0002 + 0059 + + ZW089 + + aeon/zw089.xml + 0003 @@ -574,6 +654,15 @@ aeon/4in1ms.xml + + + 0002 + 004A + + 4in1MS + + aeon/4in1ms_g5.xml + 0006 @@ -716,6 +805,10 @@ + + 0001 + 0058 + 0201 0058 @@ -724,6 +817,33 @@ aeon/keyfobg5.xml + + + 0001 + 0058 + + KeyFobG5 + + aeon/keyfobg1.xml + + + + 0001 + 0026 + + DSA38 + + aeon/dsa38.xml + + + + 0003 + 000B + + SmartStrip + + aeon/smart_strip.xml + 0098 @@ -753,6 +873,15 @@ rtc/ct30.xml + + + 0000 + 0000 + + 3M-30 + + rtc/ct30.xml + 6401 @@ -770,6 +899,28 @@ rtc/ct100.xml + + + 5002 + 0100 + + + 5003 + 0109 + + CT80 + + rtc/ct30.xml + + + + 6501 + 000c + + CT101 + + rtc/ct100.xml + 0099 @@ -909,36 +1060,33 @@ 0100 - 0104 + 0107 0100 - 0106 + 0109 - FGD211 - - fibaro/fgd211-14.xml - - 0100 - 0107 + 300A 0100 - 0109 + 100A 0100 - 300A + 0104 0100 - 100A + 0106 FGD211 - - fibaro/fgd211-21.xml + + fibaro/fgd211-14.xml + fibaro/fgd211-19.xml + fibaro/fgd211-21.xml @@ -982,6 +1130,10 @@ 0200 0102 + + 0200 + 0103 + 0200 0104 @@ -1028,6 +1180,10 @@ fibaro/fgk101.xml + + 0501 + 0102 + 0501 1002 @@ -1062,6 +1218,15 @@ fibaro/fgss101.xml + + + 0C02 + 1002 + + FGSD002 + + fibaro/fgsd002.xml + 0600 @@ -1074,11 +1239,15 @@ 0900 - 4000 + 1000 0900 - 1000 + 2000 + + + 0900 + 4000 FGRGBW @@ -1149,6 +1318,15 @@ eco/dwzwave2.xml + + + 0001 + 0003 + + TILTZWAVE1 + + eco/tiltzwave1.xml + 001E @@ -1170,6 +1348,15 @@ 0115 ZWave.me + + + 1000 + 0200 + + ZME_064374 + + zwaveme/zme_064374.xml + 1000 @@ -1179,6 +1366,15 @@ zwaveme/zme_054313z.xml + + + 1000 + 0003 + + ZME_05459 + + zwaveme/zme_blindscontroller.xml + 0100 @@ -1215,6 +1411,10 @@ zwaveme/zme_wcd2.xml + + 0400 + 0004 + 1000 0004 @@ -1261,6 +1461,15 @@ tkb/tz65d.xml + + + 0001 + 0004 + + TZ06 + + tkb/tz06.xml + 0102 @@ -1359,6 +1568,19 @@ philio/psm02.xml + + + 0002 + 000C + + + 0002 + 000D + + PST-02 + + philio/pst02.xml + 0001 @@ -1379,6 +1601,15 @@ philio/pan06_1.xml + + + 0001 + 0001 + + PAN11-1 + + philio/pan11_1.xml + 0096 @@ -1514,6 +1745,15 @@ leviton/dzmx1-1lz.xml + + + 802 + 261 + + VRCZ4-M0Z + + leviton/vrcz4-m0z.xml + 007e @@ -1571,6 +1811,15 @@ qubino/zmnhda.xml + + + 5 + 1 + + ZMNHIA + + qubino/zmnhia.xml + 97 @@ -1607,6 +1856,10 @@ 84 FortrezZ + + 453 + 10E + 453 110 @@ -1620,6 +1873,10 @@ 0313 0108 + + 0313 + 010B + SSA1/SSA2 fortrezz/ssa1.xml @@ -1672,6 +1929,15 @@ 0154 POPP + + + 0001 + 0001 + + 123665 + + popp/123665.xml + 1100 @@ -1704,5 +1970,96 @@ yale/yrd210.xml - + + 0166 + Swiid + + + 0100 + 0100 + + SW-ZCS-1 + + swiid/SW-ZCS-1.xml + + + + 0131 + Zipato + + + 0002 + 0002 + + RGBWE27ZW + + zipato/rgbwe27.xml + + + + 0138 + BRK Brands + + + 0001 + 0002 + + ZCOMBO + + brk/zcombo.xml + + + + 0001 + 0001 + + ZSMOKE + + brk/zsmoke.xml + + + + 003b + Schlage + + + 6349 + 5044 + + BE468 + + schlage/be468.xml + + + + 0184 + Dragon Tech Industrial, Ltd. + + + 4447 + 3031 + + PA-100 + + dragontech/pa100.xml + + + + 4447 + 3033 + + WS-100 + + dragontech/ws100.xml + + + + 4447 + 3034 + + WD-100 + + dragontech/wd100.xml + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/qubino/zmnhba.xml b/bundles/binding/org.openhab.binding.zwave/database/qubino/zmnhba.xml index 2e45e630bb5..62761a790c7 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/qubino/zmnhba.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/qubino/zmnhba.xml @@ -6,8 +6,24 @@ 0x00 0x20 0x25 - 0x31 - 0x32 + + 0x31 + false + + + 0x32 + 1 + true + ELECTRIC + E_W,E_KWh + + + 0x32 + 2 + true + ELECTRIC + E_W,E_KWh + 0x60 0x70 0x72 diff --git a/bundles/binding/org.openhab.binding.zwave/database/qubino/zmnhia.xml b/bundles/binding/org.openhab.binding.zwave/database/qubino/zmnhia.xml new file mode 100644 index 00000000000..d906cb61997 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/qubino/zmnhia.xml @@ -0,0 +1,293 @@ + + + ZMNHIA + + + 0x00 + 0x20 + 0x25 + 0x31 + 0x32 + 0x60 + 0x70 + 0x72 + 0x85 + 0x86 + + + + 1 + list + 1 + 1 + + + 0 + + + + 1 + + + Input 1 switch type + + + + 2 + list + 1 + 1 + + + 0 + + + + 1 + + + Input 2 switch type + + + + 3 + list + 1 + 1 + + + 0 + + + + 1 + + + Input 3 switch type + + + + 4 + list + 0 + 1 + + + 0 + + + + 1 + + + + + + + 5 + list + 0 + 1 + + + 0 + + + + 1 + + + + + + + 10 + list + 255 + 1 + + + 255 + + + + 0 + + + + 1 + + + + 2 + + + Module responds to commands ALL ON / ALL OFF + that may be sent by the main controller or by other controller belonging to the system. + + + + 11 + byte + 0 + 2 + + + From 0 to 990 set point from 0.0 °C to 99.0 °C
      + From 1001 to 1150 – set point from -0.1 °C to -15.0 °C]]>
      +
      + + + 12 + byte + 0 + 2 + + + From 0 to 990 set point from 0.0 °C to 99.0 °C
      + From 1001 to 1150 – set point from -0.1 °C to -15.0 °C]]>
      +
      + + + 30 + list + 0 + 1 + + + 0 + + + + 1 + + + Saving the state of the relay after a power failure + + + + 40 + byte + 1 + 1 + + +
      • 0 = Reporting Disabled
      • +
      • 1–100 = 1% - 100% Reporting enabled
      + NOTE: if power changed is less than 1W, the report is not sent (pushed), regardless of percentage set.]]>
      +
      + + + 42 + byte + 300 + 2 + + +
      • 0 = Reporting Disabled
      • +
      • 1–65535 = 1 second – 65535 seconds. Reporting enabled. + Power report is sent with time interval set by entered value.
      ]]>
      +
      + + + 43 + byte + 132 + 1 + + + + + + 44 + byte + 5 + 1 + + + + + + 45 + byte + 5 + 1 + + + + + + 60 + byte + 50 + 2 + + + + + + 61 + byte + 700 + 2 + + + + + + 63 + byte + 0 + 2 + + + + +
      + + + + 1 + 16 + + Triggered at change of the output Q1 state and reflecting its state + + + 2 + 16 + + Triggered at change of the output I2 state and reflecting its state + + + 3 + 16 + + Triggered at change of the output I3 state and reflecting its state + + + 4 + 16 + + + + + 5 + 16 + true + + + + + 6 + 1 + true + + Reporting for controller + + +
      diff --git a/bundles/binding/org.openhab.binding.zwave/database/rtc/ct100.xml b/bundles/binding/org.openhab.binding.zwave/database/rtc/ct100.xml index 37e99219a3b..b4de6649535 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/rtc/ct100.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/rtc/ct100.xml @@ -20,5 +20,14 @@ 0x86 0x87 + + + + 1 + 2 + + Send report about Thermostat Mode, Thermostat Operating State, Fan Mode, Fan State, Setpoint, Sensor Multilevel + +
      diff --git a/bundles/binding/org.openhab.binding.zwave/database/rtc/ct30.xml b/bundles/binding/org.openhab.binding.zwave/database/rtc/ct30.xml index 59837a34aec..db82af908f5 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/rtc/ct30.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/rtc/ct30.xml @@ -149,7 +149,8 @@ 1 2 - + + Send report about Thermostat Mode, Thermostat Operating State, Fan Mode, Fan State, Setpoint, Sensor Multilevel diff --git a/bundles/binding/org.openhab.binding.zwave/database/schlage/be468.xml b/bundles/binding/org.openhab.binding.zwave/database/schlage/be468.xml new file mode 100644 index 00000000000..11cfe5c17e2 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/schlage/be468.xml @@ -0,0 +1,105 @@ + + + BE-468 + + + 0x20 + 0x22 + 0x62 + 0x63 + 0x70 + 0x71 + 0x72 + 0x80 + 0x84 + 0x85 + 0x86 + 0x98 + + + + + 3 + list + 255 + 1 + + Audio feedback when keypad pressed during normal operation + + 0 + + + + 255 + + + + + 4 + list + 0 + 1 + + Prevents all user codes from unlocking the deadbolt + + 0 + + + + 255 + + + + + 5 + list + 255 + 1 + + Press the Schlage button to lock the deadbolt + + 0 + + + + 255 + + + + + 15 + list + 0 + 1 + + Automatically locks 30 seconds after unlocking + + 0 + + + + 255 + + + + + 16 + byte + 4 + 1 + 4 + 8 + + User codes can be 4-8 digits. Changing length will delete all existing codes. + + + + + + 1 + 2 + + true + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/swiid/SW-ZCS-1.xml b/bundles/binding/org.openhab.binding.zwave/database/swiid/SW-ZCS-1.xml new file mode 100644 index 00000000000..38c172ee17c --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/swiid/SW-ZCS-1.xml @@ -0,0 +1,51 @@ + + + SwiidInter + + + 0x20 + 0x25 + 0x27 + 0x72 + 0x85 + 0x86 + + + + 1 + list + 255 + 1 + + + 0 + + + + 1 + + + + 2 + + + + 255 + + + + + + + 1 + 5 + + + + 2 + 5 + + true + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/tkb/tz06.xml b/bundles/binding/org.openhab.binding.zwave/database/tkb/tz06.xml new file mode 100644 index 00000000000..10fe2709e8e --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/tkb/tz06.xml @@ -0,0 +1,93 @@ + + + TK06 + + + + 0x20 + 0x25 + 0x27 + 0x60 + 0x70 + 0x71 + 0x72 + 0x85 + 0x86 + + + + 1 + list + 1 + 1 + + + If Controller not using Multi_Channel command class + to access the endpoint of PAN06, you may configure + the endpoint value to react the Basic Command Class + Wenn der Controller die Multi_Channel command class nicht unterstützt, + kann durch die Endpunktselektion der Endpunkt gewählt werden, + der auf die Basic Command Class reagiert + + 1 + + + + + 2 + + + + + 3 + + + + + + 2 + list + 1 + 1 + + + Change the external switch mode + Externer Schaltertyp ändern + + 1 + + + + + 2 + + + + + 3 + + + + + + + + 1 + 1 + + + + + 2 + 1 + + + + + 3 + 1 + + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/vision/zp3102.xml b/bundles/binding/org.openhab.binding.zwave/database/vision/zp3102.xml index c929aa90d8a..6c828fdb902 100644 --- a/bundles/binding/org.openhab.binding.zwave/database/vision/zp3102.xml +++ b/bundles/binding/org.openhab.binding.zwave/database/vision/zp3102.xml @@ -19,10 +19,10 @@ 1 short 1 - 15300 - 180 + 255 + 3 1 - + Delay before sending OFF
      @@ -33,6 +33,7 @@ 5 + true diff --git a/bundles/binding/org.openhab.binding.zwave/database/zipato/rgbwe27.xml b/bundles/binding/org.openhab.binding.zwave/database/zipato/rgbwe27.xml new file mode 100644 index 00000000000..29a540217fa --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/zipato/rgbwe27.xml @@ -0,0 +1,57 @@ + + + RGBWE27ZW + + + + 0x33 + false + + 0x5e + 0x86 + 0x72 + 0x98 + 0x5a + 0x85 + 0x59 + 0x73 + 0x25 + 0x20 + 0x27 + 0x32 + 0x70 + 0x71 + 0x75 + 0x7a + + + + 1 + byte + 50 + 1 + 100 + 1 + + Configuration option 1 is used to adjust color temperature. Values range from 0 to 100 where 0 means full cold white and 100 means full warm white. + + + 2 + byte + 16 + 0 + 31 + 1 + + Configuration option 2 is used to adjust shock sensor sensitivity. Values range from 0 to 31 where 0 means minimum sensitivity and 31 means maximum sensitivity. + + + + + 1 + 7 + true + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/zwaveme/zme_064374.xml b/bundles/binding/org.openhab.binding.zwave/database/zwaveme/zme_064374.xml new file mode 100644 index 00000000000..f669bdd9167 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/zwaveme/zme_064374.xml @@ -0,0 +1,181 @@ + + + ZME_064374 + + + 0x20 + 0x25 + 0x27 + 0x32 + 0x59 + 0x5a + 0x5e + 0x70 + 0x72 + 0x75 + 0x85 + 0x86 + 0x8e + 0x60 + 0x87 + + + + 1 + list + 3 + 1 + + + 0 + + + + 1 + + + + 2 + + + + + + + 2 + short + 0 + 2 + + + + + + 3 + list + 0 + 1 + + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + + + + 5 + list + 1 + 1 + + + 0 + + + + 1 + + + + + + + 20 + byte + 0 + 2 + + 0 + 1800 + + + + + 21 + list + 0 + 1 + + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + + + + 22 + list + 3 + 1 + + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + + + + + + + 1 + 5 + + + + + 2 + 5 + + + + + + diff --git a/bundles/binding/org.openhab.binding.zwave/database/zwaveme/zme_blindscontroller.xml b/bundles/binding/org.openhab.binding.zwave/database/zwaveme/zme_blindscontroller.xml new file mode 100644 index 00000000000..a897c66260c --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/database/zwaveme/zme_blindscontroller.xml @@ -0,0 +1,367 @@ + + + ZME_05459 + + + 0x20 + 0x25 + 0x26 + 0x27 + 0x60 + 0x70 + 0x72 + 0x75 + 0x77 + 0x85 + 0x86 + 0x87 + 0x8e + + + + 1 + list + 3 + 1 + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + Set LED indication mode + + + 2 + short + 0 + 65535 + 0 + 2 + + 0 + + + + If not zero, automatically open or close blind after a user defined time in seconds + + + 3 + list + 0 + 1 + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + Defines how to interpret RF Off command. Can be used in conjunction with Auto Close function: Ignore - to open the door by motion detectors and close it back after some amount of time: in case of multiple motion detectors each would try to open that would break logics; Open - to open on both On and Off paddle press on the remote and close after some amount of time. Button close click will still work (if button operations are not disabled). Note that Dim Down command will still begin close motion. + + + 4 + byte + 0 + 255 + 60 + 1 + + 0 + + + + Time in seconds to go from opened to closed state. Used to estimate the current level. Note that in Permanent motion mode the reported value would a be Closed or Opened, while all Basic and Multilevel Set values (1-99, 255) would Open except 0 value that would Close. + + + 5 + byte + 0 + 255 + 60 + 1 + + 0 + + + + Time in seconds to go from closed to open state. This value may differ from Full close time for some blinds due to gravity. Used to estimate the current level. Note that in Permanent motion mode the reported value would a be Closed or Opened, while all Basic and Multilevel Set values (1-99, 255) would Open except 0 value that would Close. + + + 6 + byte + 0 + 232 + 0 + 1 + + 0 + + + + Id of the device which commands would be interpreted not as Open/Close, but as block/unblock. Usefull with door opening detector: if the door is open, block the blind not to break shades while they move. + + + 7 + list + 0 + 1 + + 0 + + + + 1 + + + + Defines which command from blocking device to interpret as closed door and hence, unprotected. + + + 8 + list + 0 + 1 + + 0 + + + + 1 + + + + 2 + + + + Defines behaviour on open press while closing and vice versa. To allow Stop behavior when switched by remote, use Stop by Basic + + + 9 + list + 0 + 1 + + 0 + + + + 1 + + + + Allows exchanging open and close relays if blind control is wired to the motor incorrectly + + + 10 + byte + 0 + 100 + 50 + 1 + + Typical time used to differentiate click, hold and double and triple clicks in 10ms units + + + 11 + list + 0 + 1 + + 0 + + + + 1 + + + + Allows exchanging the functionality of the buttons + + + 12 + list + 1 + 1 + + 0 + + + + 1 + + + + 2 + + + + If disabled, the local operations by buttons will not switch the load, but only send commands to On/Off association group. In this mode buttons are not linked with the switch anymore. They can be used separately: buttons to control remote device, switch will operate by RF commands only. + + + 13 + list + 4 + 1 + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + 5 + + + + Defines which command should be sent on button single press or hold. Basic and Scene Activation commands are sent to Association group. Use Scene Controller Conf to set up Scene ID for Scene Activation. Switch All commands are sent broadcast. + + + 14 + list + 0 + 1 + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + 5 + + + + Defines which command should be sent on button double press or press-hold. Basic and Scene Activation commands are sent to Association group. Use Scene Controller Conf to set up Scene ID for Scene Activation. Switch All commands are sent broadcast. If not disabled, the device will wait for a click timeout to see if the second click would be pressed. This will introduce a small delay for single click commands + + + 15 + list + 1 + 1 + + 1 + + + + 2 + + + + 255 + + + + Defines what to do when a Switch All command arrives. + + + 16 + list + 0 + 1 + + 0 + + + + 1 + + + + 2 + + + + Defines how to interpret button Down press. Depends on "Switch by buttons" parameter. If not Disabled this parameter will affect the action selected by the latter parameter. Can be used in conjunction with Auto Off function. + + + 17 + list + 0 + 1 + + 0 + + + + 1 + + + + Defines the action to perform upon auto open or auto close. + + + + + + 1 + 8 + + + + 2 + 8 + + + + 3 + 8 + + true + + + diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/HexToIntegerConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/HexToIntegerConverter.java index 3dd3bb80b61..69c9b59e686 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/HexToIntegerConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/HexToIntegerConverter.java @@ -46,10 +46,14 @@ public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingC @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { String value = reader.getValue(); - if(value.startsWith("0x")) - return Integer.decode(value); - else - return Integer.parseInt(value, 16); + long lVal; + if(value.startsWith("0x")) { + lVal = Long.decode(value); + } + else { + lVal = Long.parseLong(value, 16); + } + + return (int)lVal; } - } \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveActivator.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveActivator.java index 17e6178f522..93f9b817a0d 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveActivator.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveActivator.java @@ -33,7 +33,7 @@ public final class ZWaveActivator implements BundleActivator { */ public void start(BundleContext bc) throws Exception { context = bc; - logger.debug("Z-Wave binding has been started."); + logger.debug("Z-Wave binding started. Version {}", ZWaveActivator.getVersion()); } /** @@ -42,7 +42,7 @@ public void start(BundleContext bc) throws Exception { */ public void stop(BundleContext bc) throws Exception { context = null; - logger.debug("Z-Wave binding has been stopped."); + logger.debug("Z-Wave binding stopped."); } /** diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveActiveBinding.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveActiveBinding.java index 8cfadd60ff8..4355b2d6951 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveActiveBinding.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveActiveBinding.java @@ -21,10 +21,11 @@ import org.openhab.binding.zwave.internal.protocol.SerialInterfaceException; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEventListener; +import org.openhab.binding.zwave.internal.protocol.ZWaveNode; import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; import org.openhab.binding.zwave.internal.protocol.event.ZWaveEvent; import org.openhab.binding.zwave.internal.protocol.event.ZWaveInitializationCompletedEvent; -import org.openhab.binding.zwave.internal.protocol.event.ZWaveTransactionCompletedEvent; +import org.openhab.binding.zwave.internal.protocol.initialization.ZWaveNodeInitStage; import org.openhab.core.binding.AbstractActiveBinding; import org.openhab.core.binding.BindingProvider; import org.openhab.core.types.Command; @@ -55,13 +56,13 @@ public class ZWaveActiveBinding extends AbstractActiveBinding pollingIterator = null; private List pollingList = new ArrayList(); @@ -94,16 +95,10 @@ protected String getName() { */ @Override protected void execute() { - - if(!isZwaveNetworkReady){ - logger.debug("Zwave Network isn't ready yet!"); - if (this.zController != null) - this.zController.checkForDeadOrSleepingNodes(); - return; - } - // Call the network monitor - networkMonitor.execute(); + if(networkMonitor != null) { + networkMonitor.execute(); + } // If we're not currently in a poll cycle, restart the polling table if(pollingIterator == null) { @@ -175,14 +170,32 @@ public void allBindingsChanged(BindingProvider provider) { private void rebuildPollingTable() { // Rebuild the polling table pollingList.clear(); + + if(converterHandler == null) { + logger.debug("ConverterHandler not initialised. Polling disabled."); + + return; + } // Loop all binding providers for the Z-wave binding. for (ZWaveBindingProvider eachProvider : providers) { - // loop all bound items for this provider + // Loop all bound items for this provider for (String name : eachProvider.getItemNames()) { + // Find the node and check if it's completed initialisation. + ZWaveBindingConfig cfg = eachProvider.getZwaveBindingConfig(name); + ZWaveNode node = this.zController.getNode(cfg.getNodeId()); + if(node == null) { + logger.debug("NODE {}: Polling list: can't get node for item {}", cfg.getNodeId(), name); + continue; + } + if(node.getNodeInitializationStage() != ZWaveNodeInitStage.DONE) { + logger.debug("NODE {}: Polling list: item {} is not completed initialisation", cfg.getNodeId(), name); + continue; + } + logger.trace("Polling list: Checking {} == {}", name, converterHandler.getRefreshInterval(eachProvider, name)); - // This binding is configured to poll - add it to the list + // If this binding is configured to poll - add it to the list if (converterHandler.getRefreshInterval(eachProvider, name) > 0) { ZWavePollItem item = new ZWavePollItem(); item.item = name; @@ -205,23 +218,25 @@ protected void internalReceiveCommand(String itemName, Command command) { boolean handled = false; // if we are not yet initialized, don't waste time and return - if((this.isProperlyConfigured() == false) | (isZwaveNetworkReady == false)) { - logger.debug("internalReceiveCommand Called, But Not Properly Configure yet or Zwave Network Isn't Ready, returning."); + if(this.isProperlyConfigured() == false) { + logger.debug("internalReceiveCommand Called, But Not Properly Configure yet, returning."); return; } logger.trace("internalReceiveCommand(itemname = {}, Command = {})", itemName, command.toString()); for (ZWaveBindingProvider provider : providers) { - if (!provider.providesBindingFor(itemName)) + if (!provider.providesBindingFor(itemName)) { continue; + } converterHandler.receiveCommand(provider, itemName, command); handled = true; } - if (!handled) + if (!handled) { logger.warn("No converter found for item = {}, command = {}, ignoring.", itemName, command.toString()); + } } /** @@ -240,7 +255,6 @@ public void activate() { */ @Override public void deactivate() { - isZwaveNetworkReady = false; if (this.converterHandler != null) { this.converterHandler = null; } @@ -265,11 +279,11 @@ public void deactivate() { */ private void initialise() throws ConfigurationException { try { + logger.debug("Initialising zwave binding"); this.setProperlyConfigured(true); this.deactivate(); - this.zController = new ZWaveController(isSUC, port, timeout); + this.zController = new ZWaveController(masterController, isSUC, port, timeout, softReset); this.converterHandler = new ZWaveConverterHandler(this.zController, this.eventPublisher); - zController.initialize(); zController.addEventListener(this); // The network monitor service needs to know the controller... @@ -277,6 +291,9 @@ private void initialise() throws ConfigurationException { if(healtime != null) { this.networkMonitor.setHealTime(healtime); } + if(aliveCheckPeriod != null) { + this.networkMonitor.setPollPeriod(aliveCheckPeriod); + } if(softReset != false) { this.networkMonitor.resetOnError(softReset); } @@ -296,9 +313,11 @@ private void initialise() throws ConfigurationException { */ @Override public void updated(Dictionary config) throws ConfigurationException { - if (config == null) + if (config == null) { + logger.info("ZWave 'updated' with null config"); return; - + } + // Check the serial port configuration value. // This value is mandatory. if (StringUtils.isNotBlank((String) config.get("port"))) { @@ -332,6 +351,15 @@ public void updated(Dictionary config) throws ConfigurationException logger.error("Error parsing 'pollingQueue'. This must be a single number time in milliseconds."); } } + if (StringUtils.isNotBlank((String) config.get("aliveCheckPeriod"))) { + try { + aliveCheckPeriod = Integer.parseInt((String) config.get("aliveCheckPeriod")); + logger.info("Update config, aliveCheckPeriod = {}", aliveCheckPeriod); + } catch (NumberFormatException e) { + aliveCheckPeriod = null; + logger.error("Error parsing 'aliveCheckPeriod'. This must be an Integer."); + } + } if (StringUtils.isNotBlank((String) config.get("timeout"))) { try { timeout = Integer.parseInt((String) config.get("timeout")); @@ -359,7 +387,16 @@ public void updated(Dictionary config) throws ConfigurationException logger.error("Error parsing 'softReset'. This must be boolean."); } } - + if (StringUtils.isNotBlank((String) config.get("masterController"))) { + try { + masterController = Boolean.parseBoolean((String) config.get("masterController")); + logger.info("Update config, masterController = {}", masterController); + } catch (NumberFormatException e) { + masterController = true; + logger.error("Error parsing 'masterController'. This must be boolean."); + } + } + // Now that we've read ALL the configuration, initialise the binding. initialise(); } @@ -379,28 +416,22 @@ public String getPort() { @Override public void ZWaveIncomingEvent(ZWaveEvent event) { - // if we are not yet initialized, don't waste time and return - if (!this.isProperlyConfigured()) + // If we are not yet initialized, don't waste time and return + if (!this.isProperlyConfigured()) { return; - - if (!isZwaveNetworkReady) { - if (event instanceof ZWaveInitializationCompletedEvent) { - logger.debug("ZWaveIncomingEvent Called, Network Event, Init Done. Setting ZWave Network Ready."); - isZwaveNetworkReady = true; - - // Initialise the polling table - rebuildPollingTable(); - - return; - } } - - logger.debug("ZwaveIncomingEvent"); - - // ignore transaction completed events. - if (event instanceof ZWaveTransactionCompletedEvent) + + if (event instanceof ZWaveInitializationCompletedEvent) { + logger.debug("NODE {}: ZWaveIncomingEvent Called, Network Event, Init Done. Setting device ready.", event.getNodeId()); + + // Initialise the polling table + rebuildPollingTable(); + return; - + } + + logger.debug("ZwaveIncomingEvent"); + // handle command class value events. if (event instanceof ZWaveCommandClassValueEvent) { handleZWaveCommandClassValueEvent((ZWaveCommandClassValueEvent)event); @@ -416,24 +447,26 @@ private void handleZWaveCommandClassValueEvent( ZWaveCommandClassValueEvent event) { boolean handled = false; - logger.debug("Got a value event from Z-Wave network for nodeId = {}, endpoint = {}, command class = {}, value = {}", + logger.debug("NODE {}: Got a value event from Z-Wave network, endpoint = {}, command class = {}, value = {}", new Object[] { event.getNodeId(), event.getEndpoint(), event.getCommandClass().getLabel(), event.getValue() } ); for (ZWaveBindingProvider provider : providers) { for (String itemName : provider.getItemNames()) { ZWaveBindingConfig bindingConfig = provider.getZwaveBindingConfig(itemName); - if (bindingConfig.getNodeId() != event.getNodeId() || bindingConfig.getEndpoint() != event.getEndpoint()) + if (bindingConfig.getNodeId() != event.getNodeId() || bindingConfig.getEndpoint() != event.getEndpoint()) { continue; + } converterHandler.handleEvent(provider, itemName, event); handled = true; } } - if (!handled) - logger.warn("No item bound for event from nodeId = {}, endpoint = {}, command class = {}, value = {}, ignoring.", + if (!handled) { + logger.warn("NODE {}: No item bound for event, endpoint = {}, command class = {}, value = {}, ignoring.", new Object[] { event.getNodeId(), event.getEndpoint(), event.getCommandClass().getLabel(), event.getValue() } ); + } } class ZWavePollItem { diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveGenericBindingProvider.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveGenericBindingProvider.java index 8a7dbd34079..9c8b71eecc0 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveGenericBindingProvider.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveGenericBindingProvider.java @@ -13,6 +13,7 @@ import org.openhab.binding.zwave.ZWaveBindingConfig; import org.openhab.binding.zwave.ZWaveBindingProvider; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; import org.openhab.core.items.Item; import org.openhab.model.item.binding.AbstractGenericBindingProvider; import org.openhab.model.item.binding.BindingConfigParseException; @@ -23,6 +24,7 @@ * This class is responsible for parsing the binding configuration. * @author Victor Belov * @author Brian Crosby + * @author Chris Jackson * @since 1.3.0 */ public class ZWaveGenericBindingProvider extends AbstractGenericBindingProvider implements ZWaveBindingProvider { @@ -56,34 +58,57 @@ public void processBindingConfiguration(String context, Item item, String bindin super.processBindingConfiguration(context, item, bindingConfig); String[] segments = bindingConfig.split(":"); - if (segments.length < 1 || segments.length > 3) - throw new BindingConfigParseException("invalid number of segments in binding: " + bindingConfig); + if (segments.length < 1 || segments.length > 3) { + throw new BindingConfigParseException("Invalid number of segments in binding: " + bindingConfig); + } int nodeId; - try{ + try { nodeId = Integer.parseInt(segments[0]); - } catch (Exception e){ - throw new BindingConfigParseException(segments[1] + " is not a valid node id."); + } catch (Exception e) { + logger.error("{}: Invalid node ID '{}'", item.getName(), segments[0]); + throw new BindingConfigParseException(segments[0] + " is not a valid node id."); } - + + if(nodeId <= 0 || nodeId > 232) { + logger.error("{}: Invalid node ID '{}'", item.getName(), nodeId); + throw new BindingConfigParseException(nodeId + " is not a valid node number."); + } + int endpoint = 0; Integer refreshInterval = null; Map arguments = new HashMap(); - + for (int i = 1; i < segments.length; i++) { try { if (segments[i].contains("=")) { for (String keyValuePairString : segments[i].split(",")) { String[] pair = keyValuePairString.split("="); String key = pair[0].trim().toLowerCase(); - - if (key.equals("refresh_interval")) - refreshInterval = Integer.parseInt(pair[1].trim()); - else - arguments.put(key, pair[1].trim().toLowerCase()); + String value = pair[1].trim().toLowerCase(); + + if (key.equals("refresh_interval")) { + refreshInterval = Integer.parseInt(value); + } else { + arguments.put(key, value); + } + + // Sanity check the command class + if (key.equals("command")) { + if(ZWaveCommandClass.CommandClass.getCommandClass(pair[1]) == null && + value.equals("info") == false) { + logger.error("{}: Invalid command class '{}'", item.getName(), pair[1].toUpperCase()); + throw new BindingConfigParseException("Invalid command class " + pair[1].toUpperCase()); + } + } } } else { + try { endpoint = Integer.parseInt(segments[i]); + } catch (Exception e) { + logger.error("{}: Invalid endpoint ID '{}'", item.getName(), segments[i]); + throw new BindingConfigParseException(segments[i] + " is not a valid endpoint."); + } } } catch (Exception e){ throw new BindingConfigParseException(segments[i] + " is not a valid argument."); diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveNetworkMonitor.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveNetworkMonitor.java index 287a1978b16..0ea716e6fbe 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveNetworkMonitor.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/ZWaveNetworkMonitor.java @@ -23,6 +23,7 @@ import org.openhab.binding.zwave.internal.protocol.ZWaveNode; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; +import org.openhab.binding.zwave.internal.protocol.ZWaveNodeState; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveAssociationCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveNoOperationCommandClass; @@ -56,7 +57,6 @@ * # Update the associations so that we know which nodes need to talk to others * # Update the routes between devices that have associations set * # Retrieve the neighbor list so that the binding knows who's out there - * # Ping the node to see if it's awake * # Save the device files * * Observations @@ -78,7 +78,7 @@ public final class ZWaveNetworkMonitor implements ZWaveEventListener { private long HEAL_TIMEOUT_PERIOD = 90000; private long HEAL_DELAY_PERIOD = 4000; private int HEAL_MAX_RETRIES = 5; - private long PING_PERIOD = 90000; + private long pollPeriod = 90000; private int networkHealNightlyHour = -1; private long networkHealNextTime = Long.MAX_VALUE; @@ -93,7 +93,7 @@ public final class ZWaveNetworkMonitor implements ZWaveEventListener { Map healNodes = new HashMap(); enum HealState { - IDLE, WAITING, PING, SETSUCROUTE, UPDATENEIGHBORS, GETASSOCIATIONS, UPDATEROUTES, UPDATEROUTESNEXT, GETNEIGHBORS, PINGEND, SAVE, DONE, FAILED; + IDLE, WAITING, PING, SETSUCROUTE, UPDATENEIGHBORS, GETASSOCIATIONS, UPDATEROUTES, UPDATEROUTESNEXT, GETNEIGHBORS, SAVE, DONE, FAILED; public boolean isActive() { switch (this) { @@ -126,25 +126,45 @@ public ZWaveNetworkMonitor(ZWaveController controller) { * the hour of the heal (0-23) */ public void setHealTime(Integer time) { - if (time == null) + if (time == null) { networkHealNightlyHour = -1; - else + } + else { networkHealNightlyHour = time; + } // Sanity check - if (networkHealNightlyHour > 23) + if (networkHealNightlyHour > 23) { networkHealNightlyHour = -1; - if (networkHealNightlyHour < 0) + } + else if (networkHealNightlyHour < 0) { networkHealNightlyHour = -1; + } - if (initialised == false) + if (initialised == false) { return; + } // Calculate the next heal time networkHealNightlyTime = calculateNextHeal(); networkHealNextTime = networkHealNightlyTime; } + /** + * Sets the polling period (in milliseconds) between each network health + * ping. + * @param time period in seconds + */ + public void setPollPeriod(Integer time) { + pollPeriod = time; + if (pollPeriod >= 3600000) { + pollPeriod = 3600000; + } + else if (pollPeriod <= 15000) { + pollPeriod = 15000; + } + } + /** * Configures the binding to perform a soft reset during the heal * @@ -214,12 +234,18 @@ public boolean isNodeHealing(int nodeId) { * Node to perform the heal on * @return true if the heal is scheduled */ - public boolean healNode(int nodeId) { + public boolean startNodeHeal(int nodeId) { ZWaveNode node = zController.getNode(nodeId); if (node == null) { logger.error("NODE {}: Heal node - can't be found.", nodeId); return false; } + + // If so, don't start it again! + if (isNodeHealing(nodeId)) { + logger.debug("NODE {}: Node is already healing.", node.getNodeId()); + return false; + } HealNode heal = new HealNode(); heal.node = node; @@ -230,11 +256,15 @@ public boolean healNode(int nodeId) { heal.lastChange = Calendar.getInstance().getTime(); // Find out if this is a listening device - if (node.isListening()) + if (node.isListening()) { heal.listening = true; - else + } + else { heal.listening = false; + } healNodes.put(nodeId, heal); + + logger.debug("NODE {}: Starting heal", nodeId); // Start the first heal next time around the loop networkHealNextTime = 0; @@ -252,18 +282,18 @@ public boolean rescheduleHeal() { // The list is built multiple times since it seems that in order to // fully optimize the network, this is required for (ZWaveNode node : zController.getNodes()) { - // Ignore devices that haven't initialized yet - unless they are - // DEAD or FAILED. - if (node.isInitializationComplete() == false && node.isDead() == false) { + // Ignore devices that haven't initialized yet + if (node.isInitializationComplete() == false) { logger.debug("NODE {}: Initialisation NOT yet complete. Skipping heal.", node.getNodeId()); continue; } - healNode(node.getNodeId()); + startNodeHeal(node.getNodeId()); } - if (healNodes.size() == 0) + if (healNodes.size() == 0) { return false; + } // If we want to do a soft reset on the controller, do it now.... if(doSoftReset == true) { @@ -282,29 +312,31 @@ public boolean rescheduleHeal() { public void execute() { // Don't start the next node if there's a queue if (zController.getSendQueueLength() > 1) { - logger.debug("Queue length is {} - deferring HEAL.", zController.getSendQueueLength()); + logger.debug("Network Monitor: Queue length is {} - deferring network monitor functions.", zController.getSendQueueLength()); return; } if (pingNodeTime < System.currentTimeMillis()) { // Update the time and send a ping... - pingNodeTime = System.currentTimeMillis() + PING_PERIOD; + pingNodeTime = System.currentTimeMillis() + pollPeriod; - // Find the node that we haven't communicated with for the longest - // time + // Find the node that we haven't communicated with for the longest time ZWaveNode oldestNode = null; for (ZWaveNode node : zController.getNodes()) { // Ignore the controller and nodes that aren't listening - if (node.getNodeId() == zController.getOwnNodeId() || node.isListening() == false) + if (node.getNodeId() == zController.getOwnNodeId() || node.isListening() == false) { continue; - if (oldestNode == null) { + } + // Use the last sent time for comparisson. + // This avoids the situation where we only poll a dead node if we use the received time! + if (oldestNode == null || oldestNode.getLastSent() == null) { oldestNode = node; - } else if (node.getLastSent().getTime() < oldestNode.getLastSent().getTime()) { + } else if (node.getLastSent() == null || node.getLastSent().getTime() < oldestNode.getLastSent().getTime()) { oldestNode = node; } } - // We now have the oldest node that we've heard from - ping it! + // We now have the oldest node that we've sent to - ping it! if (oldestNode != null) { logger.debug("NODE {}: Sending periodic PING.", oldestNode.getNodeId()); @@ -313,8 +345,12 @@ public void execute() { ZWaveNoOperationCommandClass zwaveCommandClass = (ZWaveNoOperationCommandClass) oldestNode .getCommandClass(CommandClass.NO_OPERATION); - if (zwaveCommandClass != null) + if (zwaveCommandClass != null) { zController.sendData(zwaveCommandClass.getNoOperationMessage()); + } + } + else { + logger.debug("Network Monitor: No nodes to ping!"); } // To reduce congestion, we don't do anything else during this @@ -371,8 +407,9 @@ public void execute() { */ private void nextHealStage(HealNode healing) { // Don't do anything if it's failed already - if (healing.state == HealState.FAILED) + if (healing.state == HealState.FAILED) { return; + } healing.lastChange = Calendar.getInstance().getTime(); @@ -381,21 +418,46 @@ private void nextHealStage(HealNode healing) { // to avoid congestion and false timeouts. pingNodeTime = System.currentTimeMillis() + HEAL_TIMEOUT_PERIOD + 20000; + // Set the timeout + networkHealNextTime = System.currentTimeMillis() + HEAL_TIMEOUT_PERIOD; + + // Only do something if the node is awake! + ZWaveNode node = zController.getNode(healing.nodeId); + if(node != null) { + ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node + .getCommandClass(CommandClass.WAKE_UP); + + if(wakeupCommandClass != null && wakeupCommandClass.isAwake() == false) { + // Device is asleep - don't do anything now! + logger.debug("NODE {}: Node is asleep. Defer heal until it's awake", healing.nodeId); + return; + } + } + // Handle retries healing.retryCnt++; if (healing.retryCnt >= HEAL_MAX_RETRIES) { - logger.debug("NODE {}: Network heal has exceeded maximum retries", healing.nodeId); - healing.failState = healing.state; - healing.state = HealState.FAILED; - networkHealNextTime = System.currentTimeMillis() + HEAL_DELAY_PERIOD; - - // Save the XML file. This serialises the data we've just updated - // (neighbors etc) - healing.node.setHealState(this.getNodeState(healing.node.getNodeId())); - - ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer(); - nodeSerializer.SerializeNode(healing.node); - return; + logger.debug("NODE {}: Maximum retries in state {}", healing.nodeId, healing.state); + + // Since the GETNEIGHBORS state fails often, it seems better to + // continue with the heal than to abort here. + if (healing.state == HealState.UPDATENEIGHBORS) { + healing.state = healing.stateNext; + healing.retryCnt = 0; + logger.debug("NODE {}: Heal - continuing to state {}", healing.nodeId, healing.stateNext); + } else { + logger.debug("NODE {}: Network heal has exceeded maximum retries!", healing.nodeId); + healing.failState = healing.state; + healing.state = HealState.FAILED; + + // Save the XML file. This serialises the data we've just updated + // (neighbors etc) + healing.node.setHealState(this.getNodeState(healing.node.getNodeId())); + + ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer(); + nodeSerializer.SerializeNode(healing.node); + return; + } } // Set the timeout @@ -403,13 +465,18 @@ private void nextHealStage(HealNode healing) { switch (healing.state) { case WAITING: + // Log what we're up to... logger.debug("NODE {}: NETWORK HEAL - STARTING", healing.nodeId); // Reset the resend count. // This also resets the time so that we cycle through all the nodes healing.node.resetResendCount(); + healing.state = HealState.PING; case PING: + // Log what we're up to... + logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state); + if (healing.nodeId != zController.getOwnNodeId()) { healing.state = HealState.PING; ZWaveNoOperationCommandClass zwaveCommandClass = (ZWaveNoOperationCommandClass) healing.node @@ -421,7 +488,11 @@ private void nextHealStage(HealNode healing) { } } healing.state = HealState.SETSUCROUTE; + case SETSUCROUTE: + // Log what we're up to... + logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state); + // Only set the route if this is not the controller and there is an SUC in the network if (healing.nodeId != zController.getOwnNodeId() && zController.getSucId() != 0) { // Update the route to the controller @@ -432,13 +503,20 @@ private void nextHealStage(HealNode healing) { break; } healing.state = HealState.UPDATENEIGHBORS; + case UPDATENEIGHBORS: - logger.debug("NODE {}: Heal is updating node neighbors.", healing.nodeId); + // Log what we're up to... + logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state); + healing.event = ZWaveNetworkEvent.Type.NodeNeighborUpdate; healing.stateNext = HealState.GETASSOCIATIONS; zController.requestNodeNeighborUpdate(healing.nodeId); break; + case GETASSOCIATIONS: + // Log what we're up to... + logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state); + // Check if this node supports associations ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) healing.node .getCommandClass(CommandClass.ASSOCIATION); @@ -449,7 +527,12 @@ private void nextHealStage(HealNode healing) { associationCommandClass.getAllAssociations(); break; } + healing.stateNext = HealState.UPDATEROUTES; + case UPDATEROUTES: + // Log what we're up to... + logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state); + // Get the list of routes for this node healing.routeList = healing.node.getRoutingList(); if (healing.routeList != null && healing.routeList.size() != 0) { @@ -460,7 +543,12 @@ private void nextHealStage(HealNode healing) { zController.requestDeleteAllReturnRoutes(healing.nodeId); break; } + healing.stateNext = HealState.UPDATEROUTESNEXT; + case UPDATEROUTESNEXT: + // Log what we're up to... + logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state); + if (healing.routeList != null && healing.routeList.size() != 0) { // Loop through all the nodes and set the return route logger.debug("NODE {}: Adding return route to {}", healing.nodeId, healing.routeList.get(0)); @@ -469,32 +557,30 @@ private void nextHealStage(HealNode healing) { zController.requestAssignReturnRoute(healing.nodeId, healing.routeList.get(0)); break; } + healing.stateNext = HealState.GETNEIGHBORS; + case GETNEIGHBORS: + // Log what we're up to... + logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state); + healing.event = ZWaveNetworkEvent.Type.NodeRoutingInfo; - healing.stateNext = HealState.PINGEND; + healing.stateNext = HealState.SAVE; logger.debug("NODE {}: Heal is requesting node neighbor info.", healing.nodeId); zController.requestNodeRoutingInfo(healing.nodeId); break; - case PINGEND: - if (healing.nodeId != zController.getOwnNodeId()) { - ZWaveNoOperationCommandClass zwaveCommandClass = (ZWaveNoOperationCommandClass) healing.node - .getCommandClass(CommandClass.NO_OPERATION); - if (zwaveCommandClass == null) - break; - zController.sendData(zwaveCommandClass.getNoOperationMessage()); - healing.stateNext = HealState.SAVE; - break; - } + case SAVE: - logger.debug("NODE {}: Heal is complete - saving XML.", healing.nodeId); + // Log what we're up to... + logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state); + healing.state = HealState.DONE; networkHealNextTime = System.currentTimeMillis() + HEAL_DELAY_PERIOD; // Save the XML file. This serialises the data we've just updated // (neighbors etc) healing.node.setHealState(this.getNodeState(healing.node.getNodeId())); - + ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer(); nodeSerializer.SerializeNode(healing.node); break; @@ -511,8 +597,9 @@ private void nextHealStage(HealNode healing) { */ private long calculateNextHeal() { // Initialise the time for the first heal - if(networkHealNightlyHour == -1) + if(networkHealNightlyHour == -1) { return Long.MAX_VALUE; + } Calendar next = Calendar.getInstance(); next.set(Calendar.HOUR_OF_DAY, networkHealNightlyHour); @@ -520,8 +607,9 @@ private long calculateNextHeal() { next.set(Calendar.SECOND, 0); next.set(Calendar.MILLISECOND, 0); - if (next.getTimeInMillis() < System.currentTimeMillis()) + if (next.getTimeInMillis() < System.currentTimeMillis()) { return next.getTimeInMillis() + 86400000; + } return next.getTimeInMillis(); } @@ -537,16 +625,16 @@ public void ZWaveIncomingEvent(ZWaveEvent event) { // Handle network events if (event instanceof ZWaveNetworkEvent) { ZWaveNetworkEvent nwEvent = (ZWaveNetworkEvent) event; - logger.debug("NODE {}: Network heal EVENT", nwEvent.getNodeId()); - // Get the heal class for this notification HealNode node = healNodes.get(nwEvent.getNodeId()); - if (node == null) + if (node == null) { return; + } // Is this the event we're waiting for - if (nwEvent.getEvent() != node.event) + if (nwEvent.getEvent() != node.event) { return; + } switch (nwEvent.getState()) { case Success: @@ -560,8 +648,9 @@ public void ZWaveIncomingEvent(ZWaveEvent event) { // If retry count is 0 and we have a list of routes, then this must have // been a successful route set - remove this node - if (node.retryCnt == 0 && node.routeList != null && node.routeList.size() > 0) + if (node.retryCnt == 0 && node.routeList != null && node.routeList.size() > 0) { node.routeList.remove(0); + } // Continue.... nextHealStage(node); @@ -569,19 +658,22 @@ public void ZWaveIncomingEvent(ZWaveEvent event) { SerialMessage serialMessage = ((ZWaveTransactionCompletedEvent) event).getCompletedMessage(); if (serialMessage.getMessageClass() != SerialMessageClass.SendData - && serialMessage.getMessageType() != SerialMessageType.Request) + && serialMessage.getMessageType() != SerialMessageType.Request) { return; + } byte[] payload = serialMessage.getMessagePayload(); - if (payload.length < 3) + if (payload.length < 3) { return; + } HealNode node = healNodes.get(payload[0] & 0xFF); - if (node == null) + if (node == null) { return; + } // See if this node is waiting for a PING - if ((node.state == HealState.PING || node.state == HealState.PINGEND) && payload.length >= 3 + if (node.state == HealState.PING && payload.length >= 3 && (payload[2] & 0xFF) == ZWaveCommandClass.CommandClass.NO_OPERATION.getKey()) { node.state = node.stateNext; node.retryCnt = 0; @@ -590,18 +682,21 @@ public void ZWaveIncomingEvent(ZWaveEvent event) { } } else if (event instanceof ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) { // We only care about the wake-up notification - if (((ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) event).getEvent() != ZWaveWakeUpCommandClass.WAKE_UP_NOTIFICATION) + if (((ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) event).getEvent() != ZWaveWakeUpCommandClass.WAKE_UP_NOTIFICATION) { return; + } // A wakeup event is received. Find the node in the node list HealNode node = healNodes.get(event.getNodeId()); - if (node == null) + if (node == null) { return; + } // Check to see the state of this node // and only process if there's something to do - if (!node.state.isActive()) + if (!node.state.isActive()) { return; + } logger.debug("NODE {}: Heal WakeUp EVENT {}", node.nodeId, node.state); nextHealStage(node); @@ -611,8 +706,8 @@ public void ZWaveIncomingEvent(ZWaveEvent event) { logger.debug("NODE {}: Node Status event - Node is {}", statusEvent.getNodeId(), statusEvent.getState()); switch (statusEvent.getState()) { - case Dead: - case Failed: + case DEAD: + case FAILED: ZWaveNode node = zController.getNode(statusEvent.getNodeId()); if (node == null) { logger.error("NODE {}: Status event received, but node not found.", statusEvent.getNodeId()); @@ -620,35 +715,21 @@ public void ZWaveIncomingEvent(ZWaveEvent event) { } // If this is a DEAD notification, then ask the controller if it's really FAILED - if(statusEvent.getState() == ZWaveNodeStatusEvent.State.Dead) { + if(statusEvent.getState() == ZWaveNodeState.DEAD) { zController.requestIsFailedNode(node.getNodeId()); } // The node is dead, but we may have already started a Heal - // If so, don't start it again! - if (!isNodeHealing(node.getNodeId())) { - logger.debug("NODE {}: {} node - requesting network heal.", node.getNodeId(), statusEvent.getState()); - - healNode(node.getNodeId()); - - // Reset the node stage to PING. - // This will also set the state back to DONE in - // resetResendCount if the node - // has already completed initialisation. - // node.setNodeStage(NodeStage.PING); - - node.resetResendCount(); - } else { - logger.debug("NODE {}: {} node - already healing.", node.getNodeId(), statusEvent.getState()); - } + // If so, it won't be started again! + startNodeHeal(node.getNodeId()); break; - case Alive: + case ALIVE: break; } } else if (event instanceof ZWaveInitializationCompletedEvent) { logger.debug("Network initialised - starting network monitor."); - // Remember that we've initialsed the binding. + // Remember that we've initialised the binding. initialised = true; // Calculate the next heal time @@ -656,7 +737,7 @@ public void ZWaveIncomingEvent(ZWaveEvent event) { networkHealNextTime = networkHealNightlyTime; // Set the next PING time - pingNodeTime = System.currentTimeMillis() + PING_PERIOD; + pingNodeTime = System.currentTimeMillis() + pollPeriod; } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveConfiguration.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveConfiguration.java index 87edb2c6069..e07a04ec240 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveConfiguration.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveConfiguration.java @@ -11,6 +11,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.TimeZone; @@ -35,6 +36,7 @@ import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass; import org.openhab.binding.zwave.internal.protocol.event.ZWaveEvent; import org.openhab.binding.zwave.internal.protocol.event.ZWaveInclusionEvent; +import org.openhab.binding.zwave.internal.protocol.initialization.ZWaveNodeInitStage; import org.openhab.binding.zwave.internal.protocol.initialization.ZWaveNodeSerializer; import org.osgi.framework.FrameworkUtil; import org.slf4j.Logger; @@ -64,6 +66,8 @@ public class ZWaveConfiguration implements OpenHABConfigurationService, ZWaveEve private TimerTask timerTask = null; + private final String MAX_VERSION = "255.255"; + private PendingConfiguration PendingCfg = new PendingConfiguration(); /** @@ -103,7 +107,6 @@ public List getConfiguration(String domain) { List records = new ArrayList(); OpenHABConfigurationRecord record; -// ZWaveNode node; if (domain.equals("status/")) { // Return the z-wave status information @@ -126,8 +129,9 @@ record = new OpenHABConfigurationRecord(domain + manufacturer.Id.toString() + "/ break; case 2: // Get products list - if (database.FindManufacturer(Integer.parseInt(splitDomain[1])) == false) + if (database.FindManufacturer(Integer.parseInt(splitDomain[1])) == false) { break; + } record = new OpenHABConfigurationRecord(domain, "ManufacturerID", "Manufacturer ID", true); record.value = Integer.toHexString(database.getManufacturerId()); @@ -141,8 +145,9 @@ record = new OpenHABConfigurationRecord(domain + product.Reference.get(0).Type + break; case 4: // Get product - if (database.FindProduct(Integer.parseInt(splitDomain[1]), Integer.parseInt(splitDomain[2]), Integer.parseInt(splitDomain[3])) == false) + if (database.FindProduct(Integer.parseInt(splitDomain[1]), Integer.parseInt(splitDomain[2]), Integer.parseInt(splitDomain[3]), MAX_VERSION) == false) { break; + } if(database.doesProductImplementCommandClass(ZWaveCommandClass.CommandClass.CONFIGURATION.getKey()) == true) { record = new OpenHABConfigurationRecord(domain + "parameters/", "Configuration Parameters"); @@ -159,8 +164,9 @@ record = new OpenHABConfigurationRecord(domain + "classes/", "Command Classes"); break; case 5: // Get product - if (database.FindProduct(Integer.parseInt(splitDomain[1]), Integer.parseInt(splitDomain[2]), Integer.parseInt(splitDomain[3])) == false) + if (database.FindProduct(Integer.parseInt(splitDomain[1]), Integer.parseInt(splitDomain[2]), Integer.parseInt(splitDomain[3]), MAX_VERSION) == false) { break; + } if (splitDomain[4].equals("parameters")) { List configList = database.getProductConfigParameters(); @@ -181,8 +187,9 @@ record = new OpenHABConfigurationRecord(domain, "configuration" + parameter.Inde } if(parameter.Item != null) { - for (ZWaveDbConfigurationListItem item : parameter.Item) + for (ZWaveDbConfigurationListItem item : parameter.Item) { record.addValue(Integer.toString(item.Value), database.getLabel(item.Label)); + } } // Add the description @@ -216,8 +223,9 @@ record = new OpenHABConfigurationRecord(domain, "association" + group.Index, // records... for (ZWaveDbCommandClass iClass : classList) { // Make sure the command class exists! - if(ZWaveCommandClass.CommandClass.getCommandClass(iClass.Id) == null) + if(ZWaveCommandClass.CommandClass.getCommandClass(iClass.Id) == null) { continue; + } record = new OpenHABConfigurationRecord(domain, "class" + iClass.Id, ZWaveCommandClass.CommandClass.getCommandClass(iClass.Id).getLabel(), true); if(ZWaveCommandClass.CommandClass.getCommandClass(iClass.Id).getCommandClassClass() == null) { @@ -249,10 +257,11 @@ record = new OpenHABConfigurationRecord("nodes/" + "node" + node.getNodeId() + " record = new OpenHABConfigurationRecord("nodes/" + "node" + node.getNodeId() + "/", node.getNodeId() + ": " + node.getName()); } - // If we can't find the product, then try and find just the - // manufacturer + // If we can't find the product, then try and find just the manufacturer if (node.getManufacturer() == Integer.MAX_VALUE) { - } else if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId()) == false) { + // The device isn't know, print nothing! + } + else if(database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) { if (database.FindManufacturer(node.getManufacturer()) == false) { record.value = "Manufacturer:" + node.getManufacturer() + " [ID:" + Integer.toHexString(node.getDeviceId()) + ",Type:" @@ -264,15 +273,17 @@ record = new OpenHABConfigurationRecord("nodes/" + "node" + node.getNodeId() + " } logger.debug("NODE {}: No database entry: {}", node.getNodeId(), record.value); } else { - if (node.getLocation() == null || node.getLocation().isEmpty()) + if (node.getLocation() == null || node.getLocation().isEmpty()) { record.value = database.getProductName(); - else + } + else { record.value = database.getProductName() + ": " + node.getLocation(); + } } // Set the state boolean canDelete = false; - switch(node.getNodeStage()) { + switch(node.getNodeState()) { case DEAD: record.state = OpenHABConfigurationRecord.STATE.ERROR; break; @@ -280,21 +291,24 @@ record = new OpenHABConfigurationRecord("nodes/" + "node" + node.getNodeId() + " record.state = OpenHABConfigurationRecord.STATE.ERROR; canDelete = true; break; - case DONE: + case ALIVE: Date lastDead = node.getDeadTime(); Long timeSinceLastDead = Long.MAX_VALUE; if(lastDead != null) { timeSinceLastDead = System.currentTimeMillis() - lastDead.getTime(); } - if(node.getDeadCount() > 0 && timeSinceLastDead < 86400000) + if(node.getNodeInitializationStage() != ZWaveNodeInitStage.DONE) { + record.state = OpenHABConfigurationRecord.STATE.INITIALIZING; + } + else if(node.getDeadCount() > 0 && timeSinceLastDead < 86400000) { record.state = OpenHABConfigurationRecord.STATE.WARNING; - else if(node.getSendCount() > 0 && (node.getRetryCount() * 100 / node.getSendCount()) > 5) + } + else if(node.getSendCount() > 20 && (node.getRetryCount() * 100 / node.getSendCount()) > 5) { record.state = OpenHABConfigurationRecord.STATE.WARNING; - else + } + else { record.state = OpenHABConfigurationRecord.STATE.OK; - break; - default: - record.state = OpenHABConfigurationRecord.STATE.INITIALIZING; + } break; } @@ -324,8 +338,9 @@ else if(node.getSendCount() > 0 && (node.getRetryCount() * 100 / node.getSendCou // Return the detailed configuration for this node ZWaveNode node = zController.getNode(nodeId); - if (node == null) + if (node == null) { return null; + } // Open the product database ZWaveProductDatabase database = new ZWaveProductDatabase(); @@ -341,7 +356,7 @@ record = new OpenHABConfigurationRecord(domain, "Location", "Location", false); records.add(record); if(node.getManufacturer() != Integer.MAX_VALUE) { - if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId()) == true) { + if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == true) { // Add links to configuration if the node supports the various command classes if(database.doesProductImplementCommandClass(ZWaveCommandClass.CommandClass.CONFIGURATION.getKey()) == true) { record = new OpenHABConfigurationRecord(domain + "parameters/", "Configuration Parameters"); @@ -379,6 +394,10 @@ record = new OpenHABConfigurationRecord(domain + "status/", "Status"); record = new OpenHABConfigurationRecord(domain + "info/", "Information"); records.add(record); } else if (arg.equals("info/")) { + record = new OpenHABConfigurationRecord(domain, "NodeID", "Node ID", true); + record.value = Integer.toString(node.getNodeId()); + records.add(record); + if (node.getManufacturer() != Integer.MAX_VALUE) { if (database.FindManufacturer(node.getManufacturer()) == true) { record = new OpenHABConfigurationRecord(domain, "Manufacturer", "Manufacturer", true); @@ -386,7 +405,7 @@ record = new OpenHABConfigurationRecord(domain, "Manufacturer", "Manufacturer", records.add(record); } - if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId()) == true) { + if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == true) { record = new OpenHABConfigurationRecord(domain, "Product", "Product", true); record.value = database.getProductName(); records.add(record); @@ -442,7 +461,17 @@ record = new OpenHABConfigurationRecord(domain, "Power", "Power", true); else { record.value = "BATTERY " + batteryCommandClass.getBatteryLevel() + "%"; } - } else { + + // If the node is reporting low battery, mark it up... + if(batteryCommandClass.getBatteryLow() == true) { + record.value += " LOW"; + } + } + else if(node.getNodeInitializationStage().getStage() <= ZWaveNodeInitStage.DETAILS.getStage()) { + // If we haven't passed the DETAILS stage, then we don't know the source + record.value = "UNKNOWN"; + } + else { record.value = "MAINS"; } records.add(record); @@ -451,24 +480,30 @@ record = new OpenHABConfigurationRecord(domain, "Power", "Power", true); .getCommandClass(CommandClass.VERSION); if (versionCommandClass != null) { record = new OpenHABConfigurationRecord(domain, "LibType", "Library Type", true); - if (versionCommandClass.getLibraryType() == null) + if (versionCommandClass.getLibraryType() == null) { record.value = "Unknown"; - else + } + else { record.value = versionCommandClass.getLibraryType().getLabel(); + } records.add(record); record = new OpenHABConfigurationRecord(domain, "ProtocolVersion", "Protocol Version", true); - if (versionCommandClass.getProtocolVersion() == null) + if (versionCommandClass.getProtocolVersion() == null) { record.value = "Unknown"; - else - record.value = Double.toString(versionCommandClass.getProtocolVersion()); + } + else { + record.value = versionCommandClass.getProtocolVersion(); + } records.add(record); record = new OpenHABConfigurationRecord(domain, "AppVersion", "Application Version", true); - if (versionCommandClass.getApplicationVersion() == null) + if (versionCommandClass.getApplicationVersion() == null) { record.value = "Unknown"; - else - record.value = Double.toString(versionCommandClass.getApplicationVersion()); + } + else { + record.value = versionCommandClass.getApplicationVersion(); + } records.add(record); } @@ -505,16 +540,18 @@ record = new OpenHABConfigurationRecord(domain, "LastReceived", "Last Packet Rec if(networkMonitor != null) { record = new OpenHABConfigurationRecord(domain, "LastHeal", "Heal Status", true); - if (node.getHealState() == null) - record.value = networkMonitor.getNodeState(nodeId); - else - record.value = node.getHealState(); + if (node.getHealState() == null) { + record.value = networkMonitor.getNodeState(nodeId); + } + else { + record.value = node.getHealState(); + } records.add(record); } record = new OpenHABConfigurationRecord(domain, "NodeStage", "Node Stage", true); - record.value = node.getNodeStage() + " @ " + df.format(node.getQueryStageTimeStamp()); + record.value = node.getNodeState() + " " + node.getNodeInitializationStage() + " " + df.format(node.getQueryStageTimeStamp()); records.add(record); record = new OpenHABConfigurationRecord(domain, "Packets", "Packet Statistics", true); @@ -530,17 +567,16 @@ record = new OpenHABConfigurationRecord(domain, "Dead", "Dead", true); } records.add(record); } else if (arg.equals("parameters/")) { - if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId()) != false) { + if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) != false) { List configList = database.getProductConfigParameters(); - if(configList == null) + if(configList == null) { return records; + } - // Get the configuration command class for this node + // Get the configuration command class for this node if it's supported ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node .getCommandClass(CommandClass.CONFIGURATION); - if (configurationCommandClass == null) { - logger.error("NODE {}: Error getting configurationCommandClass", nodeId); return null; } @@ -552,10 +588,11 @@ record = new OpenHABConfigurationRecord(domain, "configuration" + parameter.Inde ConfigurationParameter configurationParameter = configurationCommandClass .getParameter(parameter.Index); - // Only provide a value if it's stored in the node + // Only provide a value if it's stored in the node and is not WriteOnly // This is the only way we can be sure of its real value - if (configurationParameter != null) + if (configurationParameter != null && configurationParameter.getWriteOnly() == false) { record.value = Integer.toString(configurationParameter.getValue()); + } // If the value is in our PENDING list, then use that instead Integer pendingValue = PendingCfg.Get(ZWaveCommandClass.CommandClass.CONFIGURATION.getKey(), nodeId, parameter.Index); @@ -586,38 +623,44 @@ record = new OpenHABConfigurationRecord(domain, "configuration" + parameter.Inde } } } else if (arg.equals("associations/")) { - if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId()) != false) { + if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) != false) { List groupList = database.getProductAssociationGroups(); + if (groupList == null) { + return records; + } - if (groupList != null) { - // Loop through the associations and add all groups to the - // records... - for (ZWaveDbAssociationGroup group : groupList) { - // TODO: Controller reporting associations are set to read only - record = new OpenHABConfigurationRecord(domain, "association" + group.Index + "/", - database.getLabel(group.Label), true); + // Get the association command class for this node if it's supported + ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node + .getCommandClass(CommandClass.ASSOCIATION); + if (associationCommandClass == null) { + return null; + } - // Add the description - record.description = database.getLabel(group.Help); - - // For the 'value', describe how many devices are set and the maximum allowed - ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node - .getCommandClass(CommandClass.ASSOCIATION); - int memberCnt = 0; - List members = associationCommandClass.getGroupMembers(group.Index); - if(members != null) - memberCnt = members.size(); - record.value = memberCnt + " of " + group.Maximum + " group members"; - - // Add the action for refresh - record.addAction("Refresh", "Refresh"); + // Loop through the associations and add all groups to the + // records... + for (ZWaveDbAssociationGroup group : groupList) { + record = new OpenHABConfigurationRecord(domain, "association" + group.Index + "/", + database.getLabel(group.Label), true); - records.add(record); + // Add the description + record.description = database.getLabel(group.Help); + + // For the 'value', describe how many devices are set and the maximum allowed + int memberCnt = 0; + List members = associationCommandClass.getGroupMembers(group.Index); + if(members != null) { + memberCnt = members.size(); } + record.value = memberCnt + " of " + group.Maximum + " group members"; + + // Add the action for refresh + record.addAction("Refresh", "Refresh"); + + records.add(record); } } } else if (arg.startsWith("associations/association")) { - if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId()) != false) { + if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) != false) { String groupString = arg.substring(24); int nextDelimiter = groupString.indexOf('/'); @@ -631,8 +674,9 @@ record = new OpenHABConfigurationRecord(domain, "association" + group.Index + "/ // Get the requested group so we have access to the // attributes List groupList = database.getProductAssociationGroups(); - if (groupList == null) + if (groupList == null) { return null; + } ZWaveDbAssociationGroup group = null; for (int cnt = 0; cnt < groupList.size(); cnt++) { if (groupList.get(cnt).Index == groupId) { @@ -642,42 +686,61 @@ record = new OpenHABConfigurationRecord(domain, "association" + group.Index + "/ } // Return if the group wasn't found - if (group == null) + if (group == null) { return null; + } // Get the group members ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node .getCommandClass(CommandClass.ASSOCIATION); - List members = associationCommandClass.getGroupMembers(groupId); + // First we build a list of all nodes, starting with the group members + // This ensures that old nodes included in a group, but not now part + // of the network will still be listed, and can be removed. + List nodes = new ArrayList(); + nodes.addAll(associationCommandClass.getGroupMembers(groupId)); for(ZWaveNode nodeList : zController.getNodes()) { // Don't allow an association with itself - if(nodeList.getNodeId() == node.getNodeId()) + if(nodeList.getNodeId() == node.getNodeId()) { continue; - + } + if(!nodes.contains(nodeList.getNodeId())) { + nodes.add(nodeList.getNodeId()); + } + } + // Let's sort them! + Collections.sort(nodes); + + // Now we loop through the node list and create an entry for each node. + List members = associationCommandClass.getGroupMembers(groupId); + for(int i = 0; i < nodes.size(); i++) { + int nodeNum = nodes.get(i); + ZWaveNode nodeList = zController.getNode(nodeNum); // Add the member - if (nodeList.getName() == null || nodeList.getName().isEmpty()) - record = new OpenHABConfigurationRecord(domain, "node" + nodeList.getNodeId(), "Node " + nodeList.getNodeId(), false); - else - record = new OpenHABConfigurationRecord(domain, "node" + nodeList.getNodeId(), nodeList.getName(), false); + if (nodeList == null || nodeList.getName() == null || nodeList.getName().isEmpty()) { + record = new OpenHABConfigurationRecord(domain, "node" + nodeNum, "Node " + nodeNum, false); + } else { + record = new OpenHABConfigurationRecord(domain, "node" + nodeNum, nodeList.getName(), false); + } record.type = OpenHABConfigurationRecord.TYPE.LIST; record.addValue("true", "Member"); record.addValue("false", "Non-Member"); - if (members != null && members.contains(nodeList.getNodeId())) { + if (members != null && members.contains(nodeNum)) { record.value = "true"; } else { record.value = "false"; } // If the value is in our PENDING list, then use that instead - Integer pendingValue = PendingCfg.Get(ZWaveCommandClass.CommandClass.ASSOCIATION.getKey(), nodeId, groupId, nodeList.getNodeId()); + Integer pendingValue = PendingCfg.Get(ZWaveCommandClass.CommandClass.ASSOCIATION.getKey(), nodeId, groupId, nodeNum); if(pendingValue != null) { - if(pendingValue == 1) + if(pendingValue == 1) { record.value = "true"; - else + } else { record.value = "false"; + } record.state = OpenHABConfigurationRecord.STATE.PENDING; } @@ -689,7 +752,7 @@ record = new OpenHABConfigurationRecord(domain, "node" + nodeList.getNodeId(), n .getCommandClass(CommandClass.WAKE_UP); if(wakeupCommandClass == null) { - logger.error("NODE {}: Error getting wakeupCommandClass", nodeId); + logger.debug("NODE {}: wakeupCommandClass not supported", nodeId); return null; } @@ -707,6 +770,10 @@ record = new OpenHABConfigurationRecord(domain, "Interval", "Wakeup Interval", f } records.add(record); + record = new OpenHABConfigurationRecord(domain, "Target", "Target Node", true); + record.value = Integer.toString(wakeupCommandClass.getTargetNodeId()); + records.add(record); + record = new OpenHABConfigurationRecord(domain, "Minimum", "Minimum Interval", true); record.value = Integer.toString(wakeupCommandClass.getMinInterval()); records.add(record); @@ -724,26 +791,31 @@ record = new OpenHABConfigurationRecord(domain, "Step", "Interval Step", true); records.add(record); } else if (arg.equals("neighbors/")) { // Check that we have the neighbor list for this node - if(node.getNeighbors() == null) + if(node.getNeighbors() == null) { return null; + } for (Integer neighbor : node.getNeighbors()) { ZWaveNode nodeNeighbor = zController.getNode(neighbor); String neighborName; - if (nodeNeighbor == null) + if (nodeNeighbor == null) { neighborName = "Node " + neighbor + " (UNKNOWN)"; - else if (nodeNeighbor.getName() == null || nodeNeighbor.getName().isEmpty()) + } + else if (nodeNeighbor.getName() == null || nodeNeighbor.getName().isEmpty()) { neighborName = "Node " + neighbor; - else + } + else { neighborName = nodeNeighbor.getName(); + } // Create the record record = new OpenHABConfigurationRecord(domain, "node" + neighbor, neighborName, false); record.readonly = true; // If this node isn't known, mark it as an error - if(nodeNeighbor == null) + if(nodeNeighbor == null) { record.state = OpenHABConfigurationRecord.STATE.ERROR; + } records.add(record); } @@ -825,8 +897,9 @@ public void doAction(String domain, String action) { if (splitDomain[0].equals("binding")) { if (splitDomain[1].equals("network")) { if (action.equals("Heal")) { - if (networkMonitor != null) + if (networkMonitor != null) { networkMonitor.rescheduleHeal(); + } } if (action.equals("Include") || action.equals("Exclude")) { // Only do include/exclude if it's not already in progress @@ -863,8 +936,9 @@ public void doAction(String domain, String action) { if (action.equals("Heal")) { logger.debug("NODE {}: Heal node", nodeId); - if (networkMonitor != null) - networkMonitor.healNode(nodeId); + if (networkMonitor != null) { + networkMonitor.startNodeHeal(nodeId); + } } if (action.equals("Save")) { @@ -886,9 +960,7 @@ public void doAction(String domain, String action) { logger.debug("NODE {}: Get node version", nodeId); ZWaveVersionCommandClass versionCommandClass = (ZWaveVersionCommandClass) node .getCommandClass(CommandClass.VERSION); - if (versionCommandClass == null) { - logger.error("NODE {}: Error getting versionCommandClass in doAction", nodeId); return; } @@ -904,40 +976,37 @@ public void doAction(String domain, String action) { if (splitDomain[2].equals("parameters")) { ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node .getCommandClass(CommandClass.CONFIGURATION); - if (configurationCommandClass == null) { - logger.error("NODE {}: Error getting configurationCommandClass in doAction", nodeId); return; } if (action.equals("Refresh")) { logger.debug("NODE {}: Refresh parameters", nodeId); ZWaveProductDatabase database = new ZWaveProductDatabase(); - if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId()) == false) { - logger.error("NODE {}: Error getting parameters - no database found", nodeId); + if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) { return; } List configList = database.getProductConfigParameters(); // Request all parameters for this node - for (ZWaveDbConfigurationParameter parameter : configList) + for (ZWaveDbConfigurationParameter parameter : configList) { this.zController.sendData(configurationCommandClass.getConfigMessage(parameter.Index)); + } } } if (splitDomain[2].equals("wakeup")) { if (action.equals("Refresh")) { - logger.debug("NODE {}: Refresh wakeup capabilities", nodeId); - + // Only update if we support the wakeup class ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node .getCommandClass(CommandClass.WAKE_UP); - if (wakeupCommandClass == null) { - logger.error("NODE {}: Error getting wakeupCommandClass in doAction", nodeId); return; } + logger.debug("NODE {}: Refresh wakeup capabilities", nodeId); + // Request the wakeup interval for this node this.zController.sendData(wakeupCommandClass.getIntervalMessage()); @@ -955,21 +1024,21 @@ public void doAction(String domain, String action) { if (splitDomain[2].equals("associations")) { if (action.equals("Refresh")) { + // Make sure the association class is supported + ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node + .getCommandClass(CommandClass.ASSOCIATION); + if (associationCommandClass == null) { + return; + } + logger.debug("NODE {}: Refresh associations", nodeId); ZWaveProductDatabase database = new ZWaveProductDatabase(); - if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId()) == false) { + if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) { logger.error("NODE {}: Error in doAction - no database found", nodeId); return; } - ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node - .getCommandClass(CommandClass.ASSOCIATION); - if (associationCommandClass == null) { - logger.error("NODE {}: Error getting associationCommandClass in doAction", nodeId); - return; - } - if (splitDomain.length == 3) { // Request all groups for this node associationCommandClass.getAllAssociations(); @@ -1009,17 +1078,21 @@ public void doSet(String domain, String value) { return; } + // TODO: Should we check that the node is finished initialising + ZWaveProductDatabase database = new ZWaveProductDatabase(); - if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId()) == false) { + if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) { logger.error("NODE {}: Error in doSet - no database found", nodeId); return; } if (splitDomain.length == 3) { - if (splitDomain[2].equals("Name")) + if (splitDomain[2].equals("Name")) { node.setName(value); - if (splitDomain[2].equals("Location")) + } + if (splitDomain[2].equals("Location")) { node.setLocation(value); + } // Write the node to disk ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer(); @@ -1110,8 +1183,9 @@ public void doSet(String domain, String value) { // When associations change, we should ensure routes are configured // So, let's start a network heal - just for this node right now - if(networkMonitor != null) - networkMonitor.healNode(nodeId); + if(networkMonitor != null) { + networkMonitor.startNodeHeal(nodeId); + } } } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbAssociationGroup.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbAssociationGroup.java index 5807a8319aa..56dcf9d4627 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbAssociationGroup.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbAssociationGroup.java @@ -19,14 +19,14 @@ * */ public class ZWaveDbAssociationGroup { - Integer Index; - Integer Maximum; - boolean SetToController; + public Integer Index; + public Integer Maximum; + public boolean SetToController; @XStreamImplicit public List Label; @XStreamImplicit public List Help; - + ZWaveDbAssociationGroup() { SetToController = false; } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbCommandClass.java index 7e6df1d883b..5e47ebba4c5 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbCommandClass.java @@ -23,4 +23,21 @@ public class ZWaveDbCommandClass { @XStreamAlias("id") @XStreamConverter(HexToIntegerConverter.class) public Integer Id; + + // Endpoint number - if we want to set these options for a specific endpoint + public Integer endpoint; + + // If we want to remove this class, set to true + public Boolean remove; + + // IF we want to add this class if it doesn't exist, set to true + public Boolean add; + + // Sets whether or not get is supported by ZWaveGetCommandClass + public Boolean isGetSupported; + + // Configuration options for meter class + public Boolean meterCanReset; + public String meterScale; + public String meterType; } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbConfigurationParameter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbConfigurationParameter.java index efb6195352a..a510f7edd62 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbConfigurationParameter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbConfigurationParameter.java @@ -26,6 +26,8 @@ public class ZWaveDbConfigurationParameter { public Integer Minimum; public Integer Maximum; public String Units; + public Boolean ReadOnly; + public Boolean WriteOnly; @XStreamImplicit public List Label; @XStreamImplicit diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbProduct.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbProduct.java index eb88552430d..27857ba1491 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbProduct.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveDbProduct.java @@ -10,7 +10,11 @@ import java.util.List; +import org.osgi.framework.Version; + +import com.thoughtworks.xstream.annotations.XStreamConverter; import com.thoughtworks.xstream.annotations.XStreamImplicit; +import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter; /** * Implements the product class for the XML product database @@ -27,5 +31,60 @@ public class ZWaveDbProduct { @XStreamImplicit public List Label; - public String ConfigFile; + @XStreamImplicit + private List ConfigFile; + + @XStreamConverter(value=ToAttributedValueConverter.class, strings={"Filename", "VersionMin", "VersionMax"}) + private class ZWaveDbConfigFile { + String VersionMin; + String VersionMax; + + String Filename; + } + + public String getConfigFile(String version) { + if(ConfigFile == null) { + return null; + } + + Version vIn = new Version(version); + String filename = null; + // Check for a version'ed file + // There are multiple permutations of the file that we need to account for -: + // * No version information + // * Only a min version + // * Only a max version + // * Both min and max versions + // Versions need to be evaluated with the max and min specifiers separately + // i.e. the part either side of the decimal. + // So, version 1.3 is lower than version 1.11 + for(ZWaveDbConfigFile cfg : ConfigFile) { + // Find a default - ie one with no version information + if(cfg.VersionMin == null && cfg.VersionMax == null && filename == null) { + filename = cfg.Filename; + continue; + } + + if(cfg.VersionMin != null) { + Version vMin = new Version(cfg.VersionMin); + if(vIn.compareTo(vMin) < 0) { + continue; + } + } + + if(cfg.VersionMax != null) { + Version vMax = new Version(cfg.VersionMax); + + if(vIn.compareTo(vMax) > 0) { + continue; + } + } + + // This version matches the criterea + return cfg.Filename; + } + + // Otherwise return the default if there was one! + return filename; + } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveProductDatabase.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveProductDatabase.java index 5a2eb7fab55..b3fb4643e1f 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveProductDatabase.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/config/ZWaveProductDatabase.java @@ -11,6 +11,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.Collections; import java.util.List; import org.osgi.framework.FrameworkUtil; @@ -41,6 +42,7 @@ public class ZWaveProductDatabase { ZWaveDbProduct selProduct = null; ZWaveDbProductFile productFile = null; + String productVersion; public ZWaveProductDatabase() { loadDatabase(); @@ -88,30 +90,39 @@ private void loadDatabase() { // this.Manufacturer = (ZWaveDbManufacturer) InputStream x = entry.openStream(); database = (ZWaveDbRoot) xstream.fromXML(x); - if (database == null) + if (database == null) { return; + } } catch (IOException e) { - // TODO Auto-generated catch block e.printStackTrace(); } } - public ZWaveDbProductFile LoadProductFile() { + /** + * Loads the product file relating to the requested version. + * @param version the required device version + * @return filename of the product file + */ + private ZWaveDbProductFile LoadProductFile() { // If the file is already loaded, then just return the class - if (productFile != null) + if (productFile != null) { return productFile; + } // Have we selected a product? - if (selProduct == null) + if (selProduct == null) { return null; - - if(selProduct.ConfigFile == null || selProduct.ConfigFile.isEmpty()) + } + + String cfgFile = selProduct.getConfigFile(productVersion); + if(cfgFile == null || cfgFile.isEmpty()) { return null; + } - URL entry = FrameworkUtil.getBundle(ZWaveProductDatabase.class).getEntry("database/" + selProduct.ConfigFile); + URL entry = FrameworkUtil.getBundle(ZWaveProductDatabase.class).getEntry("database/" + cfgFile); if (entry == null) { database = null; - logger.error("Unable to load ZWave product file: '{}'", selProduct.ConfigFile); + logger.error("Unable to load ZWave product file: '{}'", cfgFile); return null; } @@ -132,7 +143,7 @@ public ZWaveDbProductFile LoadProductFile() { InputStream x = entry.openStream(); productFile = (ZWaveDbProductFile) xstream.fromXML(x); } catch (IOException e) { - logger.error("Unable to load ZWave product file '{}' : {}", selProduct.ConfigFile, e.toString()); + logger.error("Unable to load ZWave product file '{}' : {}", cfgFile, e.toString()); } return productFile; @@ -183,11 +194,12 @@ public boolean FindManufacturer(int manufacturerId) { * The product ID * @return true if the product was found */ - public boolean FindProduct(int manufacturerId, int productType, int productId) { - if (FindManufacturer(manufacturerId) == false) + public boolean FindProduct(int manufacturerId, int productType, int productId, String version) { + if (FindManufacturer(manufacturerId) == false) { return false; + } - return FindProduct(productType, productId); + return FindProduct(productType, productId, version); } /** @@ -200,9 +212,11 @@ public boolean FindProduct(int manufacturerId, int productType, int productId) { * The product ID * @return true if the product was found */ - public boolean FindProduct(int productType, int productId) { - if (selManufacturer == null) + public boolean FindProduct(int productType, int productId, String version) { + if (selManufacturer == null) { return false; + } + productVersion = version; for (ZWaveDbProduct product : selManufacturer.Product) { for (ZWaveDbProductReference reference : product.Reference) { @@ -287,11 +301,13 @@ public Integer getProductEndpoints() { * @return true if the class is supported */ public boolean doesProductImplementCommandClass(Integer classNumber) { - if (LoadProductFile() == null) + if (LoadProductFile() == null) { return false; + } - if(productFile.CommandClasses == null || productFile.CommandClasses.Class == null) + if(productFile.CommandClasses == null || productFile.CommandClasses.Class == null) { return false; + } for(ZWaveDbCommandClass iClass : productFile.CommandClasses.Class) { if(iClass.Id.equals(classNumber)) @@ -308,11 +324,13 @@ public boolean doesProductImplementCommandClass(Integer classNumber) { * @return true if the class is supported */ public List getProductCommandClasses() { - if (LoadProductFile() == null) + if (LoadProductFile() == null) { return null; + } - if(productFile.CommandClasses == null) + if(productFile.CommandClasses == null) { return null; + } return productFile.CommandClasses.Class; } @@ -324,8 +342,9 @@ public List getProductCommandClasses() { * @return List of configuration parameters */ public List getProductConfigParameters() { - if (LoadProductFile() == null) - return null; + if (LoadProductFile() == null) { + return Collections.emptyList(); + } return productFile.getConfiguration(); } @@ -337,8 +356,9 @@ public List getProductConfigParameters() { * @return List of association groups */ public List getProductAssociationGroups() { - if (LoadProductFile() == null) + if (LoadProductFile() == null) { return null; + } return productFile.getAssociations(); } @@ -358,15 +378,18 @@ private class ZWaveDbRoot { * @return String of the respective language */ public String getLabel(List labelList) { - if (labelList == null) + if (labelList == null) { return null; + } for (ZWaveDbLabel label : labelList) { - if (label.Language == null) + if (label.Language == null) { return label.Label; + } - if (label.Language.equals(language.toString())) + if (label.Language.equals(language.toString())) { return label.Label; + } } return null; } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/FibaroFGRM222Converter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/FibaroFGRM222Converter.java new file mode 100644 index 00000000000..7a2b3defc36 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/FibaroFGRM222Converter.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2014 openHAB.org. + * 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 + * + * Contributors: + * openHAB.org - initial API and implementation and/or initial documentation + */ +package org.openhab.binding.zwave.internal.converter; + +import java.util.Map; + +import org.openhab.binding.zwave.internal.converter.command.MultiLevelPercentCommandConverter; +import org.openhab.binding.zwave.internal.converter.command.MultiLevelUpDownCommandConverter; +import org.openhab.binding.zwave.internal.converter.command.ZWaveCommandConverter; +import org.openhab.binding.zwave.internal.converter.state.IntegerOnOffTypeConverter; +import org.openhab.binding.zwave.internal.converter.state.IntegerPercentTypeConverter; +import org.openhab.binding.zwave.internal.converter.state.ZWaveStateConverter; +import org.openhab.binding.zwave.internal.protocol.SerialMessage; +import org.openhab.binding.zwave.internal.protocol.ZWaveController; +import org.openhab.binding.zwave.internal.protocol.ZWaveNode; +import org.openhab.binding.zwave.internal.protocol.commandclass.proprietary.FibaroFGRM222CommandClass; +import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; +import org.openhab.core.events.EventPublisher; +import org.openhab.core.items.Item; +import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.StopMoveType; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author wenzel + * @author Markus Rathgeb + */ +public class FibaroFGRM222Converter extends ZWaveCommandClassConverter { + + private static final Logger logger = LoggerFactory.getLogger(FibaroFGRM222Converter.class); + private static final int REFRESH_INTERVAL = 0; // refresh interval in seconds + + public FibaroFGRM222Converter(final ZWaveController controller, final EventPublisher eventPublisher) { + super(controller, eventPublisher); + this.addStateConverter(new IntegerPercentTypeConverter()); + this.addStateConverter(new IntegerOnOffTypeConverter()); + + this.addCommandConverter(new MultiLevelPercentCommandConverter()); + this.addCommandConverter(new MultiLevelUpDownCommandConverter()); + } + + @Override + SerialMessage executeRefresh(final ZWaveNode node, final FibaroFGRM222CommandClass commandClass, + final int endpointId, final Map arguments) { + logger.debug("NODE {}: executeRefresh() -- nothing to do", node.getNodeId()); + return null; + } + + @Override + void handleEvent(final ZWaveCommandClassValueEvent event, final Item item, final Map arguments) { + logger.debug("NODE {}: handleEvent()", event.getNodeId()); + ZWaveStateConverter converter = this.getStateConverter(item, event.getValue()); + + if (converter == null) { + logger.warn("NODE {}: No converter found for item = {}, endpoint = {}, ignoring event.", event.getNodeId(), + item.getName(), event.getEndpoint()); + return; + } + + String sensorType = arguments.get("type"); + FibaroFGRM222CommandClass.FibaroFGRM222ValueEvent sensorEvent = (FibaroFGRM222CommandClass.FibaroFGRM222ValueEvent) event; + // Don't trigger event if this item is bound to another sensor type + if (sensorType != null && !sensorType.equalsIgnoreCase(sensorEvent.getSensorType().name())) { + return; + } + State state = converter.convertFromValueToState(event.getValue()); + if (converter instanceof IntegerPercentTypeConverter) { + state = new PercentType(100 - ((DecimalType) state).intValue()); + } + this.getEventPublisher().postUpdate(item.getName(), state); + + } + + @Override + void receiveCommand(final Item item, final Command command, final ZWaveNode node, + final FibaroFGRM222CommandClass commandClass, final int endpointId, final Map arguments) { + logger.debug("NODE {}: receiveCommand()", node.getNodeId()); + Command internalCommand = command; + SerialMessage serialMessage = null; + if (internalCommand instanceof StopMoveType && (StopMoveType) internalCommand == StopMoveType.STOP) { + // special handling for the STOP command + serialMessage = commandClass.stopLevelChangeMessage(arguments.get("type")); + } else { + ZWaveCommandConverter converter = this.getCommandConverter(command.getClass()); + if (converter == null) { + logger.warn("NODE {}: No converter found for item = {}, endpoint = {}, ignoring command.", + node.getNodeId(), item.getName(), endpointId); + return; + } + if (converter instanceof MultiLevelPercentCommandConverter) { + internalCommand = new PercentType(100 - ((DecimalType) command).intValue()); + } + + Integer value = (Integer) converter.convertFromCommandToValue(item, internalCommand); + if (value == 0) { + value = 1; + } + logger.trace("NODE {}: Converted command '{}' to value {} for item = {}, endpoint = {}.", node.getNodeId(), + internalCommand.toString(), value, item.getName(), endpointId); + + serialMessage = commandClass.setValueMessage(value, arguments.get("type")); + } + + // encapsulate the message in case this is a multi-instance node + serialMessage = node.encapsulate(serialMessage, commandClass, endpointId); + + if (serialMessage == null) { + logger.warn("NODE {}: Generating message failed for command class = {}, node = {}, endpoint = {}", + node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); + return; + } + this.getController().sendData(serialMessage); + + if (command instanceof State) { + this.getEventPublisher().postUpdate(item.getName(), (State)command); + } + } + + @Override + int getRefreshInterval() { + return REFRESH_INTERVAL; + } + +} \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveAlarmConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveAlarmConverter.java index ab35374c913..c0984d75aa3 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveAlarmConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveAlarmConverter.java @@ -61,24 +61,16 @@ public ZWaveAlarmConverter(ZWaveController controller, EventPublisher eventPubli * {@inheritDoc} */ @Override - public void executeRefresh(ZWaveNode node, + public SerialMessage executeRefresh(ZWaveNode node, ZWaveAlarmCommandClass commandClass, int endpointId, Map arguments) { logger.debug("NODE {}: Generating poll message for {}, endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); - SerialMessage serialMessage; String alarmType = arguments.get("alarm_type"); if (alarmType != null) { - serialMessage = node.encapsulate(commandClass.getMessage(AlarmType.getAlarmType(Integer.parseInt(alarmType))), commandClass, endpointId); + return node.encapsulate(commandClass.getMessage(AlarmType.getAlarmType(Integer.parseInt(alarmType))), commandClass, endpointId); } else { - serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } - - if (serialMessage == null) { - logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); - return; - } - - this.getController().sendData(serialMessage); } /** diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveAlarmSensorConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveAlarmSensorConverter.java index 3fa85018b38..ce5fab77358 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveAlarmSensorConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveAlarmSensorConverter.java @@ -61,24 +61,16 @@ public ZWaveAlarmSensorConverter(ZWaveController controller, EventPublisher even * {@inheritDoc} */ @Override - public void executeRefresh(ZWaveNode node, + public SerialMessage executeRefresh(ZWaveNode node, ZWaveAlarmSensorCommandClass commandClass, int endpointId, Map arguments) { - logger.debug("Generating poll message for {} for node {} endpoint {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - SerialMessage serialMessage; + logger.debug("NODE {}: Generating poll message for {}, endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); String alarmType = arguments.get("alarm_type"); if (alarmType != null) { - serialMessage = node.encapsulate(commandClass.getMessage(AlarmType.getAlarmType(Integer.parseInt(alarmType))), commandClass, endpointId); + return node.encapsulate(commandClass.getMessage(AlarmType.getAlarmType(Integer.parseInt(alarmType))), commandClass, endpointId); } else { - serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } - - if (serialMessage == null) { - logger.warn("Generating message failed for command class = {}, node = {}, endpoint = {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - return; - } - - this.getController().sendData(serialMessage); } /** diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBasicConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBasicConverter.java index 2212082fd37..653960e0dbc 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBasicConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBasicConverter.java @@ -53,7 +53,7 @@ public class ZWaveBasicConverter extends ZWaveCommandClassConverter arguments) { - logger.debug("Generating poll message for {} for node {} endpoint {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - SerialMessage serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); - - if (serialMessage == null) { - logger.warn("Generating message failed for command class = {}, node = {}, endpoint = {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - return; - } - - this.getController().sendData(serialMessage); + logger.debug("NODE {}: Generating poll message for {}, endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } /** diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBatteryConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBatteryConverter.java index 679fb3103ec..78cf83f947d 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBatteryConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBatteryConverter.java @@ -55,17 +55,10 @@ public ZWaveBatteryConverter(ZWaveController controller, EventPublisher eventPub * {@inheritDoc} */ @Override - public void executeRefresh(ZWaveNode node, + public SerialMessage executeRefresh(ZWaveNode node, ZWaveBatteryCommandClass commandClass, int endpointId, Map arguments) { - logger.debug("Generating poll message for {} for node {} endpoint {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - SerialMessage serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); - - if (serialMessage == null) { - logger.warn("Generating message failed for command class = {}, node = {}, endpoint = {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - return; - } - - this.getController().sendData(serialMessage); + logger.debug("NODE {}: Generating poll message for {} endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } /** diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBinarySensorConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBinarySensorConverter.java index 6b9765c1e81..3d3bc1ab744 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBinarySensorConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveBinarySensorConverter.java @@ -62,17 +62,10 @@ public ZWaveBinarySensorConverter(ZWaveController controller, EventPublisher eve * {@inheritDoc} */ @Override - public void executeRefresh(ZWaveNode node, + public SerialMessage executeRefresh(ZWaveNode node, ZWaveBinarySensorCommandClass commandClass, int endpointId, Map arguments) { - logger.debug("Generating poll message for {} for node {} endpoint {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - SerialMessage serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); - - if (serialMessage == null) { - logger.warn("Generating message failed for command class = {}, node = {}, endpoint = {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - return; - } - - this.getController().sendData(serialMessage); + logger.debug("NODE {}: Generating poll message for {}, endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } /** @@ -90,9 +83,10 @@ public void handleEvent(ZWaveCommandClassValueEvent event, Item item, Map arguments) { - logger.debug("Generating poll message for {} for node {} endpoint {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - SerialMessage serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); - - if (serialMessage == null) { - logger.warn("Generating message failed for command class = {}, node = {}, endpoint = {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - return; - } - - this.getController().sendData(serialMessage); + logger.debug("NODE {}: Generating poll message for {}, endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } /** @@ -86,7 +79,7 @@ public void handleEvent(ZWaveCommandClassValueEvent event, Item item, Map converter = this.getStateConverter(item, event.getValue()); if (converter == null) { - logger.warn("No converter found for item = {}, node = {} endpoint = {}, ignoring event.", item.getName(), event.getNodeId(), event.getEndpoint()); + logger.warn("NODE {}: No converter found for item = {}, node = {} endpoint = {}, ignoring event.", event.getNodeId(), item.getName(), event.getEndpoint()); return; } @@ -103,21 +96,22 @@ public void receiveCommand(Item item, Command command, ZWaveNode node, ZWaveCommandConverter converter = this.getCommandConverter(command.getClass()); if (converter == null) { - logger.warn("No converter found for item = {}, node = {} endpoint = {}, ignoring command.", item.getName(), node.getNodeId(), endpointId); + logger.warn("NODE {}: No converter found for item = {}, endpoint = {}, ignoring command.", node.getNodeId(), item.getName(), endpointId); return; } - + SerialMessage serialMessage = node.encapsulate(commandClass.setValueMessage((Integer)converter.convertFromCommandToValue(item, command)), commandClass, endpointId); if (serialMessage == null) { - logger.warn("Generating message failed for command class = {}, node = {}, endpoint = {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); + logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); return; } this.getController().sendData(serialMessage); - - if (command instanceof State) + + if (command instanceof State) { this.getEventPublisher().postUpdate(item.getName(), (State)command); + } } /** diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveCommandClassConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveCommandClassConverter.java index 8f8f01235c2..f746bf30c66 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveCommandClassConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveCommandClassConverter.java @@ -10,6 +10,7 @@ import java.util.Map; +import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; @@ -46,7 +47,7 @@ public ZWaveCommandClassConverter(ZWaveController controller, EventPublisher eve * @param commandClass the {@link ZWaveCommandClass} that will be used to send a polling message. * @param endpointId the endpoint id to send the message. */ - abstract void executeRefresh(ZWaveNode node, COMMAND_CLASS_TYPE commandClass, int endpointId, Map arguments); + abstract SerialMessage executeRefresh(ZWaveNode node, COMMAND_CLASS_TYPE commandClass, int endpointId, Map arguments); /** * Handles an incoming {@link ZWaveCommandClassValueEvent}. Implement diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveConfigurationConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveConfigurationConverter.java new file mode 100644 index 00000000000..01d3bf39119 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveConfigurationConverter.java @@ -0,0 +1,174 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.zwave.internal.converter; + +import java.util.List; +import java.util.Map; + +import org.openhab.binding.zwave.internal.config.ZWaveDbConfigurationParameter; +import org.openhab.binding.zwave.internal.config.ZWaveProductDatabase; +import org.openhab.binding.zwave.internal.converter.command.IntegerCommandConverter; +import org.openhab.binding.zwave.internal.converter.command.MultiLevelPercentCommandConverter; +import org.openhab.binding.zwave.internal.converter.command.ZWaveCommandConverter; +import org.openhab.binding.zwave.internal.converter.state.BigDecimalDecimalTypeConverter; +import org.openhab.binding.zwave.internal.converter.state.IntegerDecimalTypeConverter; +import org.openhab.binding.zwave.internal.converter.state.IntegerPercentTypeConverter; +import org.openhab.binding.zwave.internal.converter.state.ZWaveStateConverter; +import org.openhab.binding.zwave.internal.protocol.ConfigurationParameter; +import org.openhab.binding.zwave.internal.protocol.SerialMessage; +import org.openhab.binding.zwave.internal.protocol.ZWaveController; +import org.openhab.binding.zwave.internal.protocol.ZWaveNode; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass.ZWaveConfigurationParameterEvent; +import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; +import org.openhab.core.events.EventPublisher; +import org.openhab.core.items.Item; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/*** + * ZWaveConfigurationConverter class. Converter for communication with the + * {@link ZWaveConfigurationCommandClass}. + * @author Chris Jackson + * @since 1.7.0 + */ +public class ZWaveConfigurationConverter extends ZWaveCommandClassConverter { + + private static final Logger logger = LoggerFactory.getLogger(ZWaveConfigurationConverter.class); + private static final int REFRESH_INTERVAL = 0; // refresh interval in seconds for the binary switch; + + /** + * Constructor. Creates a new instance of the {@link ZWaveConfigurationConverter} class. + * @param controller the {@link ZWaveController} to use for sending messages. + * @param eventPublisher the {@link EventPublisher} to use to publish events. + */ + public ZWaveConfigurationConverter(ZWaveController controller, EventPublisher eventPublisher) { + super(controller, eventPublisher); + + // State and commmand converters used by this converter. + this.addStateConverter(new IntegerDecimalTypeConverter()); + this.addStateConverter(new IntegerPercentTypeConverter()); + this.addStateConverter(new BigDecimalDecimalTypeConverter()); + + this.addCommandConverter(new IntegerCommandConverter()); + this.addCommandConverter(new MultiLevelPercentCommandConverter()); + } + + /** + * {@inheritDoc} + */ + @Override + public SerialMessage executeRefresh(ZWaveNode node, + ZWaveConfigurationCommandClass commandClass, int endpointId, Map arguments) { + logger.debug("NODE {}: Generating poll message for {}, endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); + String parmNumber = arguments.get("parameter"); + if(parmNumber == null) { + logger.error("NODE {}: 'parameter' option must be specified.", node.getNodeId()); + return null; + } + int parmValue = Integer.parseInt(parmNumber); + if(parmValue <= 0 || parmValue > 255) { + logger.error("NODE {}: 'parameter' option must be between 1 and 255.", node.getNodeId()); + return null; + } + return node.encapsulate(commandClass.getConfigMessage(parmValue), commandClass, endpointId); + } + + /** + * {@inheritDoc} + */ + @Override + public void handleEvent(ZWaveCommandClassValueEvent event, Item item, Map arguments) { + String parmNumber = arguments.get("parameter"); + ZWaveConfigurationParameterEvent cfgEvent = (ZWaveConfigurationParameterEvent)event; + // Make sure this is for the parameter we want + if(cfgEvent.getParameter() != null && cfgEvent.getParameter().getIndex() != Integer.parseInt(parmNumber)) { + return; + } + + ZWaveStateConverter converter = this.getStateConverter(item, cfgEvent.getParameter().getValue()); + if (converter == null) { + logger.warn("NODE {}: No converter found for item = {}, endpoint = {}, ignoring event.", event.getNodeId(), item.getName(), event.getEndpoint()); + return; + } + + State state = converter.convertFromValueToState(cfgEvent.getParameter().getValue()); + this.getEventPublisher().postUpdate(item.getName(), state); + } + + /** + * {@inheritDoc} + */ + @Override + public void receiveCommand(Item item, Command command, ZWaveNode node, + ZWaveConfigurationCommandClass commandClass, int endpointId, Map arguments) { + ZWaveCommandConverter converter = this.getCommandConverter(command.getClass()); + if (converter == null) { + logger.warn("NODE {}: No converter found for item={}, type={}, endpoint={}, ignoring command.", node.getNodeId(), item.getName(), command.getClass().getSimpleName(), endpointId); + return; + } + String parmNumber = arguments.get("parameter"); + if(parmNumber == null) { + logger.error("NODE {}: 'parameter' option must be specified.", node.getNodeId()); + return; + } + + int parmValue = Integer.parseInt(parmNumber); + if(parmValue <= 0 || parmValue > 255) { + logger.error("NODE {}: 'parameter' option must be between 1 and 255.", node.getNodeId()); + return; + } + + ZWaveProductDatabase database = new ZWaveProductDatabase(); + if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) { + logger.error("NODE {}: database can't find product.", node.getNodeId()); + return; + } + + List configList = database.getProductConfigParameters(); + if(configList == null) { + logger.error("NODE {}: Device has no configuration.", node.getNodeId()); + return; + } + + ZWaveDbConfigurationParameter dbParameter = configList.get(parmValue); + if(dbParameter == null) { + logger.error("NODE {}: Device has no parameter {}.", node.getNodeId(), parmValue); + return; + } + ConfigurationParameter configurationParameter = new ConfigurationParameter(parmValue, (Integer)converter.convertFromCommandToValue(item, command), dbParameter.Size); + + // Set the parameter + SerialMessage serialMessage = commandClass.setConfigMessage(configurationParameter); + if (serialMessage == null) { + logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); + return; + } + + this.getController().sendData(serialMessage); + + // And request a read-back + serialMessage = commandClass.getConfigMessage(parmValue); + this.getController().sendData(serialMessage); + + if (command instanceof State) { + this.getEventPublisher().postUpdate(item.getName(), (State)command); + } + } + + /** + * {@inheritDoc} + */ + @Override + int getRefreshInterval() { + return REFRESH_INTERVAL; + } +} diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveConverterBase.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveConverterBase.java index ca87a6eaa8e..ec0f23034db 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveConverterBase.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveConverterBase.java @@ -97,8 +97,9 @@ protected void addCommandConverter(ZWaveCommandConverter converter) { * @return a converter object that converts between the value and the state; */ protected ZWaveStateConverter getStateConverter(Item item, Object value) { - if(item == null) + if(item == null) { return null; + } List> list = new ArrayList>(item.getAcceptedDataTypes()); Collections.sort(list, new StateComparator()); @@ -106,8 +107,9 @@ protected ZWaveStateConverter getStateConverter(Item item, Object value) { for (Class stateClass : list) { ZWaveStateConverter result = stateConverters.get(stateClass); - if (result == null || !result.getType().isInstance(value)) + if (result == null || !result.getType().isInstance(value)) { continue; + } return result; } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveConverterHandler.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveConverterHandler.java index 51d45f14d2e..8b03532a258 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveConverterHandler.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveConverterHandler.java @@ -14,13 +14,13 @@ import org.openhab.binding.zwave.ZWaveBindingConfig; import org.openhab.binding.zwave.ZWaveBindingProvider; +import org.openhab.binding.zwave.internal.protocol.SerialMessage; +import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.ZWaveController; -import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; -import org.openhab.binding.zwave.internal.protocol.NodeStage; +import org.openhab.binding.zwave.internal.protocol.ZWaveNodeState; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass.CommandClass; -import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveMultiInstanceCommandClass; import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; import org.openhab.core.events.EventPublisher; import org.openhab.core.items.Item; @@ -34,35 +34,44 @@ import org.slf4j.LoggerFactory; /** - * ZWaveConverterHandler class. Acts as a factory - * and manager of all the converters the binding can - * use to convert between the Z-Wave api and the binding. + * ZWaveConverterHandler class. Acts as a factory and manager of all the + * converters the binding can use to convert between the Z-Wave api and the + * binding. + * * @author Jan-Willem Spuij * @since 1.4.0 */ public class ZWaveConverterHandler { private static final Logger logger = LoggerFactory.getLogger(ZWaveConverterHandler.class); - + private final Map> converters = new HashMap>(); private final Map, CommandClass[]> preferredCommandClasses = new HashMap, CommandClass[]>(); private final ZWaveController controller; private final ZWaveInfoConverter infoConverter; - + /** - * Constructor. Creates a new instance of the {@ link ZWaveConverterHandler} class. - * @param controller the {@link ZWaveController} to use to send messages. - * @param eventPublisher the {@link EventPublisher} to use to post updates. + * Constructor. Creates a new instance of the @ link ZWaveConverterHandler} + * class. + * + * @param controller + * the {@link ZWaveController} to use to send messages. + * @param eventPublisher + * the {@link EventPublisher} to use to post updates. */ public ZWaveConverterHandler(ZWaveController controller, EventPublisher eventPublisher) { this.controller = controller; // add converters here - converters.put(CommandClass.THERMOSTAT_SETPOINT, new ZWaveThermostatSetpointConverter(controller, eventPublisher)); + converters.put(CommandClass.THERMOSTAT_SETPOINT, new ZWaveThermostatSetpointConverter(controller, + eventPublisher)); converters.put(CommandClass.THERMOSTAT_MODE, new ZWaveThermostatModeConverter(controller, eventPublisher)); - converters.put(CommandClass.THERMOSTAT_FAN_MODE, new ZWaveThermostatFanModeConverter(controller, eventPublisher)); - converters.put(CommandClass.THERMOSTAT_OPERATING_STATE, new ZWaveThermostatOperatingStateConverter(controller, eventPublisher)); - converters.put(CommandClass.THERMOSTAT_FAN_STATE, new ZWaveThermostatFanStateConverter(controller, eventPublisher)); + converters.put(CommandClass.THERMOSTAT_FAN_MODE, + new ZWaveThermostatFanModeConverter(controller, eventPublisher)); + converters.put(CommandClass.THERMOSTAT_OPERATING_STATE, new ZWaveThermostatOperatingStateConverter(controller, + eventPublisher)); + converters.put(CommandClass.THERMOSTAT_FAN_STATE, new ZWaveThermostatFanStateConverter(controller, + eventPublisher)); converters.put(CommandClass.BATTERY, new ZWaveBatteryConverter(controller, eventPublisher)); converters.put(CommandClass.SWITCH_BINARY, new ZWaveBinarySwitchConverter(controller, eventPublisher)); converters.put(CommandClass.SWITCH_MULTILEVEL, new ZWaveMultiLevelSwitchConverter(controller, eventPublisher)); @@ -72,44 +81,58 @@ public ZWaveConverterHandler(ZWaveController controller, EventPublisher eventPub converters.put(CommandClass.METER, new ZWaveMeterConverter(controller, eventPublisher)); converters.put(CommandClass.BASIC, new ZWaveBasicConverter(controller, eventPublisher)); converters.put(CommandClass.SCENE_ACTIVATION, new ZWaveSceneConverter(controller, eventPublisher)); + converters.put(CommandClass.FIBARO_FGRM_222, new FibaroFGRM222Converter(controller, eventPublisher)); converters.put(CommandClass.ALARM, new ZWaveAlarmConverter(controller, eventPublisher)); + converters.put(CommandClass.CONFIGURATION, new ZWaveConfigurationConverter(controller, eventPublisher)); infoConverter = new ZWaveInfoConverter(controller, eventPublisher); - + // add preferred command classes per Item class here - preferredCommandClasses.put(SwitchItem.class, new CommandClass[] { CommandClass.SWITCH_BINARY, CommandClass.SWITCH_MULTILEVEL, - CommandClass.METER, CommandClass.BASIC, CommandClass.SENSOR_BINARY, CommandClass.SENSOR_ALARM }); - preferredCommandClasses.put(DimmerItem.class, new CommandClass[] { CommandClass.SWITCH_MULTILEVEL, CommandClass.SWITCH_BINARY, - CommandClass.BASIC, CommandClass.SENSOR_MULTILEVEL, CommandClass.SENSOR_BINARY, CommandClass.SENSOR_ALARM }); - preferredCommandClasses.put(RollershutterItem.class, new CommandClass[] { CommandClass.SWITCH_MULTILEVEL, CommandClass.SWITCH_BINARY, - CommandClass.BASIC, CommandClass.SENSOR_MULTILEVEL, CommandClass.SENSOR_BINARY, CommandClass.SENSOR_ALARM }); - preferredCommandClasses.put(NumberItem.class, new CommandClass[] { CommandClass.SENSOR_MULTILEVEL, CommandClass.METER, - CommandClass.SWITCH_MULTILEVEL, CommandClass.BATTERY, CommandClass.BASIC, CommandClass.SENSOR_BINARY, - CommandClass.SENSOR_ALARM, CommandClass.SWITCH_BINARY, CommandClass.THERMOSTAT_SETPOINT, - CommandClass.THERMOSTAT_MODE, CommandClass.THERMOSTAT_FAN_MODE, CommandClass.THERMOSTAT_OPERATING_STATE, - CommandClass.THERMOSTAT_FAN_STATE}); - preferredCommandClasses.put(ContactItem.class, new CommandClass[] { CommandClass.SENSOR_BINARY, CommandClass.SENSOR_ALARM, - CommandClass.SWITCH_BINARY, CommandClass.BASIC }); + preferredCommandClasses.put(SwitchItem.class, new CommandClass[] { CommandClass.SWITCH_BINARY, + CommandClass.SWITCH_MULTILEVEL, CommandClass.METER, CommandClass.BASIC, CommandClass.SENSOR_BINARY, + CommandClass.SENSOR_ALARM }); + preferredCommandClasses.put(DimmerItem.class, new CommandClass[] { CommandClass.SWITCH_MULTILEVEL, + CommandClass.SWITCH_BINARY, CommandClass.BASIC, CommandClass.SENSOR_MULTILEVEL, + CommandClass.SENSOR_BINARY, CommandClass.SENSOR_ALARM }); + preferredCommandClasses.put(RollershutterItem.class, new CommandClass[] { CommandClass.SWITCH_MULTILEVEL, + CommandClass.SWITCH_BINARY, CommandClass.BASIC, CommandClass.SENSOR_MULTILEVEL, + CommandClass.SENSOR_BINARY, CommandClass.SENSOR_ALARM }); + preferredCommandClasses.put(NumberItem.class, new CommandClass[] { CommandClass.SENSOR_MULTILEVEL, + CommandClass.METER, CommandClass.SWITCH_MULTILEVEL, CommandClass.BATTERY, CommandClass.BASIC, + CommandClass.SENSOR_BINARY, CommandClass.SENSOR_ALARM, CommandClass.SWITCH_BINARY, + CommandClass.THERMOSTAT_SETPOINT, CommandClass.THERMOSTAT_MODE, CommandClass.THERMOSTAT_FAN_MODE, + CommandClass.THERMOSTAT_OPERATING_STATE, CommandClass.THERMOSTAT_FAN_STATE }); + preferredCommandClasses.put(ContactItem.class, new CommandClass[] { CommandClass.SENSOR_BINARY, + CommandClass.SENSOR_ALARM, CommandClass.SWITCH_BINARY, CommandClass.BASIC }); } /** * Returns a converter to convert between the Z-Wave API and the binding. - * @param commandClass the {@link CommandClass} to create a converter for. - * @return a {@link ZWaveCommandClassConverter} or null if a converter is not found. + * + * @param commandClass + * the {@link CommandClass} to create a converter for. + * @return a {@link ZWaveCommandClassConverter} or null if a converter is + * not found. */ public ZWaveCommandClassConverter getConverter(CommandClass commandClass) { return converters.get(commandClass); } - + /** - * Returns the command class that provides the best suitable converter to convert between the Z-Wave API and the binding. - * @param item the {@link item} to resolve a converter for. - * @param node the {@link ZWaveNode} node to resolve a Command class on. - * @param the enpoint ID to use to resolve a converter. - * @return the {@link ZWaveCommandClass} that can be used to get a converter suitable to do the conversion. + * Returns the command class that provides the best suitable converter to + * convert between the Z-Wave API and the binding. + * + * @param item + * the {@link item} to resolve a converter for. + * @param node + * the {@link ZWaveNode} node to resolve a Command class on. + * @param the + * enpoint ID to use to resolve a converter. + * @return the {@link ZWaveCommandClass} that can be used to get a converter + * suitable to do the conversion. */ private ZWaveCommandClass resolveConverter(Item item, ZWaveNode node, int endpointId) { - if(item == null) { + if (item == null) { return null; } @@ -120,91 +143,118 @@ private ZWaveCommandClass resolveConverter(Item item, ZWaveNode node, int endpoi for (CommandClass commandClass : preferredCommandClasses.get(item.getClass())) { ZWaveCommandClass result = node.resolveCommandClass(commandClass, endpointId); - + if (result != null && converters.containsKey(commandClass)) { return result; } } - - logger.warn("No matching command classes found for item class = {}, node id = {}, endpoint id = {}", - item.getClass().toString(), node.getNodeId(), endpointId); + + logger.warn("No matching command classes found for item class = {}, node id = {}, endpoint id = {}", item + .getClass().toString(), node.getNodeId(), endpointId); return null; } - + /** - * Execute refresh method. This method is called every time a binding item is - * refreshed and the corresponding node should be sent a message. - * @param provider the {@link ZWaveBindingProvider} that provides the item - * @param itemName the name of the item to poll. - * @param forceRefresh indicates that a polling refresh should be forced. + * Execute refresh method. This method is called every time a binding item + * is refreshed and the corresponding node should be sent a message. + * + * @param provider + * the {@link ZWaveBindingProvider} that provides the item + * @param itemName + * the name of the item to poll. + * @param forceRefresh + * indicates that a polling refresh should be forced. */ @SuppressWarnings("unchecked") public void executeRefresh(ZWaveBindingProvider provider, String itemName, boolean forceRefresh) { ZWaveBindingConfig bindingConfiguration = provider.getZwaveBindingConfig(itemName); ZWaveCommandClass commandClass; String commandClassName = bindingConfiguration.getArguments().get("command"); - + // this binding is configured not to poll. - if (!forceRefresh && bindingConfiguration.getRefreshInterval() != null && 0 == bindingConfiguration.getRefreshInterval()) + if (!forceRefresh && bindingConfiguration.getRefreshInterval() != null + && 0 == bindingConfiguration.getRefreshInterval()) { return; - + } + ZWaveNode node = this.controller.getNode(bindingConfiguration.getNodeId()); - + // ignore nodes that are not initialized. - if (node == null) + if (node == null) { return; - + } + if (commandClassName != null) { - + // this is a report item, handle it with the report info converter. if (commandClassName.equalsIgnoreCase("info")) { - infoConverter.executeRefresh(provider.getItem(itemName), node, bindingConfiguration.getEndpoint(), bindingConfiguration.getArguments()); + infoConverter.executeRefresh(provider.getItem(itemName), node, bindingConfiguration.getEndpoint(), + bindingConfiguration.getArguments()); return; } - + // ignore nodes that are not initialized or dead. - if (node.getNodeStage() != NodeStage.DONE) + if (node.getNodeState() != ZWaveNodeState.ALIVE || node.isInitializationComplete() == false) { return; - - commandClass = node.resolveCommandClass(CommandClass.getCommandClass(commandClassName), bindingConfiguration.getEndpoint()); - + } + + commandClass = node.resolveCommandClass(CommandClass.getCommandClass(commandClassName), + bindingConfiguration.getEndpoint()); + if (commandClass == null) { - logger.warn("No command class found for item = {}, command class name = {}, ignoring execute refresh.", itemName, commandClassName); - return; + logger.warn("No command class found for item = {}, command class name = {}, ignoring execute refresh.", + itemName, commandClassName); + return; } } else { - commandClass = resolveConverter(provider.getItem(itemName), node - , bindingConfiguration.getEndpoint()); + commandClass = resolveConverter(provider.getItem(itemName), node, bindingConfiguration.getEndpoint()); } - - if (commandClass == null) { - logger.warn("No converter found for item = {}, ignoring execute refresh.", itemName); - return; - } - - ZWaveCommandClassConverter converter = (ZWaveCommandClassConverter) getConverter(commandClass.getCommandClass()); - - if (converter == null) { - logger.warn("No converter found for item = {}, ignoring execute refresh.", itemName); - return; - } - - if (bindingConfiguration.getRefreshInterval() == null) { - bindingConfiguration.setRefreshInterval(converter.getRefreshInterval()); - - // this binding is configured not to poll. - if (!forceRefresh && 0 == bindingConfiguration.getRefreshInterval()) + + if (commandClass == null) { + logger.warn("No converter found for item = {}, ignoring execute refresh.", itemName); + return; + } + + ZWaveCommandClassConverter converter = (ZWaveCommandClassConverter) getConverter(commandClass + .getCommandClass()); + + if (converter == null) { + logger.warn("No converter found for item = {}, ignoring execute refresh.", itemName); + return; + } + + if (bindingConfiguration.getRefreshInterval() == null) { + bindingConfiguration.setRefreshInterval(converter.getRefreshInterval()); + + // this binding is configured not to poll. + if (!forceRefresh && 0 == bindingConfiguration.getRefreshInterval()) { return; - } - - // not enough time has passed to refresh the item. - if (!forceRefresh && bindingConfiguration.getLastRefreshed() != null - && (bindingConfiguration.getLastRefreshed().getTime() + (bindingConfiguration.getRefreshInterval() * 1000) - > Calendar.getInstance().getTimeInMillis())) - return; - - bindingConfiguration.setLastRefreshed(Calendar.getInstance().getTime()); - converter.executeRefresh(node, commandClass, bindingConfiguration.getEndpoint(), bindingConfiguration.getArguments()); + } + } + + // not enough time has passed to refresh the item. + if (!forceRefresh + && bindingConfiguration.getLastRefreshed() != null + && (bindingConfiguration.getLastRefreshed().getTime() + + (bindingConfiguration.getRefreshInterval() * 1000) > Calendar.getInstance().getTimeInMillis())) { + return; + } + + bindingConfiguration.setLastRefreshed(Calendar.getInstance().getTime()); + SerialMessage serialMessage = converter.executeRefresh(node, commandClass, bindingConfiguration.getEndpoint(), + bindingConfiguration.getArguments()); + + if (serialMessage == null) { + logger.warn("NODE {}: Generating message failed for command class = {}", node.getNodeId(), + commandClass.getCommandClass().getLabel()); + return; + } + + // This is a poll - treat it as a low priority! + serialMessage.setPriority(SerialMessagePriority.Poll); + + // Queue the message + this.controller.sendData(serialMessage); } /** @@ -270,86 +320,101 @@ public Integer getRefreshInterval(ZWaveBindingProvider provider, String itemName } /** - * Handles an incoming {@link ZWaveCommandClassValueEvent}. Implement - * this message in derived classes to convert the value and post an - * update on the openHAB bus. - * @param provider the {@link ZWaveBindingProvider} that provides the item - * @param itemName the name of the item that will receive the event. - * @param event the received {@link ZWaveCommandClassValueEvent}. + * Handles an incoming {@link ZWaveCommandClassValueEvent}. Implement this + * message in derived classes to convert the value and post an update on the + * openHAB bus. + * + * @param provider + * the {@link ZWaveBindingProvider} that provides the item + * @param itemName + * the name of the item that will receive the event. + * @param event + * the received {@link ZWaveCommandClassValueEvent}. */ - public void handleEvent(ZWaveBindingProvider provider, String itemName, ZWaveCommandClassValueEvent event) { + public void handleEvent(ZWaveBindingProvider provider, String itemName, ZWaveCommandClassValueEvent event) { ZWaveBindingConfig bindingConfiguration = provider.getZwaveBindingConfig(itemName); Item item = provider.getItem(itemName); String commandClassName = bindingConfiguration.getArguments().get("command"); boolean respondToBasic = "true".equalsIgnoreCase(bindingConfiguration.getArguments().get("respond_to_basic")); - logger.trace("Getting converter for item = {}, command class = {}, item command class = {}", itemName, event.getCommandClass().getLabel(), commandClassName); - + logger.trace("Getting converter for item = {}, command class = {}, item command class = {}", itemName, event + .getCommandClass().getLabel(), commandClassName); + if (item == null) { return; } - + // check whether this item is bound to the right command class. - - if (commandClassName != null && !commandClassName.equalsIgnoreCase(event.getCommandClass().getLabel().toLowerCase()) && - !(respondToBasic && event.getCommandClass() == CommandClass.BASIC)) { + + if (commandClassName != null + && !commandClassName.equalsIgnoreCase(event.getCommandClass().getLabel().toLowerCase()) + && !(respondToBasic && event.getCommandClass() == CommandClass.BASIC)) { return; } - + ZWaveCommandClassConverter converter = this.getConverter(event.getCommandClass()); - - + if (converter == null) { - logger.warn("No converter found for command class = {}, ignoring event.",event.getCommandClass().toString()); + logger.warn("No converter found for command class = {}, ignoring event.", event.getCommandClass() + .toString()); return; } - + converter.handleEvent(event, item, bindingConfiguration.getArguments()); - } - + } + /** - * Receives a command from openHAB and translates it to an operation - * on the Z-Wave network. - * @param provider the {@link ZWaveBindingProvider} that provides the item - * @param itemName the name of the item that will receive the event. - * @param command the received {@link Command} + * Receives a command from openHAB and translates it to an operation on the + * Z-Wave network. + * + * @param provider + * the {@link ZWaveBindingProvider} that provides the item + * @param itemName + * the name of the item that will receive the event. + * @param command + * the received {@link Command} */ @SuppressWarnings("unchecked") public void receiveCommand(ZWaveBindingProvider provider, String itemName, Command command) { ZWaveBindingConfig bindingConfiguration = provider.getZwaveBindingConfig(itemName); ZWaveNode node = this.controller.getNode(bindingConfiguration.getNodeId()); - if(node == null) { + if (node == null) { logger.error("Item {} has non existant node {}", itemName, bindingConfiguration.getNodeId()); return; } ZWaveCommandClass commandClass; String commandClassName = bindingConfiguration.getArguments().get("command"); - + if (commandClassName != null) { - commandClass = node.resolveCommandClass(CommandClass.getCommandClass(commandClassName), bindingConfiguration.getEndpoint()); - + commandClass = node.resolveCommandClass(CommandClass.getCommandClass(commandClassName), + bindingConfiguration.getEndpoint()); + if (commandClass == null) { - logger.warn("No command class found for item = {}, command class name = {}, ignoring command.", itemName, commandClassName); - return; + logger.warn( + "NODE {}: No command class found for item = {}. Class = {}({}), endpoint = {}. Ignoring command.", + node.getNodeId(), itemName, commandClassName, CommandClass.getCommandClass(commandClassName) + .toString(), bindingConfiguration.getEndpoint()); + return; } } else { - commandClass = resolveConverter(provider.getItem(itemName), node - , bindingConfiguration.getEndpoint()); + commandClass = resolveConverter(provider.getItem(itemName), node, bindingConfiguration.getEndpoint()); } - - if (commandClass == null) { - logger.warn("No converter found for item = {}, ignoring command.", itemName); - return; - } - - ZWaveCommandClassConverter converter = (ZWaveCommandClassConverter) getConverter(commandClass.getCommandClass()); - - if (converter == null) { - logger.warn("No converter found for item = {}, ignoring command.", itemName); - return; - } - - converter.receiveCommand(provider.getItem(itemName), command, node, commandClass, bindingConfiguration.getEndpoint(), bindingConfiguration.getArguments()); + + if (commandClass == null) { + logger.warn("NODE {}: No converter found for item = {}, ignoring command.", node.getNodeId(), itemName); + return; + } + + ZWaveCommandClassConverter converter = (ZWaveCommandClassConverter) getConverter(commandClass + .getCommandClass()); + + if (converter == null) { + logger.warn("NODE {}: No converter found for item = {}, ignoring command.", node.getNodeId(), itemName); + return; + } + + converter.receiveCommand(provider.getItem(itemName), command, node, commandClass, + bindingConfiguration.getEndpoint(), bindingConfiguration.getArguments()); } - + } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveInfoConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveInfoConverter.java index b3e2735bc9d..220cad308a5 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveInfoConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveInfoConverter.java @@ -138,6 +138,8 @@ private Object getInformationItemValue(ZWaveNode node, ZWaveInformationItem info return node.isListening(); case REPORT_DEAD: return node.isDead(); + case REPORT_LASTUPDATE: + return node.getLastReceived(); case REPORT_NAK: return this.getController().getNAKCount(); case REPORT_SOF: @@ -150,8 +152,8 @@ private Object getInformationItemValue(ZWaveNode node, ZWaveInformationItem info return this.getController().getOOFCount(); case REPORT_TIME_OUT: return this.getController().getTimeOutCount(); - case REPORT_LASTUPDATE: - return node.getLastReceived(); + case REPORT_TX_QUEUE: + return this.getController().getSendQueueLength(); } return null; @@ -275,7 +277,12 @@ public enum ZWaveInformationItem { /** * Reports the amount of out of timed out packets this node has received. */ - REPORT_TIME_OUT("TIME_OUT"); + REPORT_TIME_OUT("TIME_OUT"), + + /** + * Reports the total number of frames in the transmit queue(s) + */ + REPORT_TX_QUEUE("TX_QUEUE"); private String label; private static Map labelToZWaveInfoItemMapping; diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveMeterConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveMeterConverter.java index 886e0ee9410..2cd0a0ef416 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveMeterConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveMeterConverter.java @@ -61,25 +61,17 @@ public ZWaveMeterConverter(ZWaveController controller, EventPublisher eventPubli * {@inheritDoc} */ @Override - public void executeRefresh(ZWaveNode node, + public SerialMessage executeRefresh(ZWaveNode node, ZWaveMeterCommandClass commandClass, int endpointId, Map arguments) { String meterScale = arguments.get("meter_scale"); - SerialMessage serialMessage; - logger.debug("Generating poll message for {} for node {} endpoint {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - + logger.debug("NODE {}: Generating poll message for {}, endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); + if (meterScale != null) { - serialMessage = node.encapsulate(commandClass.getMessage(MeterScale.getMeterScale(meterScale)), commandClass, endpointId); + return node.encapsulate(commandClass.getMessage(MeterScale.getMeterScale(meterScale)), commandClass, endpointId); } else { - serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } - - if (serialMessage == null) { - logger.warn("Generating message failed for command class = {}, node = {}, endpoint = {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - return; - } - - this.getController().sendData(serialMessage); } /** @@ -135,7 +127,7 @@ public void receiveCommand(Item item, Command command, ZWaveNode node, this.getController().sendData(serialMessage); // poll the device - for (SerialMessage serialGetMessage : commandClass.getDynamicValues()) { + for (SerialMessage serialGetMessage : commandClass.getDynamicValues(true)) { this.getController().sendData(node.encapsulate(serialGetMessage, commandClass, endpointId)); } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveMultiLevelSensorConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveMultiLevelSensorConverter.java index 37bde6d4cdf..6334b65a491 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveMultiLevelSensorConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveMultiLevelSensorConverter.java @@ -35,6 +35,7 @@ * {@link ZWaveMultiLevelSensorCommandClass}. Implements polling of the sensor * status and receiving of sensor events. * @author Jan-Willem Spuij + * @author Chris Jackson * @since 1.4.0 */ public class ZWaveMultiLevelSensorConverter extends ZWaveCommandClassConverter { @@ -60,25 +61,17 @@ public ZWaveMultiLevelSensorConverter(ZWaveController controller, EventPublisher * {@inheritDoc} */ @Override - public void executeRefresh(ZWaveNode node, + public SerialMessage executeRefresh(ZWaveNode node, ZWaveMultiLevelSensorCommandClass commandClass, int endpointId, Map arguments) { String sensorType = arguments.get("sensor_type"); - SerialMessage serialMessage; - logger.debug("Generating poll message for {} for node {} endpoint {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); + logger.debug("NODE {}: Generating poll message for {}, endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); if (sensorType != null) { - serialMessage = node.encapsulate(commandClass.getMessage(SensorType.getSensorType(Integer.parseInt(sensorType))), commandClass, endpointId); + return node.encapsulate(commandClass.getMessage(SensorType.getSensorType(Integer.parseInt(sensorType))), commandClass, endpointId); } else { - serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } - - if (serialMessage == null) { - logger.warn("Generating message failed for command class = {}, node = {}, endpoint = {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - return; - } - - this.getController().sendData(serialMessage); } /** @@ -92,34 +85,45 @@ public void handleEvent(ZWaveCommandClassValueEvent event, Item item, Map arguments) { - logger.debug("Generating poll message for {} for node {} endpoint {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - SerialMessage serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); - - if (serialMessage == null) { - logger.warn("Generating message failed for command class = {}, node = {}, endpoint = {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId); - return; - } - - this.getController().sendData(serialMessage); + logger.debug("NODE {}: Generating poll message for {} for node {} endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } /** @@ -143,16 +136,18 @@ public void receiveCommand(Item item, Command command, ZWaveNode node, if (command instanceof OnOffType) { restoreLastValue = arguments.get("restore_last_value"); - if ("true".equalsIgnoreCase(restoreLastValue)) + if ("true".equalsIgnoreCase(restoreLastValue)) { converter = this.restoreValueOnOffConverter; - else + } + else { converter = this.normalOnOffConverter; + } } else { converter = this.getCommandConverter(command.getClass()); } if (converter == null) { - logger.warn("No converter found for item = {}, node = {} endpoint = {}, ignoring command.", item.getName(), node.getNodeId(), endpointId); + logger.warn("NODE {}: No converter found for item = {}, endpoint = {}, ignoring command.", node.getNodeId(), item.getName(), endpointId); return; } @@ -160,28 +155,29 @@ public void receiveCommand(Item item, Command command, ZWaveNode node, if (converter instanceof MultiLevelUpDownCommandConverter) { logger.debug("Multilevel Switch MultiLevelUpDownCommandConverter"); if ("true".equalsIgnoreCase(arguments.get("invert_state"))) { - logger.debug("Multilevel Switch MultiLevelUpDownCommandConverter - invert"); - if(command == UpDownType.UP) + logger.trace("Multilevel Switch MultiLevelUpDownCommandConverter - invert"); + if(command == UpDownType.UP) { command = UpDownType.DOWN; - else + } + else { command = UpDownType.UP; - logger.debug("Multilevel Switch MultiLevelUpDownCommandConverter - inverted: {}", command); + } + logger.trace("Multilevel Switch MultiLevelUpDownCommandConverter - inverted: {}", command); } } - // Alloe inversion of roller shutter PERCENT value + // Allow inversion of roller shutter PERCENT value if(converter instanceof MultiLevelPercentCommandConverter){ logger.debug("Multilevel Switch MultiLevelPercentCommandConverter"); if ("true".equalsIgnoreCase(arguments.get("invert_percent"))) { - logger.debug("Multilevel Switch MultiLevelPercentCommandConverter - invert"); + logger.trace("Multilevel Switch MultiLevelPercentCommandConverter - invert"); command = new PercentType(100 - ((DecimalType)command).intValue()); - logger.debug("Multilevel Switch MultiLevelPercentCommandConverter - inverted: {}", command); + logger.trace("Multilevel Switch MultiLevelPercentCommandConverter - inverted: {}", command); } } - Integer value = (Integer)converter.convertFromCommandToValue(item, command); - logger.trace("Converted command '{}' to value {} for item = {}, node = {}, endpoint = {}.", command.toString(), value, item.getName(), node.getNodeId(), endpointId); + logger.trace("NODE {}: Converted command '{}' to value {} for item = {}, endpoint = {}.", node.getNodeId(), command.toString(), value, item.getName(), endpointId); serialMessage = commandClass.setValueMessage(value); } @@ -197,10 +193,12 @@ public void receiveCommand(Item item, Command command, ZWaveNode node, this.getController().sendData(serialMessage); // update the bus in case of normal dimming. schedule refresh in case of restore to last value dimming. - if (!"true".equalsIgnoreCase(restoreLastValue) && command instanceof OnOffType && (OnOffType)command == OnOffType.ON) + if (!"true".equalsIgnoreCase(restoreLastValue) && command instanceof OnOffType && (OnOffType)command == OnOffType.ON) { executeRefresh(node, commandClass, endpointId, arguments); - else if (command instanceof State) + } + else if (command instanceof State) { this.getEventPublisher().postUpdate(item.getName(), (State)command); + } } /** diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveSceneConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveSceneConverter.java index 8e3e14083ab..f0d9c184635 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveSceneConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveSceneConverter.java @@ -14,6 +14,7 @@ import org.openhab.binding.zwave.internal.converter.state.IntegerOnOffTypeConverter; import org.openhab.binding.zwave.internal.converter.state.IntegerOpenClosedTypeConverter; import org.openhab.binding.zwave.internal.converter.state.ZWaveStateConverter; +import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveBasicCommandClass; @@ -59,8 +60,9 @@ int getRefreshInterval() { } @Override - void executeRefresh(ZWaveNode node, ZWaveBasicCommandClass commandClass, int endpointId, + SerialMessage executeRefresh(ZWaveNode node, ZWaveBasicCommandClass commandClass, int endpointId, Map arguments) { + return null; } @Override diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatFanModeConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatFanModeConverter.java index b35a99548f5..0baaf2057e7 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatFanModeConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatFanModeConverter.java @@ -8,12 +8,11 @@ */ package org.openhab.binding.zwave.internal.converter; -import java.math.BigDecimal; import java.util.Map; -import org.openhab.binding.zwave.internal.converter.command.DecimalCommandConverter; +import org.openhab.binding.zwave.internal.converter.command.IntegerCommandConverter; import org.openhab.binding.zwave.internal.converter.command.ZWaveCommandConverter; -import org.openhab.binding.zwave.internal.converter.state.BigDecimalDecimalTypeConverter; +import org.openhab.binding.zwave.internal.converter.state.IntegerDecimalTypeConverter; import org.openhab.binding.zwave.internal.converter.state.ZWaveStateConverter; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; @@ -48,26 +47,19 @@ public class ZWaveThermostatFanModeConverter extends public ZWaveThermostatFanModeConverter(ZWaveController controller, EventPublisher eventPublisher) { super(controller, eventPublisher); - this.addCommandConverter(new DecimalCommandConverter()); - this.addStateConverter(new BigDecimalDecimalTypeConverter()); + this.addCommandConverter(new IntegerCommandConverter()); + this.addStateConverter(new IntegerDecimalTypeConverter()); } /** * {@inheritDoc} */ @Override - void executeRefresh(ZWaveNode node, + SerialMessage executeRefresh(ZWaveNode node, ZWaveThermostatFanModeCommandClass commandClass, int endpointId, Map arguments) { logger.debug("NODE {}: Generating poll message for {} endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); - SerialMessage serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); - - if (serialMessage == null) { - logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); - return; - } - - this.getController().sendData(serialMessage); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } /** @@ -104,7 +96,7 @@ void receiveCommand(Item item, Command command, ZWaveNode node, logger.debug("NODE {}: receiveCommand with converter {} ", node.getNodeId(), converter.getClass()); - SerialMessage serialMessage = node.encapsulate(commandClass.setValueMessage(((BigDecimal)converter.convertFromCommandToValue(item, command)).intValue()), commandClass, endpointId); + SerialMessage serialMessage = node.encapsulate(commandClass.setValueMessage((Integer)converter.convertFromCommandToValue(item, command)), commandClass, endpointId); logger.debug("NODE {}: receiveCommand sending message {} ", node.getNodeId(), serialMessage); if (serialMessage == null) { logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatFanStateConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatFanStateConverter.java index 7af22ac1cab..21fac154621 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatFanStateConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatFanStateConverter.java @@ -10,7 +10,7 @@ import java.util.Map; -import org.openhab.binding.zwave.internal.converter.state.BigDecimalDecimalTypeConverter; +import org.openhab.binding.zwave.internal.converter.state.IntegerDecimalTypeConverter; import org.openhab.binding.zwave.internal.converter.state.ZWaveStateConverter; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; @@ -45,25 +45,18 @@ public class ZWaveThermostatFanStateConverter extends public ZWaveThermostatFanStateConverter(ZWaveController controller, EventPublisher eventPublisher) { super(controller, eventPublisher); - this.addStateConverter(new BigDecimalDecimalTypeConverter()); + this.addStateConverter(new IntegerDecimalTypeConverter()); } /** * {@inheritDoc} */ @Override - void executeRefresh(ZWaveNode node, + SerialMessage executeRefresh(ZWaveNode node, ZWaveThermostatFanStateCommandClass commandClass, int endpointId, Map arguments) { logger.debug("NODE {}: Generating poll message for {} endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); - SerialMessage serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); - - if (serialMessage == null) { - logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); - return; - } - - this.getController().sendData(serialMessage); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } /** diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatModeConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatModeConverter.java index 05db1d2c859..7088bc3a06e 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatModeConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatModeConverter.java @@ -8,12 +8,11 @@ */ package org.openhab.binding.zwave.internal.converter; -import java.math.BigDecimal; import java.util.Map; -import org.openhab.binding.zwave.internal.converter.command.DecimalCommandConverter; +import org.openhab.binding.zwave.internal.converter.command.IntegerCommandConverter; import org.openhab.binding.zwave.internal.converter.command.ZWaveCommandConverter; -import org.openhab.binding.zwave.internal.converter.state.BigDecimalDecimalTypeConverter; +import org.openhab.binding.zwave.internal.converter.state.IntegerDecimalTypeConverter; import org.openhab.binding.zwave.internal.converter.state.ZWaveStateConverter; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; @@ -48,26 +47,19 @@ public class ZWaveThermostatModeConverter extends public ZWaveThermostatModeConverter(ZWaveController controller, EventPublisher eventPublisher) { super(controller, eventPublisher); - this.addCommandConverter(new DecimalCommandConverter()); - this.addStateConverter(new BigDecimalDecimalTypeConverter()); + this.addCommandConverter(new IntegerCommandConverter()); + this.addStateConverter(new IntegerDecimalTypeConverter()); } /** * {@inheritDoc} */ @Override - void executeRefresh(ZWaveNode node, + SerialMessage executeRefresh(ZWaveNode node, ZWaveThermostatModeCommandClass commandClass, int endpointId, Map arguments) { logger.debug("NODE {}: Generating poll message for {} endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); - SerialMessage serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); - - if (serialMessage == null) { - logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); - return; - } - - this.getController().sendData(serialMessage); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } /** @@ -103,8 +95,8 @@ void receiveCommand(Item item, Command command, ZWaveNode node, } logger.debug("NODE {}: receiveCommand with converter {} ", node.getNodeId(), converter.getClass()); - - SerialMessage serialMessage = node.encapsulate(commandClass.setValueMessage(((BigDecimal)converter.convertFromCommandToValue(item, command)).intValue()), commandClass, endpointId); + + SerialMessage serialMessage = node.encapsulate(commandClass.setValueMessage((Integer)converter.convertFromCommandToValue(item, command)), commandClass, endpointId); logger.debug("NODE {}: receiveCommand sending message {} ", node.getNodeId(), serialMessage); if (serialMessage == null) { logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatOperatingStateConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatOperatingStateConverter.java index 1cd13751e1f..f768d27eac8 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatOperatingStateConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatOperatingStateConverter.java @@ -52,18 +52,11 @@ public ZWaveThermostatOperatingStateConverter(ZWaveController controller, * {@inheritDoc} */ @Override - void executeRefresh(ZWaveNode node, + SerialMessage executeRefresh(ZWaveNode node, ZWaveThermostatOperatingStateCommandClass commandClass, int endpointId, Map arguments) { logger.debug("NODE {}: Generating poll message for {}, endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); - SerialMessage serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); - - if (serialMessage == null) { - logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); - return; - } - - this.getController().sendData(serialMessage); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } /** diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatSetpointConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatSetpointConverter.java index 32fa3cc8e54..f19a37cf7a1 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatSetpointConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/ZWaveThermostatSetpointConverter.java @@ -11,7 +11,7 @@ import java.math.BigDecimal; import java.util.Map; -import org.openhab.binding.zwave.internal.converter.command.DecimalCommandConverter; +import org.openhab.binding.zwave.internal.converter.command.BigDecimalCommandConverter; import org.openhab.binding.zwave.internal.converter.command.ZWaveCommandConverter; import org.openhab.binding.zwave.internal.converter.state.BigDecimalDecimalTypeConverter; import org.openhab.binding.zwave.internal.converter.state.ZWaveStateConverter; @@ -52,7 +52,7 @@ public class ZWaveThermostatSetpointConverter extends public ZWaveThermostatSetpointConverter(ZWaveController controller, EventPublisher eventPublisher) { super(controller, eventPublisher); - this.addCommandConverter(new DecimalCommandConverter()); + this.addCommandConverter(new BigDecimalCommandConverter()); this.addStateConverter(new BigDecimalDecimalTypeConverter()); } @@ -60,25 +60,17 @@ public ZWaveThermostatSetpointConverter(ZWaveController controller, * {@inheritDoc} */ @Override - void executeRefresh(ZWaveNode node, + SerialMessage executeRefresh(ZWaveNode node, ZWaveThermostatSetpointCommandClass commandClass, int endpointId, Map arguments) { logger.debug("NODE {}: Generating poll message for {}, endpoint {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId); - SerialMessage serialMessage; String setpointType = arguments.get("setpoint_type"); - + if (setpointType != null) { - serialMessage = node.encapsulate(commandClass.getMessage(SetpointType.getSetpointType(Integer.parseInt(setpointType))), commandClass, endpointId); + return node.encapsulate(commandClass.getMessage(SetpointType.getSetpointType(Integer.parseInt(setpointType))), commandClass, endpointId); } else { - serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); + return node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId); } - - if (serialMessage == null) { - logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel(),endpointId); - return; - } - - this.getController().sendData(serialMessage); } /** diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/command/DecimalCommandConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/command/BigDecimalCommandConverter.java similarity index 94% rename from bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/command/DecimalCommandConverter.java rename to bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/command/BigDecimalCommandConverter.java index 4bcd65b1b05..5138460e272 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/command/DecimalCommandConverter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/command/BigDecimalCommandConverter.java @@ -18,7 +18,7 @@ * @author Matthew Bowman * @since 1.4.0 */ -public class DecimalCommandConverter extends +public class BigDecimalCommandConverter extends ZWaveCommandConverter { /** diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/command/IntegerCommandConverter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/command/IntegerCommandConverter.java new file mode 100644 index 00000000000..b30a68b202b --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/converter/command/IntegerCommandConverter.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.zwave.internal.converter.command; + +import org.openhab.core.items.Item; +import org.openhab.core.library.types.DecimalType; + +/** + * Converts from {@link DecimalType} command to a Z-Wave value. + * @author Chris Jackson + * @since 1.7.0 + */ +public class IntegerCommandConverter extends + ZWaveCommandConverter { + + /** + * {@inheritDoc} + */ + @Override + protected Integer convert(Item item, DecimalType command) { + return command.intValue(); + } + +} diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ConfigurationParameter.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ConfigurationParameter.java index e40d3c4381e..e0220642c54 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ConfigurationParameter.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ConfigurationParameter.java @@ -19,10 +19,12 @@ */ @XStreamAlias("configurationParameter") public class ConfigurationParameter { - + private final int index; private final int size; private int value; + private boolean readOnly; + private boolean writeOnly; /*** * Constructor. Creates a new instance of the {@link ConfigurationParameter} class. @@ -76,4 +78,36 @@ public int getIndex() { public int getSize() { return size; } + + /** + * Sets the parameter as a WriteOnly parameter + * @param write true if the parameter should not be read + */ + public void setWriteOnly(boolean write) { + writeOnly = write; + } + + /** + * Returns true if this parameter is write only + * @return true if the parameter should not be read back + */ + public boolean getWriteOnly() { + return writeOnly; + } + + /** + * Sets the parameter as a ReadOnly parameter + * @param read true if the parameters is readonly + */ + public void setReadOnly(boolean read) { + readOnly = read; + } + + /** + * Returns true if this parameter is read only + * @return true if the parameter should not be written to + */ + public boolean getReadOnly() { + return readOnly; + } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/NodeStage.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/NodeStage.java deleted file mode 100644 index f4ec95392d5..00000000000 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/NodeStage.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.zwave.internal.protocol; - -import java.util.HashMap; -import java.util.Map; - -/** - * Node Stage Enumeration. Represents the state the node - * is in. - * @author Brian Crosby - * @since 1.3.0 - */ -public enum NodeStage { - EMPTYNODE(0, "Empty New Node"), - PROTOINFO(1, "Protocol Information"), - PING(2, "Ping Node"), - WAKEUP(3, "Wake Up"), - DETAILS(4, "Node Information"), - MANSPEC01(5, "Manufacture Name and Product Identification"), - MANSPEC02(6, "Manufacture Name and Product Identification"), - VERSION(7, "Node Version"), - INSTANCES_ENDPOINTS(8, "Command Class Instances"), - STATIC_VALUES(9, "Static Information"), - // States below are not restored from the configuration files - ASSOCIATIONS(10, "Association Information"), - NEIGHBORS(11, "Node Neighbor Information"), - SESSION(12, "Infrequently Changed Information"), - DYNAMIC(13, "Frequently Changed Information"), - CONFIG(14, "Parameter Information"), - DONE(15, "Node Complete"), - INIT(16, "Node Not Started"), - DEAD(17, "Node Dead"), - FAILED(18,"Node Failed"); - - private int stage; - private String label; - - /** - * A mapping between the integer code and its corresponding - * Node Stage to facilitate lookup by code. - */ - private static Map codeToNodeStageMapping; - - private NodeStage (int s, String l) { - stage = s; - label = l; - } - - private static void initMapping() { - codeToNodeStageMapping = new HashMap(); - for (NodeStage s : values()) { - codeToNodeStageMapping.put(s.stage, s); - } - } - - /** - * Get the stage protocol number. - * @return number - */ - public int getStage() { - return this.stage; - } - - /** - * Get the stage label - * @return label - */ - public String getLabel() { - return this.label; - } - - /** - * Lookup function based on the command class code. - * Returns null if there is no command class with code i - * @param i the code to lookup - * @return enumeration value of the command class. - */ - public static NodeStage getNodeStage(int i) { - if (codeToNodeStageMapping == null) { - initMapping(); - } - - return codeToNodeStageMapping.get(i); - } -} - diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/SerialMessage.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/SerialMessage.java index db30391d051..ed3e96f2298 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/SerialMessage.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/SerialMessage.java @@ -57,7 +57,8 @@ public class SerialMessage { private int transmitOptions = 0; private int callbackId = 0; - private boolean transActionCanceled = false; + private boolean transactionCanceled = false; + private boolean ackPending = false; /** * Indicates whether the serial message is valid. @@ -136,16 +137,16 @@ public SerialMessage(int nodeId, byte[] buffer) { messageLength = buffer.length - 2; // buffer[1]; byte messageCheckSumm = calculateChecksum(buffer); byte messageCheckSummReceived = buffer[messageLength+1]; - logger.trace(String.format("NODE %d: Message checksum calculated = 0x%02X, received = 0x%02X", nodeId, messageCheckSumm, messageCheckSummReceived)); if (messageCheckSumm == messageCheckSummReceived) { logger.trace("NODE {}: Checksum matched", nodeId); isValid = true; } else { - logger.trace("NODE {}: Checksum error", nodeId); + logger.trace("NODE {}: Checksum error. Calculated = 0x%02X, Received = 0x%02X", nodeId, messageCheckSumm, messageCheckSummReceived); isValid = false; return; } - this.messageType = buffer[2] == 0x00 ? SerialMessageType.Request : SerialMessageType.Response;; + this.priority = SerialMessagePriority.High; + this.messageType = buffer[2] == 0x00 ? SerialMessageType.Request : SerialMessageType.Response; this.messageClass = SerialMessageClass.getMessageClass(buffer[3] & 0xFF); this.messagePayload = ArrayUtils.subarray(buffer, 4, messageLength + 1); this.messageNode = nodeId; @@ -158,11 +159,11 @@ public SerialMessage(int nodeId, byte[] buffer) { * @return string the string representation */ static public String bb2hex(byte[] bb) { - String result = ""; + StringBuilder result = new StringBuilder(); for (int i=0; i codeToTransmissionStateMapping; - - private int key; - private String label; - - private TransmissionState(int key, String label) { - this.key = key; - this.label = label; - } - - private static void initMapping() { - codeToTransmissionStateMapping = new HashMap(); - for (TransmissionState s : values()) { - codeToTransmissionStateMapping.put(s.key, s); - } - } - - /** - * Lookup function based on the transmission state code. - * Returns null when there is no transmission state with code i. - * @param i the code to lookup - * @return enumeration value of the transmission state. - */ - public static TransmissionState getTransmissionState(int i) { - if (codeToTransmissionStateMapping == null) { - initMapping(); - } - - return codeToTransmissionStateMapping.get(i); - } - - /** - * @return the key - */ - public int getKey() { - return key; - } - - /** - * @return the label - */ - public String getLabel() { - return label; - } -} \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/UpdateState.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/UpdateState.java deleted file mode 100644 index b13afb094b2..00000000000 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/UpdateState.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.zwave.internal.protocol; - -import java.util.HashMap; -import java.util.Map; - -/** - * Update state enumeration. Indicates the type of application update state that was sent. - * @author Jan-Willem Spuij - * @ since 1.3.0 - */ -public enum UpdateState { - NODE_INFO_RECEIVED(0x84, "Node info received"), - NODE_INFO_REQ_DONE(0x82, "Node info request done"), - NODE_INFO_REQ_FAILED(0x81, "Node info request failed"), - ROUTING_PENDING(0x80, "Routing pending"), - NEW_ID_ASSIGNED(0x40, "New ID Assigned"), - DELETE_DONE(0x20, "Delete done"), - SUC_ID(0x10, "SUC ID"); - - /** - * A mapping between the integer code and its corresponding update state - * class to facilitate lookup by code. - */ - private static Map codeToUpdateStateMapping; - - private int key; - private String label; - - private UpdateState(int key, String label) { - this.key = key; - this.label = label; - } - - private static void initMapping() { - codeToUpdateStateMapping = new HashMap(); - for (UpdateState s : values()) { - codeToUpdateStateMapping.put(s.key, s); - } - } - - /** - * Lookup function based on the update state code. - * Returns null when there is no update state with code i. - * @param i the code to lookup - * @return enumeration value of the update state. - */ - public static UpdateState getUpdateState(int i) { - if (codeToUpdateStateMapping == null) { - initMapping(); - } - - return codeToUpdateStateMapping.get(i); - } - - /** - * @return the key - */ - public int getKey() { - return key; - } - - /** - * @return the label - */ - public String getLabel() { - return label; - } -} \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveController.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveController.java index 84b9c2ba55f..86183f0230e 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveController.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveController.java @@ -13,16 +13,17 @@ import gnu.io.NoSuchPortException; import gnu.io.PortInUseException; import gnu.io.SerialPort; +import gnu.io.SerialPortEvent; +import gnu.io.SerialPortEventListener; import gnu.io.UnsupportedCommOperationException; import java.io.IOException; import java.util.ArrayList; -import java.util.Calendar; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; import java.util.Timer; import java.util.TimerTask; +import java.util.TooManyListenersException; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -31,7 +32,6 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass.CommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClassDynamicState; @@ -39,11 +39,9 @@ import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass; import org.openhab.binding.zwave.internal.protocol.event.ZWaveEvent; import org.openhab.binding.zwave.internal.protocol.event.ZWaveInclusionEvent; -import org.openhab.binding.zwave.internal.protocol.event.ZWaveInitializationCompletedEvent; import org.openhab.binding.zwave.internal.protocol.event.ZWaveNetworkEvent; import org.openhab.binding.zwave.internal.protocol.event.ZWaveNodeStatusEvent; import org.openhab.binding.zwave.internal.protocol.event.ZWaveTransactionCompletedEvent; -import org.openhab.binding.zwave.internal.protocol.event.ZWaveNetworkEvent.State; import org.openhab.binding.zwave.internal.protocol.initialization.ZWaveNodeSerializer; import org.openhab.binding.zwave.internal.protocol.serialmessage.AddNodeMessageClass; import org.openhab.binding.zwave.internal.protocol.serialmessage.AssignReturnRouteMessageClass; @@ -60,6 +58,7 @@ import org.openhab.binding.zwave.internal.protocol.serialmessage.RequestNodeInfoMessageClass; import org.openhab.binding.zwave.internal.protocol.serialmessage.GetRoutingInfoMessageClass; import org.openhab.binding.zwave.internal.protocol.serialmessage.SendDataMessageClass; +import org.openhab.binding.zwave.internal.protocol.serialmessage.SerialApiSetTimeoutsMessageClass; import org.openhab.binding.zwave.internal.protocol.serialmessage.SerialApiSoftResetMessageClass; import org.openhab.binding.zwave.internal.protocol.serialmessage.SetSucNodeMessageClass; import org.openhab.binding.zwave.internal.protocol.serialmessage.ZWaveCommandProcessor; @@ -81,23 +80,26 @@ public class ZWaveController { private static final Logger logger = LoggerFactory.getLogger(ZWaveController.class); - - private static final int QUERY_STAGE_TIMEOUT = 120000; + private static final int ZWAVE_RESPONSE_TIMEOUT = 5000; // 5000 ms ZWAVE_RESPONSE TIMEOUT private static final int ZWAVE_RECEIVE_TIMEOUT = 1000; // 1000 ms ZWAVE_RECEIVE_TIMEOUT - private static final int INITIAL_QUEUE_SIZE = 128; + private static final int INITIAL_TX_QUEUE_SIZE = 128; + private static final int INITIAL_RX_QUEUE_SIZE = 8; private static final long WATCHDOG_TIMER_PERIOD = 10000; // 10 seconds watchdog timer private static final int TRANSMIT_OPTION_ACK = 0x01; private static final int TRANSMIT_OPTION_AUTO_ROUTE = 0x04; private static final int TRANSMIT_OPTION_EXPLORE = 0x20; - private final Map zwaveNodes = new HashMap(); + private final ConcurrentHashMap zwaveNodes = new ConcurrentHashMap(); private final ArrayList zwaveEventListeners = new ArrayList(); - private final PriorityBlockingQueue sendQueue = new PriorityBlockingQueue(INITIAL_QUEUE_SIZE, new SerialMessage.SerialMessageComparator(this)); + private final PriorityBlockingQueue sendQueue = new PriorityBlockingQueue(INITIAL_TX_QUEUE_SIZE, new SerialMessage.SerialMessageComparator(this)); + private final PriorityBlockingQueue recvQueue = new PriorityBlockingQueue(INITIAL_RX_QUEUE_SIZE, new SerialMessage.SerialMessageComparator(this)); private ZWaveSendThread sendThread; private ZWaveReceiveThread receiveThread; - + private ZWaveInputThread inputThread; + + private final Semaphore sendAllowed = new Semaphore(1); private final Semaphore transactionCompleted = new Semaphore(1); private volatile SerialMessage lastSentMessage = null; private long lastMessageStartTime = 0; @@ -105,7 +107,7 @@ public class ZWaveController { private SerialPort serialPort; private int zWaveResponseTimeout = ZWAVE_RESPONSE_TIMEOUT; private Timer watchdog; - + private String zWaveVersion = "Unknown"; private String serialAPIVersion = "Unknown"; private int homeId = 0; @@ -118,6 +120,8 @@ public class ZWaveController { private boolean setSUC = false; private ZWaveDeviceType controllerType = ZWaveDeviceType.UNKNOWN; private int sucID = 0; + private boolean softReset = false; + private boolean masterController = false; private int SOFCount = 0; private int CANCount = 0; @@ -125,9 +129,9 @@ public class ZWaveController { private int ACKCount = 0; private int OOFCount = 0; private AtomicInteger timeOutCount = new AtomicInteger(0); - - private boolean initializationComplete = false; - + +// private boolean initializationComplete = false; + private boolean isConnected; // Constructors @@ -138,20 +142,44 @@ public class ZWaveController { * communication with the Z-Wave controller stick. * @throws SerialInterfaceException when a connection error occurs. */ - public ZWaveController(final boolean isSUC, final String serialPortName, final Integer timeout) throws SerialInterfaceException { + public ZWaveController(final boolean masterController, final boolean isSUC, final String serialPortName, final Integer timeout, final boolean reset) + throws SerialInterfaceException { logger.info("Starting Z-Wave controller"); + this.masterController = masterController; this.setSUC = isSUC; + this.softReset = reset; + if(timeout != null && timeout >= 1500 && timeout <= 10000) { zWaveResponseTimeout = timeout; } - logger.info("Z-Wave timeout is set to {}ms.", zWaveResponseTimeout); + logger.info("Z-Wave timeout is set to {}ms. Soft reset is {}.", zWaveResponseTimeout, reset); connect(serialPortName); this.watchdog = new Timer(true); this.watchdog.schedule( new WatchDogTimerTask(serialPortName), WATCHDOG_TIMER_PERIOD, WATCHDOG_TIMER_PERIOD); + + // We have a delay in running the initialisation sequence to allow any + // frames queued in the controller to be received before sending the init + // sequence. This avoids protocol errors (CAN errors). + Timer initTimer = new Timer(); + initTimer.schedule(new InitializeDelayTask(), 3000); + } + + private class InitializeDelayTask extends TimerTask { + private final Logger logger = LoggerFactory.getLogger(WatchDogTimerTask.class); + + /** + * {@inheritDoc} + */ + @Override + public void run() { + logger.debug("Initialising network"); + initialize(); + } } + // Incoming message handlers /** @@ -160,7 +188,6 @@ public ZWaveController(final boolean isSUC, final String serialPortName, final I * @param incomingMessage the incoming message to process. */ private void handleIncomingMessage(SerialMessage incomingMessage) { - logger.trace("Incoming message to process"); logger.debug(incomingMessage.toString()); switch (incomingMessage.getMessageType()) { @@ -171,7 +198,7 @@ private void handleIncomingMessage(SerialMessage incomingMessage) { handleIncomingResponseMessage(incomingMessage); break; default: - logger.warn("Unsupported incomingMessageType: 0x%02X", incomingMessage.getMessageType()); + logger.warn("Unsupported incomingMessageType: {}", incomingMessage.getMessageType()); } } @@ -181,22 +208,22 @@ private void handleIncomingMessage(SerialMessage incomingMessage) { * @param incomingMessage the incoming message to process. */ private void handleIncomingRequestMessage(SerialMessage incomingMessage) { - logger.trace("Message type = REQUEST"); + logger.trace("Incoming Message type = REQUEST"); ZWaveCommandProcessor processor = ZWaveCommandProcessor.getMessageDispatcher(incomingMessage.getMessageClass()); - if(processor != null) { - processor.handleRequest(this, lastSentMessage, incomingMessage); - - if(processor.isTransactionComplete()) { - notifyEventListeners(new ZWaveTransactionCompletedEvent(this.lastSentMessage)); - transactionCompleted.release(); - logger.trace("Released. Transaction completed permit count -> {}", transactionCompleted.availablePermits()); - } - } - else { + if(processor == null) { logger.warn(String.format("TODO: Implement processing of Request Message = %s (0x%02X)", incomingMessage.getMessageClass().getLabel(), incomingMessage.getMessageClass().getKey())); + + return; + } + + boolean result = processor.handleRequest(this, lastSentMessage, incomingMessage); + if(processor.isTransactionComplete()) { + notifyEventListeners(new ZWaveTransactionCompletedEvent(this.lastSentMessage, result)); + transactionCompleted.release(); + logger.trace("Released. Transaction completed permit count -> {}", transactionCompleted.availablePermits()); } } @@ -215,22 +242,22 @@ private void handleFailedSendDataRequest(SerialMessage originalMessage) { * @param incomingMessage the response message to process. */ private void handleIncomingResponseMessage(SerialMessage incomingMessage) { - logger.trace("Message type = RESPONSE"); + logger.trace("Incoming Message type = RESPONSE"); ZWaveCommandProcessor processor = ZWaveCommandProcessor.getMessageDispatcher(incomingMessage.getMessageClass()); - if(processor != null) { - processor.handleResponse(this, lastSentMessage, incomingMessage); - - if(processor.isTransactionComplete()) { - notifyEventListeners(new ZWaveTransactionCompletedEvent(this.lastSentMessage)); - transactionCompleted.release(); - logger.trace("Released. Transaction completed permit count -> {}", transactionCompleted.availablePermits()); - } - } - else { + if(processor == null) { logger.warn(String.format("TODO: Implement processing of Response Message = %s (0x%02X)", incomingMessage.getMessageClass().getLabel(), incomingMessage.getMessageClass().getKey())); + + return; + } + + boolean result = processor.handleResponse(this, lastSentMessage, incomingMessage); + if(processor.isTransactionComplete()) { + notifyEventListeners(new ZWaveTransactionCompletedEvent(this.lastSentMessage, result)); + transactionCompleted.release(); + logger.trace("Released. Transaction completed permit count -> {}", transactionCompleted.availablePermits()); } switch (incomingMessage.getMessageClass()) { @@ -245,6 +272,11 @@ private void handleIncomingResponseMessage(SerialMessage incomingMessage) { case SerialApiGetInitData: this.isConnected = true; for(Integer nodeId : ((SerialApiGetInitDataMessageClass)processor).getNodes()) { + // if(nodeId != 35) + // continue; + + + ZWaveNode node = null; try { ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer(); @@ -327,7 +359,7 @@ private void handleIncomingResponseMessage(SerialMessage incomingMessage) { // Place nodes in the local ZWave Controller this.zwaveNodes.put(nodeId, node); - node.advanceNodeStage(NodeStage.PROTOINFO); + node.initialiseNode(); } break; case GetSucNodeId: @@ -385,20 +417,30 @@ public void connect(final String serialPortName) this.receiveThread.start(); this.sendThread = new ZWaveSendThread(); this.sendThread.start(); + this.inputThread = new ZWaveInputThread(); + this.inputThread.start(); + + // RXTX serial port library causes high CPU load + // Start event listener, which will just sleep and slow down event loop + serialPort.addEventListener(this.receiveThread); + serialPort.notifyOnDataAvailable(true); logger.info("Serial port is initialized"); } catch (NoSuchPortException e) { - logger.error(String.format("Port %s does not exist", serialPortName)); + logger.error("Serial Error: Port {} does not exist", serialPortName); throw new SerialInterfaceException(String.format("Port %s does not exist", serialPortName), e); } catch (PortInUseException e) { - logger.error(String.format("Port %s in use.", serialPortName)); + logger.error("Serial Error: Port {} in use.", serialPortName); throw new SerialInterfaceException(String.format("Port %s in use.", serialPortName), e); } catch (UnsupportedCommOperationException e) { - logger.error(String.format("Unsupported comm operation on Port %s.", serialPortName)); + logger.error("Serial Error: Unsupported comm operation on Port {}.", serialPortName); throw new SerialInterfaceException(String.format("Unsupported comm operation on Port %s.", serialPortName), e); + } catch (TooManyListenersException e) { + logger.error("Serial Error: Too many listeners on Port {}.", serialPortName); + e.printStackTrace(); } } - + /** * Closes the connection to the Z-Wave controller. */ @@ -407,9 +449,9 @@ public void close() { watchdog.cancel(); watchdog = null; } - + disconnect(); - + // clear nodes collection and send queue ArrayList copy = new ArrayList(this.zwaveEventListeners); for (Object listener : copy.toArray()) { @@ -418,10 +460,11 @@ public void close() { this.zwaveEventListeners.remove(listener); } - - this.zwaveNodes.clear(); + + this.zwaveNodes.clear(); this.sendQueue.clear(); - + this.recvQueue.clear(); + logger.info("Stopped Z-Wave controller"); } @@ -446,8 +489,17 @@ public void disconnect() { } receiveThread = null; } - if(transactionCompleted.availablePermits() < 0) + if (inputThread != null) { + inputThread.interrupt(); + try { + inputThread.join(); + } catch (InterruptedException e) { + } + inputThread = null; + } + if(transactionCompleted.availablePermits() < 0) { transactionCompleted.release(transactionCompleted.availablePermits()); + } transactionCompleted.drainPermits(); logger.trace("Transaction completed permit count -> {}", transactionCompleted.availablePermits()); @@ -458,11 +510,151 @@ public void disconnect() { logger.info("Disconnected from serial port"); } + /** + * Add a node to the controller + * @param nodeId the node number to add + */ + private void addNode(int nodeId) { + new ZWaveInitNodeThread(this, nodeId).start(); + } + + private class ZWaveInitNodeThread extends Thread { + int nodeId; + ZWaveController controller; + + ZWaveInitNodeThread(ZWaveController controller, int nodeId) { + this.nodeId = nodeId; + this.controller = controller; + } + + @Override + public void run() { + logger.debug("NODE {}: Init node thread start", nodeId); + + // Check if the node exists + if(zwaveNodes.get(nodeId) != null) { + logger.warn("NODE {}: Attempting to add node that already exists", nodeId); + return; + } + + ZWaveNode node = null; + try { + ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer(); + node = nodeSerializer.DeserializeNode(nodeId); + } + catch (Exception e) { + logger.error("NODE {}: Restore from config: Error deserialising XML file. {}", nodeId, e.toString()); + node = null; + } + String name = null; + String location = null; + + // Did the node deserialise ok? + if (node != null) { + // Remember the name and location - in case we decide the file was invalid + name = node.getName(); + location = node.getLocation(); + + // Sanity check the data from the file + if (node.getManufacturer() == Integer.MAX_VALUE || + node.getHomeId() != controller.homeId || + node.getNodeId() != nodeId) { + logger.warn("NODE {}: Restore from config: Error. Data invalid, ignoring config.", nodeId); + node = null; + } + else { + // The restore was ok, but we have some work to set up the links that aren't + // made as the deserialiser doesn't call the constructor + logger.debug("NODE {}: Restore from config: Ok.", nodeId); + node.setRestoredFromConfigfile(controller); + + // Set the controller and node references for all command classes + for (ZWaveCommandClass commandClass : node.getCommandClasses()) { + commandClass.setController(controller); + commandClass.setNode(node); + + // Handle event handlers + if (commandClass instanceof ZWaveEventListener) { + controller.addEventListener((ZWaveEventListener)commandClass); + } + + // If this is the multi-instance class, add all command classes for the endpoints + if (commandClass instanceof ZWaveMultiInstanceCommandClass) { + for (ZWaveEndpoint endPoint : ((ZWaveMultiInstanceCommandClass) commandClass) + .getEndpoints()) { + for (ZWaveCommandClass endpointCommandClass : endPoint.getCommandClasses()) { + endpointCommandClass.setController(controller); + endpointCommandClass.setNode(node); + endpointCommandClass.setEndpoint(endPoint); + + // Handle event handlers + if (endpointCommandClass instanceof ZWaveEventListener) { + controller.addEventListener((ZWaveEventListener)endpointCommandClass); + } + } + } + } + } + } + } + + // Create a new node if it wasn't deserialised ok + if(node == null) { + node = new ZWaveNode(controller.homeId, nodeId, controller); + + // Try to maintain the name and location (user supplied data) + // even if the XML file was considered corrupt and we reload data from the device. + node.setName(name); + node.setLocation(location); + } + + if(nodeId == controller.ownNodeId) { + // This is the controller node. + // We already know the device type, id, manufacturer so set it here + // It won't be set later as we probably won't request the manufacturer specific data + node.setDeviceId(controller.getDeviceId()); + node.setDeviceType(controller.getDeviceType()); + node.setManufacturer(controller.getManufactureId()); + } + + // Place nodes in the local ZWave Controller + controller.zwaveNodes.putIfAbsent(nodeId, node); + node.initialiseNode(); + + logger.debug("NODE {}: Init node thread finished", nodeId); + } + } + /** * Enqueues a message for sending on the send queue. * @param serialMessage the serial message to enqueue. */ public void enqueue(SerialMessage serialMessage) { + // Sanity check! + if(serialMessage == null) { + return; + } + + // First try and get the node + // If we're sending to a node, then this obviously isn't to the controller, and we should + // queue anything to a battery node (ie a node supporting the WAKEUP class)! + ZWaveNode node = this.getNode(serialMessage.getMessageNode()); + if (node != null) { + // Keep track of the number of packets sent to this device + node.incrementSendCount(); + + // If the device isn't listening, queue the message if it supports the wakeup class + if (!node.isListening() && !node.isFrequentlyListening()) { + ZWaveWakeUpCommandClass wakeUpCommandClass = (ZWaveWakeUpCommandClass)node.getCommandClass(CommandClass.WAKE_UP); + + // If it's a battery operated device, check if it's awake or place in wake-up queue. + if (wakeUpCommandClass != null && !wakeUpCommandClass.processOutgoingWakeupMessage(serialMessage)) { + return; + } + } + } + + // Add the message to the queue this.sendQueue.add(serialMessage); logger.debug("Enqueueing message. Queue length = {}", this.sendQueue.size()); } @@ -479,10 +671,9 @@ public int getSendQueueLength() { * @param event the event to send. */ public void notifyEventListeners(ZWaveEvent event) { - logger.debug("Notifying event listeners"); + logger.debug("Notifying event listeners: {}", event.getClass().getSimpleName()); ArrayList copy = new ArrayList(this.zwaveEventListeners); for (ZWaveEventListener listener : copy) { - logger.trace("Notifying {}", listener.toString()); listener.ZWaveIncomingEvent(event); } @@ -499,10 +690,7 @@ public void notifyEventListeners(ZWaveEvent event) { } // Initialise the new node - ZWaveNode node = new ZWaveNode(this.homeId, incEvent.getNodeId(), this); - - this.zwaveNodes.put(incEvent.getNodeId(), node); - node.advanceNodeStage(NodeStage.PROTOINFO); + addNode(incEvent.getNodeId()); break; case ExcludeDone: logger.debug("NODE {}: Excluding node.", incEvent.getNodeId()); @@ -512,7 +700,7 @@ public void notifyEventListeners(ZWaveEvent event) { break; } this.zwaveNodes.remove(incEvent.getNodeId()); - + // Remove the XML file ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer(); nodeSerializer.DeleteNode(event.getNodeId()); @@ -520,23 +708,9 @@ public void notifyEventListeners(ZWaveEvent event) { default: break; } - } - if(event instanceof ZWaveNetworkEvent) { + } else if(event instanceof ZWaveNetworkEvent) { ZWaveNetworkEvent networkEvent = (ZWaveNetworkEvent)event; switch(networkEvent.getEvent()) { - case FailedNode: - if(getNode(networkEvent.getNodeId()) == null) { - logger.debug("NODE {}: Deleting a node that doesn't exist.", networkEvent.getNodeId()); - break; - } - if (networkEvent.getState() == State.Success) { - logger.debug("NODE {}: Marking node as failed because its on the controllers failed node list.", networkEvent.getNodeId()); - getNode(networkEvent.getNodeId()).setNodeStage(NodeStage.FAILED); - - ZWaveEvent zEvent = new ZWaveNodeStatusEvent(networkEvent.getNodeId(), ZWaveNodeStatusEvent.State.Failed); - this.notifyEventListeners(zEvent); - break; - } case DeleteNode: if(getNode(networkEvent.getNodeId()) == null) { logger.debug("NODE {}: Deleting a node that doesn't exist.", networkEvent.getNodeId()); @@ -551,6 +725,26 @@ public void notifyEventListeners(ZWaveEvent event) { default: break; } + } else if (event instanceof ZWaveNodeStatusEvent) { + ZWaveNodeStatusEvent statusEvent = (ZWaveNodeStatusEvent) event; + logger.debug("NODE {}: Node Status event - Node is {}", statusEvent.getNodeId(), statusEvent.getState()); + + // Get the node + ZWaveNode node = getNode(event.getNodeId()); + if (node == null) { + logger.error("NODE {}: Node is unknown!", statusEvent.getNodeId()); + return; + } + + // Handle node state changes + switch (statusEvent.getState()) { + case DEAD: + break; + case FAILED: + break; + case ALIVE: + break; + } } } @@ -561,94 +755,26 @@ public void initialize() { this.enqueue(new GetVersionMessageClass().doRequest()); this.enqueue(new MemoryGetIdMessageClass().doRequest()); this.enqueue(new SerialApiGetCapabilitiesMessageClass().doRequest()); + this.enqueue(new SerialApiSetTimeoutsMessageClass().doRequest(150, 15)); this.enqueue(new GetSucNodeIdMessageClass().doRequest()); } - + /** * Send Identify Node message to the controller. * @param nodeId the nodeId of the node to identify - * @throws SerialInterfaceException when timing out or getting an invalid response. */ - public void identifyNode(int nodeId) throws SerialInterfaceException { + public void identifyNode(int nodeId) { this.enqueue(new IdentifyNodeMessageClass().doRequest(nodeId)); } /** * Send Request Node info message to the controller. * @param nodeId the nodeId of the node to identify - * @throws SerialInterfaceException when timing out or getting an invalid response. */ public void requestNodeInfo(int nodeId) { this.enqueue(new RequestNodeInfoMessageClass().doRequest(nodeId)); } - - /** - * Checks for dead or sleeping nodes during Node initialization. - * JwS: merged checkInitComplete and checkForDeadOrSleepingNodes to prevent possibly looping nodes multiple times. - */ - public void checkForDeadOrSleepingNodes(){ - int completeCount = 0; - - if (zwaveNodes.isEmpty()) - return; - - // There are still nodes waiting to get a ping. - // So skip the dead node checking. - for (SerialMessage serialMessage : sendQueue) { - if (serialMessage.getPriority() == SerialMessagePriority.Low) - return; - } - - logger.trace("Checking for Dead or Sleeping Nodes."); - for (Map.Entry entry : zwaveNodes.entrySet()){ - if (entry.getValue().getNodeStage() == NodeStage.EMPTYNODE) - continue; - - logger.debug("NODE {}: In Stage {} since {}, listening={}, FLiRS={}", entry.getKey(), - entry.getValue().getNodeStage().getLabel(), entry.getValue().getQueryStageTimeStamp().toString(), - entry.getValue().isListening(), entry.getValue().isFrequentlyListening()); - - if(entry.getValue().getNodeStage() == NodeStage.DONE || entry.getValue().isDead() == true - || (!entry.getValue().isListening() && !entry.getValue().isFrequentlyListening())) { - completeCount++; - continue; - } - - logger.trace("NODE {}: Checking if {} miliseconds have passed in current stage.", entry.getKey(), QUERY_STAGE_TIMEOUT); - - if(Calendar.getInstance().getTimeInMillis() < (entry.getValue().getQueryStageTimeStamp().getTime() + QUERY_STAGE_TIMEOUT)) - continue; - - logger.warn("NODE {}: May be dead, setting stage to DEAD.", entry.getKey()); - entry.getValue().setNodeStage(NodeStage.DEAD); - completeCount++; - } - - // If all nodes are completed, then we say the binding is ready for business - if(this.zwaveNodes.size() == completeCount && initializationComplete == false) { - logger.debug("ZWave Initialisation Complete"); - - // We only want this event once! - initializationComplete = true; - - ZWaveEvent zEvent = new ZWaveInitializationCompletedEvent(this.ownNodeId); - this.notifyEventListeners(zEvent); - - // If there are DEAD nodes, send a Node Status event - // We do that here to avoid messing with the binding initialisation - for(ZWaveNode node : this.getNodes()) { - logger.debug("NODE {}: Checking completion state - {}.", node.getNodeId(), node.getNodeStage()); - if (node.isDead()) { - logger.debug("NODE {}: DEAD node.", node.getNodeId()); - - zEvent = new ZWaveNodeStatusEvent(node.getNodeId(), ZWaveNodeStatusEvent.State.Dead); - this.notifyEventListeners(zEvent); - } - } - } - } - /** * Polls a node for any dynamic information * @param node @@ -661,14 +787,14 @@ public void pollNode(ZWaveNode node) { .getLabel()); ZWaveCommandClassDynamicState zdds = (ZWaveCommandClassDynamicState) zwaveCommandClass; int instances = zwaveCommandClass.getInstances(); - if (instances == 0) { - Collection dynamicQueries = zdds.getDynamicValues(); + if (instances == 1) { + Collection dynamicQueries = zdds.getDynamicValues(true); for (SerialMessage serialMessage : dynamicQueries) { sendData(serialMessage); } } else { for (int i = 1; i <= instances; i++) { - Collection dynamicQueries = zdds.getDynamicValues(); + Collection dynamicQueries = zdds.getDynamicValues(true); for (SerialMessage serialMessage : dynamicQueries) { sendData(node.encapsulate(serialMessage, zwaveCommandClass, i)); } @@ -678,13 +804,13 @@ public void pollNode(ZWaveNode node) { ZWaveMultiInstanceCommandClass multiInstanceCommandClass = (ZWaveMultiInstanceCommandClass) zwaveCommandClass; for (ZWaveEndpoint endpoint : multiInstanceCommandClass.getEndpoints()) { for (ZWaveCommandClass endpointCommandClass : endpoint.getCommandClasses()) { - logger.trace(String.format("NODE %d: Inspecting command class %s for endpoint %d", node.getNodeId(), endpointCommandClass - .getCommandClass().getLabel(), endpoint.getEndpointId())); + logger.trace("NODE {}: Inspecting command class {} for endpoint {}", node.getNodeId(), endpointCommandClass + .getCommandClass().getLabel(), endpoint.getEndpointId()); if (endpointCommandClass instanceof ZWaveCommandClassDynamicState) { logger.debug("NODE {}: Found dynamic state command class {}", node.getNodeId(), endpointCommandClass .getCommandClass().getLabel()); ZWaveCommandClassDynamicState zdds2 = (ZWaveCommandClassDynamicState) endpointCommandClass; - Collection dynamicQueries = zdds2.getDynamicValues(); + Collection dynamicQueries = zdds2.getDynamicValues(true); for (SerialMessage serialMessage : dynamicQueries) { sendData(node.encapsulate(serialMessage, endpointCommandClass, endpoint.getEndpointId())); @@ -839,6 +965,10 @@ public int getCallbackId() { */ public void sendData(SerialMessage serialMessage) { + if (serialMessage == null) { + logger.error("Null message for sendData"); + return; + } if (serialMessage.getMessageClass() != SerialMessageClass.SendData) { logger.error(String.format("Invalid message class %s (0x%02X) for sendData", serialMessage.getMessageClass().getLabel(), serialMessage.getMessageClass().getKey())); return; @@ -847,21 +977,11 @@ public void sendData(SerialMessage serialMessage) logger.error("Only request messages can be sent"); return; } - - ZWaveNode node = this.getNode(serialMessage.getMessageNode()); - - // Keep track of the number of packets sent to this device - node.incrementSendCount(); - if (!node.isListening() && !node.isFrequentlyListening() && serialMessage.getPriority() != SerialMessagePriority.Low) { - ZWaveWakeUpCommandClass wakeUpCommandClass = (ZWaveWakeUpCommandClass)node.getCommandClass(CommandClass.WAKE_UP); + // We need to wait on the ACK from the controller before completing the transaction. + // This is required in case the Application Message is received from the SendData ACK + serialMessage.setAckRequired(); - // If it's a battery operated device, check if it's awake or place in wake-up queue. - if (wakeUpCommandClass != null && !wakeUpCommandClass.processOutgoingWakeupMessage(serialMessage)) { - return; - } - } - serialMessage.setTransmitOptions(TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE | TRANSMIT_OPTION_EXPLORE); serialMessage.setCallbackId(getCallbackId()); this.enqueue(serialMessage); @@ -872,7 +992,9 @@ public void sendData(SerialMessage serialMessage) * @param eventListener the event listener to add. */ public void addEventListener(ZWaveEventListener eventListener) { - this.zwaveEventListeners.add(eventListener); + synchronized(this.zwaveEventListeners) { + this.zwaveEventListeners.add(eventListener); + } } /** @@ -880,7 +1002,9 @@ public void addEventListener(ZWaveEventListener eventListener) { * @param eventListener the event listener to remove. */ public void removeEventListener(ZWaveEventListener eventListener) { - this.zwaveEventListeners.remove(eventListener); + synchronized(this.zwaveEventListeners) { + this.zwaveEventListeners.remove(eventListener); + } } /** @@ -947,6 +1071,15 @@ public int getSucId() { return sucID; } + /** + * Returns true if the binding is the master controller in the network. + * The master controller simply means that we get notifications. + * @return true if this is the master + */ + public boolean isMasterController() { + return masterController; + } + /** * Gets the node object using it's node ID as key. * Returns null if the node is not found @@ -971,7 +1104,7 @@ public Collection getNodes() { * @return isConnected; */ public boolean isConnected() { - return isConnected && initializationComplete; + return isConnected; // && initializationComplete; } /** @@ -1008,7 +1141,7 @@ public int getACKCount() { /** * Returns the number of Out of Order frames received. - * @return the oOFCount + * @return the OOFCount */ public int getOOFCount() { return OOFCount; @@ -1016,7 +1149,7 @@ public int getOOFCount() { /** * Returns the number of Time-Outs while sending. - * @return the oOFCount + * @return the timeoutCount */ public int getTimeOutCount() { return timeOutCount.get(); @@ -1024,14 +1157,54 @@ public int getTimeOutCount() { // Nested classes and enumerations + /** + * Input thread. This processes incoming messages - it decouples the receive thread, + * which responds to messages from the controller, and the actual processing of messages + * to ensure we respond to the controller in a timely manner + * @author Chris Jackson + */ + private class ZWaveInputThread extends Thread { + /** + * Run method. Runs the actual receiving process. + */ + @Override + public void run() { + logger.debug("Starting Z-Wave thread: Input"); + + SerialMessage recvMessage; + while (!interrupted()) { + try { + if(recvQueue.size() == 0) { + sendAllowed.release(); + } + recvMessage = recvQueue.take(); + logger.debug("Receive queue TAKE: Length={}", recvQueue.size()); + logger.debug("Process Message = {}", SerialMessage.bb2hex(recvMessage.getMessageBuffer())); + + handleIncomingMessage(recvMessage); + sendAllowed.tryAcquire(); + } + catch (InterruptedException e) { + break; + } + catch (Exception e) { + logger.error("Exception during Z-Wave thread: Input.", e); + } + } + + logger.debug("Stopped Z-Wave thread: Input"); + } + } + /** * Z-Wave controller Send Thread. Takes care of sending all messages. * It uses a semaphore to synchronize communication with the receiving thread. * @author Jan-Willem Spuij + * @author Chris Jackson * @since 1.3.0 */ private class ZWaveSendThread extends Thread { - + private final Logger logger = LoggerFactory.getLogger(ZWaveSendThread.class); /** @@ -1039,61 +1212,104 @@ private class ZWaveSendThread extends Thread { */ @Override public void run() { - logger.debug("Starting Z-Wave send thread"); + logger.debug("Starting Z-Wave thread: Send"); try { while (!interrupted()) { - + // To avoid sending lots of frames when we still have input frames to + // process, we wait here until we've processed all receive frames + if(!sendAllowed.tryAcquire(1, zWaveResponseTimeout, TimeUnit.MILLISECONDS)) { + logger.warn("Receive queue TIMEOUT:", recvQueue.size()); + continue; + } + sendAllowed.release(); + + // Take the next message from the send queue try { lastSentMessage = sendQueue.take(); logger.debug("Took message from queue for sending. Queue length = {}", sendQueue.size()); } catch (InterruptedException e1) { break; } - - if (lastSentMessage == null) + + // Check we got a message + if (lastSentMessage == null) { continue; - - // If this message is a data packet to a node - // then make sure the node is not a battery device. + } + + // Get the node for this message + ZWaveNode node = getNode(lastSentMessage.getMessageNode()); + // If it's a battery device, it needs to be awake, or we queue the frame until it is. - if (lastSentMessage.getMessageClass() == SerialMessageClass.SendData) { - ZWaveNode node = getNode(lastSentMessage.getMessageNode()); - - if (node != null && !node.isListening() && !node.isFrequentlyListening() && lastSentMessage.getPriority() != SerialMessagePriority.Low) { - ZWaveWakeUpCommandClass wakeUpCommandClass = (ZWaveWakeUpCommandClass)node.getCommandClass(CommandClass.WAKE_UP); - - // If it's a battery operated device, check if it's awake or place in wake-up queue. - if (wakeUpCommandClass != null && !wakeUpCommandClass.processOutgoingWakeupMessage(lastSentMessage)) { - continue; - } + if (node != null && !node.isListening() && !node.isFrequentlyListening()) { + ZWaveWakeUpCommandClass wakeUpCommandClass = (ZWaveWakeUpCommandClass)node.getCommandClass(CommandClass.WAKE_UP); + + // If it's a battery operated device, check if it's awake or place in wake-up queue. + if (wakeUpCommandClass != null && !wakeUpCommandClass.processOutgoingWakeupMessage(lastSentMessage)) { + continue; } } - // Clear the semaphore used to acknowledge the response. - transactionCompleted.drainPermits(); + // A transaction consists of (up to) 4 parts -: + // 1) We send a REQUEST to the controller. + // 2) The controller sends a RESPONSE almost immediately. + // This RESPONSE typically tells us that the message was, + // or wasn't, added to the sticks queue. + // 3) The controller sends a REQUEST once it's received + // the response from the device. + // We need to be aware that there is no synchronization of + // messages between steps 2 and 3 so we can get other messages + // received at step 3 that are not related to our original + // request. + // 4) We ultimately receive the requested message from the device + // if we're requesting such a message. + // + // A transaction is generally completed at the completion of step 4. + // However, for some messages, there may not be a further REQUEST + // so the transaction is terminated at step 2. This is handled + // by the serial message class processor by setting + // transactionCompleted. + // + // It seems that some of these steps may occur out of order. For + // example, the requested message at step 4 may be received before + // the REQUEST at step 3. This can (I guess) occur if the message to + // the device is received by the device, but the ACK back to the controller + // is lost. The device then sends the requested data, and then finally + // the ACK is received. + // We cover this by setting an 'AckPending' flag in the sent message. + // This needs to be cleared before the transacion is completed. - // Send the message to the controller + // Clear the semaphore used to acknowledge the completed transaction. + transactionCompleted.drainPermits(); + + // Send the REQUEST message TO the controller byte[] buffer = lastSentMessage.getMessageBuffer(); - logger.debug("Sending Message = " + SerialMessage.bb2hex(buffer)); + logger.debug("NODE {}: Sending REQUEST Message = {}", lastSentMessage.getMessageNode(), SerialMessage.bb2hex(buffer)); lastMessageStartTime = System.currentTimeMillis(); try { synchronized (serialPort.getOutputStream()) { serialPort.getOutputStream().write(buffer); serialPort.getOutputStream().flush(); + logger.trace("Message SENT"); } - } catch (IOException e) { + } + catch (IOException e) { logger.error("Got I/O exception {} during sending. exiting thread.", e.getLocalizedMessage()); break; } - - // Now wait for the response... + + // Now wait for the RESPONSE, or REQUEST message FROM the controller + // This will terminate when the transactionCompleted flag gets set + // So, this might complete on a RESPONSE if there's an error (or no further REQUEST expected) + // or it might complete on a subsequent REQUEST. try { if (!transactionCompleted.tryAcquire(1, zWaveResponseTimeout, TimeUnit.MILLISECONDS)) { timeOutCount.incrementAndGet(); - if (lastSentMessage.getMessageClass() == SerialMessageClass.SendData) { - - buffer = new SerialMessage(SerialMessageClass.SendDataAbort, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.High).getMessageBuffer(); - logger.debug("Sending Message = " + SerialMessage.bb2hex(buffer)); + // If this is a SendData message, then we need to abort + // This should only be sent if we didn't get the initial ACK!!! + // So we need to check the ACK flag and only abort if it's not set + if (lastSentMessage.getMessageClass() == SerialMessageClass.SendData && lastSentMessage.isAckPending()) { + buffer = new SerialMessage(SerialMessageClass.SendDataAbort, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Immediate).getMessageBuffer(); + logger.debug("NODE {}: Sending ABORT Message = {}", lastSentMessage.getMessageNode(), SerialMessage.bb2hex(buffer)); try { synchronized (serialPort.getOutputStream()) { serialPort.getOutputStream().write(buffer); @@ -1104,33 +1320,40 @@ public void run() { break; } } - + + // Check if we've exceeded the number of retries. + // Requeue if we're ok, otherwise discard the message if (--lastSentMessage.attempts >= 0) { - logger.error("NODE {}: Timeout while sending message. Requeueing", lastSentMessage.getMessageNode()); - if (lastSentMessage.getMessageClass() == SerialMessageClass.SendData) + logger.error("NODE {}: Timeout while sending message. Requeueing - {} attempts left!", + lastSentMessage.getMessageNode(), lastSentMessage.attempts); + if (lastSentMessage.getMessageClass() == SerialMessageClass.SendData) { handleFailedSendDataRequest(lastSentMessage); - else + } + else { enqueue(lastSentMessage); - } else - { - logger.warn("NODE {}: Discarding message: {}", lastSentMessage.getMessageNode(), lastSentMessage.toString()); + } + } else { + logger.warn("NODE {}: Too many retries. Discarding message: {}", + lastSentMessage.getMessageNode(), lastSentMessage.toString()); } continue; } long responseTime = System.currentTimeMillis() - lastMessageStartTime; - if(responseTime > longestResponseTime) + if(responseTime > longestResponseTime) { longestResponseTime = responseTime; - logger.debug("Response processed after {}ms/{}ms.", responseTime, longestResponseTime); + } + logger.debug("NODE {}: Response processed after {}ms/{}ms.", lastSentMessage.getMessageNode(), responseTime, longestResponseTime); logger.trace("Acquired. Transaction completed permit count -> {}", transactionCompleted.availablePermits()); - } catch (InterruptedException e) { + } + catch (InterruptedException e) { break; } - } - } catch (Exception e) { - logger.error("Got an exception during sending. exiting thread.", e); } - logger.debug("Stopped Z-Wave send thread"); + catch (Exception e) { + logger.error("Exception during Z-Wave thread: Send", e); + } + logger.debug("Stopped Z-Wave thread: Send"); } } @@ -1140,15 +1363,24 @@ public void run() { * @author Jan-Willem Spuij * @since 1.3.0 */ - private class ZWaveReceiveThread extends Thread { + private class ZWaveReceiveThread extends Thread implements SerialPortEventListener { private static final int SOF = 0x01; private static final int ACK = 0x06; private static final int NAK = 0x15; private static final int CAN = 0x18; - + private final Logger logger = LoggerFactory.getLogger(ZWaveReceiveThread.class); + @Override + public void serialEvent(SerialPortEvent arg0) { + try { + logger.trace("RXTX library CPU load workaround, sleep forever"); + Thread.sleep(Long.MAX_VALUE); + } catch (InterruptedException e) { + } + } + /** * Sends 1 byte frame response. * @param response the response code to send. @@ -1158,63 +1390,94 @@ private void sendResponse(int response) { synchronized (serialPort.getOutputStream()) { serialPort.getOutputStream().write(response); serialPort.getOutputStream().flush(); + logger.trace("Response SENT"); } } catch (IOException e) { logger.error(e.getMessage()); } } - + /** * Processes incoming message and notifies event handlers. * @param buffer the buffer to process. + * @throws InterruptedException */ - private void processIncomingMessage(byte[] buffer) { - SerialMessage serialMessage = new SerialMessage(buffer); - if (serialMessage.isValid) { + private void processIncomingMessage(byte[] buffer) throws InterruptedException { + SerialMessage recvMessage = new SerialMessage(buffer); + if (recvMessage.isValid) { logger.trace("Message is valid, sending ACK"); sendResponse(ACK); } else { logger.error("Message is not valid, discarding"); + sendResponse(NAK); + + // The semaphore is acquired when we start the receive. + // We need to release it now... + if(recvQueue.size() == 0) { + sendAllowed.release(); + } return; } - - handleIncomingMessage(serialMessage); + + recvQueue.add(recvMessage); + logger.debug("Receive queue ADD: Length={}", recvQueue.size()); } - + /** * Run method. Runs the actual receiving process. */ @Override public void run() { - logger.debug("Starting Z-Wave receive thread"); + logger.debug("Starting Z-Wave thread: Receive"); try { - // Send a NAK to resynchronise communications sendResponse(NAK); - + + // If we want to do a soft reset on the serial interfaces, do it here. + // It seems there's no response to this message, so sending it through + // 'normal' channels will cause a timeout. + if(softReset == true) { + try { + synchronized (serialPort.getOutputStream()) { + SerialMessage resetMsg = new SerialApiSoftResetMessageClass().doRequest(); + byte[] buffer = resetMsg.getMessageBuffer(); + + serialPort.getOutputStream().write(buffer); + serialPort.getOutputStream().flush(); + } + } catch (IOException e) { + logger.error("Error sending soft reset on initialisation: {}", e.getMessage()); + } + } + while (!interrupted()) { int nextByte; - + try { nextByte = serialPort.getInputStream().read(); - - if (nextByte == -1) + + if (nextByte == -1) { continue; - + } } catch (IOException e) { logger.error("Got I/O exception {} during receiving. exiting thread.", e.getLocalizedMessage()); break; } - + switch (nextByte) { case SOF: + // Use the sendAllowed semaphore to signal that the receive queue is not empty! + sendAllowed.acquire(); + + SOFCount++; int messageLength; - + try { messageLength = serialPort.getInputStream().read(); - } catch (IOException e) { logger.error("Got I/O exception {} during receiving. exiting thread.", e.getLocalizedMessage()); + + sendAllowed.release(); break; } @@ -1232,24 +1495,23 @@ public void run() { return; } } - - logger.trace("Reading message finished" ); + logger.debug("Receive Message = {}", SerialMessage.bb2hex(buffer)); processIncomingMessage(buffer); - SOFCount++; break; case ACK: - logger.trace("Received ACK"); ACKCount++; + logger.trace("Received ACK"); break; case NAK: - logger.error("Message not acklowledged by controller (NAK), discarding"); + NAKCount++; + logger.error("Protocol error (NAK), discarding"); transactionCompleted.release(); logger.trace("Released. Transaction completed permit count -> {}", transactionCompleted.availablePermits()); - NAKCount++; break; case CAN: - logger.error("Message cancelled by controller (CAN), resending"); + CANCount++; + logger.error("Protocol error (CAN), resending"); try { Thread.sleep(100); } catch (InterruptedException e) { @@ -1258,19 +1520,20 @@ public void run() { enqueue(lastSentMessage); transactionCompleted.release(); logger.trace("Released. Transaction completed permit count -> {}", transactionCompleted.availablePermits()); - CANCount++; break; default: - logger.warn(String.format("Out of Frame flow. Got 0x%02X. Sending NAK.", nextByte)); - sendResponse(NAK); OOFCount++; + logger.warn(String.format("Protocol error (OOF). Got 0x%02X. Sending NAK.", nextByte)); + sendResponse(NAK); break; } } } catch (Exception e) { - logger.error("Got an exception during receiving. exiting thread.", e); + logger.error("Exception during Z-Wave thread: Receive", e); } - logger.debug("Stopped Z-Wave receive thread"); + logger.debug("Stopped Z-Wave thread: Receive"); + + serialPort.removeEventListener(); } } @@ -1302,14 +1565,16 @@ public WatchDogTimerTask(String serialPortName) { public void run() { logger.trace("Watchdog: Checking Serial threads"); if ((receiveThread != null && !receiveThread.isAlive()) || - (sendThread != null && !sendThread.isAlive())) + (sendThread != null && !sendThread.isAlive()) || + (inputThread != null && !inputThread.isAlive()) + ) { logger.warn("Threads not alive, respawning"); disconnect(); try { connect(serialPortName); } catch (SerialInterfaceException e) { - logger.error("unable to restart Serial threads: {}", e.getLocalizedMessage()); + logger.error("Unable to restart Serial threads: {}", e.getLocalizedMessage()); } } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveDeviceClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveDeviceClass.java index 740e43214ea..86420bd3571 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveDeviceClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveDeviceClass.java @@ -22,6 +22,7 @@ * functionality together in a class. * TODO: Complete all device classes. * @author Jan-Willem Spuij + * @author Chris Jackson * @since 1.3.0 */ @XStreamAlias("deviceClass") @@ -45,7 +46,6 @@ public ZWaveDeviceClass(Basic basicDeviceClass, Generic genericDeviceClass, Spec this.basicDeviceClass = basicDeviceClass; this.genericDeviceClass = genericDeviceClass; this.specificDeviceClass = specificDeviceClass; - } /** @@ -121,19 +121,26 @@ public int hashCode() { */ @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (obj == null) + } + if (obj == null) { return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()) { return false; + } + ZWaveDeviceClass other = (ZWaveDeviceClass) obj; - if (basicDeviceClass != other.basicDeviceClass) + if (basicDeviceClass != other.basicDeviceClass) { return false; - if (genericDeviceClass != other.genericDeviceClass) + } + if (genericDeviceClass != other.genericDeviceClass) { return false; - if (specificDeviceClass != other.specificDeviceClass) + } + if (specificDeviceClass != other.specificDeviceClass) { return false; + } return true; } @@ -210,32 +217,36 @@ public String getLabel() { * to Basic Device Classes. E.G. a BINARY_SWITCH can be a ROUTING_SLAVE or a SLAVE. * @author Brian Crosby * @author Jan-Willem Spuij + * @author Chris Jackson * @since 1.3.0 */ public enum Generic { NOT_KNOWN(0, "Not Known"), - REMOTE_CONTROLLER(1, "Remote Controller"), - STATIC_CONTOLLER(2, "Static Controller"), - AV_CONTROL_POINT(3, "A/V Control Point"), - DISPLAY(4, "Display"), - THERMOSTAT(8, "Thermostat"), - WINDOW_COVERING(9, "Window Covering"), - REPEATER_SLAVE( 15, "Repeater Slave"), - BINARY_SWITCH(16, "Binary Switch"), - MULTILEVEL_SWITCH( 17, "Multi-Level Switch"), - REMOTE_SWITCH(18, "Remote Switch"), - TOGGLE_SWITCH( 19, "Toggle Switch"), - Z_IP_GATEWAY(20, "Z/IP Gateway"), - Z_IP_NODE( 21, "Z/IP Node"), - VENTILATION(22, "Ventilation"), - BINARY_SENSOR( 32, "Binary Sensor"), - MULTILEVEL_SENSOR(33, "Multi-Level Sensor"), - PULSE_METER(48, "Pulse Meter"), - METER( 49, "Meter"), - ENTRY_CONTROL(64, "Entry Control"), - SEMI_INTEROPERABLE( 80, "Semi-Interoperable"), - ALARM_SENSOR(161, "Alarm Sensor"), - NON_INTEROPERABLE(255, "Non-Interoperable"); + REMOTE_CONTROLLER(0x01, "Remote Controller"), + STATIC_CONTOLLER(0x02, "Static Controller"), + AV_CONTROL_POINT(0x03, "A/V Control Point"), + DISPLAY(0x06, "Display"), + GARAGE_DOOR(0x07, "Garage Door"), + THERMOSTAT(0x08, "Thermostat"), + WINDOW_COVERING(0x09, "Window Covering"), + REPEATER_SLAVE(0x0f, "Repeater Slave"), + BINARY_SWITCH(0x10, "Binary Switch"), + MULTILEVEL_SWITCH(0x11, "Multi-Level Switch"), + REMOTE_SWITCH(0x12, "Remote Switch"), + TOGGLE_SWITCH(0x13, "Toggle Switch"), + Z_IP_GATEWAY(0x14, "Z/IP Gateway"), + Z_IP_NODE(0x15, "Z/IP Node"), + VENTILATION(0x16, "Ventilation"), + REMOTE_SWITCH_2(0x18, "Remote Switch 2"), + BINARY_SENSOR(0x20, "Binary Sensor"), + MULTILEVEL_SENSOR(0x21, "Multi-Level Sensor"), + WATER_CONTROL(0x22, "Water Control"), + PULSE_METER(0x30, "Pulse Meter"), + METER(0x31, "Meter"), + ENTRY_CONTROL(0x40, "Entry Control"), + SEMI_INTEROPERABLE(0x50, "Semi-Interoperable"), + ALARM_SENSOR(0xa1, "Alarm Sensor"), + NON_INTEROPERABLE(0xff, "Non-Interoperable"); /** * A mapping between the integer code and its corresponding Generic @@ -296,9 +307,11 @@ public CommandClass[] getMandatoryCommandClasses() { return new CommandClass[0]; case REMOTE_CONTROLLER: case STATIC_CONTOLLER: + case GARAGE_DOOR: case REPEATER_SLAVE: case TOGGLE_SWITCH: case REMOTE_SWITCH: + case REMOTE_SWITCH_2: case WINDOW_COVERING: case THERMOSTAT: case AV_CONTROL_POINT: @@ -336,6 +349,7 @@ public CommandClass[] getMandatoryCommandClasses() { * be specified for a Specific Device Class. * @author Brian Crosby * @author Jan-Willem Spuij + * @author Chris Jackson * @since 1.3.0 */ public enum Specific { @@ -343,24 +357,34 @@ public enum Specific { PORTABLE_REMOTE_CONTROLLER(1, Generic.REMOTE_CONTROLLER, "Portable Remote Controller"), PORTABLE_SCENE_CONTROLLER(2, Generic.REMOTE_CONTROLLER, "Portable Scene Controller"), PORTABLE_INSTALLER_TOOL(3, Generic.REMOTE_CONTROLLER, "Portable Installer Tool"), + PC_CONTROLLER(1, Generic.STATIC_CONTOLLER, "PC Controller"), SCENE_CONTROLLER(2, Generic.STATIC_CONTOLLER, "Scene Controller"), INSTALLER_TOOL(3, Generic.STATIC_CONTOLLER, "Static Installer Tool"), + SATELLITE_RECEIVER(4, Generic.AV_CONTROL_POINT, "Satellite Receiver"), SATELLITE_RECEIVER_V2(17, Generic.AV_CONTROL_POINT, "Satellite Receiver V2"), DOORBELL(18, Generic.AV_CONTROL_POINT, "Doorbell"), + SIMPLE_DISPLAY(1, Generic.DISPLAY, "Simple Display"), + THERMOSTAT_HEATING(1, Generic.THERMOSTAT, "Heating Thermostat"), THERMOSTAT_GENERAL(2, Generic.THERMOSTAT, "General Thermostat"), SETBACK_SCHEDULE_THERMOSTAT(3, Generic.THERMOSTAT, "Setback Schedule Thermostat"), SETPOINT_THERMOSTAT(4, Generic.THERMOSTAT, "Setpoint Thermostat"), SETBACK_THERMOSTAT(5, Generic.THERMOSTAT, "Setback Thermostat"), THERMOSTAT_GENERAL_V2(6, Generic.THERMOSTAT, "General Thermostat V2"), + SIMPLE_WINDOW_COVERING(1, Generic.WINDOW_COVERING, "Simple Window Covering Control"), + BASIC_REPEATER_SLAVE(1, Generic.REPEATER_SLAVE, "Basic Repeater Slave"), + POWER_SWITCH_BINARY(1, Generic.BINARY_SWITCH, "Binary Power Switch"), + SCENE_SWITCH_BINARY_DISCONTINUED(2, Generic.BINARY_SWITCH, "Binary Scene Switch (Discontinued)"), - SCENE_SWITCH_BINARY(3, Generic.BINARY_SWITCH, "Binary Scene Switch"), + SCENE_SWITCH_BINARY(3, Generic.BINARY_SWITCH, "Binary Scene Switch"), + SIREN_SWITCH_BINARY(5, Generic.BINARY_SWITCH, "Siren Switch"), + POWER_SWITCH_MULTILEVEL(1, Generic.MULTILEVEL_SWITCH, "Multilevel Power Switch"), SCENE_SWITCH_MULTILEVEL_DISCONTINUED(2, Generic.MULTILEVEL_SWITCH, "Multilevel Scene Switch (Discontinued)"), MOTOR_MULTIPOSITION(3, Generic.MULTILEVEL_SWITCH, "Multiposition Motor"), @@ -368,24 +392,39 @@ public enum Specific { MOTOR_CONTROL_CLASS_A(5, Generic.MULTILEVEL_SWITCH, "Motor Control Class A"), MOTOR_CONTROL_CLASS_B(6, Generic.MULTILEVEL_SWITCH, "Motor Control Class B"), MOTOR_CONTROL_CLASS_C(7, Generic.MULTILEVEL_SWITCH, "Motor Control Class C"), + SWITCH_REMOTE_BINARY(1, Generic.REMOTE_SWITCH, "Binary Remote Switch"), SWITCH_REMOTE_MULTILEVEL(2, Generic.REMOTE_SWITCH, "Multilevel Remote Switch"), SWITCH_REMOTE_TOGGLE_BINARY(3, Generic.REMOTE_SWITCH, "Binary Toggle Remote Switch"), - SWITCH_REMOTE_TOGGLE_MULTILEVEL(4, Generic.REMOTE_SWITCH, "Multilevel Toggle Remote Switch"), + SWITCH_REMOTE_TOGGLE_MULTILEVEL(4, Generic.REMOTE_SWITCH, "Multilevel Toggle Remote Switch"), + + SWITCH_REMOTE2_MULTILEVEL(1, Generic.REMOTE_SWITCH_2, "Multilevel Remote Switch"), + SWITCH_TOGGLE_BINARY(1, Generic.TOGGLE_SWITCH, "Binary Toggle Switch"), SWITCH_TOGGLE_MULTILEVEL(2, Generic.TOGGLE_SWITCH, "Multilevel Toggle Switch"), + Z_IP_TUNNELING_GATEWAY(1, Generic.Z_IP_GATEWAY, "Z/IP Tunneling Gateway"), Z_IP_ADVANCED_GATEWAY(2, Generic.Z_IP_GATEWAY, "Z/IP Advanced Gateway"), + Z_IP_TUNNELING_NODE(1, Generic.Z_IP_NODE, "Z/IP Tunneling Node"), Z_IP_ADVANCED_NODE(2, Generic.Z_IP_NODE, "Z/IP Advanced Node"), + RESIDENTIAL_HEAT_RECOVERY_VENTILATION(1, Generic.VENTILATION, "Residential Heat Recovery Ventilation"), + ROUTING_SENSOR_BINARY(1, Generic.BINARY_SENSOR, "Routing Binary Sensor"), + ROUTING_SENSOR_MULTILEVEL(1, Generic.MULTILEVEL_SENSOR, "Routing Multilevel Sensor"), + SIMPLE_METER(1, Generic.METER, "Simple Meter"), + + SIMPLE_GARAGE_DOOR(1, Generic.GARAGE_DOOR, "Simple Garage Door"), + DOOR_LOCK(1, Generic.ENTRY_CONTROL, "Door Lock"), ADVANCED_DOOR_LOCK(2, Generic.ENTRY_CONTROL, "Advanced Door Lock"), SECURE_KEYPAD_DOOR_LOCK(3, Generic.ENTRY_CONTROL, "Secure Keypad Door Lock"), + ENERGY_PRODUCTION(1, Generic.SEMI_INTEROPERABLE, "Energy Production"), + ALARM_SENSOR_ROUTING_BASIC(1, Generic.ALARM_SENSOR, "Basic Routing Alarm Sensor"), ALARM_SENSOR_ROUTING(2, Generic.ALARM_SENSOR, "Routing Alarm Sensor"), ALARM_SENSOR_ZENSOR_BASIC(3, Generic.ALARM_SENSOR, "Basic Zensor Alarm Sensor"), @@ -396,7 +435,7 @@ public enum Specific { SMOKE_SENSOR_ZENSOR_BASIC(8, Generic.ALARM_SENSOR, "Basic Zensor Smoke Sensor"), SMOKE_SENSOR_ZENSOR(9, Generic.ALARM_SENSOR, "Zensor Smoke Sensor"), SMOKE_SENSOR_ZENSOR_ADVANCED(10, Generic.ALARM_SENSOR, "Advanced Zensor Smoke Sensor"); - + /** * A mapping between the integer code and its corresponding Generic Device class to facilitate lookup by code. */ diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveNode.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveNode.java index 4179210c95a..a37c4a3b138 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveNode.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveNode.java @@ -22,11 +22,13 @@ import org.openhab.binding.zwave.internal.protocol.ZWaveDeviceClass.Specific; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveAssociationCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveVersionCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass.CommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveMultiInstanceCommandClass; import org.openhab.binding.zwave.internal.protocol.event.ZWaveEvent; import org.openhab.binding.zwave.internal.protocol.event.ZWaveNodeStatusEvent; +import org.openhab.binding.zwave.internal.protocol.initialization.ZWaveNodeInitStage; import org.openhab.binding.zwave.internal.protocol.initialization.ZWaveNodeStageAdvancer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,14 +54,17 @@ public class ZWaveNode { private ZWaveController controller; @XStreamOmitField private ZWaveNodeStageAdvancer nodeStageAdvancer; + @XStreamOmitField + private ZWaveNodeState nodeState; - private int homeId; - private int nodeId; - private int version; + @XStreamConverter(HexToIntegerConverter.class) + private int homeId = Integer.MAX_VALUE; + private int nodeId = Integer.MAX_VALUE; + private int version = Integer.MAX_VALUE; private String name; private String location; - + @XStreamConverter(HexToIntegerConverter.class) private int manufacturer = Integer.MAX_VALUE; @XStreamConverter(HexToIntegerConverter.class) @@ -74,13 +79,10 @@ public class ZWaveNode { private Map supportedCommandClasses = new HashMap(); private List nodeNeighbors = new ArrayList(); - private Date lastSent; - private Date lastReceived; + private Date lastSent = null; + private Date lastReceived = null; - @XStreamOmitField - private Date queryStageTimeStamp; - @XStreamOmitField - private volatile NodeStage nodeStage; + private boolean applicationUpdateReceived = false; @XStreamOmitField private int resendCount = 0; @@ -96,8 +98,6 @@ public class ZWaveNode { @XStreamOmitField private int retryCount = 0; - // TODO: Implement ZWaveNodeValue for Nodes that store multiple values. - /** * Constructor. Creates a new instance of the ZWaveNode class. * @param homeId the home ID to use. @@ -105,27 +105,30 @@ public class ZWaveNode { * @param controller the wave controller instance */ public ZWaveNode(int homeId, int nodeId, ZWaveController controller) { + nodeState = ZWaveNodeState.ALIVE; this.homeId = homeId; this.nodeId = nodeId; this.controller = controller; this.nodeStageAdvancer = new ZWaveNodeStageAdvancer(this, controller); - this.nodeStage = NodeStage.EMPTYNODE; this.deviceClass = new ZWaveDeviceClass(Basic.NOT_KNOWN, Generic.NOT_KNOWN, Specific.NOT_USED); - this.lastSent = null; - this.lastReceived = null; } /** - * Configures the node after it's been restored from file + * Configures the node after it's been restored from file. + * NOTE: XStream doesn't run any default constructor. So, any initialisation + * made in a constructor, or statically, won't be performed!!! + * Set defaults here if it's important!!! * @param controller the wave controller instance */ public void setRestoredFromConfigfile(ZWaveController controller) { + nodeState = ZWaveNodeState.ALIVE; + this.controller = controller; - + // Create the initialisation advancer and tell it we've loaded from file this.nodeStageAdvancer = new ZWaveNodeStageAdvancer(this, controller); this.nodeStageAdvancer.setRestoredFromConfigfile(); - this.nodeStage = NodeStage.EMPTYNODE; + nodeStageAdvancer.setCurrentStage(ZWaveNodeInitStage.EMPTYNODE); } /** @@ -191,14 +194,13 @@ public String getHealState() { public void setHealState(String healState) { this.healState = healState; } - + /** - * Gets whether the node is dead or failed. - * In either case, the device is not considered functioning + * Gets whether the node is dead. * @return */ public boolean isDead() { - if(this.nodeStage == NodeStage.DEAD || this.nodeStage == NodeStage.FAILED) { + if(nodeState == ZWaveNodeState.DEAD || nodeState == ZWaveNodeState.FAILED) { return true; } else { @@ -208,24 +210,45 @@ public boolean isDead() { /** * Sets the node to be 'undead'. - * @return */ - public void setAlive(){ - if(this.nodeStageAdvancer.isInitializationComplete()) { - logger.debug("NODE {}: Node is now ALIVE", this.nodeId); - this.nodeStage = NodeStage.DONE; + public void setNodeState(ZWaveNodeState state) { + // Make sure we only handle real state changes + if(state == nodeState) { + return; } - else { - this.nodeStage = NodeStage.DYNAMIC; - this.nodeStageAdvancer.advanceNodeStage(NodeStage.DONE); + + switch(state) { + case ALIVE: + logger.debug("NODE {}: Node has risen from the DEAD. Init stage is {}:{}.", nodeId, + this.getNodeInitializationStage().toString()); + + // Reset the resend counter + this.resendCount = 0; + break; + + case DEAD: + // If the node is failed, then we don't allow transitions to DEAD + // The only valid state change from FAILED is to ALIVE + if(nodeState == ZWaveNodeState.FAILED) { + return; + } + case FAILED: + this.deadCount++; + this.deadTime = Calendar.getInstance().getTime(); + logger.debug("NODE {}: Node is DEAD.", this.nodeId); + break; } - // Reset the resend counter - this.resendCount = 0; + // Don't alert state changes while we're still initialising + if(nodeStageAdvancer.isInitializationComplete() == true) { + ZWaveEvent zEvent = new ZWaveNodeStatusEvent(this.getNodeId(), ZWaveNodeState.DEAD); + controller.notifyEventListeners(zEvent); + } + else { + logger.debug("NODE {}: Initialisation incomplete, not signalling state change.", this.nodeId); + } - // Alert anyone who wants to know... - ZWaveEvent zEvent = new ZWaveNodeStatusEvent(this.getNodeId(), ZWaveNodeStatusEvent.State.Alive); - controller.notifyEventListeners(zEvent); + nodeState = state; } /** @@ -332,14 +355,22 @@ public Date getLastSent() { return lastSent; } + /** + * Gets the node state. + * @return the nodeState + */ + public ZWaveNodeState getNodeState() { + return this.nodeState; + } + /** * Gets the node stage. * @return the nodeStage */ - public NodeStage getNodeStage() { - return nodeStage; + public ZWaveNodeInitStage getNodeInitializationStage() { + return this.nodeStageAdvancer.getCurrentStage(); } - + /** * Gets the initialization state * @return true if initialization has been completed @@ -353,8 +384,8 @@ public boolean isInitializationComplete() { * Sets the node stage. * @param nodeStage the nodeStage to set */ - public void setNodeStage(NodeStage nodeStage) { - this.nodeStage = nodeStage; + public void setNodeStage(ZWaveNodeInitStage nodeStage) { + nodeStageAdvancer.setCurrentStage(nodeStage); } /** @@ -373,6 +404,26 @@ public void setVersion(int version) { this.version = version; } + + /** + * Gets the node application firmware version + * @return the version + */ + public String getApplicationVersion() { + ZWaveVersionCommandClass versionCmdClass = (ZWaveVersionCommandClass) this.getCommandClass(CommandClass.VERSION); + if(versionCmdClass == null) { + return "0.0"; + } + + String appVersion = versionCmdClass.getApplicationVersion(); + if(appVersion == null) { + logger.trace("NODE {}: App version requested but version is unknown", this.getNodeId()); + return "0.0"; + } + + return appVersion; + } + /** * Gets whether the node is routing messages. * @return the routing @@ -394,37 +445,18 @@ public void setRouting(boolean routing) { * @return the queryStageTimeStamp */ public Date getQueryStageTimeStamp() { - return queryStageTimeStamp; - } - - /** - * Sets the time stamp the node was last queried. - * @param queryStageTimeStamp the queryStageTimeStamp to set - */ - public void setQueryStageTimeStamp(Date queryStageTimeStamp) { - this.queryStageTimeStamp = queryStageTimeStamp; + return this.nodeStageAdvancer.getQueryStageTimeStamp(); } /** * Increments the resend counter. * On three increments the node stage is set to DEAD and no * more messages will be sent. + * This is only used for SendData messages. */ public void incrementResendCount() { if (++resendCount >= 3) { - this.nodeStage = NodeStage.DEAD; - this.deadCount++; - this.deadTime = Calendar.getInstance().getTime(); - this.queryStageTimeStamp = Calendar.getInstance().getTime(); - logger.debug("NODE {}: Retry count exceeded. Node is DEAD.", this.nodeId); - - if(nodeStageAdvancer.isInitializationComplete() == true) { - ZWaveEvent zEvent = new ZWaveNodeStatusEvent(this.getNodeId(), ZWaveNodeStatusEvent.State.Dead); - controller.notifyEventListeners(zEvent); - } - else { - logger.debug("NODE {}: Initialisation incomplete, not signalling DEAD node.", this.nodeId); - } + setNodeState(ZWaveNodeState.DEAD); } this.retryCount++; } @@ -438,7 +470,7 @@ public void incrementResendCount() { public void resetResendCount() { this.resendCount = 0; if (this.nodeStageAdvancer.isInitializationComplete() && this.isDead() == false) { - this.nodeStage = NodeStage.DONE; + nodeStageAdvancer.setCurrentStage(ZWaveNodeInitStage.DONE); } } @@ -497,6 +529,16 @@ public void addCommandClass(ZWaveCommandClass commandClass) } } + /** + * Removes a command class from the node. + * This is used to remove classes that a node may report it supports + * but it doesn't respond to. + * @param commandClass The command class key + */ + public void removeCommandClass(CommandClass commandClass) { + supportedCommandClasses.remove(commandClass); + } + /** * Resolves a command class for this node. First endpoint is checked. * If endpoint == 0 or (endpoint != 1 and version of the multi instance @@ -544,17 +586,12 @@ else if (multiInstanceCommandClass.getVersion() == 1) { return null; } - + /** - * Advances the initialization stage for this node. - * Every node follows a certain path through it's - * initialization phase. These stages are visited one by - * one to finally end up with a completely built node structure - * through querying the controller / node. + * Initialise the node */ - public void advanceNodeStage(NodeStage targetStage) { - // call the advanceNodeStage method on the advancer. - this.nodeStageAdvancer.advanceNodeStage(targetStage); + public void initialiseNode() { + this.nodeStageAdvancer.startInitialisation(); } /** @@ -571,8 +608,9 @@ public SerialMessage encapsulate(SerialMessage serialMessage, ZWaveCommandClass commandClass, int endpointId) { ZWaveMultiInstanceCommandClass multiInstanceCommandClass; - if (serialMessage == null) + if (serialMessage == null) { return null; + } // no encapsulation necessary. if (endpointId == 0) { @@ -600,7 +638,7 @@ public SerialMessage encapsulate(SerialMessage serialMessage, } } - logger.warn("NODE {}:Encapsulating message, instance / endpoint {} failed, will discard message.", this.getNodeId(), endpointId); + logger.warn("NODE {}: Encapsulating message, instance / endpoint {} failed, will discard message.", this.getNodeId(), endpointId); return null; } @@ -728,4 +766,22 @@ public void incrementReceiveCount() { public int getSendCount() { return sendCount; } + + /** + * Gets the applicationUpdateReceived flag. + * This is set to indicate that we have received the required information from the device + * @return true if information received + */ + public boolean getApplicationUpdateReceived() { + return applicationUpdateReceived; + } + + /** + * Sets the applicationUpdateReceived flag. + * This is set to indicate that we have received the required information from the device + * @param received true if received + */ + public void setApplicationUpdateReceived(boolean received) { + applicationUpdateReceived = received; + } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveNodeState.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveNodeState.java new file mode 100644 index 00000000000..aed2f57cd7f --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveNodeState.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.zwave.internal.protocol; + +/** + * Represents the state that the node is in. + * @author Chris Jackson + * @since 1.7.0 + */ +public enum ZWaveNodeState { + ALIVE, + DEAD, + FAILED; +} + diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAlarmCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAlarmCommandClass.java index e4605249139..ec6d1e3b572 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAlarmCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAlarmCommandClass.java @@ -8,11 +8,12 @@ */ package org.openhab.binding.zwave.internal.protocol.commandclass; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; @@ -20,7 +21,6 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +36,7 @@ */ @XStreamAlias("alarmCommandClass") public class ZWaveAlarmCommandClass extends ZWaveCommandClass - implements ZWaveGetCommands { + implements ZWaveGetCommands, ZWaveCommandClassDynamicState { @XStreamOmitField private static final Logger logger = LoggerFactory.getLogger(ZWaveAlarmCommandClass.class); @@ -44,8 +44,15 @@ public class ZWaveAlarmCommandClass extends ZWaveCommandClass private static final int ALARM_GET = 0x04; private static final int ALARM_REPORT = 0x05; - private final Set alarms = new HashSet(); + private final Map alarms = new HashMap(); + @XStreamOmitField + private boolean initialiseDone = false; + @XStreamOmitField + private boolean dynamicDone = false; + + private boolean isGetSupported = true; + /** * Creates a new instance of the ZWaveAlarmCommandClass class. * @param node the node this command class belongs to @@ -72,11 +79,11 @@ public CommandClass getCommandClass() { public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { logger.trace("Handle Message Alarm Request"); - logger.debug(String.format("NODE %d: Received Alarm Request", this.getNode().getNodeId())); + logger.debug("NODE {}: Received Alarm Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { case ALARM_GET: - logger.warn(String.format("Command 0x%02X not implemented.", command)); + logger.warn("Command {} not implemented.", command); return; case ALARM_REPORT: logger.trace("Process Alarm Report"); @@ -84,28 +91,30 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, int alarmTypeCode = serialMessage.getMessagePayloadByte(offset + 1); int value = serialMessage.getMessagePayloadByte(offset + 2); - logger.debug(String.format("NODE %d: Alarm report - Value = 0x%02x", this.getNode().getNodeId(), value)); + logger.debug("NODE {}: Alarm report - Value = {}", this.getNode().getNodeId(), value); AlarmType alarmType = AlarmType.getAlarmType(alarmTypeCode); if (alarmType == null) { - logger.error(String.format("NODE %d: Unknown Alarm Type = 0x%02x, ignoring report.", this.getNode().getNodeId(), alarmTypeCode)); + logger.error("NODE {}: Unknown Alarm Type = {}, ignoring report.", this.getNode().getNodeId(), alarmTypeCode); return; } // alarm type seems to be supported, add it to the list. - if (!alarms.contains(alarmType)) { - this.alarms.add(alarmType); + // alarm type seems to be supported, add it to the list. + Alarm alarm = alarms.get(alarmType); + if (alarm == null) { + alarm = new Alarm(alarmType); + this.alarms.put(alarmType, alarm); } + alarm.setInitialised(); - logger.debug(String.format("NODE %d: Alarm Type = %s (0x%02x)", this.getNode().getNodeId(), alarmType.getLabel(), alarmTypeCode)); + logger.debug("NODE {}: Alarm Type = {} ({})", this.getNode().getNodeId(), alarmType.getLabel(), alarmTypeCode); ZWaveAlarmValueEvent zEvent = new ZWaveAlarmValueEvent(this.getNode().getNodeId(), endpoint, alarmType, value); this.getController().notifyEventListeners(zEvent); - if (this.getNode().getNodeStage() != NodeStage.DONE) { - this.getNode().advanceNodeStage(NodeStage.DONE); - } + dynamicDone = true; break; default: logger.warn(String.format("Unsupported Command 0x%02X for command class %s (0x%02X).", @@ -121,10 +130,11 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, * @return the serial message */ public SerialMessage getValueMessage() { - for (AlarmType alarmType : this.alarms) { - return getMessage(alarmType); + //TODO: Why does this return!!!???!!! + for (Map.Entry entry : this.alarms.entrySet()) { + return getMessage(entry.getValue().getAlarmType()); } - + // in case there are no supported alarms, get them. return getMessage(AlarmType.GENERAL); @@ -135,6 +145,11 @@ public SerialMessage getValueMessage() { * @return the serial message */ public SerialMessage getMessage(AlarmType alarmType) { + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + logger.debug("NODE {}: Creating new message for application command ALARM_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] newPayload = { (byte) this.getNode().getNodeId(), @@ -153,7 +168,18 @@ public SerialMessage getMessage(AlarmType alarmType) { */ @XStreamAlias("alarmType") public enum AlarmType { - GENERAL(0, "General"); + GENERAL(0, "General"), + SMOKE(1, "Smoke"), + CARBON_MONOXIDE(2, "Carbon Monoxide"), + CARBON_DIOXIDE(3, "Carbon Dioxide"), + HEAT(4, "Heat"), + FLOOD(5, "Flood"), + ACCESS_CONTROL(6, "Access Control"), + BURGLAR(7, "Burglar"), + POWER_MANAGEMENT(8, "Power Management"), + SYSTEM(9, "System"), + EMERGENCY(10, "Emergency"), + COUNT(11, "Count"); /** * A mapping between the integer code and its corresponding Alarm type @@ -205,6 +231,30 @@ public String getLabel() { } } + /** + * Class to hold alarm state + * @author Chris Jackson + */ + private class Alarm { + AlarmType alarmType; + boolean initialised = false; + + public Alarm(AlarmType type) { + alarmType = type; + } + + public AlarmType getAlarmType() { + return alarmType; + } + + public void setInitialised() { + initialised = true; + } + + public boolean getInitialised() { + return initialised; + } + } /** * Z-Wave Alarm Event class. Indicates that an alarm value @@ -234,4 +284,26 @@ public AlarmType getAlarmType() { return alarmType; } } + + @Override + public Collection getDynamicValues(boolean refresh) { + ArrayList result = new ArrayList(); + + for (Map.Entry entry : this.alarms.entrySet()) { + if(refresh == true || entry.getValue().getInitialised() == false) { + result.add(getMessage(entry.getValue().getAlarmType())); + } + } + + return result; + } + + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAlarmSensorCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAlarmSensorCommandClass.java index a24a135c7de..0e1f02427dc 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAlarmSensorCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAlarmSensorCommandClass.java @@ -11,10 +11,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; @@ -22,7 +21,6 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,8 +34,8 @@ * The event is reported as occurs (0xFF) or does not occur (0x00). * The commands include the possibility to get a given * value and report a value. - * TODO: Add support for more than one sensor type. * @author Jan-Willem Spuij + * @author Chris Jackson * @since 1.3.0 */ @XStreamAlias("alarmSensorCommandClass") @@ -51,9 +49,14 @@ public class ZWaveAlarmSensorCommandClass extends ZWaveCommandClass private static final int SENSOR_ALARM_REPORT = 0x02; private static final int SENSOR_ALARM_SUPPORTED_GET = 0x03; private static final int SENSOR_ALARM_SUPPORTED_REPORT = 0x04; + + private final Map alarms = new HashMap(); + + @XStreamOmitField + private boolean initialiseDone = false; - private final Set alarms = new HashSet(); - + private boolean isGetSupported = true; + /** * Creates a new instance of the ZWaveAlarmSensorCommandClass class. * @param node the node this command class belongs to @@ -79,13 +82,12 @@ public CommandClass getCommandClass() { @Override public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { - logger.trace("Handle Message Sensor Alarm Request"); - logger.debug(String.format("Received Sensor Alarm Request for Node ID = %d", this.getNode().getNodeId())); + logger.debug("NODE {}: Received Sensor Alarm Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { case SENSOR_ALARM_GET: case SENSOR_ALARM_SUPPORTED_GET: - logger.warn(String.format("Command 0x%02X not implemented.", command)); + logger.warn("Command {} not implemented.", command); return; case SENSOR_ALARM_REPORT: logger.trace("Process Sensor Alarm Report"); @@ -93,72 +95,65 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, int sourceNode = serialMessage.getMessagePayloadByte(offset + 1); int alarmTypeCode = serialMessage.getMessagePayloadByte(offset + 2); int value = serialMessage.getMessagePayloadByte(offset + 3); - - logger.debug(String.format("Sensor Alarm report from nodeId = %d", this.getNode().getNodeId())); - logger.debug(String.format("Source node ID = %d", sourceNode)); - logger.debug(String.format("Value = 0x%02x", value)); - - AlarmType alarmType = AlarmType.getAlarmType(alarmTypeCode); - - if (alarmType == null) { - logger.error(String.format("Unknown Alarm Type = 0x%02x, ignoring report.", alarmTypeCode)); - return; - } - - // alarm type seems to be supported, add it to the list. - if (!alarms.contains(alarmType)) - this.alarms.add(alarmType); - logger.debug(String.format("Alarm Type = %s (0x%02x)", alarmType.getLabel(), alarmTypeCode)); - - ZWaveAlarmSensorValueEvent zEvent = new ZWaveAlarmSensorValueEvent(this.getNode().getNodeId(), endpoint, alarmType, value); - this.getController().notifyEventListeners(zEvent); - - if (this.getNode().getNodeStage() != NodeStage.DONE) - this.getNode().advanceNodeStage(NodeStage.DONE); + // Alarm type seems to be supported, add it to the list if it's not already there. + Alarm alarm = getAlarm(alarmTypeCode); + if(alarm != null) { + alarm.setInitialised(); + + logger.debug("NODE {}: Alarm Report: Source={}, Type={}({}), Value={}", + this.getNode().getNodeId(), + sourceNode, + alarm.getAlarmType().getLabel(), alarmTypeCode, + value); + + ZWaveAlarmSensorValueEvent zEvent = new ZWaveAlarmSensorValueEvent(this.getNode().getNodeId(), endpoint, alarm.getAlarmType(), value); + this.getController().notifyEventListeners(zEvent); + } break; case SENSOR_ALARM_SUPPORTED_REPORT: - logger.debug("Process Sensor Supported Alarm Report"); + logger.debug("NODE {}: Process Sensor Supported Alarm Report", this.getNode().getNodeId()); int numBytes = serialMessage.getMessagePayloadByte(offset + 1); int manufacturerId = this.getNode().getManufacturer(); int deviceType = this.getNode().getDeviceType(); + // TODO: This bodge should be configured through the database!!! // Fibaro alarm sensors do not provide a bitmap of alarm types, but list them byte by byte. - if (manufacturerId == 0x010F && deviceType == 0x0700) { - logger.warn("Detected Fibaro FGK - 101 Door / Window sensor, activating workaround for incorrect encoding of supported alarm bitmap."); + logger.debug("Detected Fibaro FGK - 101 Door / Window sensor, activating workaround for incorrect encoding of supported alarm bitmap."); for(int i=0; i < numBytes; ++i ) { int index = serialMessage.getMessagePayloadByte(offset + i + 2); - if(index >= AlarmType.values().length) + if(index >= AlarmType.values().length) { continue; - - AlarmType alarmTypeToAdd = AlarmType.getAlarmType(index); - this.alarms.add(alarmTypeToAdd); - logger.debug(String.format("Added alarm type %s (0x%02x)", alarmTypeToAdd.getLabel(), index)); + } + + // Alarm type seems to be supported, add it to the list if it's not already there. + getAlarm(index); } } else { for(int i=0; i < numBytes; ++i ) { for(int bit = 0; bit < 8; ++bit) { - if( ((serialMessage.getMessagePayloadByte(offset + i +2)) & (1 << bit) ) == 0 ) - continue; - - int index = (i << 3) + bit; - if(index >= AlarmType.values().length) - continue; - - // (n)th bit is set. n is the index for the alarm type enumeration. - - AlarmType alarmTypeToAdd = AlarmType.getAlarmType(index); - this.alarms.add(alarmTypeToAdd); - logger.debug(String.format("Added alarm type %s (0x%02x)", alarmTypeToAdd.getLabel(), index)); + if (((serialMessage.getMessagePayloadByte(offset + i + 2)) & (1 << bit)) == 0) { + continue; + } + + int index = (i << 3) + bit; + if (index >= AlarmType.values().length) { + continue; + } + + // (n)th bit is set. n is the index for the alarm type + // enumeration. + // Alarm type seems to be supported, add it to the list if it's not already there. + getAlarm(index); } } } - - this.getNode().advanceNodeStage(NodeStage.DYNAMIC); + + initialiseDone = true; break; default: logger.warn(String.format("Unsupported Command 0x%02X for command class %s (0x%02X).", @@ -168,17 +163,36 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, } } + private Alarm getAlarm(int alarmTypeCode) { + AlarmType alarmType = AlarmType.getAlarmType(alarmTypeCode); + if (alarmType == null) { + logger.error("NODE {}: Unknown Alarm Type = {}, ignoring report.", this.getNode().getNodeId(), alarmTypeCode); + return null; + } + + // Add alarm to the list if it's not already there. + Alarm alarm = alarms.get(alarmType); + if (alarm == null) { + logger.debug("NODE {}: Adding new alarm type {}({})", this.getNode().getNodeId(), + alarmType.getLabel(), alarmTypeCode); + alarm = new Alarm(alarmType); + this.alarms.put(alarmType, alarm); + } + + return alarm; + } + /** * Gets a SerialMessage with the SENSOR_ALARM_GET command * @return the serial message */ public SerialMessage getValueMessage() { - for (AlarmType alarmType : this.alarms) { - return getMessage(alarmType); + //TODO: Why does this return!!!???!!! + for (Map.Entry entry : this.alarms.entrySet()) { + return getMessage(entry.getValue().getAlarmType()); } // in case there are no supported alarms, get them. - return this.getSupportedMessage(); } @@ -187,7 +201,12 @@ public SerialMessage getValueMessage() { * @return the serial message */ public SerialMessage getMessage(AlarmType alarmType) { - logger.debug("Creating new message for application command SENSOR_ALARM_GET for node {}", this.getNode().getNodeId()); + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + + logger.debug("NODE {}: Creating new message for command SENSOR_ALARM_GET, type {}", this.getNode().getNodeId(), alarmType.getLabel()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] newPayload = { (byte) this.getNode().getNodeId(), 3, @@ -197,20 +216,29 @@ public SerialMessage getMessage(AlarmType alarmType) { result.setMessagePayload(newPayload); return result; } - + + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } + /** * Gets a SerialMessage with the SENSOR_ALARM_SUPPORTED_GET command * @return the serial message, or null if the supported command is not supported. */ public SerialMessage getSupportedMessage() { - logger.debug("Creating new message for application command SENSOR_ALARM_SUPPORTED_GET for node {}", this.getNode().getNodeId()); + logger.debug("NODE {}: Creating new message for command SENSOR_ALARM_SUPPORTED_GET", this.getNode().getNodeId()); if (this.getNode().getManufacturer() == 0x010F && this.getNode().getDeviceType() == 0x0501) { - logger.warn("Detected Fibaro FGBS001 Universal Sensor - this device fails to respond to SENSOR_ALARM_GET and SENSOR_ALARM_SUPPORTED_GET."); + logger.warn("NODE {}: Detected Fibaro FGBS001 Universal Sensor - this device fails to respond to SENSOR_ALARM_GET and SENSOR_ALARM_SUPPORTED_GET.", this.getNode().getNodeId()); return null; } if (this.getNode().getManufacturer() == 0x010F && this.getNode().getDeviceType() == 0x0600) { - logger.warn("Detected Fibaro FGWPE Wall Plug - this device fails to respond to SENSOR_ALARM_GET and SENSOR_ALARM_SUPPORTED_GET."); + logger.warn("NODE {}: Detected Fibaro FGWPE Wall Plug - this device fails to respond to SENSOR_ALARM_GET and SENSOR_ALARM_SUPPORTED_GET.", this.getNode().getNodeId()); return null; } @@ -227,19 +255,12 @@ public SerialMessage getSupportedMessage() { * Initializes the alarm sensor command class. Requests the supported alarm types. */ @Override - public Collection initialize() { + public Collection initialize(boolean refresh) { ArrayList result = new ArrayList(); - - if (this.getNode().getManufacturer() == 0x010F && this.getNode().getDeviceType() == 0x0501) { - logger.warn("Detected Fibaro FGBS001 Universal Sensor - this device fails to respond to SENSOR_ALARM_GET and SENSOR_ALARM_SUPPORTED_GET."); - return result; + // If we're already initialized, then don't do it again unless we're refreshing + if(refresh == true || initialiseDone == false) { + result.add(this.getSupportedMessage()); } - if (this.getNode().getManufacturer() == 0x010F && this.getNode().getDeviceType() == 0x0600) { - logger.warn("Detected Fibaro FGWPE Wall Plug - this device fails to respond to SENSOR_ALARM_GET and SENSOR_ALARM_SUPPORTED_GET."); - return result; - } - - result.add(this.getSupportedMessage()); return result; } @@ -247,17 +268,30 @@ public Collection initialize() { * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { ArrayList result = new ArrayList(); - - for (AlarmType alarmType : this.alarms) { - result.add(getMessage(alarmType)); - if (this.getNode().getManufacturer() == 0x010F && this.getNode().getDeviceType() == 0x0700) { - logger.warn("Detected Fibaro FGK - 101 Door / Window sensor, only requesting alarm type {}.", alarmType.getLabel()); - break; + + // If we want to refresh, then reset the init flag on all sensors + if(refresh == true) { + logger.debug("====---- Resetting init flag!"); + for (Map.Entry entry : this.alarms.entrySet()) { + entry.getValue().resetInitialised(); } } - + + logger.debug("RESET IS {}", refresh); + for (Map.Entry entry : this.alarms.entrySet()) { + logger.debug("NODE {}: ====---- Checking alarm {} - init {}", this.getNode().getNodeId(), entry.getValue().getAlarmType(), entry.getValue().getInitialised()); + if(entry.getValue().getInitialised() == false) { + // TODO: This bodge should be configured through the database + if (this.getNode().getManufacturer() == 0x010F && this.getNode().getDeviceType() == 0x0700) { + logger.warn("NODE {}: Detected Fibaro FGK - 101 Door / Window sensor, only requesting alarm type {}.", this.getNode().getNodeId(), entry.getValue().getAlarmType().getLabel()); + break; + } + result.add(getMessage(entry.getValue().getAlarmType())); + } + } + return result; } @@ -266,16 +300,24 @@ public Collection getDynamicValues() { * Z-Wave AlarmType enumeration. The alarm type indicates the type * of alarm that is reported. * @author Jan-Willem Spuij + * @author Chris Jackson * @since 1.3.0 */ - @XStreamAlias("alarmType") + @XStreamAlias("alarmSensorType") public enum AlarmType { GENERAL(0, "General"), SMOKE(1, "Smoke"), CARBON_MONOXIDE(2, "Carbon Monoxide"), CARBON_DIOXIDE(3, "Carbon Dioxide"), HEAT(4, "Heat"), - FLOOD(5, "Flood"); + FLOOD(5, "Flood"), + ACCESS_CONTROL(6, "Access Control"), + BURGLAR(7, "Burglar"), + POWER_MANAGEMENT(8, "Power Management"), + SYSTEM(9, "System"), + EMERGENCY(10, "Emergency"), + COUNT(11, "Count"); + /** * A mapping between the integer code and its corresponding Alarm type @@ -326,8 +368,38 @@ public String getLabel() { return label; } } - - + + /** + * Class to hold alarm state + * @author Chris Jackson + */ + @XStreamAlias("alarmSensor") + private static class Alarm { + AlarmType alarmType; + @XStreamOmitField + boolean initialised = false; + + public Alarm(AlarmType type) { + alarmType = type; + } + + public AlarmType getAlarmType() { + return alarmType; + } + + public void setInitialised() { + initialised = true; + } + + public void resetInitialised() { + initialised = false; + } + + public boolean getInitialised() { + return initialised; + } + } + /** * Z-Wave Alarm Sensor Event class. Indicates that an alarm value * changed. diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveApplicationStatusClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveApplicationStatusClass.java index 733b4ce0f6f..a03bdc3e2ac 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveApplicationStatusClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveApplicationStatusClass.java @@ -12,11 +12,11 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; +import org.openhab.binding.zwave.internal.protocol.ZWaveNodeState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -90,7 +90,7 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, scheduler.schedule(new Runnable() { @Override public void run() { - if (node== null || node.getNodeStage() != NodeStage.DONE) + if (node == null || node.getNodeState() != ZWaveNodeState.ALIVE) return; controller.pollNode(node); diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAssociationCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAssociationCommandClass.java index e33c0b2934b..29fea4aa6f5 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAssociationCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveAssociationCommandClass.java @@ -9,6 +9,7 @@ package org.openhab.binding.zwave.internal.protocol.commandclass; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,7 +38,8 @@ * @since 1.4.0 */ @XStreamAlias("associationCommandClass") -public class ZWaveAssociationCommandClass extends ZWaveCommandClass { +public class ZWaveAssociationCommandClass extends ZWaveCommandClass + implements ZWaveCommandClassInitialization { @XStreamOmitField private static final Logger logger = LoggerFactory.getLogger(ZWaveAssociationCommandClass.class); @@ -58,9 +60,12 @@ public class ZWaveAssociationCommandClass extends ZWaveCommandClass { @XStreamOmitField private AssociationGroup pendingAssociation = null; - //this will be set when we query a node for the number of groups it supports + // This will be set when we query a node for the number of groups it supports private int maxGroups = 0; + @XStreamOmitField + private boolean initialiseDone = false; + /** * Creates a new instance of the ZWaveAssociationCommandClass class. * @@ -219,13 +224,18 @@ protected void processAssociationReport(SerialMessage serialMessage, int offset) */ protected void processGroupingsReport(SerialMessage serialMessage, int offset) { maxGroups = serialMessage.getMessagePayloadByte(offset + 1); - logger.debug("NODE {} processGroupingsReport number of groups {}", getNode().getNodeId(), maxGroups); - //Start the process to query these nodes - updateAssociationsNode = 1; - configAssociations.clear(); - SerialMessage sm = getAssociationMessage(updateAssociationsNode); - if(sm != null) - this.getController().sendData(sm); + logger.debug("NODE {}: processGroupingsReport number of groups {}", getNode(), maxGroups); + + initialiseDone = true; + + // Start the process to query these nodes +// updateAssociationsNode = 1; + +// configAssociations.clear(); +// SerialMessage sm = getAssociationMessage(updateAssociationsNode); +// if(sm != null) { +// this.getController().sendData(sm); +// } } /** @@ -241,7 +251,7 @@ public SerialMessage setAssociationMessage(int group, int node) { logger.debug("NODE {}: Creating new message for application command ASSOCIATIONCMD_SET", this.getNode() .getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, - SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Set); + SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 4, (byte) getCommandClass().getKey(), (byte) ASSOCIATIONCMD_SET, (byte) (group & 0xff), (byte) (node & 0xff) }; @@ -263,7 +273,7 @@ public SerialMessage removeAssociationMessage(int group, int node) { logger.debug("NODE {}: Creating new message for application command ASSOCIATIONCMD_REMOVE", this.getNode() .getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, - SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Set); + SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 4, (byte) getCommandClass().getKey(), (byte) ASSOCIATIONCMD_REMOVE, (byte) (group & 0xff), (byte) (node & 0xff) }; @@ -283,13 +293,13 @@ public SerialMessage getAssociationMessage(int group) { logger.debug("NODE {}: Creating new message for application command ASSOCIATIONCMD_GET group {}", this.getNode() .getNodeId(), group); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, - SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); + SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 3, (byte) getCommandClass().getKey(), (byte) ASSOCIATIONCMD_GET, (byte) (group & 0xff) }; result.setMessagePayload(newPayload); return result; } - + /** * Gets a SerialMessage with the ASSOCIATIONCMD_GROUPINGSGET command * @@ -299,7 +309,7 @@ public SerialMessage getGroupingsMessage() { logger.debug("NODE {}: Creating new message for application command ASSOCIATIONCMD_GROUPINGSGET", this.getNode() .getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, - SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); + SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), (byte) ASSOCIATIONCMD_GROUPINGSGET }; result.setMessagePayload(newPayload); @@ -316,11 +326,13 @@ public SerialMessage getGroupingsMessage() { * a group with no members. */ public void getAllAssociations() { - SerialMessage serialMessage = getGroupingsMessage(); - if(serialMessage != null) + updateAssociationsNode = 1; + SerialMessage serialMessage = getAssociationMessage(updateAssociationsNode); + if(serialMessage != null) { this.getController().sendData(serialMessage); + } } - + /** * Returns a list of nodes that are currently members of the association * group. This method only returns the list that is currently in the @@ -333,8 +345,9 @@ public void getAllAssociations() { * @return List of nodes in the group */ public List getGroupMembers(int group) { - if(configAssociations.get(group) == null) - return null; + if(configAssociations.get(group) == null) { + return new ArrayList(); + } return configAssociations.get(group).getNodes(); } @@ -346,6 +359,14 @@ public int getGroupCount() { return configAssociations.size(); } + /** + * Returns the maximum number of association groups + * @return Number of association groups + */ + public int getMaxGroups() { + return maxGroups; + } + /** * ZWave association group received event. * Send from the association members to the binding @@ -386,4 +407,15 @@ public void addMember(int member) { members.add(member); } } + + @Override + public Collection initialize(boolean refresh) { + ArrayList result = new ArrayList(); + // If we're already initialized, then don't do it again unless we're refreshing + if(refresh == true || initialiseDone == false) { + result.add(this.getGroupingsMessage()); + } + + return result; + } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBasicCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBasicCommandClass.java index 04fb28a1c6a..ca20e7e3d72 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBasicCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBasicCommandClass.java @@ -8,6 +8,7 @@ */ package org.openhab.binding.zwave.internal.protocol.commandclass; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; @@ -41,7 +42,9 @@ public class ZWaveBasicCommandClass extends ZWaveCommandClass implements ZWaveBa private static final int BASIC_SET = 0x01; private static final int BASIC_GET = 0x02; private static final int BASIC_REPORT = 0x03; - + + private boolean isGetSupported = true; + /** * Creates a new instance of the ZWaveBasicCommandClass class. * @param node the node this command class belongs to @@ -68,13 +71,11 @@ public CommandClass getCommandClass() { @Override public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { - logger.trace("Handle Message Basic Request"); - logger.debug(String.format("Received Basic Request for Node ID = %d", this.getNode().getNodeId())); + logger.debug("NODE {}: Received Basic Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { case BASIC_SET: - logger.trace("Process Basic Set"); - logger.debug("Basic Set sent to the controller will be processed as Basic Report"); + logger.debug("NODE {}: Basic Set sent to the controller will be processed as Basic Report", this.getNode().getNodeId()); // Now, some devices report their value as a basic set. For instance the Fibaro FGK - 101 Door / Window sensor. // Process this as if it was a value report. processBasicReport(serialMessage, offset, endpoint); @@ -83,7 +84,7 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, logger.warn(String.format("Command 0x%02X not implemented.", command)); return; case BASIC_REPORT: - logger.trace("Process Basic Report"); + logger.trace("NODE {}: Process Basic Report", this.getNode().getNodeId()); processBasicReport(serialMessage, offset, endpoint); break; default: @@ -103,7 +104,7 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, protected void processBasicReport(SerialMessage serialMessage, int offset, int endpoint) { int value = serialMessage.getMessagePayloadByte(offset + 1); - logger.debug(String.format("Basic report from nodeId = %d, value = 0x%02X", this.getNode().getNodeId(), value)); + logger.debug(String.format("NODE %d: Basic report, value = 0x%02X", this.getNode().getNodeId(), value)); ZWaveCommandClassValueEvent zEvent = new ZWaveCommandClassValueEvent(this.getNode().getNodeId(), endpoint, this.getCommandClass(), value); this.getController().notifyEventListeners(zEvent); } @@ -113,7 +114,12 @@ protected void processBasicReport(SerialMessage serialMessage, int offset, * @return the serial message */ public SerialMessage getValueMessage() { - logger.debug("Creating new message for application command BASIC_GET for node {}", this.getNode().getNodeId()); + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + + logger.debug("NODE {}: Creating new message for application command BASIC_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, @@ -122,6 +128,15 @@ public SerialMessage getValueMessage() { result.setMessagePayload(newPayload); return result; } + + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } /** * Gets a SerialMessage with the BASIC SET command @@ -129,7 +144,7 @@ public SerialMessage getValueMessage() { * @return the serial message */ public SerialMessage setValueMessage(int level) { - logger.debug("Creating new message for application command BASIC_SET for node {}", this.getNode().getNodeId()); + logger.debug("NODE {}: Creating new message for application command BASIC_SET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Set); byte[] newPayload = { (byte) this.getNode().getNodeId(), 3, diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBatteryCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBatteryCommandClass.java index 09888522812..d6df5074b8a 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBatteryCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBatteryCommandClass.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.Collection; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; @@ -18,7 +19,6 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,9 +43,15 @@ public class ZWaveBatteryCommandClass extends ZWaveCommandClass implements ZWave private static final int BATTERY_GET = 0x02; private static final int BATTERY_REPORT = 0x03; - + private Integer batteryLevel = null; + private Boolean batteryLow = null; + + @XStreamOmitField + private boolean dynamicDone = false; + private boolean isGetSupported = true; + /** * Creates a new instance of the ZWaveBatteryCommandClass class. * @param node the node this command class belongs to @@ -72,26 +78,46 @@ public CommandClass getCommandClass() { @Override public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { - logger.trace("Handle Message Battery Request"); - logger.debug("Node {}: Received Battery Request", this.getNode().getNodeId()); + logger.debug("NODE {}: Received Battery Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { case BATTERY_GET: - logger.warn(String.format("Command 0x%02X not implemented.", command)); + logger.warn("Command {} not implemented.", command); return; case BATTERY_REPORT: logger.trace("Process Battery Report"); - batteryLevel = serialMessage.getMessagePayloadByte(offset + 1); - logger.debug(String.format("Node %d: Battery report value = 0x%02X", this.getNode().getNodeId(), batteryLevel)); + if(serialMessage.getMessagePayload().length < offset + 1) { + logger.error("NODE {}: Battery report length too short"); + return; + } + + batteryLevel = serialMessage.getMessagePayloadByte(offset + 1); + logger.debug("NODE {}: Battery report value = {}", this.getNode().getNodeId(), batteryLevel); + + // A Battery level of 255 means battery low. + // Set battery level to 0 + if(batteryLevel == 255) { + batteryLevel = 0; + batteryLow = true; + logger.warn("NODE {}: BATTERY LOW!", this.getNode().getNodeId()); + } + else { + batteryLow = false; + } + + // If the battery level is outside bounds, then we don't know what's up! + if(batteryLevel < 0 || batteryLevel > 100) { + logger.warn("NODE {}: Battery state unknown ({})!", this.getNode().getNodeId(), batteryLevel); + batteryLevel = null; + } ZWaveCommandClassValueEvent zEvent = new ZWaveCommandClassValueEvent(this.getNode().getNodeId(), endpoint, this.getCommandClass(), batteryLevel); this.getController().notifyEventListeners(zEvent); - if (this.getNode().getNodeStage() != NodeStage.DONE) - this.getNode().advanceNodeStage(NodeStage.DONE); + dynamicDone = true; break; default: - logger.warn(String.format("Unsupported Command 0x%02X for command class %s (0x%02X).", + logger.warn(String.format("Unsupported Command 0x%02X for command class %s (0x%02X).", command, this.getCommandClass().getLabel(), this.getCommandClass().getKey())); @@ -103,7 +129,12 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, * @return the serial message */ public SerialMessage getValueMessage() { - logger.debug("Node {}: Creating new message for application command BATTERY_GET", this.getNode().getNodeId()); + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + + logger.debug("NODE {}: Creating new message for application command BATTERY_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, @@ -112,24 +143,50 @@ public SerialMessage getValueMessage() { result.setMessagePayload(newPayload); return result; } + + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } /** * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { + if (refresh == true) { + dynamicDone = false; + } + + if (dynamicDone == true) { + return null; + } + ArrayList result = new ArrayList(); - result.add(getValueMessage()); - return result; } - + /** * Returns the current battery level. If the battery level is unknown, returns null - * @return + * @return battery level */ public Integer getBatteryLevel() { return batteryLevel; } + + /** + * Returns the current battery warning state. + * @return true if device is saying battery is low + */ + public Boolean getBatteryLow() { + if(batteryLow == null) { + return false; + } + return batteryLow; + } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBinarySensorCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBinarySensorCommandClass.java index ba5fc587375..5cce5d03cba 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBinarySensorCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBinarySensorCommandClass.java @@ -13,6 +13,7 @@ import java.util.HashMap; import java.util.Map; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; @@ -20,7 +21,6 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,7 +46,12 @@ public class ZWaveBinarySensorCommandClass extends ZWaveCommandClass implements private static final int SENSOR_BINARY_GET = 0x02; private static final int SENSOR_BINARY_REPORT = 0x03; - + + @XStreamOmitField + private boolean dynamicDone = false; + + private boolean isGetSupported = true; + /** * Creates a new instance of the ZWaveBinarySensorCommandClass class. * @param node the node this command class belongs to @@ -78,7 +83,7 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, int command = serialMessage.getMessagePayloadByte(offset); switch (command) { case SENSOR_BINARY_GET: - logger.warn(String.format("NODE %d: Command 0x%02X not implemented.", this.getNode().getNodeId(), command)); + logger.warn("NODE {}: Command {} not implemented.", this.getNode().getNodeId(), command); return; case SENSOR_BINARY_REPORT: logger.trace("Process Sensor Binary Report"); @@ -94,13 +99,12 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, sensorType = SensorType.UNKNOWN; } - logger.debug(String.format("NODE %d: Sensor Binary report, type=%s, value=0x%02X", this.getNode().getNodeId(), sensorType.getLabel(), value)); + logger.debug("NODE {}: Sensor Binary report, type={}, value={}", this.getNode().getNodeId(), sensorType.getLabel(), value); ZWaveBinarySensorValueEvent zEvent = new ZWaveBinarySensorValueEvent(this.getNode().getNodeId(), endpoint, sensorType, value); this.getController().notifyEventListeners(zEvent); - if (this.getNode().getNodeStage() != NodeStage.DONE) - this.getNode().advanceNodeStage(NodeStage.DONE); + dynamicDone = true; break; default: logger.warn(String.format("NODE %d: Unsupported Command 0x%02X for command class %s (0x%02X).", @@ -116,6 +120,11 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, * @return the serial message */ public SerialMessage getValueMessage() { + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + logger.debug("NODE {}: Creating new message for application command SENSOR_BINARY_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] newPayload = { (byte) this.getNode().getNodeId(), @@ -132,19 +141,28 @@ public SerialMessage getValueMessage() { result.setMessagePayload(newPayload); return result; } - + + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } + /** * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { ArrayList result = new ArrayList(); - - result.add(getValueMessage()); - + if(refresh == true || dynamicDone == false) { + result.add(getValueMessage()); + } return result; } - + /** * {@inheritDoc} */ @@ -159,7 +177,7 @@ public int getMaxVersion() { * @author Chris Jackson * @since 1.5.0 */ - @XStreamAlias("sensorType") + @XStreamAlias("binarySensorType") public enum SensorType { UNKNOWN(0x00, "Unknown"), GENERAL(0x01, "General Purpose"), diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBinarySwitchCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBinarySwitchCommandClass.java index 49e2f3d55f8..2cef0a7129b 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBinarySwitchCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveBinarySwitchCommandClass.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.Collection; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; @@ -18,7 +19,6 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +43,12 @@ public class ZWaveBinarySwitchCommandClass extends ZWaveCommandClass implements private static final int SWITCH_BINARY_SET = 0x01; private static final int SWITCH_BINARY_GET = 0x02; private static final int SWITCH_BINARY_REPORT = 0x03; - + + @XStreamOmitField + private boolean dynamicDone = false; + + private boolean isGetSupported = true; + /** * Creates a new instance of the ZWaveBinarySwitchCommandClass class. * @param node the node this command class belongs to @@ -82,14 +87,13 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, processSwitchBinaryReport(serialMessage, offset, endpoint); break; case SWITCH_BINARY_GET: - logger.warn(String.format("Command 0x%02X not implemented.", command)); + logger.warn("Command {} not implemented.", command); return; case SWITCH_BINARY_REPORT: logger.trace("Process Switch Binary Report"); processSwitchBinaryReport(serialMessage, offset, endpoint); - if (this.getNode().getNodeStage() != NodeStage.DONE) - this.getNode().advanceNodeStage(NodeStage.DONE); + dynamicDone = true; break; default: logger.warn(String.format("Unsupported Command 0x%02X for command class %s (0x%02X).", @@ -108,7 +112,7 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, protected void processSwitchBinaryReport(SerialMessage serialMessage, int offset, int endpoint) { int value = serialMessage.getMessagePayloadByte(offset + 1); - logger.debug(String.format("Switch Binary report from nodeId = %d, value = 0x%02X", this.getNode().getNodeId(), value)); + logger.debug(String.format("NODE %d: Switch Binary report, value = 0x%02X", this.getNode().getNodeId(), value)); ZWaveCommandClassValueEvent zEvent = new ZWaveCommandClassValueEvent(this.getNode().getNodeId(), endpoint, this.getCommandClass(), value); this.getController().notifyEventListeners(zEvent); } @@ -118,7 +122,7 @@ protected void processSwitchBinaryReport(SerialMessage serialMessage, int offset * @return the serial message */ public SerialMessage getValueMessage() { - logger.debug("Creating new message for application command SWITCH_BINARY_GET for node {}", this.getNode().getNodeId()); + logger.debug("NODE {}: Creating new message for application command SWITCH_BINARY_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, @@ -127,14 +131,19 @@ public SerialMessage getValueMessage() { result.setMessagePayload(newPayload); return result; } - + /** * Gets a SerialMessage with the SWITCH_BINARY_SET command * @param the level to set. 0 is mapped to off, > 0 is mapped to on. * @return the serial message */ public SerialMessage setValueMessage(int level) { - logger.debug("Creating new message for application command SWITCH_BINARY_SET for node {}", this.getNode().getNodeId()); + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + + logger.debug("NODE {}: Creating new message for application command SWITCH_BINARY_SET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Set); byte[] newPayload = { (byte) this.getNode().getNodeId(), 3, @@ -146,15 +155,25 @@ public SerialMessage setValueMessage(int level) { return result; } + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } + /** * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { ArrayList result = new ArrayList(); - result.add(getValueMessage()); - + if(refresh == true || dynamicDone == false) { + result.add(getValueMessage()); + } return result; } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCRC16EncapsulationCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCRC16EncapsulationCommandClass.java new file mode 100644 index 00000000000..4a92efefc28 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCRC16EncapsulationCommandClass.java @@ -0,0 +1,154 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.zwave.internal.protocol.commandclass; + +import java.nio.ByteBuffer; +import java.util.Arrays; + +import org.openhab.binding.zwave.internal.protocol.SerialMessage; +import org.openhab.binding.zwave.internal.protocol.ZWaveController; +import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; +import org.openhab.binding.zwave.internal.protocol.ZWaveNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamOmitField; + +/** + * Handles the CRC 16 Encapsulation Command command class. + * + * @author Hans Vanbellingen + * @since 1.7.0 + */ +@XStreamAlias("crc16EncapsulationCommandClass") +public class ZWaveCRC16EncapsulationCommandClass extends ZWaveCommandClass { + + @XStreamOmitField + private static final Logger logger = LoggerFactory.getLogger(ZWaveCRC16EncapsulationCommandClass.class); + + /** + * Creates a new instance of the ZWaveMultiCommandCommandClass class. + * + * @param node + * the node this command class belongs to + * @param controller + * the controller to use + * @param endpoint + * the endpoint this Command class belongs to + */ + public ZWaveCRC16EncapsulationCommandClass(ZWaveNode node, ZWaveController controller, ZWaveEndpoint endpoint) { + super(node, controller, endpoint); + } + + /** + * {@inheritDoc} + */ + @Override + public CommandClass getCommandClass() { + return CommandClass.CRC_16_ENCAP; + } + + /** + * {@inheritDoc} + */ + @Override + public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpointId) { + logger.debug("NODE {}: Received CRC 16 Encapsulation Request", this.getNode().getNodeId()); + int command = serialMessage.getMessagePayloadByte(offset); + switch (command) { + case 0x01: // crc 16 Encapsulation + handleCRC16EncapResponse(serialMessage, offset + 1); + break; + } + } + + /** + * Handle the crc16 encapsulated message. This processes the received frame, + * checks the crc and forwards to the real command class. + * + * @param serialMessage + * The received message + * @param offset + * The starting offset into the payload + */ + private void handleCRC16EncapResponse(SerialMessage serialMessage, int offset) { + logger.trace("Process CRC16 Encapsulation"); + + // calculate CRC + byte[] payload = serialMessage.getMessagePayload(); + byte[] messageCrc = Arrays.copyOfRange(payload, payload.length - 2, payload.length); + byte[] tocheck = Arrays.copyOfRange(payload, offset - 2, payload.length - 2); + + short calculatedCrc = crc_ccit(tocheck); + // check if messageCrc = calculatedCrc + ByteBuffer byteBuffer = ByteBuffer.allocate(2); + byteBuffer.putShort(calculatedCrc); + if (!Arrays.equals(messageCrc, byteBuffer.array())) { + logger.error("NODE {}: CRC check failed message contains {} but should be {}", + this.getNode().getNodeId(), SerialMessage.bb2hex(messageCrc), SerialMessage.bb2hex(byteBuffer.array())); + return; + } + + // Execute underlying command + CommandClass commandClass; + ZWaveCommandClass zwaveCommandClass; + int commandClassCode = serialMessage.getMessagePayloadByte(offset); + commandClass = CommandClass.getCommandClass(commandClassCode); + if (commandClass == null) { + logger.error(String.format("NODE %d: Unsupported command class 0x%02x", this.getNode().getNodeId(), commandClassCode)); + } else { + zwaveCommandClass = this.getNode().getCommandClass(commandClass); + + // Apparently, this node supports a command class that we did not + // get (yet) during initialization. + // Let's add it now then to support handling this message. + if (zwaveCommandClass == null) { + logger.debug(String.format("NODE %d: Command class %s (0x%02x) not found, trying to add it.", + getNode().getNodeId(), commandClass.getLabel(), commandClass.getKey())); + + zwaveCommandClass = ZWaveCommandClass.getInstance(commandClass.getKey(), getNode(), getController()); + + if (zwaveCommandClass != null) { + logger.debug(String.format("NODE %d: Adding command class %s (0x%02x)", + getNode().getNodeId(), commandClass.getLabel(), commandClass.getKey())); + getNode().addCommandClass(zwaveCommandClass); + } + } + + if (zwaveCommandClass == null) { + logger.error(String.format("NODE %d: CommandClass %s (0x%02x) not implemented.", + this.getNode().getNodeId(), commandClass.getLabel(), commandClassCode)); + } else { + logger.debug(String.format("NODE %d: Calling handleApplicationCommandRequest.", + this.getNode().getNodeId())); + zwaveCommandClass.handleApplicationCommandRequest(serialMessage, offset+1, 0); + } + } + } + + private short crc_ccit(final byte[] args) { + int crc = 0x1D0F; + int polynomial = 0x1021; + for (byte b : args) { + for (int i = 0; i < 8; i++) { + boolean bit = ((b >> (7 - i) & 1) == 1); + boolean c15 = ((crc >> 15 & 1) == 1); + crc <<= 1; + // If coefficient of bit and remainder polynomial = 1 xor crc with polynomial + if (c15 ^ bit) { + crc ^= polynomial; + } + } + } + + crc &= 0xffff; + return (short) crc; + } +} diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClass.java index 52248331f8c..2216357803e 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClass.java @@ -16,10 +16,12 @@ import java.util.Map; import java.lang.NumberFormatException; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; +import org.openhab.binding.zwave.internal.protocol.commandclass.proprietary.FibaroFGRM222CommandClass; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -139,7 +141,17 @@ public void setVersion(int version) { public int getMaxVersion () { return MAX_SUPPORTED_VERSION; } - + + /** + * Set options for this command class. + * Options are provided from the device configuration database + * @param options class + * @return true if options set ok + */ + public boolean setOptions (ZWaveDbCommandClass options) { + return false; + } + /** * Returns the number of instances of this command class * in case the node supports the MULTI_INSTANCE command class (Version 1). @@ -148,7 +160,7 @@ public int getMaxVersion () { public int getInstances() { return instances; } - + /** * Returns the number of instances of this command class * in case the node supports the MULTI_INSTANCE command class (Version 1). @@ -157,13 +169,13 @@ public int getInstances() { public void setInstances(int instances) { this.instances = instances; } - + /** * Returns the command class. * @return command class */ public abstract CommandClass getCommandClass(); - + /** * Handles an incoming application command request. * @param serialMessage the incoming message to process. @@ -183,31 +195,34 @@ public void setInstances(int instances) { public static ZWaveCommandClass getInstance(int i, ZWaveNode node, ZWaveController controller) { return ZWaveCommandClass.getInstance(i, node, controller, null); } - + /** * Gets an instance of the right command class. * Returns null if the command class is not found. - * @param i the code to instantiate + * @param classId the code to instantiate * @param node the node this instance commands. * @param controller the controller to send messages to. * @param endpoint the endpoint this Command class belongs to * @return the ZWaveCommandClass instance that was instantiated, null otherwise */ - public static ZWaveCommandClass getInstance(int i, ZWaveNode node, ZWaveController controller, ZWaveEndpoint endpoint) { - logger.debug(String.format("Creating new instance of command class 0x%02X", i)); + public static ZWaveCommandClass getInstance(int classId, ZWaveNode node, ZWaveController controller, ZWaveEndpoint endpoint) { try { - CommandClass commandClass = CommandClass.getCommandClass(i); + CommandClass commandClass = CommandClass.getCommandClass(classId); + if (commandClass != null && commandClass.equals(CommandClass.MANUFACTURER_PROPRIETARY)){ + commandClass = CommandClass.getCommandClass(node.getManufacturer(), node.getDeviceType()); + } if (commandClass == null) { - logger.warn(String.format("Unsupported command class 0x%02x", i)); + logger.warn(String.format("NODE %d: Unknown command class 0x%02x", node.getNodeId(), classId)); return null; } Class commandClassClass = commandClass.getCommandClassClass(); if (commandClassClass == null) { - logger.warn(String.format("Unsupported command class %s (0x%02x)", commandClass.getLabel(), i, endpoint)); + logger.warn("NODE {}: Unsupported command class {}", node.getNodeId(), commandClass.getLabel(), classId); return null; } - + logger.debug("NODE {}: Creating new instance of command class {}", node.getNodeId(), commandClass.getLabel()); + Constructor constructor = commandClassClass.getConstructor(ZWaveNode.class, ZWaveController.class, ZWaveEndpoint.class); return constructor.newInstance(new Object[] {node, controller, endpoint}); } catch (InstantiationException e) { @@ -217,7 +232,7 @@ public static ZWaveCommandClass getInstance(int i, ZWaveNode node, ZWaveControll } catch (NoSuchMethodException e) { } catch (SecurityException e) { } - logger.error(String.format("Error instantiating command class 0x%02x", i)); + logger.error(String.format("NODE %d: Error instantiating command class 0x%02x", node.getNodeId(), classId)); return null; } @@ -378,6 +393,10 @@ public enum CommandClass { SCHEDULE_ENTRY_LOCK(0x4E,"SCHEDULE_ENTRY_LOCK",null), BASIC_WINDOW_COVERING(0x50,"BASIC_WINDOW_COVERING",null), MTP_WINDOW_COVERING(0x51,"MTP_WINDOW_COVERING",null), + CRC_16_ENCAP(0x56,"CRC_16_ENCAP",ZWaveCRC16EncapsulationCommandClass.class), + ASSOCIATION_GROUP_INFO(0x59,"ASSOCIATION_GROUP_INFO",null), + DEVICE_RESET_LOCALLY(0x5a,"DEVICE_RESET_LOCALLY",null), + ZWAVE_PLUS_INFO(0x5e,"ZWAVE_PLUS_INFO",null), MULTI_INSTANCE(0x60,"MULTI_INSTANCE",ZWaveMultiInstanceCommandClass.class), DOOR_LOCK(0x62,"DOOR_LOCK",null), USER_CODE(0x63,"USER_CODE",null), @@ -408,6 +427,9 @@ public enum CommandClass { MULTI_INSTANCE_ASSOCIATION(0x8E,"MULTI_INSTANCE_ASSOCIATION",null), MULTI_CMD(0x8F,"MULTI_CMD",ZWaveMultiCommandCommandClass.class), ENERGY_PRODUCTION(0x90,"ENERGY_PRODUCTION",null), + // Note that MANUFACTURER_PROPRIETARY shouldn't be instantiated directly + // The getInstance method will catch this and translate to the correct + // class for the device. MANUFACTURER_PROPRIETARY(0x91,"MANUFACTURER_PROPRIETARY",null), SCREEN_MD(0x92,"SCREEN_MD",null), SCREEN_ATTRIBUTES(0x93,"SCREEN_ATTRIBUTES",null), @@ -423,7 +445,10 @@ public enum CommandClass { SILENCE_ALARM(0x9D,"SILENCE_ALARM",null), SENSOR_CONFIGURATION(0x9E,"SENSOR_CONFIGURATION",null), MARK(0xEF,"MARK",null), - NON_INTEROPERABLE(0xF0,"NON_INTEROPERABLE",null); + NON_INTEROPERABLE(0xF0,"NON_INTEROPERABLE",null), + + // MANUFACTURER_PROPRIETARY class definitions are defined by the manufacturer and device id + FIBARO_FGRM_222(0x010F, 0x0301, "FIBARO_FGRM_222", FibaroFGRM222CommandClass.class); /** * A mapping between the integer code and its corresponding @@ -437,17 +462,34 @@ public enum CommandClass { */ private static Map labelToCommandClassMapping; + /** + * Get unique command class code for manufacturer and device ID. + * + * To support manufacturer specific implementations of a manufacturer proprietary command class we use the + * manufacturer and the device id to generate a unique key. + * + * @param manufacturer the manufacturer ID + * @param deviceId the device ID + * @return a unique command class key + */ + private static int getKeyFromManufacturerAndDeviceId(int manufacturer, int deviceId) { + return manufacturer << 16 | deviceId; + } + private int key; private String label; private Class commandClassClass; - private CommandClass(int key, String label, Class commandClassClass) { this.key = key; this.label = label; this.commandClassClass = commandClassClass; } + private CommandClass(int manufacturer, int deviceId, String label, Class commandClassClass) { + this(getKeyFromManufacturerAndDeviceId(manufacturer, deviceId), label, commandClassClass); + } + private static void initMapping() { codeToCommandClassMapping = new HashMap(); labelToCommandClassMapping = new HashMap(); @@ -470,7 +512,18 @@ public static CommandClass getCommandClass(int i) { return codeToCommandClassMapping.get(i); } - + + /** + * Lookup function based on the manufacturer and device ID. + * + * @param manufacturer the manufacturer ID + * @param deviceId the device ID + * @return enumeration value of the command class or null if there is no command class. + */ + public static CommandClass getCommandClass(int manufacturer, int deviceId) { + return getCommandClass(getKeyFromManufacturerAndDeviceId(manufacturer, deviceId)); + } + /** * Lookup function based on the command class label. * Returns null if there is no command class with that label. diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClassDynamicState.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClassDynamicState.java index 0d27fdbf743..1424e65aff1 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClassDynamicState.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClassDynamicState.java @@ -17,15 +17,17 @@ * dynamic state information.. * For instance to support getting dynamic values from a node. * @author Jan-Willem Spuij + * @author Chris Jackson * @since 1.3.0 */ public interface ZWaveCommandClassDynamicState { /** * Gets the dynamic state information from the node. Returns queries that fetch dynamic * state information. These queries need to be completed to be able to proceed to the next - * node phase. The queries are returned so that the node can handle processing and counting + * node phase. The queries are returned so that the node can handle processing * to proceed to the next node phase. + * @param refresh if true will request all dynamic states even if they are already initialised * @return the messages with the queries for dynamic values. */ - public Collection getDynamicValues(); + public Collection getDynamicValues(boolean refresh); } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClassInitialization.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClassInitialization.java index 96a19238cf3..d9603f3ccfa 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClassInitialization.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveCommandClassInitialization.java @@ -17,6 +17,7 @@ * For instance to support getting static values from a node, or handle dependencies * on other command classes. * @author Jan-Willem Spuij + * @author Chris Jackson * @since 1.3.0 */ public interface ZWaveCommandClassInitialization { @@ -25,7 +26,8 @@ public interface ZWaveCommandClassInitialization { * to be performed. These queries need to be completed to be able to proceed to the next * node phase. The queries are returned so that the node can handle processing and counting * to proceed to the next node phase. + * @param refresh if true will request all initialised even if the class is already initialised * @return the messages with the queries for initialization. */ - public Collection initialize(); + public Collection initialize(boolean refresh); } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveConfigurationCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveConfigurationCommandClass.java index 550e28040d1..1f87ac4302f 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveConfigurationCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveConfigurationCommandClass.java @@ -13,13 +13,13 @@ import org.openhab.binding.zwave.internal.protocol.ConfigurationParameter; import org.openhab.binding.zwave.internal.protocol.SerialMessage; -import org.openhab.binding.zwave.internal.protocol.ZWaveController; -import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; -import org.openhab.binding.zwave.internal.protocol.ZWaveNode; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.event.ZWaveEvent; +import org.openhab.binding.zwave.internal.protocol.ZWaveController; +import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; +import org.openhab.binding.zwave.internal.protocol.ZWaveNode; +import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -73,7 +73,7 @@ public CommandClass getCommandClass() { */ @Override public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { - logger.debug(String.format("NODE %d: Received Configuration Request", this.getNode().getNodeId())); + logger.debug("NODE {}: Received Configuration Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { case CONFIGURATIONCMD_SET: @@ -112,13 +112,22 @@ protected void processConfigurationReport(SerialMessage serialMessage, int offse try { int value = extractValue(serialMessage.getMessagePayload(), offset + 3, size); - logger.debug(String.format("NODE %d: Node configuration report, parameter = %d, value = 0x%02X", this - .getNode().getNodeId(), parameter, value)); + logger.debug("NODE {}: Node configuration report, parameter = {}, value = {}", + this.getNode().getNodeId(), parameter, value); + + ConfigurationParameter configurationParameter; + + // Check if the parameter exists in our list + configurationParameter = this.configParameters.get(parameter); + if(configurationParameter == null) { + configurationParameter = new ConfigurationParameter(parameter, value, size); + } + else { + configurationParameter.setValue(value); + } - ConfigurationParameter configurationParameter = new ConfigurationParameter(parameter, value, size); - this.configParameters.put(parameter, configurationParameter); - + ZWaveConfigurationParameterEvent zEvent = new ZWaveConfigurationParameterEvent(this.getNode().getNodeId(), configurationParameter); this.getController().notifyEventListeners(zEvent); @@ -134,12 +143,25 @@ protected void processConfigurationReport(SerialMessage serialMessage, int offse * @return the serial message */ public SerialMessage getConfigMessage(int parameter) { - logger.debug("NODE {}: Creating new message for application command CONFIGURATIONCMD_GET", this.getNode() - .getNodeId()); + // Check if the parameter exists in our list + ConfigurationParameter configurationParameter = this.configParameters.get(parameter); + if(configurationParameter != null && configurationParameter.getWriteOnly() == true) { + logger.debug("NODE {}: CONFIGURATIONCMD_GET ignored for parameter {} - parameter is write only", + this.getNode().getNodeId(), parameter); + return null; + } + + logger.debug("NODE {}: Creating new message for application command CONFIGURATIONCMD_GET", + this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, - SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); - byte[] newPayload = { (byte) this.getNode().getNodeId(), 3, (byte) getCommandClass().getKey(), - (byte) CONFIGURATIONCMD_GET, (byte) (parameter & 0xff) }; + SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); + byte[] newPayload = { + (byte) this.getNode().getNodeId(), + 3, + (byte) getCommandClass().getKey(), + (byte) CONFIGURATIONCMD_GET, + (byte) (parameter & 0xff) + }; result.setMessagePayload(newPayload); return result; } @@ -151,10 +173,16 @@ public SerialMessage getConfigMessage(int parameter) { * @return the serial message */ public SerialMessage setConfigMessage(ConfigurationParameter parameter) { + if(parameter != null && parameter.getReadOnly() == true) { + logger.debug("NODE {}: CONFIGURATIONCMD_SET ignored for parameter {} - parameter is read only", + this.getNode().getNodeId(), parameter); + return null; + } + logger.debug("NODE {}: Creating new message for application command CONFIGURATIONCMD_SET", this.getNode() .getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, - SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Set); + SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Config); byte[] newPayload = new byte[parameter.getSize() + 6]; newPayload[0] = (byte) this.getNode().getNodeId(); newPayload[1] = (byte) (4 + parameter.getSize()); @@ -179,6 +207,44 @@ public SerialMessage setConfigMessage(ConfigurationParameter parameter) { public ConfigurationParameter getParameter(Integer index) { return this.configParameters.get(index); } + + /** + * Sets a parameter as Read Only + * Some parameters in some devices can not be written to. Trying to write them results + * in a timeout and this should be avoided. + * @param index the parameter index + * @param readOnly true if the parameter can not be read + */ + public void setParameterReadOnly(Integer index, boolean readOnly) { + ConfigurationParameter configurationParameter; + + // Check if the parameter exists in our list + configurationParameter = this.configParameters.get(index); + if(configurationParameter == null) { + configurationParameter = new ConfigurationParameter(index, 0, 1); + } + + configurationParameter.setReadOnly(readOnly); + } + + /** + * Sets a parameter as Write Only + * Some parameters in some devices can not be read. Trying to read them results + * in a timeout and this should be avoided. + * @param index the parameter index + * @param writeOnly true if the parameter can not be read + */ + public void setParameterWriteOnly(Integer index, boolean writeOnly) { + ConfigurationParameter configurationParameter; + + // Check if the parameter exists in our list + configurationParameter = this.configParameters.get(index); + if(configurationParameter == null) { + configurationParameter = new ConfigurationParameter(index, 0, 1); + } + + configurationParameter.setWriteOnly(writeOnly); + } /** * ZWave configuration parameter received event. @@ -188,18 +254,15 @@ public ConfigurationParameter getParameter(Integer index) { * @author Chris Jackson * @since 1.4.0 */ - public class ZWaveConfigurationParameterEvent extends ZWaveEvent { + public class ZWaveConfigurationParameterEvent extends ZWaveCommandClassValueEvent { - private final ConfigurationParameter parameter; - /** * Constructor. Creates a new instance of the ZWaveConfigurationParameterEvent * class. * @param nodeId the nodeId of the event. Must be set to the controller node. */ public ZWaveConfigurationParameterEvent(int nodeId, ConfigurationParameter parameter) { - super(nodeId); - this.parameter = parameter; + super(nodeId, 0, CommandClass.CONFIGURATION, parameter); } /** @@ -207,7 +270,7 @@ public ZWaveConfigurationParameterEvent(int nodeId, ConfigurationParameter param * @return the configuration parameter. */ public ConfigurationParameter getParameter() { - return parameter; + return (ConfigurationParameter) this.getValue(); } } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveGetCommands.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveGetCommands.java index 94f489b55a1..4b46996e3fe 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveGetCommands.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveGetCommands.java @@ -20,5 +20,5 @@ public interface ZWaveGetCommands { * Gets a SerialMessage with the GET command * @return the serial message */ - public SerialMessage getValueMessage() ; + public SerialMessage getValueMessage(); } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveHailCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveHailCommandClass.java index 4a3fc91f8e4..032d1ab0365 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveHailCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveHailCommandClass.java @@ -13,7 +13,7 @@ import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; -import org.openhab.binding.zwave.internal.protocol.NodeStage; +import org.openhab.binding.zwave.internal.protocol.ZWaveNodeState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,22 +60,25 @@ public CommandClass getCommandClass() { public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { logger.trace("Handle Message Manufacture Specific Request"); - logger.debug(String.format("Received Hail command for Node ID = %d", this.getNode().getNodeId())); + logger.debug("NODE {}: Received Hail command (v{})", this.getNode().getNodeId(), this.getVersion()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { case HAIL: - logger.trace("Process Hail command"); - logger.debug(String.format("Request an update of the dynamic values for node id %d", this.getNode().getNodeId())); + logger.trace("Process Hail command"); - // We only rerequest dynamic values for nodes that are completely initialized. - if (this.getNode().getNodeStage() != NodeStage.DONE) + logger.debug("NODE {}: Request an update of the dynamic values", this.getNode().getNodeId()); + + // We only re-request dynamic values for nodes that are completely initialized. + if (this.getNode().getNodeState() != ZWaveNodeState.ALIVE || this.getNode().isInitializationComplete() == false) { return; + } getController().pollNode(getNode()); break; default: - logger.warn(String.format("Unsupported Command 0x%02X for command class %s (0x%02X).", + logger.warn(String.format("NODE %d: Unsupported Command 0x%02X for command class %s (0x%02X).", + this.getNode().getNodeId(), command, this.getCommandClass().getLabel(), this.getCommandClass().getKey())); diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveManufacturerSpecificCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveManufacturerSpecificCommandClass.java index 55301e7bd45..b24fc8a9d2d 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveManufacturerSpecificCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveManufacturerSpecificCommandClass.java @@ -15,7 +15,6 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,12 +63,11 @@ public CommandClass getCommandClass() { public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { - logger.trace("Handle Message Manufacture Specific Request"); - logger.debug(String.format("NODE %d: Received Manufacture Specific Information", this.getNode().getNodeId())); + logger.debug("NODE {}: Received Manufacture Specific Information", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { case MANUFACTURER_SPECIFIC_GET: - logger.warn(String.format("NODE %d: Command 0x%02X not implemented.", this.getNode().getNodeId(), command)); + logger.warn("NODE {}: Command {} not implemented.", this.getNode().getNodeId(), command); return; case MANUFACTURER_SPECIFIC_REPORT: logger.trace("Process Manufacturer Specific Report"); @@ -85,11 +83,9 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, logger.debug(String.format("NODE %d: Manufacturer ID = 0x%04x", this.getNode().getNodeId(), this.getNode().getManufacturer())); logger.debug(String.format("NODE %d: Device Type = 0x%04x", this.getNode().getNodeId(), this.getNode().getDeviceType())); logger.debug(String.format("NODE %d: Device ID = 0x%04x", this.getNode().getNodeId(), this.getNode().getDeviceId())); - - this.getNode().advanceNodeStage(NodeStage.VERSION); break; default: - logger.warn(String.format("NODE %d: Unsupported Command 0x%02X for command class %s (0x%02X).", + logger.warn(String.format("NODE %d: Unsupported Command 0x%02X for command class %s (0x%02X).", this.getNode().getNodeId(), command, this.getCommandClass().getLabel(), @@ -102,8 +98,8 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, * @return the serial message */ public SerialMessage getManufacturerSpecificMessage() { - logger.debug("NODE {}: Creating new message for application command MANUFACTURER_SPECIFIC_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); + logger.debug("NODE {}: Creating new message for command MANUFACTURER_SPECIFIC_GET", this.getNode().getNodeId()); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMeterCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMeterCommandClass.java index 1717a0b923d..42293a66b16 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMeterCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMeterCommandClass.java @@ -10,17 +10,19 @@ import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; @@ -38,6 +40,7 @@ * * @author Ben Jones * @author Jan-Willem Spuij + * @author Chris Jackson * @since 1.4.0 */ @XStreamAlias("meterCommandClass") @@ -50,7 +53,7 @@ public class ZWaveMeterCommandClass extends ZWaveCommandClass implements ZWaveGe private static final int METER_GET = 0x01; private static final int METER_REPORT = 0x02; - // version 2 and 3 + // Version 2 and 3 private static final int METER_SUPPORTED_GET = 0x03; private static final int METER_SUPPORTED_REPORT = 0x04; private static final int METER_RESET = 0x05; @@ -58,8 +61,17 @@ public class ZWaveMeterCommandClass extends ZWaveCommandClass implements ZWaveGe private MeterType meterType = null; private final Set meterScales = new HashSet(); + @XStreamOmitField private volatile boolean canReset = false; + @XStreamOmitField + private boolean initialiseDone = false; + @XStreamOmitField + private boolean dynamicDone = false; + + private boolean isGetSupported = true; + private boolean isSupportRequestSupported = true; + /** * Creates a new instance of the ZWaveMeterCommandClass class. * @@ -95,7 +107,6 @@ public int getMaxVersion() { */ @Override public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { - logger.trace("Handle Message Meter Request"); logger.debug("NODE {}: Received Meter Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); MeterScale scale; @@ -108,15 +119,14 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, int off logger.warn("Command {} not implemented.", command); return; case METER_REPORT: - logger.trace("Process Meter Report"); - logger.debug("NODE {}: Meter report received", this.getNode().getNodeId()); + logger.trace("NODE {}: Meter report received", this.getNode().getNodeId()); if(serialMessage.getMessagePayload().length < offset+3) { - logger.error("NODE {}: Buffer too short: length={}, required={}", this.getNode().getNodeId(), + logger.error("NODE {}: Meter Report: Buffer too short: length={}, required={}", this.getNode().getNodeId(), serialMessage.getMessagePayload().length, offset+3); return; } - + meterTypeIndex = serialMessage.getMessagePayloadByte(offset + 1) & 0x1F; if (meterTypeIndex >= MeterType.values().length) { logger.warn("NODE {}: Invalid meter type {}", this.getNode().getNodeId(), meterTypeIndex); @@ -124,12 +134,10 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, int off } meterType = MeterType.getMeterType(meterTypeIndex); - logger.debug("NODE {}: Meter Type = {} ({})", this.getNode().getNodeId(), meterType.getLabel(), meterTypeIndex); int scaleIndex = (serialMessage.getMessagePayloadByte(offset + 2) & 0x18) >> 0x03; - if(this.getVersion() > 2) - { + if (this.getVersion() > 2) { // In version 3, an extra scale bit is stored in the meter type byte. scaleIndex |= ((serialMessage.getMessagePayloadByte(offset + 1) & 0x80) >> 0x05); } @@ -139,8 +147,6 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, int off logger.warn("NODE {}: Invalid meter scale {}", this.getNode().getNodeId(), scaleIndex); return; } - - logger.debug("NODE {}: Meter Scale = {} ({})", this.getNode().getNodeId(), scale.getUnit(), scale.getScale()); // add scale to the list of supported scales. if (!this.meterScales.contains(scale)) { @@ -149,19 +155,22 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, int off try { BigDecimal value = extractValue(serialMessage.getMessagePayload(), offset + 2); - logger.debug("NODE {}: Meter Value = {}", this.getNode().getNodeId(), value); + logger.debug("NODE {}: Meter: Type={}({}), Scale={}({}), Value={}", + this.getNode().getNodeId(), + meterType.getLabel(), meterTypeIndex, + scale.getUnit(), scale.getScale(), + value); ZWaveMeterValueEvent zEvent = new ZWaveMeterValueEvent(this.getNode().getNodeId(), endpoint, meterType, scale, value); this.getController().notifyEventListeners(zEvent); } catch (NumberFormatException e) { + logger.error("NODE {}: Meter Value Error {}", this.getNode().getNodeId(), e); return; } - if (this.getNode().getNodeStage() != NodeStage.DONE) { - this.getNode().advanceNodeStage(NodeStage.DONE); - } + dynamicDone = true; break; case METER_SUPPORTED_REPORT: logger.trace("Process Meter Supported Report"); @@ -181,27 +190,28 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, int off } meterType = MeterType.getMeterType(meterTypeIndex); - logger.debug("NODE {}: Identified meter type {} ({})", this.getNode().getNodeId(), meterType.getLabel(), meterTypeIndex); - + logger.debug("NODE {}: Identified meter type {}({})", this.getNode().getNodeId(), meterType.getLabel(), meterTypeIndex); + for (int i = 0; i < 8; ++i) { // scale is supported if ((supportedScales & (1 << i)) == (1 << i)) { scale = MeterScale.getMeterScale(meterType, i); - + if (scale == null) { logger.warn("NODE {}: Invalid meter scale {}", this.getNode().getNodeId(), i); continue; } - - logger.debug("NODE {}: Meter Scale = {} ({})", this.getNode().getNodeId(), scale.getUnit(), scale.getScale()); + + logger.debug("NODE {}: Meter Scale = {}({})", this.getNode().getNodeId(), scale.getUnit(), scale.getScale()); // add scale to the list of supported scales. - if (!this.meterScales.contains(scale)) + if (!this.meterScales.contains(scale)) { this.meterScales.add(scale); + } } } - this.getNode().advanceNodeStage(NodeStage.DYNAMIC); + initialiseDone = true; break; default: logger.warn(String.format("Unsupported Command 0x%02X for command class %s (0x%02X).", command, this @@ -215,6 +225,11 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, int off * @return the serial message */ public SerialMessage getValueMessage() { + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + logger.debug("NODE {}: Creating new message for application command METER_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); @@ -224,6 +239,43 @@ public SerialMessage getValueMessage() { return result; } + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + if(options.meterCanReset != null) { + canReset = options.meterCanReset; + } + + if(options.meterType != null && options.meterScale != null) { + meterType = MeterType.valueOf(options.meterType); + logger.debug("NODE {}: Set meter type {}", this.getNode().getNodeId(), meterType.getLabel()); + + List scaleList = Arrays.asList(options.meterScale.split(",")); + for (String name : scaleList) { + MeterScale scale = MeterScale.valueOf(name); + if (scale == null) { + logger.warn("NODE {}: Invalid meter scale {}", this.getNode().getNodeId(), name); + continue; + } + + logger.debug("NODE {}: Meter Scale {} = {}", this.getNode().getNodeId(), + meterType.getLabel(), scale.getUnit()); + + // Add scale to the list of supported scales. + if (!this.meterScales.contains(scale)) { + this.meterScales.add(scale); + } + } + + isSupportRequestSupported = false; + } + + return true; + } + /** * Gets a SerialMessage with the METER_GET command * @@ -249,7 +301,7 @@ public SerialMessage getSupportedMessage() { logger.debug("NODE {}: Creating new message for application command METER_SUPPORTED_GET", this.getNode() .getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, - SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); + SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), (byte) METER_SUPPORTED_GET }; result.setMessagePayload(newPayload); @@ -280,12 +332,14 @@ public SerialMessage getResetMessage() { * Initializes the meter command class. Requests the supported meter types. */ @Override - public Collection initialize() { + public Collection initialize(boolean refresh) { ArrayList result = new ArrayList(); - - if (this.getVersion() > 1) + // If we're already initialized, then don't do it again unless we're refreshing + if(isSupportRequestSupported == true && + (refresh == true || initialiseDone == false) && + this.getVersion() > 1) { result.add(this.getSupportedMessage()); - + } return result; } @@ -293,19 +347,21 @@ public Collection initialize() { * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { ArrayList result = new ArrayList(); - switch (this.getVersion()) { - case 1: - result.add(this.getValueMessage()); - break; - case 2: - case 3: - for (MeterScale scale : this.meterScales) { - result.add(this.getMessage(scale)); - } - break; + if(refresh == true || dynamicDone == false) { + switch (this.getVersion()) { + case 1: + result.add(this.getValueMessage()); + break; + case 2: + case 3: + for (MeterScale scale : this.meterScales) { + result.add(this.getMessage(scale)); + } + break; + } } return result; diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiCommandCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiCommandCommandClass.java index d50828bfbb2..bfd7d6b1975 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiCommandCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiCommandCommandClass.java @@ -29,6 +29,8 @@ public class ZWaveMultiCommandCommandClass extends ZWaveCommandClass { @XStreamOmitField private static final Logger logger = LoggerFactory.getLogger(ZWaveMultiCommandCommandClass.class); + private static final int MULTI_COMMMAND_ENCAP = 0x01; + /** * Creates a new instance of the ZWaveMultiCommandCommandClass class. * @param node the node this command class belongs to @@ -58,7 +60,7 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, logger.debug("NODE {}: Received Multi-Command Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { - case 0x01: // Multi Cmd Encapsulation + case MULTI_COMMMAND_ENCAP: // Multi Cmd Encapsulation handleMultiCommandEncapResponse(serialMessage, offset+1); break; } @@ -84,15 +86,31 @@ private void handleMultiCommandEncapResponse( int commandClassCode = serialMessage.getMessagePayloadByte(offset + 1); commandClass = CommandClass.getCommandClass(commandClassCode); if (commandClass == null) { - logger.error(String.format("NODE %d: Unsupported command class 0x%02x", this.getNode().getNodeId(), commandClassCode)); + logger.error(String.format("NODE %d: Unknown command class 0x%02x", getNode().getNodeId(), commandClassCode)); } else { - zwaveCommandClass = this.getNode().getCommandClass(commandClass); + logger.debug("NODE {}: Incoming command class {}", getNode().getNodeId(), commandClass.getLabel()); + zwaveCommandClass = getNode().getCommandClass(commandClass); + + // Apparently, this node supports a command class that we did not get (yet) during initialization. + // Let's add it now then to support handling this message. + if (zwaveCommandClass == null) { + logger.debug("NODE {}: Command class {} not found, trying to add it.", + getNode().getNodeId(), commandClass.getLabel(), commandClass.getKey()); + + zwaveCommandClass = ZWaveCommandClass.getInstance(commandClass.getKey(), getNode(), this.getController()); + + if (zwaveCommandClass != null) { + logger.debug("NODE {}: Adding command class %s", getNode().getNodeId(), commandClass.getLabel()); + getNode().addCommandClass(zwaveCommandClass); + } + } + if (zwaveCommandClass == null) { - logger.error(String.format("NODE %d: CommandClass %s (0x%02x) not implemented.", this.getNode().getNodeId(), commandClass.getLabel(), commandClassCode)); + logger.error("NODE {}: CommandClass %s not implemented.", this.getNode().getNodeId(), commandClass.getLabel()); } else { - logger.debug(String.format("NODE %d: Calling handleApplicationCommandRequest.", this.getNode().getNodeId())); + logger.debug("NODE {}: Calling handleApplicationCommandRequest.", this.getNode().getNodeId()); zwaveCommandClass.handleApplicationCommandRequest(serialMessage, offset + 2, 1); } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiInstanceCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiInstanceCommandClass.java index 6f655f86e4f..783d00b187f 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiInstanceCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiInstanceCommandClass.java @@ -8,11 +8,13 @@ */ package org.openhab.binding.zwave.internal.protocol.commandclass; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; @@ -36,7 +38,13 @@ * of the same device class on the node. Multi Channel support (version 2) * of the command class can also handle multiple instances of different * command classes. The instances are called endpoints in this version. + * + * Useful references -: + * https://groups.google.com/d/msg/openzwave/FeFNBI8GAKk/dyXAO54BiqgJ + * * @author Jan-Willem Spuij + * @author Chris Jackson + * @author Michiel Leegwater * @since 1.3.0 */ @XStreamAlias("multiInstanceCommandClass") @@ -60,10 +68,25 @@ public class ZWaveMultiInstanceCommandClass extends ZWaveCommandClass { private static final int MULTI_CHANNEL_ENDPOINT_FIND = 0x0b; private static final int MULTI_CHANNEL_ENDPOINT_FIND_REPORT = 0x0c; private static final int MULTI_CHANNEL_ENCAP = 0x0d; - + private final Map endpoints = new HashMap(); - + private boolean endpointsAreTheSameDeviceClass; + + // List of classes that DO NOT support multiple instances. + // This is used to reduce the number of requests during initialisation. + // Only add a class to this list if you are sure it doesn't support multiple instances! + @XStreamOmitField + private static final List singleInstanceClasses = Arrays.asList( + CommandClass.NO_OPERATION, + CommandClass.ASSOCIATION, + CommandClass.MULTI_INSTANCE_ASSOCIATION, + CommandClass.CONFIGURATION, + CommandClass.CLOCK, + CommandClass.WAKE_UP, + CommandClass.BATTERY + ); + /** * Creates a new instance of the ZWaveMultiInstanceCommandClass class. @@ -119,7 +142,6 @@ public Collection getEndpoints() { @Override public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpointId) { - logger.trace("Handle Message Multi-instance/Multi-channel Request"); logger.debug("NODE {}: Received Multi-instance/Multi-channel Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { @@ -128,7 +150,7 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, case MULTI_CHANNEL_CAPABILITY_GET: case MULTI_CHANNEL_ENDPOINT_FIND: case MULTI_CHANNEL_ENDPOINT_FIND_REPORT: - logger.warn(String.format("NODE %d: Command 0x%02X not implemented.", this.getNode().getNodeId(), command)); + logger.warn("NODE {}: Command {} not implemented.", this.getNode().getNodeId(), command); return; case MULTI_INSTANCE_REPORT: handleMultiInstanceReportResponse(serialMessage, offset + 1); @@ -157,58 +179,36 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, /** * Handles Multi Instance Report message. Handles Report on * the number of instances for the command class. + * This is for Version 1 of the command class. * @param serialMessage the serial message to process. - * @param offset the offset at which to start procesing. + * @param offset the offset at which to start processing. */ - private void handleMultiInstanceReportResponse(SerialMessage serialMessage, - int offset) { + private void handleMultiInstanceReportResponse(SerialMessage serialMessage, int offset) { logger.trace("Process Multi-instance Report"); int commandClassCode = serialMessage.getMessagePayloadByte(offset); int instances = serialMessage.getMessagePayloadByte(offset + 1); - if (instances == 0) { - setInstances(1); - } else - { - CommandClass commandClass = CommandClass.getCommandClass(commandClassCode); - - if (commandClass == null) { - logger.error(String.format("NODE %d: Unsupported command class 0x%02x", this.getNode().getNodeId(), commandClassCode)); - return; - } - - logger.debug(String.format("NODE %d: Requested Command Class = %s (0x%02x)", this.getNode().getNodeId(), commandClass.getLabel() , commandClassCode)); - ZWaveCommandClass zwaveCommandClass = this.getNode().getCommandClass(commandClass); - - if (zwaveCommandClass == null) { - logger.error(String.format("NODE %d: Unsupported command class %s (0x%02x)", this.getNode().getNodeId(), commandClass.getLabel(), commandClassCode)); - return; - } - - zwaveCommandClass.setInstances(instances); - logger.debug("NODE {}: Instances = {}, number of instances set.", this.getNode().getNodeId(), instances); + CommandClass commandClass = CommandClass.getCommandClass(commandClassCode); + if (commandClass == null) { + logger.error(String.format("NODE %d: Unsupported command class 0x%02x", this.getNode().getNodeId(), commandClassCode)); + return; } + + logger.debug("NODE {}: Requested Command Class = {}", this.getNode().getNodeId(), commandClass.getLabel()); - // Check how many outstanding requests we're waiting for before advancing... - int waiting = 0; - for (ZWaveCommandClass zwaveCommandClass : this.getNode().getCommandClasses()) { - // We never sent the NO_OP request, so ignore it here. - if (zwaveCommandClass.getCommandClass() == CommandClass.NO_OPERATION) - continue; - - if (zwaveCommandClass.getInstances() == 0) { - // Still waiting for an instance report of another command class. - waiting++; - logger.debug("NODE {}: Waiting for command class {}.", this.getNode().getNodeId(), zwaveCommandClass.getCommandClass().getLabel()); - } - } - if(waiting != 0) { - logger.debug("NODE {}: Waiting for {} responses.", this.getNode().getNodeId(), waiting); + ZWaveCommandClass zwaveCommandClass = this.getNode().getCommandClass(commandClass); + if (zwaveCommandClass == null) { + logger.error(String.format("NODE %d: Unsupported command class %s (0x%02x)", this.getNode().getNodeId(), commandClass.getLabel(), commandClassCode)); return; } - - // All requests received - advance node stage. - this.getNode().advanceNodeStage(NodeStage.STATIC_VALUES); + + if(instances == 0) { + logger.debug("NODE {}: Instances = 0. Setting to 1.", this.getNode().getNodeId()); + instances = 1; + } + + zwaveCommandClass.setInstances(instances); + logger.debug("NODE {}: Command class {}, has {} instance(s).", this.getNode().getNodeId(), commandClass.getLabel(), instances); } /** @@ -262,6 +262,7 @@ private void handleMultiInstanceEncapResponse( * Handles Multi Channel Endpoint Report message. Handles Report on * the number of endpoints and whether they are dynamic and/or have the * same command classes. + * This is for Version 2 of the command class. * @param serialMessage the serial message to process. * @param offset the offset at which to start processing. */ @@ -278,20 +279,21 @@ private void handleMultiChannelEndpointReportResponse( logger.debug("NODE {}: Number of endpoints = {}", this.getNode().getNodeId(), endpoints); // TODO: handle dynamically added endpoints. Have never seen such a device. - if (changingNumberOfEndpoints) + if (changingNumberOfEndpoints) { logger.warn("NODE {}: Changing number of endpoints, expect some weird behavior during multi channel handling.", this.getNode().getNodeId()); - + } + + // Add all the endpoints for (int i=1; i <= endpoints; i++) { ZWaveEndpoint endpoint = new ZWaveEndpoint(i); this.endpoints.put(i, endpoint); - if (!endpointsAreTheSameDeviceClass || i == 1) - this.getController().sendData(this.getMultiChannelCapabilityGetMessage(endpoint)); } } - + /** * Handles Multi Channel Capability Report message. Handles Report on * an endpoint and adds command classes to the endpoint. + * This is for Version 2 of the command class. * @param serialMessage the serial message to process. * @param offset the offset at which to start processing. */ @@ -310,79 +312,112 @@ private void handleMultiChannelCapabilityReportResponse(SerialMessage serialMess int endId = this.endpointsAreTheSameDeviceClass ? this.endpoints.size() : receivedEndpointId; boolean supportsBasicCommandClass = this.getNode().supportsCommandClass(CommandClass.BASIC); - + for (int endpointId = startId; endpointId <= endId; endpointId++) { + // Create a new endpoint ZWaveEndpoint endpoint = this.endpoints.get(endpointId); - - if (endpoint == null){ - logger.error("Endpoint {} not found on node {}. Cannot set command classes.", endpointId, this.getNode().getNodeId()); + if (endpoint == null) { + logger.error("NODE {}: Endpoint {} not found. Cannot set command classes.", this.getNode().getNodeId(), endpointId); continue; } - - Basic basic = this.getNode().getDeviceClass().getBasicDeviceClass(); - Generic generic = Generic.getGeneric(genericDeviceClass); - if (generic == null) { - logger.error(String.format("NODE %d: Endpoint %d has invalid device class. generic = 0x%02x, specific = 0x%02x.", - this.getNode().getNodeId(), endpoint, genericDeviceClass, specificDeviceClass)); - continue; - } - Specific specific = Specific.getSpecific(generic, specificDeviceClass); - if (specific == null) { - logger.error(String.format("NODE %d: Endpoint %d has invalid device class. generic = 0x%02x, specific = 0x%02x.", - this.getNode().getNodeId(), endpoint, genericDeviceClass, specificDeviceClass)); + + // Add the device classes + if (!updateDeviceClass(endpoint, genericDeviceClass, specificDeviceClass, dynamic)) { + // Updating device class failed, already logged, continue with next endpoint continue; } - logger.debug("NODE {}: Endpoint Id = {}", this.getNode().getNodeId(), endpointId); - logger.debug("NODE {}: Endpoints is dynamic = {}", this.getNode().getNodeId(), dynamic ? "true" : false); - logger.debug(String.format("NODE %d: Basic = %s 0x%02x", this.getNode().getNodeId(), basic.getLabel(), basic.getKey())); - logger.debug(String.format("NODE %d: Generic = %s 0x%02x", this.getNode().getNodeId(), generic.getLabel(), generic.getKey())); - logger.debug(String.format("NODE %d: Specific = %s 0x%02x", this.getNode().getNodeId(), specific.getLabel(), specific.getKey())); - - ZWaveDeviceClass deviceClass = endpoint.getDeviceClass(); - deviceClass.setBasicDeviceClass(basic); - deviceClass.setGenericDeviceClass(generic); - deviceClass.setSpecificDeviceClass(specific); - - // add basic command class, if it's also supported by the parent node. + // Add basic command class, if it's also supported by the parent node. if (supportsBasicCommandClass) { ZWaveCommandClass commandClass = new ZWaveBasicCommandClass(this.getNode(), this.getController(), endpoint); endpoint.addCommandClass(commandClass); } - - for (int i = 0; i < serialMessage.getMessagePayload().length - offset - 3; i++) { - int data = serialMessage.getMessagePayloadByte(offset + 3 + i); - if(data == 0xef ) { - // TODO: Implement control command classes - break; + + // Add all the command classes supported by this endpoint + addSupportedCommandClasses(serialMessage, offset, endpoint); + } + + if (!this.endpointsAreTheSameDeviceClass) { + for (ZWaveEndpoint ep : this.endpoints.values()) { + // only advance node stage when all endpoints are known. + if (ep.getDeviceClass().getBasicDeviceClass() == Basic.NOT_KNOWN) { + return; } - logger.debug(String.format("NODE %d: Adding command class 0x%02X to the list of supported command classes.", this.getNode().getNodeId(), data)); - ZWaveCommandClass commandClass = ZWaveCommandClass.getInstance(data, this.getNode(), this.getController(), endpoint); - - if (commandClass == null) - continue; - - endpoint.addCommandClass(commandClass); - - ZWaveCommandClass parentClass = this.getNode().getCommandClass(commandClass.getCommandClass()); - - // copy version info to endpoint classes. - if (parentClass != null) - commandClass.setVersion(parentClass.getVersion()); } } + } + + /** + * Determines the device class properties of the endpoint. + * @param endpoint The endpoint to update. + * @param genericDeviceClass The generic device class of the parent device of the endpoint + * @param specificDeviceClass The specific device class of the parent device of the endpoint + * @param dynamic True when the endpoint is dynamic. + * @return True when successful, false otherwise + */ + private boolean updateDeviceClass(ZWaveEndpoint endpoint, int genericDeviceClass, int specificDeviceClass, boolean dynamic) { + Basic basic = this.getNode().getDeviceClass().getBasicDeviceClass(); + Generic generic = Generic.getGeneric(genericDeviceClass); + if (generic == null) { + logger.error(String.format("NODE %d: Endpoint %d has invalid device class. generic = 0x%02x, specific = 0x%02x.", + this.getNode().getNodeId(), endpoint, genericDeviceClass, specificDeviceClass)); + return false; + } + Specific specific = Specific.getSpecific(generic, specificDeviceClass); + if (specific == null) { + logger.error(String.format("NODE %d: Endpoint %d has invalid device class. generic = 0x%02x, specific = 0x%02x.", + this.getNode().getNodeId(), endpoint, genericDeviceClass, specificDeviceClass)); + return false; + } + + logger.debug("NODE {}: Endpoint Id = {}", this.getNode().getNodeId(), endpoint.getEndpointId()); + logger.debug("NODE {}: Endpoints is dynamic = {}", this.getNode().getNodeId(), dynamic ? "true" : false); + logger.debug(String.format("NODE %d: Basic = %s 0x%02x", this.getNode().getNodeId(), basic.getLabel(), basic.getKey())); + logger.debug(String.format("NODE %d: Generic = %s 0x%02x", this.getNode().getNodeId(), generic.getLabel(), generic.getKey())); + logger.debug(String.format("NODE %d: Specific = %s 0x%02x", this.getNode().getNodeId(), specific.getLabel(), specific.getKey())); - if (this.endpointsAreTheSameDeviceClass) - // advance node stage. - this.getNode().advanceNodeStage(NodeStage.STATIC_VALUES); - else { - for (ZWaveEndpoint ep : this.endpoints.values()) - { - if (ep.getDeviceClass().getBasicDeviceClass() == Basic.NOT_KNOWN) // only advance node stage when all endpoints are known. - return; + ZWaveDeviceClass deviceClass = endpoint.getDeviceClass(); + deviceClass.setBasicDeviceClass(basic); + deviceClass.setGenericDeviceClass(generic); + deviceClass.setSpecificDeviceClass(specific); + + return true; + } + + /** + * Adds command classes to the endpoint based on the message from the device. + * @param serialMessage The message to get command classes from. + * @param offset The offset in the message. + * @param endpoint The endpoint + */ + private void addSupportedCommandClasses(SerialMessage serialMessage, int offset, ZWaveEndpoint endpoint) { + for (int i = 0; i < serialMessage.getMessagePayload().length - offset - 3; i++) { + // Get the command class ID + int data = serialMessage.getMessagePayloadByte(offset + 3 + i); + if (data == 0xef) { + // TODO: Implement control command classes + break; + } + + // Create the command class + ZWaveCommandClass commandClass = ZWaveCommandClass.getInstance(data, this.getNode(), this.getController(), endpoint); + if (commandClass == null) { + continue; + } + + logger.debug("NODE {}: Endpoint {}: Adding command class {}.", + this.getNode().getNodeId(), endpoint.getEndpointId(), commandClass.getCommandClass().getLabel()); + endpoint.addCommandClass(commandClass); + + ZWaveCommandClass parentClass = this.getNode().getCommandClass(commandClass.getCommandClass()); + + // Copy version info to endpoint classes. + if (parentClass != null) { + commandClass.setVersion(parentClass.getVersion()); } - // advance node stage. - this.getNode().advanceNodeStage(NodeStage.STATIC_VALUES); + + // With V2, we only have a single instance + commandClass.setInstances(1); } } @@ -391,11 +426,17 @@ private void handleMultiChannelCapabilityReportResponse(SerialMessage serialMess * an Application Command message and handles it using the right * endpoint. * @param serialMessage the serial message to process. - * @param offset the offset at which to start procesing. + * @param offset the offset at which to start processing. */ private void handleMultiChannelEncapResponse( SerialMessage serialMessage, int offset) { logger.trace("Process Multi-channel Encapsulation"); + + if(serialMessage.getMessagePayload().length < offset + 2) { + logger.error("NODE {}: Invalid data length", this.getNode().getNodeId()); + return; + } + CommandClass commandClass; ZWaveCommandClass zwaveCommandClass; int endpointId = serialMessage.getMessagePayloadByte(offset); @@ -427,18 +468,18 @@ private void handleMultiChannelEncapResponse( return; } - logger.debug(String.format("NODE %d: Endpoint = %d, calling handleApplicationCommandRequest.", this.getNode().getNodeId(), endpointId)); + logger.debug("NODE {}: Endpoint = {}, calling handleApplicationCommandRequest.", this.getNode().getNodeId(), endpointId); zwaveCommandClass.handleApplicationCommandRequest(serialMessage, offset + 3, endpointId); } /** - * Gets a SerialMessage with the MULTI INSTANCE GET command. + * Gets a SerialMessage with the MULTI_INSTANCE_GET command. * Returns the number of instances for this command class. * @param the command class to return the number of instances for. * @return the serial message. */ public SerialMessage getMultiInstanceGetMessage(CommandClass commandClass) { - logger.debug("NODE {}: Creating new message for application command MULTI_INSTANCE_GET command class {}", this.getNode().getNodeId(), commandClass.getLabel()); + logger.debug("NODE {}: Creating new message for command MULTI_INSTANCE_GET command class {}", this.getNode().getNodeId(), commandClass.getLabel()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] newPayload = { (byte) this.getNode().getNodeId(), 3, @@ -451,14 +492,14 @@ public SerialMessage getMultiInstanceGetMessage(CommandClass commandClass) { } /** - * Gets a SerialMessage with the MULTI INSTANCE ENCAP command. + * Gets a SerialMessage with the MULTI_INSTANCE_ENCAP command. * Encapsulates a message for a specific instance. * @param serialMessage the serial message to encapsulate * @param instance the number of the instance to encapsulate the message for. * @return the encapsulated serial message. */ public SerialMessage getMultiInstanceEncapMessage(SerialMessage serialMessage, int instance) { - logger.debug("NODE {}: Creating new message for application command MULTI_INSTANCE_ENCAP instance {}", this.getNode().getNodeId(), instance); + logger.debug("NODE {}: Creating new message for command MULTI_INSTANCE_ENCAP instance {}", this.getNode().getNodeId(), instance); byte[] payload = serialMessage.getMessagePayload(); byte[] newPayload = new byte[payload.length + 3]; @@ -479,8 +520,8 @@ public SerialMessage getMultiInstanceEncapMessage(SerialMessage serialMessage, i * @return the serial message. */ public SerialMessage getMultiChannelEndpointGetMessage() { - logger.debug("NODE {}: Creating new message for application command MULTI_CHANNEL_ENDPOINT_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); + logger.debug("NODE {}: Creating new message for command MULTI_CHANNEL_ENDPOINT_GET", this.getNode().getNodeId()); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), @@ -490,14 +531,14 @@ public SerialMessage getMultiChannelEndpointGetMessage() { } /** - * Gets a SerialMessage with the MULTI CHANNEL CAPABILITY GET command. + * Gets a SerialMessage with the MULTI_CHANNEL_CAPABILITY_GET command. * Gets the capabilities for a specific endpoint. * @param the number of the endpoint to get the * @return the serial message. */ public SerialMessage getMultiChannelCapabilityGetMessage(ZWaveEndpoint endpoint) { - logger.debug("NODE {}: Creating new message for application command MULTI_CHANNEL_CAPABILITY_GET endpoint {}", this.getNode().getNodeId(), endpoint.getEndpointId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); + logger.debug("NODE {}: Creating new message for command MULTI_CHANNEL_CAPABILITY_GET endpoint {}", this.getNode().getNodeId(), endpoint.getEndpointId()); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 3, (byte) getCommandClass().getKey(), @@ -508,14 +549,14 @@ public SerialMessage getMultiChannelCapabilityGetMessage(ZWaveEndpoint endpoint) } /** - * Gets a SerialMessage with the MULTI INSTANCE ENCAP command. + * Gets a SerialMessage with the MULTI_INSTANCE_ENCAP command. * Encapsulates a message for a specific instance. * @param serialMessage the serial message to encapsulate * @param endpoint the endpoint to encapsulate the message for. * @return the encapsulated serial message. */ public SerialMessage getMultiChannelEncapMessage(SerialMessage serialMessage, ZWaveEndpoint endpoint) { - logger.debug("NODE {}: Creating new message for application command MULTI_CHANNEL_ENCAP endpoint {}", this.getNode().getNodeId(), endpoint.getEndpointId()); + logger.debug("NODE {}: Creating new message for command MULTI_CHANNEL_ENCAP endpoint {}", this.getNode().getNodeId(), endpoint.getEndpointId()); byte[] payload = serialMessage.getMessagePayload(); byte[] newPayload = new byte[payload.length + 4]; @@ -534,26 +575,60 @@ public SerialMessage getMultiChannelEncapMessage(SerialMessage serialMessage, ZW /** * Initializes the Multi instance / endpoint command class by setting the number of instances * or getting the endpoints. + * @return SerialMessage message to send */ - public void initEndpoints() { + public ArrayList initEndpoints(boolean refresh) { + ArrayList result = new ArrayList(); + logger.debug("NODE {}: Initialising endpoints - version {}", this.getNode().getNodeId(), this.getVersion()); switch (this.getVersion()) { case 1: - // get number of instances for all command classes on this node. + // Get number of instances for all command classes on this node. for (ZWaveCommandClass commandClass : this.getNode().getCommandClasses()) { - if (commandClass.getCommandClass() == CommandClass.NO_OPERATION) + logger.debug("NODE {}: ENDPOINTS - checking {}, Instances {}", this.getNode().getNodeId(), + commandClass.getCommandClass().toString(), commandClass.getInstances()); + + // Skip classes known NOT to support multiple instances. + // This allows us to reduce the number of frames we send during initialisation + // where we already know it doesn't support multi-instance. + if (singleInstanceClasses.contains(commandClass.getCommandClass())) { + commandClass.setInstances(1); + logger.debug("NODE {}: ENDPOINTS - skipping {}", this.getNode().getNodeId(), + commandClass.getCommandClass().toString()); continue; - this.getController().sendData(this.getMultiInstanceGetMessage(commandClass.getCommandClass())); + } + // Instances is set to 1 after it's initialised + if (commandClass.getInstances() == 0) { + logger.debug("NODE {}: ENDPOINTS - found {}", this.getNode().getNodeId(), + commandClass.getCommandClass().toString()); + result.add(getMultiInstanceGetMessage(commandClass.getCommandClass())); + } } break; case 2: - this.getController().sendData(this.getMultiChannelEndpointGetMessage()); + // Set all classes to a single instance + for (ZWaveCommandClass commandClass : this.getNode().getCommandClasses()) { + commandClass.setInstances(1); + } + + // Request the number of endpoints + if(refresh == true || this.endpoints.size() == 0) { + result.add(getMultiChannelEndpointGetMessage()); + } + else { + for (Map.Entry entry : this.endpoints.entrySet()) { + if(refresh == true || entry.getValue().getCommandClasses().size() == 0) { + result.add(this.getMultiChannelCapabilityGetMessage(entry.getValue())); + } + } + } break; default: logger.warn(String.format("NODE %d: Unknown version %d for command class %s (0x%02x)", - this.getNode().getNodeId(), this.getVersion(), this.getCommandClass().getLabel(), this.getCommandClass().getKey())); + this.getNode().getNodeId(), this.getVersion(), this.getCommandClass().toString(), this.getCommandClass().getKey())); break; } + + return result; }; - } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiLevelSensorCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiLevelSensorCommandClass.java index f632d57b839..ccae6f32b27 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiLevelSensorCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiLevelSensorCommandClass.java @@ -12,10 +12,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; @@ -23,7 +22,6 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,7 +51,14 @@ public class ZWaveMultiLevelSensorCommandClass extends ZWaveCommandClass impleme private static final int SENSOR_MULTI_LEVEL_GET = 0x04; private static final int SENSOR_MULTI_LEVEL_REPORT = 0x05; - private final Set sensors = new HashSet(); + private final Map sensors = new HashMap(); + + @XStreamOmitField + private boolean initialiseDone = false; + @XStreamOmitField + private boolean dynamicDone = false; + + private boolean isGetSupported = true; /** * Creates a new instance of the ZWaveMultiLevelSensorCommandClass class. @@ -89,71 +94,68 @@ public int getMaxVersion() { @Override public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { - logger.trace("Handle Message Sensor Multi Level Request"); logger.debug("NODE {}: Received Sensor Multi Level Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { case SENSOR_MULTI_LEVEL_GET: case SENSOR_MULTI_LEVEL_SUPPORTED_GET: - logger.warn(String.format("Command 0x%02X not implemented.", - command)); + logger.warn("Command {} not implemented.", command); return; case SENSOR_MULTI_LEVEL_SUPPORTED_REPORT: - logger.debug("Process Multi Level Supported Sensor Report"); + logger.debug("NODE {}: Process Multi Level Supported Sensor Report", this.getNode().getNodeId()); int payloadLength = serialMessage.getMessagePayload().length; for(int i = offset + 1; i < payloadLength; ++i ) { for(int bit = 0; bit < 8; ++bit) { - if( ((serialMessage.getMessagePayloadByte(i)) & (1 << bit) ) == 0 ) - continue; - - int index = ((i - (offset + 1)) * 8 ) + bit + 1; - if(index >= SensorType.values().length) - continue; - - // (n)th bit is set. n is the index for the alarm type enumeration. - SensorType sensorTypeToAdd = SensorType.getSensorType(index); - this.sensors.add(sensorTypeToAdd); - logger.debug(String.format("NODE %d: Added sensor type %s (0x%02x)", this.getNode().getNodeId(), sensorTypeToAdd.getLabel(), index)); + if( ((serialMessage.getMessagePayloadByte(i)) & (1 << bit) ) == 0 ) { + continue; + } + + int index = ((i - (offset + 1)) * 8 ) + bit + 1; + if(index >= SensorType.values().length) { + continue; + } + + // (n)th bit is set. n is the index for the sensor type enumeration. + SensorType sensorTypeToAdd = SensorType.getSensorType(index); + Sensor newSensor = new Sensor(sensorTypeToAdd); + this.sensors.put(sensorTypeToAdd, newSensor); + logger.debug("NODE {}: Added sensor type {} ({})", this.getNode().getNodeId(), sensorTypeToAdd.getLabel(), index); } } - - this.getNode().advanceNodeStage(NodeStage.DYNAMIC); + + initialiseDone = true; break; case SENSOR_MULTI_LEVEL_REPORT: - logger.trace("Process Multi Level Sensor Report"); - logger.debug("NODE {}: Sensor Multi Level report received", this.getNode().getNodeId()); + logger.debug("NODE {}: Sensor Multi Level REPORT received", this.getNode().getNodeId()); int sensorTypeCode = serialMessage.getMessagePayloadByte(offset + 1); int sensorScale = (serialMessage.getMessagePayloadByte(offset + 2) >> 3) & 0x03; - logger.debug(String.format("NODE %d: Sensor Type = (0x%02x), Scale = %d", this.getNode().getNodeId(), sensorTypeCode, sensorScale)); - SensorType sensorType = SensorType.getSensorType(sensorTypeCode); - - if (sensorType == null) { - logger.error(String.format("NODE %d: Unknown Sensor Type = 0x%02x, ignoring report.", this.getNode().getNodeId(), sensorTypeCode)); - return; - } - - // sensor type seems to be supported, add it to the list. - if (!sensors.contains(sensorType)) - this.sensors.add(sensorType); + // Sensor type seems to be supported, add it to the list. + Sensor sensor = getSensor(sensorTypeCode); + if(sensor != null) { + sensor.setInitialised(); - try { - BigDecimal value = extractValue(serialMessage.getMessagePayload(), offset + 2); + logger.debug("NODE {}: Sensor Type = {}({}), Scale = {}", this.getNode().getNodeId(), + sensor.getSensorType().getLabel(), sensorTypeCode, sensorScale); - logger.debug(String.format("NODE %d: Sensor Value = (%f)", this.getNode().getNodeId(), value)); - - ZWaveMultiLevelSensorValueEvent zEvent = new ZWaveMultiLevelSensorValueEvent(this.getNode().getNodeId(), endpoint, sensorType, sensorScale, value); - this.getController().notifyEventListeners(zEvent); - } - catch (NumberFormatException e) { - return; + // Set the global flag. This is mainly used for version < 4 + dynamicDone = true; + + try { + BigDecimal value = extractValue(serialMessage.getMessagePayload(), offset + 2); + + logger.debug("NODE {}: Sensor Value = {}", this.getNode().getNodeId(), value); + + ZWaveMultiLevelSensorValueEvent zEvent = new ZWaveMultiLevelSensorValueEvent(this.getNode().getNodeId(), endpoint, sensor.getSensorType(), sensorScale, value); + this.getController().notifyEventListeners(zEvent); + } + catch (NumberFormatException e) { + return; + } } - - if (this.getNode().getNodeStage() != NodeStage.DONE) - this.getNode().advanceNodeStage(NodeStage.DONE); break; default: logger.warn(String @@ -163,20 +165,44 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, } } + private Sensor getSensor(int sensorTypeCode) { + SensorType sensorType = SensorType.getSensorType(sensorTypeCode); + if (sensorType == null) { + logger.error("NODE {}: Unknown Sensor Type = {}, ignoring report.", this.getNode().getNodeId(), sensorTypeCode); + return null; + } + + // Sensor type seems to be supported, add it to the list. + Sensor sensor = sensors.get(sensorType); + if (sensor == null) { + sensor = new Sensor(sensorType); + this.sensors.put(sensorType, sensor); + logger.debug("NODE {}: Adding new sensor Type = {}({})", this.getNode().getNodeId(), + sensorType.getLabel(), sensorTypeCode); + } + + return sensor; + } + /** * Gets a SerialMessage with the SENSOR_MULTI_LEVEL_GET command * * @return the serial message */ public SerialMessage getValueMessage() { + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + // TODO: Why does this return???!!!??? if (this.getVersion() > 4) { - for (SensorType sensorType : this.sensors) - return this.getMessage(sensorType); + for (Map.Entry entry : this.sensors.entrySet()) { + return this.getMessage(entry.getValue().getSensorType()); + } } - - logger.debug( - "NODE {}: Creating new message for application command SENSOR_MULTI_LEVEL_GET", + + logger.debug("NODE {}: Creating new message for command SENSOR_MULTI_LEVEL_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, @@ -196,13 +222,12 @@ public SerialMessage getValueMessage() { * @return the serial message */ public SerialMessage getSupportedValueMessage() { - logger.debug( - "NODE {}: Creating new message for application command SENSOR_MULTI_LEVEL_SUPPORTED_GET", + logger.debug("NODE {}: Creating new message for command SENSOR_MULTI_LEVEL_SUPPORTED_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, - SerialMessagePriority.High); + SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), @@ -218,8 +243,12 @@ public SerialMessage getSupportedValueMessage() { * @return the serial message */ public SerialMessage getMessage(SensorType sensorType) { - logger.debug( - "NODE {}: Creating new message for application command SENSOR_MULTI_LEVEL_GET", + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests for MULTI_LEVEL_SENSOR", this.getNode().getNodeId()); + return null; + } + + logger.debug("NODE {}: Creating new message for command SENSOR_MULTI_LEVEL_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, @@ -233,17 +262,27 @@ public SerialMessage getMessage(SensorType sensorType) { }; result.setMessagePayload(newPayload); return result; - } + } + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } + /** * {@inheritDoc} */ - public Collection initialize() { + public Collection initialize(boolean refresh) { ArrayList result = new ArrayList(); - - if (this.getVersion() > 4) + + if ((refresh == true || initialiseDone == false) && this.getVersion() > 4) { result.add(getSupportedValueMessage()); - + } + return result; } @@ -251,16 +290,31 @@ public Collection initialize() { * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { ArrayList result = new ArrayList(); - + + // If we want to refresh, then reset the init flag on all sensors + if(refresh == true && this.getVersion() > 4) { + logger.debug("=========== Resetting init flag!"); + for (Map.Entry entry : this.sensors.entrySet()) { + entry.getValue().resetInitialised(); + } + + dynamicDone = false; + } + if (this.getVersion() > 4) { - for (SensorType sensorType : this.sensors) - result.add(this.getMessage(sensorType)); - } else { + for (Map.Entry entry : this.sensors.entrySet()) { + if(entry.getValue().getInitialised() == false) { + logger.debug("============ Requesting {}!", entry.getValue().getSensorType()); + result.add(this.getMessage(entry.getValue().getSensorType())); + } + } + } + else if(dynamicDone == false){ result.add(this.getValueMessage()); } - + return result; } @@ -271,7 +325,7 @@ public Collection getDynamicValues() { * @author Jan-Willem Spuij * @since 1.3.0 */ - @XStreamAlias("sensorType") + @XStreamAlias("multilevelSensorType") public enum SensorType { TEMPERATURE(1,"Temperature"), @@ -356,8 +410,37 @@ public String getLabel() { return label; } } - - + + /** + * Class to hold alarm state + * @author Chris Jackson + */ + @XStreamAlias("multilevelSensor") + private static class Sensor { + SensorType sensorType; + boolean initialised = false; + + public Sensor(SensorType type) { + sensorType = type; + } + + public SensorType getSensorType() { + return sensorType; + } + + public void setInitialised() { + initialised = true; + } + + public void resetInitialised() { + initialised = false; + } + + public boolean getInitialised() { + return initialised; + } + } + /** * Z-Wave Multilevel Sensor Event class. Indicates that an sensor value * changed. diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiLevelSwitchCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiLevelSwitchCommandClass.java index 86c376d8fdb..db4f41c79be 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiLevelSwitchCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveMultiLevelSwitchCommandClass.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.Collection; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; @@ -18,7 +19,6 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,7 +52,12 @@ public class ZWaveMultiLevelSwitchCommandClass extends ZWaveCommandClass impleme private static final int SWITCH_MULTILEVEL_STOP_LEVEL_CHANGE = 0x05; private static final int SWITCH_MULTILEVEL_SUPPORTED_GET = 0x06; private static final int SWITCH_MULTILEVEL_SUPPORTED_REPORT = 0x07; - + + @XStreamOmitField + private boolean dynamicDone = false; + + private boolean isGetSupported = true; + /** * Creates a new instance of the ZWaveMultiLevelSwitchCommandClass class. * @param node the node this command class belongs to @@ -86,33 +91,31 @@ public int getMaxVersion() { @Override public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { - logger.trace("Handle Message Switch Multi Level Request"); - logger.debug(String.format("Received Switch Multi Level Request for Node ID = %d", this.getNode().getNodeId())); + logger.debug("NODE {}: Received Switch Multi Level Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { case SWITCH_MULTILEVEL_SET: case SWITCH_MULTILEVEL_GET: case SWITCH_MULTILEVEL_SUPPORTED_GET: case SWITCH_MULTILEVEL_SUPPORTED_REPORT: - logger.warn(String.format("Command 0x%02X not implemented.", command)); + logger.warn("Command {} not implemented.", command); case SWITCH_MULTILEVEL_START_LEVEL_CHANGE: return; case SWITCH_MULTILEVEL_STOP_LEVEL_CHANGE: - logger.debug("Process Switch Multi Level Stop Level Change"); + logger.debug("NODE {}: Process Switch Multi Level Stop Level Change", this.getNode().getNodeId()); // request level after dimming - logger.debug("Requesting level from node {}, endpoint {}", this.getNode().getNodeId(), endpoint); + logger.debug("NODE {}: Requesting level from endpoint {}", this.getNode().getNodeId(), endpoint); this.getController().sendData(this.getNode().encapsulate(this.getValueMessage(), this, endpoint)); break; case SWITCH_MULTILEVEL_REPORT: logger.trace("Process Switch Multi Level Report"); int value = serialMessage.getMessagePayloadByte(offset + 1); - logger.debug(String.format("Switch Multi Level report from nodeId = %d, value = 0x%02X", this.getNode().getNodeId(), value)); + logger.debug("NODE {}: Switch Multi Level report, value = {}", this.getNode().getNodeId(), value); ZWaveCommandClassValueEvent zEvent = new ZWaveCommandClassValueEvent(this.getNode().getNodeId(), endpoint, this.getCommandClass(), value); this.getController().notifyEventListeners(zEvent); - - if (this.getNode().getNodeStage() != NodeStage.DONE) - this.getNode().advanceNodeStage(NodeStage.DONE); + + dynamicDone = true; break; default: logger.warn(String.format("Unsupported Command 0x%02X for command class %s (0x%02X).", @@ -127,7 +130,12 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, * @return the serial message */ public SerialMessage getValueMessage() { - logger.debug("Creating new message for application command SWITCH_MULTILEVEL_GET for node {}", this.getNode().getNodeId()); + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + + logger.debug("NODE {}: Creating new message for command SWITCH_MULTILEVEL_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, @@ -136,14 +144,23 @@ public SerialMessage getValueMessage() { result.setMessagePayload(newPayload); return result; } - + + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } + /** * Gets a SerialMessage with the SWITCH_MULTILEVEL_SET command * @param the level to set. 0 is mapped to off, > 0 is mapped to on. * @return the serial message */ public SerialMessage setValueMessage(int level) { - logger.debug("Creating new message for application command SWITCH_MULTILEVEL_SET for node {}", this.getNode().getNodeId()); + logger.debug("NODE {}: Creating new message for command SWITCH_MULTILEVEL_SET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Set); byte[] newPayload = { (byte) this.getNode().getNodeId(), 3, @@ -160,7 +177,7 @@ public SerialMessage setValueMessage(int level) { * @return the serial message */ public SerialMessage stopLevelChangeMessage() { - logger.debug("Creating new message for application command SWITCH_MULTILEVEL_STOP_LEVEL_CHANGE for node {}", this.getNode().getNodeId()); + logger.debug("NODE {}: Creating new message for command SWITCH_MULTILEVEL_STOP_LEVEL_CHANGE", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Set); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, @@ -174,11 +191,11 @@ public SerialMessage stopLevelChangeMessage() { * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { ArrayList result = new ArrayList(); - - result.add(getValueMessage()); - + if(refresh == true || dynamicDone == false) { + result.add(getValueMessage()); + } return result; } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveNoOperationCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveNoOperationCommandClass.java index bfe4a8fbfcd..9c13d611784 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveNoOperationCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveNoOperationCommandClass.java @@ -15,7 +15,6 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,11 +61,7 @@ public CommandClass getCommandClass() { @Override public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { - logger.trace("Handle No Operation Request"); - logger.debug(String.format("NODE {}: Received No Operation", this.getNode().getNodeId())); - - // advance node stage. - this.getNode().advanceNodeStage(NodeStage.DETAILS); + logger.debug("NODE {}: Received No Operation", this.getNode().getNodeId()); } /** @@ -74,13 +69,12 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, * @return the serial message */ public SerialMessage getNoOperationMessage() { - logger.debug("NODE {}: Creating new message for application command No Operation", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Low); + logger.debug("NODE {}: Creating new message for command No Operation", this.getNode().getNodeId()); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Poll); byte[] newPayload = { (byte) this.getNode().getNodeId(), 1, (byte) getCommandClass().getKey() }; result.setMessagePayload(newPayload); return result; } - } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatFanModeCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatFanModeCommandClass.java index dd55dccdcff..60c6f8595fe 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatFanModeCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatFanModeCommandClass.java @@ -8,7 +8,6 @@ */ package org.openhab.binding.zwave.internal.protocol.commandclass; -import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -16,7 +15,7 @@ import java.util.Map; import java.util.Set; -import org.openhab.binding.zwave.internal.protocol.NodeStage; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; @@ -52,6 +51,13 @@ public class ZWaveThermostatFanModeCommandClass extends ZWaveCommandClass private final Set fanModeTypes = new HashSet(); + @XStreamOmitField + private boolean initialiseDone = false; + @XStreamOmitField + private boolean dynamicDone = false; + + private boolean isGetSupported = true; + /** * Creates a new instance of the ZWaveThermostatFanModeCommandClass class. * @param node the node this command class belongs to @@ -113,23 +119,20 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, // (n)th bit is set. n is the index for the fanMode type enumeration. FanModeType fanModeTypeToAdd = FanModeType.getFanModeType(index); if(fanModeTypeToAdd != null){ - this.fanModeTypes.add(fanModeTypeToAdd); + fanModeTypes.add(fanModeTypeToAdd); logger.debug("NODE {}: Added Fan Mode type {} ({})", this.getNode().getNodeId(), fanModeTypeToAdd.getLabel(), index); - } else { + } + else { logger.warn("NODE {}: Uknown fan mode type {}", this.getNode().getNodeId(), index); } } } - this.getNode().advanceNodeStage(NodeStage.DYNAMIC); + initialiseDone = true; break; case THERMOSTAT_FAN_MODE_REPORT: logger.trace("NODE {}: Process Thermostat Fan Mode Report",this.getNode().getNodeId()); processThermostatFanModeReport(serialMessage, offset, endpoint); - - if (this.getNode().getNodeStage() != NodeStage.DONE) - this.getNode().advanceNodeStage(NodeStage.DONE); - break; default: logger.warn("NODE {}: Unsupported Command {} for command class {} ({}).", @@ -161,11 +164,12 @@ protected void processThermostatFanModeReport(SerialMessage serialMessage, int o } // fanMode type seems to be supported, add it to the list. - if (!this.fanModeTypes.contains(fanModeType)) - this.fanModeTypes.add(fanModeType); - + if(!fanModeTypes.contains(fanModeType)) + fanModeTypes.add(fanModeType); + + dynamicDone = true; logger.debug("NODE {}: Thermostat Fan Mode Report value = {}", this.getNode().getNodeId(), fanModeType.getLabel()); - ZWaveCommandClassValueEvent zEvent = new ZWaveCommandClassValueEvent(this.getNode().getNodeId(), endpoint, this.getCommandClass(), new BigDecimal(value)); + ZWaveCommandClassValueEvent zEvent = new ZWaveCommandClassValueEvent(this.getNode().getNodeId(), endpoint, this.getCommandClass(), value); this.getController().notifyEventListeners(zEvent); } @@ -173,9 +177,11 @@ protected void processThermostatFanModeReport(SerialMessage serialMessage, int o * {@inheritDoc} */ @Override - public Collection initialize() { + public Collection initialize(boolean refresh) { ArrayList result = new ArrayList(); - result.add(this.getSupportedMessage()); + if(refresh == true || initialiseDone == false) { + result.add(this.getSupportedMessage()); + } return result; } @@ -183,9 +189,12 @@ public Collection initialize() { * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { + // TODO (or question for Dan from Chris) - shouldn't this iterate through all fan types? ArrayList result = new ArrayList(); - result.add(getValueMessage()); + if(refresh == true || dynamicDone == false) { + result.add(getValueMessage()); + } return result; } @@ -194,8 +203,13 @@ public Collection getDynamicValues() { */ @Override public SerialMessage getValueMessage() { + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + logger.debug("NODE {}: Creating new message for application command THERMOSTAT_FAN_MODE_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Get); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] payload = { (byte) this.getNode().getNodeId(), 2, @@ -206,6 +220,15 @@ public SerialMessage getValueMessage() { return result; } + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } + /** * Gets a SerialMessage with the THERMOSTAT_FAN_MODE_SUPPORTED_GET command * @return the serial message, or null if the supported command is not supported. @@ -213,7 +236,7 @@ public SerialMessage getValueMessage() { public SerialMessage getSupportedMessage() { logger.debug("NODE {}: Creating new message for application command THERMOSTAT_FAN_MODE_SUPPORTED_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.High); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), @@ -229,10 +252,12 @@ public SerialMessage getSupportedMessage() { @Override public SerialMessage setValueMessage(int value) { - if(fanModeTypes.isEmpty()) + if(fanModeTypes.isEmpty()) { + logger.warn("NODE {}: requesting fan mode types, set request ignored (try again later)", this.getNode().getNodeId()); return this.getSupportedMessage(); + } - if(!fanModeTypes.contains(FanModeType.getFanModeType(value))){ + if(!fanModeTypes.contains(FanModeType.getFanModeType(value))) { logger.error("NODE {}: Unsupported fanMode type {}", value, this.getNode().getNodeId()); return null; diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatFanStateCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatFanStateCommandClass.java index f28f0ef273d..e8bd3f5df0f 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatFanStateCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatFanStateCommandClass.java @@ -8,7 +8,6 @@ */ package org.openhab.binding.zwave.internal.protocol.commandclass; -import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -16,7 +15,7 @@ import java.util.Map; import java.util.Set; -import org.openhab.binding.zwave.internal.protocol.NodeStage; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; @@ -47,6 +46,11 @@ public class ZWaveThermostatFanStateCommandClass extends ZWaveCommandClass private static final byte THERMOSTAT_FAN_STATE_REPORT = 0x3; private final Set fanStateTypes = new HashSet(); + + @XStreamOmitField + private boolean dynamicDone = false; + + private boolean isGetSupported = true; /** * Creates a new instance of the ZWaveThermostatFanStateCommandClass class. @@ -87,10 +91,6 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, case THERMOSTAT_FAN_STATE_REPORT: logger.trace("NODE {}: Process Thermostat Fan State Report", this.getNode().getNodeId()); processThermostatFanStateReport(serialMessage, offset, endpoint); - - if (this.getNode().getNodeStage() != NodeStage.DONE) - this.getNode().advanceNodeStage(NodeStage.DONE); - break; default: logger.warn("NODE {}: Unsupported Command {} for command class {} ({}).", @@ -122,11 +122,13 @@ protected void processThermostatFanStateReport(SerialMessage serialMessage, int } // fanState type seems to be supported, add it to the list. - if (!this.fanStateTypes.contains(fanStateType)) - this.fanStateTypes.add(fanStateType); - + if(!fanStateTypes.contains(fanStateType)) + fanStateTypes.add(fanStateType); + + dynamicDone = true; + logger.debug("NODE {}: Thermostat fan state Report value = {}", this.getNode().getNodeId(), fanStateType.getLabel()); - ZWaveCommandClassValueEvent zEvent = new ZWaveCommandClassValueEvent(this.getNode().getNodeId(), endpoint, this.getCommandClass(), new BigDecimal(value)); + ZWaveCommandClassValueEvent zEvent = new ZWaveCommandClassValueEvent(this.getNode().getNodeId(), endpoint, this.getCommandClass(), value); this.getController().notifyEventListeners(zEvent); } @@ -134,9 +136,12 @@ protected void processThermostatFanStateReport(SerialMessage serialMessage, int * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { + // TODO (or question for Dan from Chris) - shouldn't this iterate through all fan modes? ArrayList result = new ArrayList(); - result.add(getValueMessage()); + if(refresh == true || dynamicDone == false) { + result.add(getValueMessage()); + } return result; } @@ -145,8 +150,13 @@ public Collection getDynamicValues() { */ @Override public SerialMessage getValueMessage() { + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + logger.debug("NODE {}: Creating new message for application command THERMOSTAT_FAN_STATE_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Get); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] payload = { (byte) this.getNode().getNodeId(), 2, @@ -157,6 +167,15 @@ public SerialMessage getValueMessage() { return result; } + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } + /** * Z-Wave FanStateType enumeration. The fanState type indicates the type * of fanState that is reported. diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatModeCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatModeCommandClass.java index 5be6dec3d2d..7f6f065c414 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatModeCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatModeCommandClass.java @@ -8,7 +8,6 @@ */ package org.openhab.binding.zwave.internal.protocol.commandclass; -import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -16,7 +15,7 @@ import java.util.Map; import java.util.Set; -import org.openhab.binding.zwave.internal.protocol.NodeStage; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; @@ -52,6 +51,13 @@ public class ZWaveThermostatModeCommandClass extends ZWaveCommandClass private final Set modeTypes = new HashSet(); + @XStreamOmitField + private boolean initialiseDone = false; + @XStreamOmitField + private boolean dynamicDone = false; + + private boolean isGetSupported = true; + /** * Creates a new instance of the ZWaveThermostatModeCommandClass class. * @param node the node this command class belongs to @@ -88,12 +94,15 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, logger.debug("NODE {}: Received Thermostat Mode Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { - case THERMOSTAT_MODE_SET: case THERMOSTAT_MODE_GET: case THERMOSTAT_MODE_SUPPORTED_GET: logger.warn("NODE {}: Command {} not implemented.", this.getNode().getNodeId(), command); return; + case THERMOSTAT_MODE_SET: + logger.trace("NODE {}: Process Thermostat Mode Get as Report", this.getNode().getNodeId()); + processThermostatModeReport(serialMessage, offset, endpoint); + break; case THERMOSTAT_MODE_SUPPORTED_REPORT: logger.debug("NODE {}: Process Thermostat Supported Mode Report", this.getNode().getNodeId()); @@ -114,21 +123,18 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, if(modeTypeToAdd != null){ this.modeTypes.add(modeTypeToAdd); logger.debug("NODE {}: Added mode type {} ({})", this.getNode().getNodeId(), modeTypeToAdd.getLabel(), index); - } else { + } + else { logger.warn("NODE {}: Unknown mode type {}", this.getNode().getNodeId(), index); } } } - this.getNode().advanceNodeStage(NodeStage.DYNAMIC); + initialiseDone = true; break; case THERMOSTAT_MODE_REPORT: logger.trace("NODE {}: Process Thermostat Mode Report", this.getNode().getNodeId()); processThermostatModeReport(serialMessage, offset, endpoint); - - if (this.getNode().getNodeStage() != NodeStage.DONE) - this.getNode().advanceNodeStage(NodeStage.DONE); - break; default: logger.warn("NODE {}: Unsupported Command {} for command class {} ({}).", @@ -160,11 +166,14 @@ protected void processThermostatModeReport(SerialMessage serialMessage, int offs } // mode type seems to be supported, add it to the list. - if (!this.modeTypes.contains(modeType)) - this.modeTypes.add(modeType); + if (!modeTypes.contains(modeType)) { + modeTypes.add(modeType); + } + + dynamicDone = true; logger.debug("NODE {}: Thermostat Mode Report, value = {}", this.getNode().getNodeId(), modeType.getLabel()); - ZWaveCommandClassValueEvent zEvent = new ZWaveCommandClassValueEvent(this.getNode().getNodeId(), endpoint, this.getCommandClass(), new BigDecimal(value)); + ZWaveCommandClassValueEvent zEvent = new ZWaveCommandClassValueEvent(this.getNode().getNodeId(), endpoint, this.getCommandClass(), value); this.getController().notifyEventListeners(zEvent); } @@ -172,9 +181,11 @@ protected void processThermostatModeReport(SerialMessage serialMessage, int offs * {@inheritDoc} */ @Override - public Collection initialize() { + public Collection initialize(boolean refresh) { ArrayList result = new ArrayList(); - result.add(this.getSupportedMessage()); + if(refresh == true || initialiseDone == false) { + result.add(this.getSupportedMessage()); + } return result; } @@ -182,9 +193,11 @@ public Collection initialize() { * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { ArrayList result = new ArrayList(); - result.add(getValueMessage()); + if(refresh == true || dynamicDone == false) { + result.add(getValueMessage()); + } return result; } @@ -193,8 +206,13 @@ public Collection getDynamicValues() { */ @Override public SerialMessage getValueMessage() { + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + logger.debug("NODE {}: Creating new message for application command THERMOSTAT_MODE_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Get); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] payload = { (byte) this.getNode().getNodeId(), 2, @@ -205,6 +223,15 @@ public SerialMessage getValueMessage() { return result; } + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } + /** * Gets a SerialMessage with the THERMOSTAT_MODE_SUPPORTED_GET command * @return the serial message, or null if the supported command is not supported. @@ -212,7 +239,7 @@ public SerialMessage getValueMessage() { public SerialMessage getSupportedMessage() { logger.debug("NODE {}: Creating new message for application command THERMOSTAT_MODE_SUPPORTED_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.High); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), @@ -231,12 +258,13 @@ public SerialMessage setValueMessage(int value) { logger.debug("NODE {}: setValueMessage {}, modeType empty {}", this.getNode().getNodeId(), value, modeTypes.isEmpty()); //if we do not have any mode types yet, get them - if(modeTypes.isEmpty()) + if(modeTypes.isEmpty()) { + logger.warn("NODE {}: requesting mode types, set request ignored (try again later)", this.getNode().getNodeId()); return this.getSupportedMessage(); + } if(!modeTypes.contains(ModeType.getModeType(value))){ logger.error("NODE {}: Unsupported mode type {}", this.getNode().getNodeId(), value); - return null; } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatOperatingStateCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatOperatingStateCommandClass.java index d571d69c6bb..9949485785e 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatOperatingStateCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatOperatingStateCommandClass.java @@ -12,11 +12,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; -import org.openhab.binding.zwave.internal.protocol.NodeStage; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; @@ -46,7 +44,10 @@ public class ZWaveThermostatOperatingStateCommandClass extends ZWaveCommandClass private static final byte THERMOSTAT_OPERATING_STATE_GET = 0x2; private static final byte THERMOSTAT_OPERATING_STATE_REPORT = 0x3; - private final Set operatingStateTypes = new HashSet(); + @XStreamOmitField + private boolean dynamicDone = false; + + private boolean isGetSupported = true; /** * Creates a new instance of the ZWaveThermostatOperatingStateCommandClass class. @@ -87,10 +88,6 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, case THERMOSTAT_OPERATING_STATE_REPORT: logger.trace("NODE {}: Process Thermostat Operating State Report", this.getNode().getNodeId()); processThermostatOperatingStateReport(serialMessage, offset, endpoint); - - if (this.getNode().getNodeStage() != NodeStage.DONE) - this.getNode().advanceNodeStage(NodeStage.DONE); - break; default: logger.warn("NODE {}: Unsupported Command {} for command class {} ({}).", @@ -121,10 +118,8 @@ protected void processThermostatOperatingStateReport(SerialMessage serialMessage return; } - // operatingState type seems to be supported, add it to the list. - if (!this.operatingStateTypes.contains(operatingStateType)) - this.operatingStateTypes.add(operatingStateType); - + dynamicDone = true; + logger.debug("NODE {}: Operating State Type = {} ({})", this.getNode().getNodeId(), operatingStateType.getLabel(), value); logger.debug("NODE {}: Thermostat Operating State Report value = {}", this.getNode().getNodeId(), operatingStateType.getLabel()); @@ -137,9 +132,11 @@ protected void processThermostatOperatingStateReport(SerialMessage serialMessage * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { ArrayList result = new ArrayList(); - result.add(getValueMessage()); + if(refresh == true || dynamicDone == false) { + result.add(getValueMessage()); + } return result; } @@ -148,8 +145,13 @@ public Collection getDynamicValues() { */ @Override public SerialMessage getValueMessage() { + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; + } + logger.debug("NODE {}: Creating new message for application command THERMOSTAT_OPERATING_STATE_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Get); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] payload = { (byte) this.getNode().getNodeId(), 2, @@ -160,6 +162,15 @@ public SerialMessage getValueMessage() { return result; } + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } + /** * Z-Wave OperatingStateType enumeration. The operating state type indicates the type * of operating state that is reported from the thermostat. diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatSetpointCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatSetpointCommandClass.java index 3ef60783e79..1c55ffefff7 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatSetpointCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveThermostatSetpointCommandClass.java @@ -12,12 +12,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import org.apache.commons.lang.ArrayUtils; -import org.openhab.binding.zwave.internal.protocol.NodeStage; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; @@ -53,7 +51,18 @@ public class ZWaveThermostatSetpointCommandClass extends ZWaveCommandClass private static final byte THERMOSTAT_SETPOINT_SUPPORTED_GET = 0x4; private static final byte THERMOSTAT_SETPOINT_SUPPORTED_REPORT = 0x5; - private final Set setpointTypes = new HashSet(); + //Some Thermostats (Honywell) will not report on all the setpoints they claim to support. + //If we try this many times for the initial dynamic queries, give up. + private static final int MAX_DYNAMIC_TRIES = 5; + + private final Map setpoints = new HashMap(); + + @XStreamOmitField + private boolean initialiseDone = false; + @XStreamOmitField + private boolean dynamicDone = false; + + private boolean isGetSupported = true; /** * Creates a new instance of the ZWaveThermostatSetpointCommandClass class. @@ -106,35 +115,33 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, for(int i = offset + 1; i < payloadLength; ++i ) { int bitMask = serialMessage.getMessagePayloadByte(i); for(int bit = 0; bit < 8; ++bit) { - if ( (bitMask & (1 << bit) ) == 0 ) - continue; - - int index = ((i - (offset + 1)) * 8 ) + bit; - if(index >= SetpointType.values().length) - continue; - - // (n)th bit is set. n is the index for the setpoint type enumeration. - SetpointType setpointTypeToAdd = SetpointType.getSetpointType(index); - - if (setpointTypeToAdd == null) { - logger.warn("NODE {}: Unknown Setpoint Type = {}, ignoring report.", this.getNode().getNodeId(),index); - return; - } - - this.setpointTypes.add(setpointTypeToAdd); - logger.debug("NODE {}: Added setpoint type {} {}", this.getNode().getNodeId(), setpointTypeToAdd.getLabel(), index); + if ( (bitMask & (1 << bit) ) == 0 ) { + continue; + } + + int index = ((i - (offset + 1)) * 8 ) + bit; + if(index >= SetpointType.values().length) { + continue; + } + + // (n)th bit is set. n is the index for the setpoint type enumeration. + SetpointType setpointTypeToAdd = SetpointType.getSetpointType(index); + if(setpointTypeToAdd != null){ + Setpoint newSetpoint = new Setpoint(setpointTypeToAdd); + this.setpoints.put(setpointTypeToAdd, newSetpoint); + logger.debug("NODE {}: Added mode type {} ({})", this.getNode().getNodeId(), setpointTypeToAdd.getLabel(), index); + } + else { + logger.warn("NODE {}: Unknown mode type {}", this.getNode().getNodeId(), index); + } } } - this.getNode().advanceNodeStage(NodeStage.DYNAMIC); + initialiseDone = true; break; case THERMOSTAT_SETPOINT_REPORT: logger.trace("NODE {}: Process Thermostat Setpoint Report", this.getNode().getNodeId()); processThermostatSetpointReport(serialMessage, offset, endpoint); - - if (this.getNode().getNodeStage() != NodeStage.DONE) - this.getNode().advanceNodeStage(NodeStage.DONE); - break; default: logger.warn("NODE {}: Unsupported Command {} for command class {} ({}).", @@ -171,12 +178,14 @@ protected void processThermostatSetpointReport(SerialMessage serialMessage, int } // setpoint type seems to be supported, add it to the list. - if (!this.setpointTypes.contains(setpointType)) - this.setpointTypes.add(setpointType); - - logger.debug("NODE {}: Setpoint Type = {} ({})", this.getNode().getNodeId(), setpointType.getLabel(), setpointTypeCode); - - logger.debug("NODE {}: Thermostat Setpoint Report value = {}", this.getNode().getNodeId(), value.toPlainString()); + Setpoint setpoint = setpoints.get(setpointType); + if (setpoint == null) { + setpoint = new Setpoint(setpointType); + setpoints.put(setpointType, setpoint); + } + setpoint.setInitialised(); + + logger.debug("NODE {}: Thermostat Setpoint Report, Type {} ({}), value = {}", this.getNode().getNodeId(), setpointType.getLabel(), setpointTypeCode, value.toPlainString()); ZWaveThermostatSetpointValueEvent zEvent = new ZWaveThermostatSetpointValueEvent(this.getNode().getNodeId(), endpoint, setpointType, scale, value); this.getController().notifyEventListeners(zEvent); } @@ -189,9 +198,11 @@ protected void processThermostatSetpointReport(SerialMessage serialMessage, int * {@inheritDoc} */ @Override - public Collection initialize() { + public Collection initialize(boolean refresh) { ArrayList result = new ArrayList(); - result.add(this.getSupportedMessage()); + if(refresh == true || initialiseDone == false) { + result.add(this.getSupportedMessage()); + } return result; } @@ -199,13 +210,17 @@ public Collection initialize() { * {@inheritDoc} */ @Override - public Collection getDynamicValues() { + public Collection getDynamicValues(boolean refresh) { ArrayList result = new ArrayList(); - for (SetpointType setpointType : this.setpointTypes) { - if(setpointType==null){ - logger.warn("NODE {}: Ignoring null setpointType in setpointTypes", this.getNode().getNodeId()); - } else { - result.add(getMessage(setpointType)); + for (Map.Entry entry : this.setpoints.entrySet()) { + if(refresh == true || entry.getValue().getInitialised() == false) { + SerialMessage mesg = getMessage(entry.getValue().getSetpointType()); + entry.getValue().incrementInitCount(); + if(mesg == null){ + logger.warn("NODE {}: Ignoring null setpointType in setpointTypes", this.getNode().getNodeId()); + } else { + result.add(mesg); + } } } return result; @@ -216,14 +231,28 @@ public Collection getDynamicValues() { */ @Override public SerialMessage getValueMessage() { - for (SetpointType setpointType : this.setpointTypes) { - return this.getMessage(setpointType); + if(isGetSupported == false) { + logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId()); + return null; } + for (Map.Entry entry : this.setpoints.entrySet()) { + return getMessage(entry.getValue().getSetpointType()); + } + // in case there are no supported setpoint types, get them. return this.getSupportedMessage(); } - + + @Override + public boolean setOptions (ZWaveDbCommandClass options) { + if(options.isGetSupported != null) { + isGetSupported = options.isGetSupported; + } + + return true; + } + /** * Gets a SerialMessage with the THERMOSTAT_SETPOINT_GET command * @param setpointType the setpoint type to get @@ -234,8 +263,8 @@ public SerialMessage getMessage(SetpointType setpointType) { return null; } - logger.debug("NODE {}: Creating new message for application command THERMOSTAT_SETPOINT_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Get); + logger.debug("NODE {}: Creating new message for application command THERMOSTAT_SETPOINT_GET ({})", this.getNode().getNodeId(),setpointType.getLabel()); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] payload = { (byte) this.getNode().getNodeId(), 3, @@ -252,9 +281,9 @@ public SerialMessage getMessage(SetpointType setpointType) { * @return the serial message, or null if the supported command is not supported. */ public SerialMessage getSupportedMessage() { - logger.debug("NODE {}: Creating new message for application command THERMOSTAT_SETPOINT_SUPPORTED_GET", this.getNode().getNodeId()); + logger.debug("NODE {}: Creating new message for command THERMOSTAT_SETPOINT_SUPPORTED_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.High); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), @@ -277,10 +306,10 @@ public SerialMessage setValueMessage(int value) { * @return the serial message */ public SerialMessage setMessage(int scale, BigDecimal setpoint) { - for (SetpointType setpointType : this.setpointTypes) { - return setMessage(scale, setpointType, setpoint); + for (Map.Entry entry : this.setpoints.entrySet()) { + return setMessage(scale, entry.getValue().getSetpointType(), setpoint); } - + // in case there are no supported setpoint types, get them. return this.getSupportedMessage(); } @@ -293,7 +322,7 @@ public SerialMessage setMessage(int scale, BigDecimal setpoint) { * @return the serial message */ public SerialMessage setMessage(int scale, SetpointType setpointType, BigDecimal setpoint) { - logger.debug("NODE {}: Creating new message for application command THERMOSTAT_SETPOINT_SET", this.getNode().getNodeId()); + logger.debug("NODE {}: Creating new message for command THERMOSTAT_SETPOINT_SET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Set); try @@ -389,6 +418,42 @@ public String getLabel() { } } + + /** + * Class to hold setpoint state + * @author Chris Jackson + */ + private class Setpoint { + SetpointType setpointType; + boolean initialised = false; + int initCount = 0; + + public Setpoint(SetpointType type) { + setpointType = type; + } + + public SetpointType getSetpointType() { + return setpointType; + } + + public void setInitialised() { + initialised = true; + initCount = 0; + } + + public boolean getInitialised() { + return initialised; + } + + public void incrementInitCount(){ + initCount++; + if(initCount >= MAX_DYNAMIC_TRIES) { + setInitialised(); + logger.warn("Reached max tries to init the setpont {}, this will be our last attempt ", setpointType.getLabel()); + } + } + } + /** * Z-Wave Thermostat Setpoint Event class. Indicates that a setpoint value * changed. diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveVersionCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveVersionCommandClass.java index 3f23526fadd..e7521330779 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveVersionCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveVersionCommandClass.java @@ -18,7 +18,6 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,8 +45,8 @@ public class ZWaveVersionCommandClass extends ZWaveCommandClass { public static final int VERSION_COMMAND_CLASS_REPORT = 0x14; private LibraryType libraryType = LibraryType.LIB_UNKNOWN; - private Double protocolVersion; - private Double applicationVersion; + private String protocolVersion; + private String applicationVersion; /** * Creates a new instance of the ZWaveVersionCommandClass class. @@ -81,59 +80,60 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, switch (command) { case VERSION_GET: case VERSION_COMMAND_CLASS_GET: - logger.warn(String.format("Command 0x%02X not implemented.", command)); + logger.warn("Command {} not implemented.", command); return; case VERSION_REPORT: - logger.debug("Process Version Report"); + logger.debug("NODE {}: Process Version Report", this.getNode().getNodeId()); libraryType = LibraryType.getLibraryType(serialMessage.getMessagePayloadByte(offset + 1)); - protocolVersion = (double)serialMessage.getMessagePayloadByte(offset + 2) + - ((double)serialMessage.getMessagePayloadByte(offset + 3) / 10); - applicationVersion = serialMessage.getMessagePayloadByte(offset + 4) + - ((double)serialMessage.getMessagePayloadByte(offset + 5) / 10); + protocolVersion = Integer.toString(serialMessage.getMessagePayloadByte(offset + 2)) + "." + + Integer.toString(serialMessage.getMessagePayloadByte(offset + 3)); + applicationVersion = Integer.toString(serialMessage.getMessagePayloadByte(offset + 4)) + "." + + Integer.toString(serialMessage.getMessagePayloadByte(offset + 5)); logger.debug(String.format("NODE %d: Library Type = 0x%02x", this.getNode().getNodeId(), libraryType.key)); logger.debug(String.format("NODE %d: Protocol Version = %.1f", this.getNode().getNodeId(), protocolVersion)); logger.debug(String.format("NODE %d: Application Version = %.1f", this.getNode().getNodeId(), applicationVersion)); break; case VERSION_COMMAND_CLASS_REPORT: - logger.debug("Process Version Command Class Report"); + logger.debug("NODE {}: Process Version Command Class Report", this.getNode().getNodeId()); int commandClassCode = serialMessage.getMessagePayloadByte(offset + 1); int commandClassVersion = serialMessage.getMessagePayloadByte(offset + 2); CommandClass commandClass = CommandClass.getCommandClass(commandClassCode); if (commandClass == null) { - logger.error(String.format("Unsupported command class 0x%02x", commandClassCode)); + logger.error(String.format("NODE %d: Unsupported command class 0x%02x", this.getNode().getNodeId(), commandClassCode)); return; } - logger.debug(String.format("NODE %d: Requested Command Class = %s (0x%02x)", this.getNode().getNodeId(), commandClass.getLabel() , commandClassCode)); - logger.debug(String.format("NODE %d: Version = %d", this.getNode().getNodeId(), commandClassVersion)); + logger.debug("NODE {}: Requested Command Class = {}, Version = {}", this.getNode().getNodeId(), commandClass.getLabel(), + commandClassVersion); // The version is set on the command class for this node. By updating the version, extra functionality is unlocked in the command class. // The messages are backwards compatible, so it's not a problem that there is a slight delay when the command class version is queried on the // node. ZWaveCommandClass zwaveCommandClass = this.getNode().getCommandClass(commandClass); if (zwaveCommandClass == null) { - logger.error(String.format("Unsupported command class %s (0x%02x)", commandClass.getLabel(), commandClassCode)); + logger.error(String.format("NODE %d: Unsupported command class %s (0x%02x)", this.getNode().getNodeId(), commandClass.getLabel(), commandClassCode)); return; } + // If the device reports version 0, it means it doesn't support this command class! + if(commandClassVersion == 0) { + logger.info("NODE {}: Command Class {} has version 0!", this.getNode().getNodeId(), commandClass.getLabel()); + + // TODO: We should remove the class + // For now, just set the version to 1 to avoid a loop on initialisation + commandClassVersion = 1; +// this.getNode().removeCommandClass(zwaveCommandClass); + } + if (commandClassVersion > zwaveCommandClass.getMaxVersion()) { zwaveCommandClass.setVersion( zwaveCommandClass.getMaxVersion() ); - logger.debug(String.format("NODE %d: Version = %d, version set to maximum supported by the binding. Enabling extra functionality.", this.getNode().getNodeId(), zwaveCommandClass.getMaxVersion())); + logger.debug("NODE {}: Version = {}, version set to maximum supported by the binding. Enabling extra functionality.", this.getNode().getNodeId(), zwaveCommandClass.getMaxVersion()); } else { zwaveCommandClass.setVersion( commandClassVersion ); - logger.debug(String.format("NODE %d: Version = %d, version set. Enabling extra functionality.", this.getNode().getNodeId(), commandClassVersion)); + logger.debug("NODE {}: Version = {}, version set. Enabling extra functionality.", this.getNode().getNodeId(), commandClassVersion); } - - for (ZWaveCommandClass zCC : this.getNode().getCommandClasses()) { - // wait for all nodes to get/set version information before advancing to the next stage. - if (zCC.getVersion() == 0) - return; - } - // advance node stage; - this.getNode().advanceNodeStage(NodeStage.INSTANCES_ENDPOINTS); - break; default: logger.warn(String.format("Unsupported Command 0x%02X for command class %s (0x%02X).", @@ -144,12 +144,12 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, } /** - * Gets a SerialMessage with the VERSION GET command + * Gets a SerialMessage with the VERSION_GET command * @return the serial message */ public SerialMessage getVersionMessage() { - logger.debug("NODE {}: Creating new message for application command VERSION_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); + logger.debug("NODE {}: Creating new message for command VERSION_GET", this.getNode().getNodeId()); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), @@ -167,7 +167,7 @@ public SerialMessage getVersionMessage() { */ public SerialMessage getCommandClassVersionMessage(CommandClass commandClass) { logger.debug("NODE {}: Creating new message for application command VERSION_COMMAND_CLASS_GET command class {}", this.getNode().getNodeId(), commandClass.getLabel()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 3, (byte) getCommandClass().getKey(), @@ -181,8 +181,9 @@ public SerialMessage getCommandClassVersionMessage(CommandClass commandClass) { /** * Check the version of a command class by sending a VERSION_COMMAND_CLASS_GET message to the node. * @param commandClass the command class to check the version for. + * @return serial message to be sent */ - public void checkVersion(ZWaveCommandClass commandClass) { + public SerialMessage checkVersion(ZWaveCommandClass commandClass) { ZWaveVersionCommandClass versionCommandClass = (ZWaveVersionCommandClass)this.getNode().getCommandClass(CommandClass.VERSION); if (versionCommandClass == null) { @@ -191,10 +192,10 @@ public void checkVersion(ZWaveCommandClass commandClass) { this.getNode().getNodeId(), commandClass.getCommandClass().getLabel(), commandClass.getCommandClass().getKey())); - return; + return null; } - - this.getController().sendData(versionCommandClass.getCommandClassVersionMessage(commandClass.getCommandClass())); + + return versionCommandClass.getCommandClassVersionMessage(commandClass.getCommandClass()); }; /** @@ -208,7 +209,7 @@ public LibraryType getLibraryType() { * Returns the version of the protocol used by the device * @return Protocol version as double (version . subversion) */ - public Double getProtocolVersion() { + public String getProtocolVersion() { return protocolVersion; } @@ -216,7 +217,7 @@ public Double getProtocolVersion() { * Returns the version of the firmware used by the device * @return Application version as double (version . subversion) */ - public Double getApplicationVersion() { + public String getApplicationVersion() { return applicationVersion; } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveWakeUpCommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveWakeUpCommandClass.java index f01455d5208..ac9a2ce2765 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveWakeUpCommandClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/ZWaveWakeUpCommandClass.java @@ -14,7 +14,6 @@ import java.util.TimerTask; import java.util.concurrent.ArrayBlockingQueue; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; @@ -57,10 +56,16 @@ public class ZWaveWakeUpCommandClass extends ZWaveCommandClass implements ZWaveC @XStreamOmitField private ArrayBlockingQueue wakeUpQueue; - + + // From interval report + @XStreamOmitField + private boolean initReportDone = false; private int targetNodeId = 0; private int interval = 0; - + + // From capabilities report + @XStreamOmitField + private boolean initCapabilitiesDone = false; private int minInterval = 0; private int maxInterval = 0; private int defaultInterval = 0; @@ -69,15 +74,14 @@ public class ZWaveWakeUpCommandClass extends ZWaveCommandClass implements ZWaveC @XStreamOmitField private volatile boolean isAwake = false; - @XStreamOmitField - private boolean initializationComplete = false; - @XStreamOmitField private Timer timer = null; @XStreamOmitField private TimerTask timerTask = null; - + @XStreamOmitField + private boolean initialiseDone = false; + /** * Creates a new instance of the ZWaveWakeUpCommandClass class. * @param node the node this command class belongs to @@ -125,7 +129,6 @@ public int getMaxVersion() { @Override public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) { - logger.trace("Handle Message Wake Up Request"); logger.debug("NODE {}: Received Wake Up Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); @@ -134,33 +137,31 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, case WAKE_UP_INTERVAL_GET: case WAKE_UP_INTERVAL_CAPABILITIES_GET: case WAKE_UP_NO_MORE_INFORMATION: - logger.warn(String.format("Command 0x%02X not implemented.", command)); + logger.warn("Command {} not implemented.", command); return; case WAKE_UP_INTERVAL_REPORT: - logger.trace("Process Wake Up Interval"); - + logger.trace("NODE {}: Process Wake Up Interval", this.getNode().getNodeId()); + initReportDone = true; + // according to open-zwave: it seems that some devices send incorrect interval report messages. Don't know if they are spurious. // if not we should advance the node stage. if(serialMessage.getMessagePayload().length < offset + 4) { - logger.error("NODE {}: Unusual response: WAKE_UP_INTERVAL_REPORT with length = {}. Ignored.", this.getNode().getNodeId(), serialMessage.getMessagePayload().length); - return; + logger.error("NODE {}: Unusual response: WAKE_UP_INTERVAL_REPORT with length = {}. Ignored.", this.getNode().getNodeId(), serialMessage.getMessagePayload().length); + return; } - - targetNodeId = serialMessage.getMessagePayloadByte(offset +4); + + targetNodeId = serialMessage.getMessagePayloadByte(offset + 4); int receivedInterval = ((serialMessage.getMessagePayloadByte(offset + 1)) << 16) | ((serialMessage.getMessagePayloadByte(offset + 2)) << 8) | (serialMessage.getMessagePayloadByte(offset + 3)); - logger.debug(String.format("NODE %d: Wake up interval report, value = %d seconds, targetNodeId = %d", this.getNode().getNodeId(), receivedInterval, targetNodeId)); - + logger.debug("NODE {}: Wake up interval report, value = {} seconds, targetNodeId = {}", this.getNode().getNodeId(), receivedInterval, targetNodeId); + this.interval = receivedInterval; - logger.debug("NODE {}: Wake up interval set", this.getNode().getNodeId()); - - this.initializationComplete = true; + ZWaveWakeUpEvent event = new ZWaveWakeUpEvent(getNode().getNodeId(), WAKE_UP_INTERVAL_REPORT); this.getController().notifyEventListeners(event); - - this.getNode().advanceNodeStage(NodeStage.DYNAMIC); break; case WAKE_UP_INTERVAL_CAPABILITIES_REPORT: - logger.trace("Process Wake Up Interval Capabilities"); + logger.trace("NODE {}: Process Wake Up Interval Capabilities", this.getNode().getNodeId()); + initCapabilitiesDone = true; this.minInterval = ((serialMessage.getMessagePayloadByte(offset + 1)) << 16) | ((serialMessage.getMessagePayloadByte(offset + 2)) << 8) | (serialMessage.getMessagePayloadByte(offset + 3)); this.maxInterval = ((serialMessage.getMessagePayloadByte(offset + 4)) << 16) | ((serialMessage.getMessagePayloadByte(offset + 5)) << 8) | (serialMessage.getMessagePayloadByte(offset + 6)); @@ -171,25 +172,11 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, logger.debug("NODE {}: Minimum interval = {}", this.getNode().getNodeId(), this.minInterval); logger.debug("NODE {}: Maximum interval = {}", this.getNode().getNodeId(), this.maxInterval); logger.debug("NODE {}: Default interval = {}", this.getNode().getNodeId(), this.defaultInterval); - logger.debug("NODE {}: Interval step = {}", this.getNode().getNodeId(), this.intervalStep); - - this.initializationComplete = true; - this.getNode().advanceNodeStage(NodeStage.DYNAMIC); + logger.debug("NODE {}: Interval step = {}", this.getNode().getNodeId(), this.intervalStep); break; case WAKE_UP_NOTIFICATION: - logger.trace("Process Wake Up Notification"); - - logger.debug("NODE {}: is awake", this.getNode().getNodeId()); - serialMessage.setTransActionCanceled(true); - - // if this node has not gone through it's query stages yet, and there - // are no initialization packets on the wake-up queue, restart initialization. - if (!this.initializationComplete && (this.wakeUpQueue.isEmpty() || this.getNode().isDead() == true)) { - logger.info("NODE {}: Got Wake Up Notification from node, continuing initialization.", this.getNode().getNodeId()); - - this.getNode().setNodeStage(NodeStage.WAKEUP); - this.getNode().advanceNodeStage(NodeStage.DETAILS); - } + logger.debug("NODE {}: Received WAKE_UP_NOTIFICATION", this.getNode().getNodeId()); + serialMessage.setTransactionCanceled(); // Set the awake flag. This will also empty the queue this.setAwake(true); @@ -209,7 +196,7 @@ public void handleApplicationCommandRequest(SerialMessage serialMessage, */ public SerialMessage getNoMoreInformationMessage() { logger.debug("NODE {}: Creating new message for application command WAKE_UP_NO_MORE_INFORMATION", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Low); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Immediate); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), @@ -232,6 +219,8 @@ public SerialMessage getNoMoreInformationMessage() { public boolean processOutgoingWakeupMessage(SerialMessage serialMessage) { // The message is Ok, if we're awake, send it now... if(isAwake) { + // We're sending a frame, so we need to stop the timer if it's running + resetSleepTimer(); return true; } @@ -245,9 +234,9 @@ public boolean processOutgoingWakeupMessage(SerialMessage serialMessage) { this.wakeUpQueue.remove(serialMessage); } - logger.debug("NODE {}: Putting message in wakeup queue.", this.getNode().getNodeId()); + logger.debug("NODE {}: Putting message {} in wakeup queue.", this.getNode().getNodeId(), serialMessage.getMessageClass()); this.wakeUpQueue.add(serialMessage); - + // This message has been queued - don't send it now... return false; } @@ -258,7 +247,7 @@ public boolean processOutgoingWakeupMessage(SerialMessage serialMessage) { */ public SerialMessage getIntervalMessage() { logger.debug("NODE {}: Creating new message for application command WAKE_UP_INTERVAL_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), @@ -273,7 +262,7 @@ public SerialMessage getIntervalMessage() { */ public SerialMessage getIntervalCapabilitiesMessage() { logger.debug("NODE {}: Creating new message for application command WAKE_UP_INTERVAL_CAPABILITIES_GET", this.getNode().getNodeId()); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), @@ -326,11 +315,22 @@ public int getIntervalStep() { * {@inheritDoc} */ @Override - public Collection initialize() { + public Collection initialize(boolean refresh) { ArrayList result = new ArrayList(2); - result.add(this.getIntervalMessage()); // get wake up interval. - if (this.getVersion() > 1) - result.add(this.getIntervalCapabilitiesMessage()); // get default values for wake up interval. + if(refresh == true) { + initReportDone = false; + initCapabilitiesDone = false; + } + + if(initReportDone == false) { + // get wake up interval. + result.add(getIntervalMessage()); + } + + if(initCapabilitiesDone == false && this.getVersion() > 1) { + // get default values for wake up interval. + result.add(getIntervalCapabilitiesMessage()); + } return result; } @@ -342,19 +342,22 @@ public Collection initialize() { */ @Override public void ZWaveIncomingEvent(ZWaveEvent event) { - if (!(event instanceof ZWaveTransactionCompletedEvent)) + if (!(event instanceof ZWaveTransactionCompletedEvent)) { return; - + } + SerialMessage serialMessage = ((ZWaveTransactionCompletedEvent)event).getCompletedMessage(); - - if (serialMessage.getMessageClass() != SerialMessageClass.SendData && serialMessage.getMessageType() != SerialMessageType.Request) + + if (serialMessage.getMessageClass() != SerialMessageClass.SendData && serialMessage.getMessageType() != SerialMessageType.Request) { return; - + } + byte[] payload = serialMessage.getMessagePayload(); - + // Check if it's addressed to this node - if (payload.length == 0 || (payload[0] & 0xFF) != this.getNode().getNodeId()) + if (payload.length == 0 || (payload[0] & 0xFF) != this.getNode().getNodeId()) { return; + } // We now know that this is a message to this node. // If it's not the WAKE_UP_NO_MORE_INFORMATION, then we need to set the wakeup timer @@ -369,7 +372,10 @@ public void ZWaveIncomingEvent(ZWaveEvent event) { // Send the next message in the wake-up queue if (!this.wakeUpQueue.isEmpty()) { + // Get the next message from the queue. + // Bump it's priority to highest to try and send it while the node is awake serialMessage = this.wakeUpQueue.poll(); + serialMessage.setPriority(SerialMessagePriority.Immediate); this.getController().sendData(serialMessage); } else if(isAwake() == true){ @@ -396,17 +402,20 @@ public boolean isAwake() { */ public void setAwake(boolean isAwake) { this.isAwake = isAwake; - + if(isAwake) { + logger.debug("NODE {}: Is awake with {} messages in the wake-up queue.", this.getNode().getNodeId(), this.wakeUpQueue.size()); + ZWaveWakeUpEvent event = new ZWaveWakeUpEvent(getNode().getNodeId(), WAKE_UP_NOTIFICATION); this.getController().notifyEventListeners(event); - - logger.debug("NODE {}: Is awake with {} messages in the wake-up queue.", this.getNode().getNodeId(), this.wakeUpQueue.size()); // Handle the wake-up queue for this node. // We send the first message, and when that's ACKed, we sent the next if (!this.wakeUpQueue.isEmpty()) { + // Get the next message from the queue. + // Bump it's priority to highest to try and send it while the node is awake SerialMessage serialMessage = this.wakeUpQueue.poll(); + serialMessage.setPriority(SerialMessagePriority.Immediate); this.getController().sendData(serialMessage); } else { @@ -416,6 +425,9 @@ public void setAwake(boolean isAwake) { setSleepTimer(); } } + else { + logger.debug("NODE {}: Is sleeping", this.getNode().getNodeId()); + } } /** @@ -427,7 +439,7 @@ public void setAwake(boolean isAwake) { */ public SerialMessage setInterval(int interval) { logger.debug("NODE {}: Creating new message for application command WAKE_UP_INTERVAL_SET to {}", this.getNode().getNodeId(), interval); - SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Config); byte[] newPayload = { (byte) this.getNode().getNodeId(), 6, (byte) getCommandClass().getKey(), @@ -437,6 +449,8 @@ public SerialMessage setInterval(int interval) { (byte)( interval & 0xff ), (byte) getController().getOwnNodeId()}; result.setMessagePayload(newPayload); + byte[] buffer = result.getMessageBuffer(); + logger.debug("NODE {}: Sending REQUEST Message = {}", result.getMessageNode(), SerialMessage.bb2hex(buffer)); return result; } @@ -479,20 +493,26 @@ public void run() { wakeup.getController().sendData(wakeup.getNoMoreInformationMessage()); } } - + public synchronized void setSleepTimer() { // Stop any existing timer - if(timerTask != null) { - timerTask.cancel(); - } + resetSleepTimer(); // Create the timer task timerTask = new WakeupTimerTask(this); // Start the timer - timer.schedule(timerTask, 2000); + timer.schedule(timerTask, 1000); } - + + public synchronized void resetSleepTimer() { + // Stop any existing timer + if(timerTask != null) { + timerTask.cancel(); + } + timerTask = null; + } + /** * ZWave wake-up event. * Notifies users that a device has woken up or changed its wakeup parameters @@ -512,7 +532,7 @@ public ZWaveWakeUpEvent(int nodeId, int event) { super(nodeId, 1); this.event = event; } - + public int getEvent() { return this.event; } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/proprietary/FibaroFGRM222CommandClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/proprietary/FibaroFGRM222CommandClass.java new file mode 100644 index 00000000000..86d79110fe6 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/commandclass/proprietary/FibaroFGRM222CommandClass.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2014 openHAB.org. + * 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 + * + * Contributors: + * openHAB.org - initial API and implementation and/or initial documentation + */ +package org.openhab.binding.zwave.internal.protocol.commandclass.proprietary; + +import org.openhab.binding.zwave.internal.protocol.SerialMessage; +import org.openhab.binding.zwave.internal.protocol.ZWaveController; +import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; +import org.openhab.binding.zwave.internal.protocol.ZWaveNode; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; +import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Have a look at: http://forum.micasaverde.com/index.php?topic=24050.0 + * + * @author wenzel + * @author Markus Rathgeb + */ +public class FibaroFGRM222CommandClass extends ZWaveCommandClass { + + private static final Logger logger = LoggerFactory.getLogger(FibaroFGRM222CommandClass.class); + private static final int blindOffset = 5; + private static final int lamellaTiltOffset = 6; + + public FibaroFGRM222CommandClass(ZWaveNode node, ZWaveController controller, ZWaveEndpoint endpoint) { + super(node, controller, endpoint); + } + + @Override + public CommandClass getCommandClass() { + return CommandClass.FIBARO_FGRM_222; + } + + @Override + public void handleApplicationCommandRequest(final SerialMessage serialMessage, final int offset, final int endpoint) { + logger.debug("NODE {}: handleApplicationCommandRequest: {}", this.getNode().getNodeId(), + serialMessage.toString()); + + int blindValue = serialMessage.getMessagePayloadByte(offset + blindOffset); + int lamellaTiltValue = serialMessage.getMessagePayloadByte(offset + lamellaTiltOffset); + + logger.debug("NODE {}: Blind Value: {}", this.getNode().getNodeId(), blindValue); + logger.debug("NODE {}: Lamella Tilt Value: {}", this.getNode().getNodeId(), lamellaTiltValue); + + FibaroFGRM222ValueEvent shutterEvent = new FibaroFGRM222ValueEvent(this.getNode().getNodeId(), endpoint, + FibaroFGRM222ValueType.Shutter, blindValue); + this.getController().notifyEventListeners(shutterEvent); + FibaroFGRM222ValueEvent lamellaEvent = new FibaroFGRM222ValueEvent(this.getNode().getNodeId(), endpoint, + FibaroFGRM222ValueType.Lamella, lamellaTiltValue); + this.getController().notifyEventListeners(lamellaEvent); + } + + public SerialMessage setValueMessage(final int level, final String type) { + logger.debug("NODE {}: Creating new message for application command FIBARO FGRM 222 set. type: {}. level {}.", + this.getNode().getNodeId(), type, level); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessage.SerialMessageClass.SendData, + SerialMessage.SerialMessageType.Request, SerialMessage.SerialMessageClass.SendData, + SerialMessage.SerialMessagePriority.Set); + byte[] newPayload; + if (type.equalsIgnoreCase(FibaroFGRM222ValueType.Shutter.name())) { + newPayload = new byte[] { (byte) this.getNode().getNodeId(), // Node ID of Target Node + (byte) 8, // Number of payload Bytes following + (byte) 0x91, // 4 Magic Fibaro Bytes. + (byte) 0x1, (byte) 0xF, (byte) 0x26, (byte) 1, // set blind % (1 --> set, 2 ? , 3 report + (byte) 2, // set lamella + (byte) level, // blind level + (byte) 0 // lamella level + }; + } else { + newPayload = new byte[] { (byte) this.getNode().getNodeId(), (byte) 8, (byte) 0x91, (byte) 0x1, (byte) 0xF, + (byte) 0x26, (byte) 1, // set blind % (1 --> set, 2 ? , 3 report + (byte) 1, // set lamella + (byte) 0, // blind level + (byte) level // lamella level + }; + } + result.setMessagePayload(newPayload); + return result; + } + + /** + * Gets a SerialMessage with the SWITCH_MULTILEVEL_STOP_LEVEL_CHANGE command + * + * @return the serial message + */ + public SerialMessage stopLevelChangeMessage(final String type) { + // logger.debug("Creating new stop message for application command FIBARO FGRM 222 set for node {}. type: {}. level {}.", + // this.getNode().getNodeId(), type); + // SerialMessage result = new SerialMessage(this.getNode().getNodeId(), + // SerialMessage.SerialMessageClass.SendData, SerialMessage.SerialMessageType.Request, + // SerialMessage.SerialMessageClass.SendData, SerialMessage.SerialMessagePriority.Set); + // byte[] newPayload; + // if (type.equalsIgnoreCase(FibaroFGRM222ValueType.Shutter.name())) { + // newPayload = new byte[]{ + // (byte) this.getNode().getNodeId(), + // (byte) 8, + // (byte) -111, // 0x91 is -111 in java because of signed und unsigned byte bullshit... + // (byte) 1, + // (byte) 15, + // (byte) 38, + // (byte) 1, // set blind % (1 --> set, 2 ? , 3 report + // (byte) 3, // set lamelle + // (byte) 0, // blind level + // (byte) 0 // lamella level + // }; + // } else { + // newPayload = new byte[]{ + // (byte) this.getNode().getNodeId(), + // (byte) 8, + // (byte) -111, + // (byte) 1, + // (byte) 15, + // (byte) 38, + // (byte) 3, // set blind % (1 --> set, 2 ? , 3 report + // (byte) 1, // set lamelle + // (byte) 0, // blind level + // (byte) 0 // lamella level + // }; + // } + // result.setMessagePayload(newPayload); + // return result; + logger.debug("NODE {}: Creating new message for application command SWITCH_MULTILEVEL_STOP_LEVEL_CHANGE", this + .getNode().getNodeId()); + SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessage.SerialMessageClass.SendData, + SerialMessage.SerialMessageType.Request, SerialMessage.SerialMessageClass.SendData, + SerialMessage.SerialMessagePriority.Set); + byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) CommandClass.SWITCH_MULTILEVEL.getKey(), + (byte) 0x05 }; + result.setMessagePayload(newPayload); + return result; + } + + public enum FibaroFGRM222ValueType { + + Shutter, Lamella; + } + + public class FibaroFGRM222ValueEvent extends ZWaveCommandClassValueEvent { + + private final FibaroFGRM222ValueType sensorType; + + /** + * Constructor. Creates a instance of the ZWaveBinarySensorValueEvent + * class. + * + * @param nodeId the nodeId of the event + * @param endpoint the endpoint of the event. + * @param sensorType the sensor type that triggered the event; + * @param value the value for the event. + */ + private FibaroFGRM222ValueEvent(int nodeId, int endpoint, FibaroFGRM222ValueType sensorType, Object value) { + super(nodeId, endpoint, CommandClass.FIBARO_FGRM_222, value); + this.sensorType = sensorType; + } + + /** + * Gets the sensor type for this value event. + * + * @return + */ + public FibaroFGRM222ValueType getSensorType() { + return sensorType; + } + } +} \ No newline at end of file diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/event/ZWaveNodeStatusEvent.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/event/ZWaveNodeStatusEvent.java index 27e4ea5d7a3..878ac124739 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/event/ZWaveNodeStatusEvent.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/event/ZWaveNodeStatusEvent.java @@ -8,30 +8,28 @@ */ package org.openhab.binding.zwave.internal.protocol.event; +import org.openhab.binding.zwave.internal.protocol.ZWaveNodeState; + /** * Node status event is used to signal if a node is alive or dead * @author Chris Jackson * @since 1.5.0 */ public class ZWaveNodeStatusEvent extends ZWaveEvent { - State state; + ZWaveNodeState state; /** * Constructor. Creates a new instance of the ZWaveNetworkEvent * class. * @param nodeId the nodeId of the event. */ - public ZWaveNodeStatusEvent(int nodeId, State state) { + public ZWaveNodeStatusEvent(int nodeId, ZWaveNodeState state) { super(nodeId); this.state = state; } - public State getState() { + public ZWaveNodeState getState() { return state; } - - public enum State { - Dead, Alive, Failed - } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/event/ZWaveTransactionCompletedEvent.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/event/ZWaveTransactionCompletedEvent.java index fc9f69b029f..defc7bb5700 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/event/ZWaveTransactionCompletedEvent.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/event/ZWaveTransactionCompletedEvent.java @@ -12,23 +12,28 @@ /** * ZWave Transaction Completed Event. Indicated that a transaction (a - * sequence of messages with an expected reply) has completed successfully. + * sequence of messages with an expected reply) has completed. * @author Jan-Willem Spuij * @since 1.4.0 */ public class ZWaveTransactionCompletedEvent extends ZWaveEvent { private final SerialMessage completedMessage; - + private final boolean state; + /** * Constructor. Creates a new instance of the ZWaveTransactionCompletedEvent * class. + * The 'state' flag is provided by the message handler when the message is processed + * and its value is defined by the message class. * @param completedMessage the original {@link SerialMessage} that has been completed. + * @param state a flag indicating success / failure of the transaction processing */ - public ZWaveTransactionCompletedEvent(SerialMessage completedMessage) { + public ZWaveTransactionCompletedEvent(SerialMessage completedMessage, boolean state) { super(completedMessage.getMessageNode()); this.completedMessage = completedMessage; + this.state = state; } /** @@ -38,4 +43,12 @@ public ZWaveTransactionCompletedEvent(SerialMessage completedMessage) { public SerialMessage getCompletedMessage() { return completedMessage; } + + /** + * Returns the processing state of this transaction + * @return + */ + public boolean getState() { + return state; + } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/initialization/ZWaveNodeInitStage.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/initialization/ZWaveNodeInitStage.java new file mode 100644 index 00000000000..d5477ee1527 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/initialization/ZWaveNodeInitStage.java @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.zwave.internal.protocol.initialization; + +import java.util.HashMap; +import java.util.Map; + +/** + * Node Stage Enumeration for node initialisation. + * @author Brian Crosby + * @author Chris Jackson + * @since 1.3.0 + */ +public enum ZWaveNodeInitStage { + EMPTYNODE(0, true, "Empty New Node"), + PROTOINFO(1, true, "Protocol Information"), + NEIGHBORS(2, true, "Node Neighbor Information"), + FAILED_CHECK(3, true, "Checking if node is failed"), + WAIT(4, true, "Waiting"), + PING(5, true, "Ping Node"), + DETAILS(6, true, "Node Information"), + MANUFACTURER(7, true, "Manufacture Name and Product Identification"), + VERSION(8, true, "Command Class Versions"), + APP_VERSION(9, true, "Application Version"), + ENDPOINTS(10, true, "Command Class Endpoints"), + UPDATE_DATABASE(11, true, "Updating database"), + STATIC_VALUES(12, true, "Static Information"), + ASSOCIATIONS(13, false, "Associations"), + SET_WAKEUP(14, false, "Wakeup Target"), + SET_ASSOCIATION(15, false, "Wakeup Target"), + GET_CONFIGURATION(16, false, "Getting configuration"), + STATIC_END(17, false, "Static Initialisation Finished"), + + // States below are not restored from the configuration files + SESSION_START(18, false, "Restore Marker"), + DYNAMIC_VALUES(19, false, "Frequently Changed Information"), + + DONE(20, false, "Node Complete"); + + private int stage; + private boolean mandatory; + private String label; + + /** + * A mapping between the integer code and its corresponding + * Node Stage to facilitate lookup by code. + */ + private static Map codeToNodeStageMapping; + + private ZWaveNodeInitStage (int s, boolean m, String l) { + stage = s; + mandatory = m; + label = l; + } + + private static void initMapping() { + codeToNodeStageMapping = new HashMap(); + for (ZWaveNodeInitStage s : values()) { + codeToNodeStageMapping.put(s.stage, s); + } + } + + /** + * Get the stage protocol number. + * @return number + */ + public int getStage() { + return this.stage; + } + + /** + * Get the stage label + * @return label + */ + public String getLabel() { + return this.label; + } + + /** + * Lookup function based on the command class code. + * Returns null if there is no command class with code i + * @param i the code to lookup + * @return enumeration value of the command class. + */ + public static ZWaveNodeInitStage getNodeStage(int i) { + if (codeToNodeStageMapping == null) { + initMapping(); + } + + return codeToNodeStageMapping.get(i); + } + + /** + * Return the next stage after the current stage + * @return the next stage + */ + public ZWaveNodeInitStage getNextStage() { + for (ZWaveNodeInitStage s : values()) { + if(s.stage == this.stage + 1) { + return s; + } + } + + return null; + } + + /** + * Check if the current stage has completed the static stages. + * @return true if static stages complete + */ + public boolean isStaticComplete() { + if(stage > SESSION_START.stage) { + return true; + } + return false; + } + + /** + * Check if the current stage has completed the static stages. + * @return true if static stages complete + */ + public boolean isStageMandatory() { + return mandatory; + } +} diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/initialization/ZWaveNodeSerializer.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/initialization/ZWaveNodeSerializer.java index c7bedb50888..fa1c3916bda 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/initialization/ZWaveNodeSerializer.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/initialization/ZWaveNodeSerializer.java @@ -17,7 +17,6 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; -import org.openhab.binding.zwave.internal.ZWaveActivator; import org.openhab.binding.zwave.internal.protocol.ZWaveDeviceClass; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; @@ -41,7 +40,7 @@ public class ZWaveNodeSerializer { private static final Logger logger = LoggerFactory.getLogger(ZWaveNodeSerializer.class); private final XStream stream = new XStream(new StaxDriver()); - private final String folderName = "etc/zwave"; + private String folderName = "etc/zwave"; /** * Constructor. Creates a new instance of the {@link ZWaveNodeSerializer} @@ -50,7 +49,16 @@ public class ZWaveNodeSerializer { public ZWaveNodeSerializer() { logger.trace("Initializing ZWaveNodeSerializer."); - File folder = new File(folderName); + // Change the folder for OH2 + // ConfigConstants.getUserDataFolder(); + final String USERDATA_DIR_PROG_ARGUMENT = "smarthome.userdata"; + final String eshUserDataFolder = System.getProperty(USERDATA_DIR_PROG_ARGUMENT); + if (eshUserDataFolder != null) { + folderName = eshUserDataFolder + "/zwave"; + } + + final File folder = new File(folderName); + // create path for serialization. if (!folder.exists()) { logger.debug("Creating directory {}", folderName); @@ -85,6 +93,14 @@ public ZWaveNodeSerializer() { */ public void SerializeNode(ZWaveNode node) { synchronized (stream) { + // Don't serialise if the stage is not at least finished static + // If we do serialise when we haven't completed the static stages + // then when the binding starts it will have incomplete information! + if(node.getNodeInitializationStage().isStaticComplete() == false) { + logger.debug("NODE {}: Serialise aborted as static stages not complete", node.getNodeId()); + return; + } + File file = new File(this.folderName, String.format("node%d.xml", node.getNodeId())); BufferedWriter writer = null; @@ -95,13 +111,14 @@ public void SerializeNode(ZWaveNode node) { stream.marshal(node, new PrettyPrintWriter(writer)); writer.flush(); } catch (IOException e) { - logger.error("NODE {}: There was an error writing the node config to a file: {}", node.getNodeId(), e.getMessage()); + logger.error("NODE {}: Error serializing to file: {}", node.getNodeId(), e.getMessage()); } finally { - if (writer != null) + if (writer != null) { try { writer.close(); } catch (IOException e) { } + } } } } @@ -118,10 +135,10 @@ public ZWaveNode DeserializeNode(int nodeId) { File file = new File(this.folderName, String.format("node%d.xml", nodeId)); BufferedReader reader = null; - logger.debug("NODE {}: Deserializing from file {}", nodeId, file.getPath()); + logger.debug("NODE {}: Serializing from file {}", nodeId, file.getPath()); if (!file.exists()) { - logger.debug("NODE {}: Deserializing from file {} failed, file does not exist.", nodeId, file.getPath()); + logger.debug("NODE {}: Error serializing from file: file does not exist.", nodeId); return null; } @@ -129,7 +146,7 @@ public ZWaveNode DeserializeNode(int nodeId) { reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); return (ZWaveNode)stream.fromXML(reader); } catch (IOException e) { - logger.error("NODE {}: There was an error reading the node config from a file: {}", nodeId, e.getMessage()); + logger.error("NODE {}: Error serializing from file: {}", nodeId, e.getMessage()); } finally { if (reader != null) try { diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/initialization/ZWaveNodeStageAdvancer.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/initialization/ZWaveNodeStageAdvancer.java index f3414965200..c2bf97cb29c 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/initialization/ZWaveNodeStageAdvancer.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/initialization/ZWaveNodeStageAdvancer.java @@ -10,21 +10,43 @@ import java.util.Calendar; import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ArrayBlockingQueue; -import org.openhab.binding.zwave.internal.protocol.NodeStage; -import org.openhab.binding.zwave.internal.protocol.SerialInterfaceException; +import org.openhab.binding.zwave.internal.config.ZWaveDbAssociationGroup; +import org.openhab.binding.zwave.internal.config.ZWaveDbCommandClass; +import org.openhab.binding.zwave.internal.config.ZWaveDbConfigurationParameter; +import org.openhab.binding.zwave.internal.config.ZWaveProductDatabase; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; +import org.openhab.binding.zwave.internal.protocol.ZWaveDeviceClass.Generic; import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; +import org.openhab.binding.zwave.internal.protocol.ZWaveEventListener; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; +import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass.CommandClass; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveVersionCommandClass.LibraryType; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveAssociationCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClassDynamicState; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClassInitialization; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveManufacturerSpecificCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveMultiInstanceCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveNoOperationCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveVersionCommandClass; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass; +import org.openhab.binding.zwave.internal.protocol.event.ZWaveEvent; +import org.openhab.binding.zwave.internal.protocol.event.ZWaveInitializationCompletedEvent; +import org.openhab.binding.zwave.internal.protocol.event.ZWaveNodeStatusEvent; +import org.openhab.binding.zwave.internal.protocol.event.ZWaveTransactionCompletedEvent; +import org.openhab.binding.zwave.internal.protocol.serialmessage.GetRoutingInfoMessageClass; +import org.openhab.binding.zwave.internal.protocol.serialmessage.IdentifyNodeMessageClass; +import org.openhab.binding.zwave.internal.protocol.serialmessage.IsFailedNodeMessageClass; +import org.openhab.binding.zwave.internal.protocol.serialmessage.RequestNodeInfoMessageClass; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,20 +54,99 @@ * ZWaveNodeStageAdvancer class. Advances the node stage, thereby controlling * the initialization of a node. * + * Node initialisation is handled solely within the NodeStageAdvancer. It is not + * based on time - it waits for the transactions to complete. Time cannot be + * used since with larger networks, it may take a long time for the + * initialisation. This is especially true if there are battery nodes since the + * PING phase, used to detect if a node is active, will time-out for battery + * devices. A timeout takes 5 seconds, and if there are retries active, this may + * be extended to 15 seconds. For a network with 8 battery nodes, this could + * mean a delay of 2 minutes! + * + * We use the 'listening' flag to prioritise the initialisation of nodes. Rather + * than kicking off all nodes at the same time and have battery nodes timing out + * and delaying the initialisation of mains nodes, we try and initialise nodes + * that are listening first. This is checked after the protocol information + * is received, and non-listening nodes are held at a WAIT state until the + * transmit queue drops below 2 frames when they are allowed to proceed to PING. + * + * The NodeStageAdvancer registers an event listener during the initialisation + * of a node. This allows it to be notified when each transaction is complete, + * and we can process this accordingly. The event listener is removed when we + * stop initialising to reduce processor loading. + * + * Command classes are responsible for building lists of messages needed to + * initialise themselves. The command class also needs to keep track of + * responses so it knows if initialisation of this stage is complete. Other than + * that, the command class does not have any input into the initialisation + * phase, and the sequencing of events - this is all handled here in the node + * advancer class. + * + * For each stage, the advancer builds a list of all messages that need to be + * sent to the node. Since the initialisation phase is an intense period, with a + * lot of messages on the network, we try and ensure that only 1 packet is + * outstanding to any node at once to avoid filling up the main transmit queue + * which could impact on the performance of other nodes. + * + * Each time we receive an ACK for a message, the node advancer gets called, and + * we see if this is an ACK for a message that's part of the initialisation. If + * it is, the message gets removed from the list. + * + * Each time we receive a command message, the node advancer gets called. This + * is called after the command class has been updated, so at this stage we know + * if the stage can be completed. + * + * Two checks are performed to allow a node stage to advance. Firstly, we make + * sure we've sent all the messages required for this phase. Sending the + * messages however doesn't guarantee that we get a response, so we then run + * through the stage again to make sure that the command class really is + * initialised. If the second run queues no messages, then we can reliably + * assume this stage is completed. If we've missed anything, then we continue + * until there are no messages to send. + * + * If a node is DEAD (or FAILED) then we still try to initialise. No HEAL is + * performed on initialising nodes, so we need to do enough here to find out + * if the node comes back to life. + * A 'is node failed' check is performed at the beginning of the init process. + * This asks the controller if it thinks the node is dead - if it is, then we + * treat the node as dead until it comes back to life. + * A DEAD node will use a backoff to reduce the traffic. We start sending data + * reasonably quickly, but if it fails, then we reduce the retry timer by a + * factor of 2 until BACKOFF_TIMER_MAX is reached. + * << NOTE THAT THE ABOVE BACKOFF ISN'T IMPLEMENTED YET >> + * * @author Jan-Willem Spuij + * @author Chris Jackson * @since 1.4.0 */ -public class ZWaveNodeStageAdvancer { +public class ZWaveNodeStageAdvancer implements ZWaveEventListener { private static final ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer(); private static final Logger logger = LoggerFactory.getLogger(ZWaveNodeStageAdvancer.class); private ZWaveNode node; private ZWaveController controller; - private int queriesPending = -1; - private boolean initializationComplete = false; private boolean restoredFromConfigfile = false; + private static final int MAX_BUFFFER_LEN = 256; + private ArrayBlockingQueue msgQueue; + private boolean freeToSend = true; + private boolean stageAdvanced = true; + + private static final int MAX_RETRIES = 5; + private int retryCount = 0; + + private final int BACKOFF_TIMER_START = 5000; + private final int BACKOFF_TIMER_MAX = 1800000; // 30 minutes max backoff + private int retryTimer; + private TimerTask timerTask = null; + private Timer timer = null; + + private int wakeupCount; + + private Date queryStageTimeStamp; + private ZWaveNodeInitStage currentStage; + /** * Constructor. Creates a new instance of the ZWaveNodeStageAdvancer class. * @@ -57,255 +158,797 @@ public class ZWaveNodeStageAdvancer { public ZWaveNodeStageAdvancer(ZWaveNode node, ZWaveController controller) { this.node = node; this.controller = controller; + + // Initialise the message queue + msgQueue = new ArrayBlockingQueue(MAX_BUFFFER_LEN, true); + } + + /** + * Starts the initialisation from the beginning. + */ + public void startInitialisation() { + // Reset the state variables + currentStage = ZWaveNodeInitStage.EMPTYNODE; + queryStageTimeStamp = Calendar.getInstance().getTime(); + retryTimer = BACKOFF_TIMER_START; + + // Create the timer and timer task + timer = new Timer(); + + wakeupCount = 0; + + // Set an event callback so we get notification of events + controller.addEventListener(this); + + // Get things moving... + advanceNodeStage(null); } /** - * Advances the initialization stage for this node. Every node follows a - * certain path through it's initialization phase. These stages are visited - * one by one to finally end up with a completely built node structure - * through querying the controller / node. TODO: Handle the rest of the node - * stages + * Handles the removal of frames from the send queue. This gets called after + * we have an ACK for our packet, but before we get the response. The actual + * sending of frames, and the advancing is carried out in the + * advanceNodeStage method. */ - public void advanceNodeStage(NodeStage targetStage) { - if (targetStage.getStage() <= this.node.getNodeStage().getStage() && targetStage != NodeStage.DONE) { - logger.warn(String.format("NODE %d: Already in or beyond node stage, ignoring. current = %s, requested = %s", this.node.getNodeId(), - this.node.getNodeStage().getLabel(), targetStage.getLabel())); + public void handleNodeQueue(SerialMessage incomingMessage) { + // If initialisation is complete, then just return. + // This probably shouldn't be necessary since we remove the event + // handler when we're done, but just to be sure... + if (currentStage == ZWaveNodeInitStage.DONE) { return; } - logger.debug(String.format("NODE %d: Setting stage. current = %s, requested = %s", this.node.getNodeId(), - this.node.getNodeStage().getLabel(), targetStage.getLabel())); - - this.node.setQueryStageTimeStamp(Calendar.getInstance().getTime()); - switch (this.node.getNodeStage()) { - case EMPTYNODE: - try { - this.node.setNodeStage(NodeStage.PROTOINFO); - this.controller.identifyNode(this.node.getNodeId()); - } catch (SerialInterfaceException e) { - logger.error("NODE {}: Got error {}, while identifying node", this.node.getNodeId(), e.getLocalizedMessage()); + + logger.debug("NODE {}: Node advancer - checking initialisation queue. Queue size {}.", + node.getNodeId(), msgQueue.size()); + + // If this message is in the queue, then remove it + if (msgQueue.contains(incomingMessage)) { + msgQueue.remove(incomingMessage); + logger.debug("NODE {}: Node advancer - message removed from queue. Queue size {}.", + node.getNodeId(), msgQueue.size()); + + freeToSend = true; + + // We've sent a frame, let's process the stage... + advanceNodeStage(incomingMessage.getMessageClass()); + } + } + + /** + * Sends a message if there is one queued + * + * @return true if a message was sent. false otherwise. + */ + private boolean sendMessage() { + if (msgQueue.isEmpty() == true) { + return false; + } + + // Check to see if we need to send a frame + if (freeToSend == true) { + SerialMessage msg = msgQueue.peek(); + if (msg != null) { + freeToSend = false; + + if (msg.getMessageClass() == SerialMessageClass.SendData) { + controller.sendData(msg); + } + else { + controller.enqueue(msg); + } + + logger.debug("NODE {}: Node advancer - queued packet. Queue length is {}", node.getNodeId(), + msgQueue.size()); } - break; - case PROTOINFO: - if (this.node.getNodeId() != this.controller.getOwnNodeId()) { - ZWaveNoOperationCommandClass zwaveCommandClass = (ZWaveNoOperationCommandClass) this.node - .getCommandClass(CommandClass.NO_OPERATION); - if (zwaveCommandClass == null) - break; + } - this.node.setNodeStage(NodeStage.PING); - this.controller.sendData(zwaveCommandClass.getNoOperationMessage()); + return true; + } + + /** + * Advances the initialization stage for this node. This method is called + * after a response is received. We don't necessarily know if the response + * is to the frame we requested though, so to be sure the initialisation + * gets all the information it needs, the command class itself gets queried. + * This method also handles the sending of frames. Since the initialisation + * phase is a busy one we try and only have one outstanding request. Again + * though, we can't be sure that a response is aligned with the node + * advancer request so it is possible that more than one packet can be + * released at once, but it will constrain things. + */ + public void advanceNodeStage(SerialMessageClass eventClass) { + // If initialisation is complete, then just return. + // This probably shouldn't be necessary since we remove the event + // handler when we're done, but just to be sure... + if (currentStage == ZWaveNodeInitStage.DONE) { + return; + } + + logger.debug("NODE {}: Node advancer - {}: queue length({}), free to send({})", node.getNodeId(), + currentStage.toString(), msgQueue.size(), freeToSend); + + // If this is a battery node, and we exceed the wakeup count without advancing + // the stage, then reset. + if(wakeupCount >= 3) { + msgQueue.clear(); + wakeupCount = 0; + } + + // Start the retry timer + startIdleTimer(); + + // If event class is null, then this call isn't the result of an + // incoming frame. + // It could be a wakeup, or the node is now alive. Get things moving + // again. + if (eventClass == null) { + freeToSend = true; + } + + // If the queue is not empty, then we can't advance any further. + if (sendMessage() == true) { + // We're still sending messages, so we're not ready to proceed. + return; + } + + // The stageAdvanced flag is used to tell command classes that this + // is the first iteration. + // During the first iteration all messages are queued. After this, + // only outstanding requests are returned. + // This continues until there are no requests required. + stageAdvanced = false; + + ZWaveProductDatabase database; + + // We run through all stages until one queues a message. + // Then we will wait for the response before continuing + do { + // Ensure we don't get stuck in an endless loop trying to initialise + // something that is broken, or not responding to a particular request + if(stageAdvanced == true) { + retryCount = 0; } else { - logger.debug("NODE {}: Initialisation complete.", this.node.getNodeId()); - initializationComplete = true; - this.node.setNodeStage(NodeStage.DONE); // nothing - // more - // to - // do - // for - // this - // node. + retryCount++; + if(retryCount > MAX_RETRIES) { + retryCount = 0; + logger.error("NODE {}: Node advancer: Retries exceeded at {}", + node.getNodeId(), currentStage.toString()); + if(currentStage.isStageMandatory() == false) { + // If the current stage is not mandatory, then we skip forward to the next + // stage. + logger.debug("NODE {}: Retry timout: Advancing", node.getNodeId()); + setCurrentStage(currentStage.getNextStage()); + } + else { + // For static stages, we MUST complete all steps otherwise we end + // up with incomplete information about the device. + // During the static stages, we use the back off timer to pace things + // and retry until the stage is complete + logger.debug("NODE {}: Retry timout: Can't advance", node.getNodeId()); + break; + } + } } - break; - case PING: - case WAKEUP: - // if restored from a config file, redo from the dynamic - // node stage. - if (this.isRestoredFromConfigfile()) { - this.node.setNodeStage(NodeStage.DYNAMIC); - advanceNodeStage(NodeStage.DONE); + + logger.debug("NODE {}: Node advancer: loop - {} try {}: stageAdvanced({})", node.getNodeId(), + currentStage.toString(), retryCount, stageAdvanced); + + switch (currentStage) { + case EMPTYNODE: + logger.debug("NODE {}: Node advancer: Initialisation starting", node.getNodeId()); break; - } - this.node.setNodeStage(NodeStage.DETAILS); - this.controller.requestNodeInfo(this.node.getNodeId()); - break; - case DETAILS: - // try and get the manufacturerSpecific command class. - ZWaveManufacturerSpecificCommandClass manufacturerSpecific = (ZWaveManufacturerSpecificCommandClass) this.node - .getCommandClass(CommandClass.MANUFACTURER_SPECIFIC); - - if (manufacturerSpecific != null) { - // if this node implements the Manufacturer Specific command - // class, we use it to get manufacturer info. - this.node.setNodeStage(NodeStage.MANSPEC01); - this.controller.sendData(manufacturerSpecific.getManufacturerSpecificMessage()); + + case PROTOINFO: + // If the incoming frame is the IdentifyNode, then we continue + if (eventClass == SerialMessageClass.IdentifyNode) { + break; + } + + logger.debug("NODE {}: Node advancer: PROTOINFO - send IdentifyNode", node.getNodeId()); + addToQueue(new IdentifyNodeMessageClass().doRequest(node.getNodeId())); break; - } - logger.warn("NODE {}: does not support MANUFACTURER_SPECIFIC, proceeding to version node stage.", - this.node.getNodeId()); - case MANSPEC01: - this.node.setNodeStage(NodeStage.VERSION); - // try and get the version command class. - ZWaveVersionCommandClass version = (ZWaveVersionCommandClass) this.node - .getCommandClass(CommandClass.VERSION); - - boolean checkVersionCalled = false; - for (ZWaveCommandClass zwaveCommandClass : this.node.getCommandClasses()) { - if (version != null && zwaveCommandClass.getMaxVersion() > 1) { - version.checkVersion(zwaveCommandClass); // check version - // for this - // command - // class. - checkVersionCalled = true; - } else - zwaveCommandClass.setVersion(1); - } + case NEIGHBORS: + // If the incoming frame is the IdentifyNode, then we continue + if (eventClass == SerialMessageClass.GetRoutingInfo) { + break; + } - if (checkVersionCalled) // wait for another call of advanceNodeStage - // before continuing. + logger.debug("NODE {}: Node advancer: NEIGHBORS - send RoutingInfo", node.getNodeId()); + addToQueue(new GetRoutingInfoMessageClass().doRequest(node.getNodeId())); break; - case VERSION: - this.node.setNodeStage(NodeStage.INSTANCES_ENDPOINTS); - // try and get the multi instance / channel command class. - ZWaveMultiInstanceCommandClass multiInstance = (ZWaveMultiInstanceCommandClass) this.node - .getCommandClass(CommandClass.MULTI_INSTANCE); - - if (multiInstance != null) { - multiInstance.initEndpoints(); + + case FAILED_CHECK: + // It seems that PC_CONTROLLERs don't respond to a lot of requests, so let's + // just assume their OK! + // If this is a controller, we're done + if (node.getDeviceClass().getGenericDeviceClass() == Generic.STATIC_CONTOLLER) { + logger.debug("NODE {}: Node advancer: FAILED_CHECK - Controller - terminating initialisation", node.getNodeId()); + currentStage = ZWaveNodeInitStage.DONE; + break; + } + + // If the incoming frame is the IdentifyNode, then we continue + if (eventClass == SerialMessageClass.IsFailedNodeID) { + break; + } + + addToQueue(new IsFailedNodeMessageClass().doRequest(node.getNodeId())); + break; + + case WAIT: + logger.debug("NODE {}: Node advancer: WAIT - Listening={}, FrequentlyListening={}", node.getNodeId(), + node.isListening(), node.isFrequentlyListening()); + // If the node is listening, or frequently listening, then we progress. + if(node.isListening() == true || node.isFrequentlyListening() == true) { + logger.debug("NODE {}: Node advancer: WAIT - Advancing", node.getNodeId()); + break; + } + + // If the device supports the wakeup class, then see if we're awake + ZWaveWakeUpCommandClass wakeUpCommandClass = (ZWaveWakeUpCommandClass) node + .getCommandClass(CommandClass.WAKE_UP); + if (wakeUpCommandClass != null && wakeUpCommandClass.isAwake() == true) { + logger.debug("NODE {}: Node advancer: WAIT - Node is awake", node.getNodeId()); + break; + } + + // If it's not listening, and not awake, + // we'll wait a while before progressing with initialisation. + logger.debug("NODE {}: Node advancer: WAIT - Still waiting!", node.getNodeId()); + return; + + case PING: + // Completion of this stage is reception of a SendData frame. + // The purpose of this stage is to ensure that the node is awake + // before requesting further information. + // It's not 100% guaranteed that this was our NoOp frame, but + // who cares! + if (eventClass == SerialMessageClass.SendData) { + break; + } + + ZWaveNoOperationCommandClass noOpCommandClass = (ZWaveNoOperationCommandClass) node + .getCommandClass(CommandClass.NO_OPERATION); + if (noOpCommandClass == null) { + break; + } + + logger.debug("NODE {}: Node advancer: PING - send NoOperation", node.getNodeId()); + SerialMessage msg = noOpCommandClass.getNoOperationMessage(); + if (msg != null) { + // We only send out a single PING - no retries at controller + // level! This is to try and reduce network congestion during + // initialisation. + // For battery devices, the PING will time-out. This takes 5 + // seconds and if there are retries, it will be 15 seconds! + // This will block the network for a considerable time if there + // are a lot of battery devices (eg. 2 minutes for 8 battery devices!). + msg.attempts = 1; + addToQueue(msg); + } + break; + + case DETAILS: + // If restored from a config file, redo from the dynamic node stage. + if (isRestoredFromConfigfile()) { + logger.debug("NODE {}: Node advancer: Restored from file - skipping static initialisation", node.getNodeId()); + currentStage = ZWaveNodeInitStage.SESSION_START; + break; + } + + // If the incoming frame is the IdentifyNode, then we continue + if (node.getApplicationUpdateReceived() == true) { + logger.debug("NODE {}: Node advancer: received RequestNodeInfo", node.getNodeId()); + break; + } + + logger.debug("NODE {}: Node advancer: DETAILS - send RequestNodeInfo", node.getNodeId()); + addToQueue(new RequestNodeInfoMessageClass().doRequest(node.getNodeId())); + break; + + case MANUFACTURER: + // If we already know the device information, then continue + if (node.getManufacturer() != Integer.MAX_VALUE && node.getDeviceType() != Integer.MAX_VALUE + && node.getDeviceId() != Integer.MAX_VALUE) { + break; + } + + // try and get the manufacturerSpecific command class. + ZWaveManufacturerSpecificCommandClass manufacturerSpecific = (ZWaveManufacturerSpecificCommandClass) node + .getCommandClass(CommandClass.MANUFACTURER_SPECIFIC); + + if (manufacturerSpecific != null) { + // If this node implements the Manufacturer Specific command + // class, we use it to get manufacturer info. + logger.debug("NODE {}: Node advancer: MANUFACTURER - send ManufacturerSpecific", node.getNodeId()); + addToQueue(manufacturerSpecific.getManufacturerSpecificMessage()); + } + break; + + case VERSION: + // Try and get the version command class. + ZWaveVersionCommandClass version = (ZWaveVersionCommandClass) node + .getCommandClass(CommandClass.VERSION); + + // Loop through all command classes, requesting their version + // using the Version command class + for (ZWaveCommandClass zwaveVersionClass : node.getCommandClasses()) { + logger.debug("NODE {}: Node advancer: VERSION - checking {}, version is {}", node.getNodeId(), + zwaveVersionClass.getCommandClass().getLabel(), zwaveVersionClass.getVersion()); + if (version != null && zwaveVersionClass.getMaxVersion() > 1 && zwaveVersionClass.getVersion() == 0) { + logger.debug("NODE {}: Node advancer: VERSION - queued {}", node.getNodeId(), zwaveVersionClass + .getCommandClass().getLabel()); + addToQueue(version.checkVersion(zwaveVersionClass)); + } + else if (zwaveVersionClass.getVersion() == 0) { + logger.debug("NODE {}: Node advancer: VERSION - VERSION default to 1", node.getNodeId()); + zwaveVersionClass.setVersion(1); + } + } + logger.debug("NODE {}: Node advancer: VERSION - queued {} frames", node.getNodeId(), msgQueue.size()); break; - } - logger.trace("NODE {}: does not support MULTI_INSTANCE, proceeding to static node stage.", - this.node.getNodeId()); - case INSTANCES_ENDPOINTS: - this.node.setNodeStage(NodeStage.STATIC_VALUES); - case STATIC_VALUES: - if (queriesPending == -1) { - queriesPending = 0; - for (ZWaveCommandClass zwaveCommandClass : this.node.getCommandClasses()) { - logger.trace("NODE {}: Inspecting command class {}", this.node.getNodeId(), zwaveCommandClass.getCommandClass().getLabel()); - if (zwaveCommandClass instanceof ZWaveCommandClassInitialization) { - logger.debug("NODE {}: Found initializable command class {}", this.node.getNodeId(), zwaveCommandClass.getCommandClass() - .getLabel()); - ZWaveCommandClassInitialization zcci = (ZWaveCommandClassInitialization) zwaveCommandClass; - int instances = zwaveCommandClass.getInstances(); - if (instances == 0) { - Collection initqueries = zcci.initialize(); - for (SerialMessage serialMessage : initqueries) { - this.controller.sendData(serialMessage); - queriesPending++; + case APP_VERSION: + ZWaveVersionCommandClass versionCommandClass = (ZWaveVersionCommandClass) node + .getCommandClass(CommandClass.VERSION); + + if (versionCommandClass == null) { + logger.debug("NODE {}: Node advancer: APP_VERSION - VERSION node supported", node.getNodeId()); + break; + } + + // If we know the library type, then we've got the app version + if (versionCommandClass.getLibraryType() != LibraryType.LIB_UNKNOWN) { + break; + } + + // Request the version report for this node + logger.debug("NODE {}: Node advancer: APP_VERSION - send VersionMessage", node.getNodeId()); + addToQueue(versionCommandClass.getVersionMessage()); + break; + + case ENDPOINTS: + // Try and get the multi instance / channel command class. + ZWaveMultiInstanceCommandClass multiInstance = (ZWaveMultiInstanceCommandClass) node + .getCommandClass(CommandClass.MULTI_INSTANCE); + + if (multiInstance != null) { + logger.debug("NODE {}: Node advancer: ENDPOINTS - MultiInstance is supported", node.getNodeId()); + addToQueue(multiInstance.initEndpoints(stageAdvanced)); + logger.debug("NODE {}: Node advancer: ENDPOINTS - queued {} frames", node.getNodeId(), msgQueue.size()); + } + else { + logger.debug("NODE {}: Node advancer: ENDPOINTS - MultiInstance not supported.", node.getNodeId()); + // Set all classes to 1 instance. + for (ZWaveCommandClass commandClass : node.getCommandClasses()) { + commandClass.setInstances(1); + } + } + break; + + case UPDATE_DATABASE: + // This stage reads information from the database to allow us to modify the configuration + logger.debug("NODE {}: Node advancer: UPDATE_DATABASE", node.getNodeId()); + + // We now should know all the command classes, so run through the database and set any options + database = new ZWaveProductDatabase(); + if(database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == true) { + List classList = database.getProductCommandClasses(); + + if (classList != null) { + // Loop through the command classes and update the records... + for (ZWaveDbCommandClass dbClass : classList) { + // If we want to remove the class, then remove it! + if(dbClass.remove != null && dbClass.remove == true) { + // TODO: This will only remove the root nodes and ignores endpoint + // TODO: Do we need to search into multi_instance? + node.removeCommandClass(CommandClass.getCommandClass(dbClass.Id)); + logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - removing {}", + node.getNodeId(), CommandClass.getCommandClass(dbClass.Id).getLabel()); + continue; } - } else { - for (int i = 1; i <= instances; i++) { - Collection initqueries = zcci.initialize(); - for (SerialMessage serialMessage : initqueries) { - this.controller - .sendData(this.node.encapsulate(serialMessage, zwaveCommandClass, i)); - queriesPending++; + + // Get the command class + int endpoint = dbClass.endpoint == null ? 0 : dbClass.endpoint; + ZWaveCommandClass zwaveClass = node.resolveCommandClass(CommandClass.getCommandClass(dbClass.Id), endpoint); + + // If we found the command class, then set its options + if(zwaveClass != null) { + zwaveClass.setOptions(dbClass); + continue; + } + + // Command class isn't found! Do we want to add it? + // TODO: Does this need to account for multiple endpoints!?! + if(dbClass.add != null && dbClass.add == true) { + ZWaveCommandClass commandClass = ZWaveCommandClass.getInstance(dbClass.Id, node, controller); + if (commandClass != null) { + logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - adding {}", + node.getNodeId(), CommandClass.getCommandClass(dbClass.Id).getLabel()); + node.addCommandClass(commandClass); } } } - } else if (zwaveCommandClass instanceof ZWaveMultiInstanceCommandClass) { - ZWaveMultiInstanceCommandClass multiInstanceCommandClass = (ZWaveMultiInstanceCommandClass) zwaveCommandClass; + } + } + break; + + case STATIC_VALUES: + // Loop through all classes looking for static initialisation + for (ZWaveCommandClass zwaveStaticClass : node.getCommandClasses()) { + logger.debug("NODE {}: Node advancer: STATIC_VALUES - checking {}", node.getNodeId(), zwaveStaticClass + .getCommandClass().getLabel()); + if (zwaveStaticClass instanceof ZWaveCommandClassInitialization) { + logger.debug("NODE {}: Node advancer: STATIC_VALUES - found {}", node.getNodeId(), zwaveStaticClass + .getCommandClass().getLabel()); + ZWaveCommandClassInitialization zcci = (ZWaveCommandClassInitialization) zwaveStaticClass; + int instances = zwaveStaticClass.getInstances(); + logger.debug("NODE {}: Found {} instances of {}", node.getNodeId(), instances, zwaveStaticClass.getCommandClass()); + if (instances == 1) { + addToQueue(zcci.initialize(stageAdvanced)); + } + else { + for (int i = 1; i <= instances; i++) { + addToQueue(zcci.initialize(stageAdvanced), zwaveStaticClass, i); + } + } + } + else if (zwaveStaticClass instanceof ZWaveMultiInstanceCommandClass) { + ZWaveMultiInstanceCommandClass multiInstanceCommandClass = (ZWaveMultiInstanceCommandClass) zwaveStaticClass; for (ZWaveEndpoint endpoint : multiInstanceCommandClass.getEndpoints()) { for (ZWaveCommandClass endpointCommandClass : endpoint.getCommandClasses()) { - logger.trace(String.format("NODE %d: Inspecting command class %s for endpoint %d", this.node.getNodeId(), endpointCommandClass - .getCommandClass().getLabel(), endpoint.getEndpointId())); + logger.debug("NODE {}: Node advancer: STATIC_VALUES - checking {} for endpoint {}", + node.getNodeId(), endpointCommandClass.getCommandClass().getLabel(), + endpoint.getEndpointId()); if (endpointCommandClass instanceof ZWaveCommandClassInitialization) { - logger.debug("NODE {}: Found initializable command class {}", this.node.getNodeId(), endpointCommandClass - .getCommandClass().getLabel()); + logger.debug("NODE {}: Node advancer: STATIC_VALUES - found {}", node.getNodeId(), + endpointCommandClass.getCommandClass().getLabel()); ZWaveCommandClassInitialization zcci2 = (ZWaveCommandClassInitialization) endpointCommandClass; - Collection initqueries = zcci2.initialize(); - for (SerialMessage serialMessage : initqueries) { - this.controller.sendData(this.node.encapsulate(serialMessage, - endpointCommandClass, endpoint.getEndpointId())); - queriesPending++; - } + addToQueue(zcci2.initialize(stageAdvanced), endpointCommandClass, + endpoint.getEndpointId()); } } } } } - } - if (queriesPending-- > 0) // there is still something to be - // initialized. + logger.debug("NODE {}: Node advancer: STATIC_VALUES - queued {} frames", node.getNodeId(), msgQueue.size()); break; - logger.trace("NODE {}: Done getting static values, proceeding to dynamic node stage.", this.node.getNodeId()); - queriesPending = -1; - this.node.setNodeStage(NodeStage.DYNAMIC); - case DYNAMIC: - if (queriesPending == -1) { - queriesPending = 0; - for (ZWaveCommandClass zwaveCommandClass : this.node.getCommandClasses()) { - logger.trace("NODE {}: Inspecting command class {}", this.node.getNodeId(), zwaveCommandClass.getCommandClass().getLabel()); - if (zwaveCommandClass instanceof ZWaveCommandClassDynamicState) { - logger.debug("NODE {}: Found dynamic state command class {}", this.node.getNodeId(), zwaveCommandClass.getCommandClass() - .getLabel()); - ZWaveCommandClassDynamicState zdds = (ZWaveCommandClassDynamicState) zwaveCommandClass; - int instances = zwaveCommandClass.getInstances(); - if (instances == 0) { - Collection dynamicQueries = zdds.getDynamicValues(); - for (SerialMessage serialMessage : dynamicQueries) { - this.controller.sendData(serialMessage); - queriesPending++; - } - } else { + case ASSOCIATIONS: + // Do we support associations + ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node.getCommandClass(CommandClass.ASSOCIATION); + if(associationCommandClass == null) { + break; + } + + // For now, we have no-way of knowing if we've received an update to the association + // so just do this once + if(stageAdvanced == false) { + break; + } + + // Open the product database + ZWaveProductDatabase associations = new ZWaveProductDatabase(); + if(associations.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == true) { + // We have this device in the database + // Assume the database is correct since some devices report invalid number of groups! + List groupList = associations.getProductAssociationGroups(); + + // No groups known + if (groupList == null) { + logger.debug("NODE {}: Node advancer: ASSOCIATIONS - none in database", node.getNodeId()); + break; + } + + // Request every group + for (ZWaveDbAssociationGroup group : groupList) { + logger.debug("NODE {}: Node advancer: ASSOCIATIONS request group {}", node.getNodeId(), group.Index); + addToQueue(associationCommandClass.getAssociationMessage(group.Index)); + } + } + else { + for(int group = 1; group <= associationCommandClass.getMaxGroups(); group++) { + logger.debug("NODE {}: Node advancer: ASSOCIATIONS request group {}", node.getNodeId(), group); + addToQueue(associationCommandClass.getAssociationMessage(group)); + } + } + break; + + case SET_WAKEUP: + // This stage sets the wakeup class if we're the master controller + // It sets the node to point to us, and the time is left along + if(controller.isMasterController() == false) { + break; + } + + ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.WAKE_UP); + + if (wakeupCommandClass == null) { + logger.debug("NODE {}: Node advancer: SET_WAKEUP - Wakeup command class not supported", node.getNodeId()); + break; + } + + if (wakeupCommandClass.getTargetNodeId() == controller.getOwnNodeId()) { + logger.debug("NODE {}: Node advancer: SET_WAKEUP - TargetNode is set to controller", node.getNodeId()); + break; + } + + int value = 3600; + if (wakeupCommandClass.getInterval() == 0) { + logger.debug("NODE {}: Node advancer: SET_WAKEUP - Interval is currently 0. Set to 3600", node.getNodeId()); + } + else { + value = wakeupCommandClass.getInterval(); + } + + logger.debug("NODE {}: Node advancer: SET_WAKEUP - Set wakeup node to controller ({}), period {}", node.getNodeId(), controller.getOwnNodeId(), value); + + // Set the wake-up interval, and request an update + addToQueue(wakeupCommandClass.setInterval(value)); + addToQueue(wakeupCommandClass.getIntervalMessage()); + break; + + case SET_ASSOCIATION: + if(controller.isMasterController() == false) { + break; + } + + database = new ZWaveProductDatabase(); + if(database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) { + // No database entry for this device! + logger.warn("NODE {}: Node advancer: SET_ASSOCIATION - Unknown device: {}:{}:{}", node.getNodeId(), + Integer.toHexString(node.getManufacturer()), Integer.toHexString(node.getDeviceType()), Integer.toHexString(node.getDeviceId())); + break; + } + + List groups = database.getProductAssociationGroups(); + if(groups == null || groups.size() == 0) { + logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - No association groups", node.getNodeId()); + break; + } + + // Get the group members + ZWaveAssociationCommandClass associationCls = (ZWaveAssociationCommandClass) node + .getCommandClass(CommandClass.ASSOCIATION); + if(associationCls == null) { + logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - ASSOCIATION class not supported", node.getNodeId()); + break; + } + + // Loop through all the groups in the database + for (ZWaveDbAssociationGroup group : groups) { + if(group.SetToController == true) { + // Check if we're already a member + if(associationCls.getGroupMembers(group.Index).contains(controller.getOwnNodeId())) { + logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - ASSOCIATION set for group {}", node.getNodeId(), group.Index); + } + else { + logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - Adding ASSOCIATION to group {}", node.getNodeId(), group.Index); + // Set the association, and request the update so we confirm if it's set + addToQueue(associationCls.setAssociationMessage(group.Index, controller.getOwnNodeId())); + addToQueue(associationCls.getAssociationMessage(group.Index)); + } + } + } + break; + + case GET_CONFIGURATION: + database = new ZWaveProductDatabase(); + if(database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) { + // No database entry for this device! + logger.warn("NODE {}: Node advancer: GET_CONFIGURATION - Unknown device: {}:{}:{}", node.getNodeId(), + Integer.toHexString(node.getManufacturer()), Integer.toHexString(node.getDeviceType()), Integer.toHexString(node.getDeviceId())); + break; + } + + ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node + .getCommandClass(CommandClass.CONFIGURATION); + + if (configurationCommandClass == null) { + logger.error("NODE {}: Node advancer: GET_CONFIGURATION - CONFIGURATION class not supported", node.getNodeId()); + break; + } + + // Request all parameters for this node + List configList = database.getProductConfigParameters(); + for (ZWaveDbConfigurationParameter parameter : configList) { + // Some parameters don't return anything, so don't request them! + if(parameter.WriteOnly != null && parameter.WriteOnly == true) { + configurationCommandClass.setParameterWriteOnly(parameter.Index, true); + continue; + } + + // If this is the first time around the loop + // or we don't have a value for this parameter + // then request it! + if(configurationCommandClass.getParameter(parameter.Index) == null) { + addToQueue(configurationCommandClass.getConfigMessage(parameter.Index)); + } + } + break; + + case DYNAMIC_VALUES: + for (ZWaveCommandClass zwaveDynamicClass : node.getCommandClasses()) { + logger.debug("NODE {}: Node advancer: DYNAMIC_VALUES - checking {}", node.getNodeId(), zwaveDynamicClass + .getCommandClass().getLabel()); + if (zwaveDynamicClass instanceof ZWaveCommandClassDynamicState) { + logger.debug("NODE {}: Node advancer: DYNAMIC_VALUES - found {}", node.getNodeId(), zwaveDynamicClass + .getCommandClass().getLabel()); + ZWaveCommandClassDynamicState zdds = (ZWaveCommandClassDynamicState) zwaveDynamicClass; + int instances = zwaveDynamicClass.getInstances(); + logger.debug("NODE {}: Found {} instances of {}", node.getNodeId(), instances, zwaveDynamicClass.getCommandClass()); + if (instances == 1) { + addToQueue(zdds.getDynamicValues(stageAdvanced)); + } + else { for (int i = 1; i <= instances; i++) { - Collection dynamicQueries = zdds.getDynamicValues(); - for (SerialMessage serialMessage : dynamicQueries) { - this.controller - .sendData(this.node.encapsulate(serialMessage, zwaveCommandClass, i)); - queriesPending++; - } + addToQueue(zdds.getDynamicValues(stageAdvanced), zwaveDynamicClass, i); } } - } else if (zwaveCommandClass instanceof ZWaveMultiInstanceCommandClass) { - ZWaveMultiInstanceCommandClass multiInstanceCommandClass = (ZWaveMultiInstanceCommandClass) zwaveCommandClass; + } + else if (zwaveDynamicClass instanceof ZWaveMultiInstanceCommandClass) { + ZWaveMultiInstanceCommandClass multiInstanceCommandClass = (ZWaveMultiInstanceCommandClass) zwaveDynamicClass; for (ZWaveEndpoint endpoint : multiInstanceCommandClass.getEndpoints()) { for (ZWaveCommandClass endpointCommandClass : endpoint.getCommandClasses()) { - logger.trace(String.format("NODE %d: Inspecting command class %s for endpoint %d", this.node.getNodeId(), endpointCommandClass - .getCommandClass().getLabel(), endpoint.getEndpointId())); + logger.debug("NODE {}: Node advancer: DYNAMIC_VALUES - checking {} for endpoint {}", + node.getNodeId(), endpointCommandClass.getCommandClass().getLabel(), + endpoint.getEndpointId()); if (endpointCommandClass instanceof ZWaveCommandClassDynamicState) { - logger.debug("NODE {}: Found dynamic state command class {}", this.node.getNodeId(), endpointCommandClass - .getCommandClass().getLabel()); + logger.debug("NODE {}: Node advancer: DYNAMIC_VALUES - found {}", node.getNodeId(), + endpointCommandClass.getCommandClass().getLabel()); ZWaveCommandClassDynamicState zdds2 = (ZWaveCommandClassDynamicState) endpointCommandClass; - Collection dynamicQueries = zdds2.getDynamicValues(); - for (SerialMessage serialMessage : dynamicQueries) { - this.controller.sendData(this.node.encapsulate(serialMessage, - endpointCommandClass, endpoint.getEndpointId())); - queriesPending++; - } + addToQueue(zdds2.getDynamicValues(stageAdvanced), endpointCommandClass, + endpoint.getEndpointId()); } } } } } - } - if (queriesPending-- > 0) // there is still something to be - // initialized. + logger.debug("NODE {}: Node advancer: DYNAMIC_VALUES - queued {} frames", node.getNodeId(), msgQueue.size()); break; - logger.trace("NODE {}: Done getting dynamic values, proceeding to done node stage.", this.node.getNodeId()); - queriesPending = -1; - - this.node.setNodeStage(NodeStage.DONE); // nothing - // more - // to - // do - // for - // this - // node. - - nodeSerializer.SerializeNode(this.node); - - logger.debug("NODE {}: Initialisation complete.", this.node.getNodeId()); - initializationComplete = true; - break; - case DONE: - case DEAD: - break; - default: - logger.error("NODE {}: Unknown node state {} encountered.", this.node.getNodeId(), this.node.getNodeStage().getLabel()); + + case STATIC_END: + case DONE: + // Save the node information to file + nodeSerializer.SerializeNode(node); + + if(currentStage != ZWaveNodeInitStage.DONE) { + break; + } + logger.debug("NODE {}: Node advancer: Initialisation complete!", node.getNodeId()); + + // Stop the retry timer + resetIdleTimer(); + + // We remove the event listener to reduce loading now that we're done + controller.removeEventListener(this); + + // Notify everyone! + ZWaveEvent zEvent = new ZWaveInitializationCompletedEvent(node.getNodeId()); + controller.notifyEventListeners(zEvent); + + // Return from here as we're now done and we don't want to + // increment the stage! + return; + + case SESSION_START: + // This is a 'do nothing' state. + // It's used as a marker within the NodeStage class to indicate + // where to start initialisation if we restored from XML. + break; + + default: + logger.debug("NODE {}: Node advancer: Unknown node state {} encountered.", + node.getNodeId(), currentStage.toString().toString()); + break; + } + + // If there are messages queued, send one. + // If there are none, then it means we're happy that we have all the + // data for this stage. + // If we have all the data, set stageAdvanced to true to tell the system + // that we're starting again, then loop around again. + if (currentStage != ZWaveNodeInitStage.DONE && sendMessage() == false) { + // Move on to the next stage + setCurrentStage(currentStage.getNextStage()); + stageAdvanced = true; + + // Reset the backoff timer + retryTimer = BACKOFF_TIMER_START; + + logger.debug("NODE {}: Node advancer - advancing to {}", node.getNodeId(), + currentStage.toString()); + } + } while (msgQueue.isEmpty()); + } + + /** + * Move the messages to the queue + * + * @param msgs + * the message collection + */ + private void addToQueue(SerialMessage serialMessage) { + if (serialMessage == null) { + return; + } + if (!msgQueue.contains(serialMessage) && msgQueue.remainingCapacity() > 1) { + msgQueue.add(serialMessage); + } + } + + /** + * Move all the messages in a collection to the queue + * + * @param msgs + * the message collection + */ + private void addToQueue(Collection msgs) { + if (msgs == null) { + return; + } + for (SerialMessage serialMessage : msgs) { + addToQueue(serialMessage); + } + } + + /** + * Move all the messages in a collection to the queue and encapsulates them + * + * @param msgs + * the message collection + * @param the + * command class to encapsulate + * @param endpointId + * the endpoint number + */ + private void addToQueue(Collection msgs, ZWaveCommandClass commandClass, int endpointId) { + if (msgs == null) { + return; + } + for (SerialMessage serialMessage : msgs) { + addToQueue(node.encapsulate(serialMessage, commandClass, endpointId)); } } + /** + * Gets the current node stage + * + * @return current node stage + */ + public ZWaveNodeInitStage getCurrentStage() { + return currentStage; + } + + /** + * Sets the current node stage + */ + public void setCurrentStage(ZWaveNodeInitStage newStage) { + currentStage = newStage; + + // Remember the time so we can handle retries and keep users + // informed + queryStageTimeStamp = Calendar.getInstance().getTime(); + } + + /** + * Sets the time stamp the node was last queried. + * + * @param queryStageTimeStamp + * the queryStageTimeStamp to set + */ + public Date getQueryStageTimeStamp() { + return queryStageTimeStamp; + } + /** * Returns whether the initialization process has completed. * * @return true if initialization has completed. False otherwise. */ public boolean isInitializationComplete() { - return initializationComplete; + return (currentStage == ZWaveNodeInitStage.DONE); } /** @@ -323,4 +966,135 @@ public boolean isRestoredFromConfigfile() { public void setRestoredFromConfigfile() { restoredFromConfigfile = true; } + + @Override + public void ZWaveIncomingEvent(ZWaveEvent event) { + // If we've already completed initialisation, then we're done! + if (currentStage == ZWaveNodeInitStage.DONE) { + return; + } + + // Process transaction complete events + if (event instanceof ZWaveTransactionCompletedEvent) { + ZWaveTransactionCompletedEvent completeEvent = (ZWaveTransactionCompletedEvent) event; + + SerialMessage serialMessage = completeEvent.getCompletedMessage(); + byte[] payload = serialMessage.getMessagePayload(); + + // Make sure this is addressed to us + if (payload.length == 0 || node.getNodeId() != (payload[0] & 0xFF)) { + // This is a corrupt frame, OR, it's not addressed to us + // We use this as a trigger to kick things off again if they've stalled + // by checking to see if the transmit queue is now empty. + // This will allow battery devices stuck in WAIT state to get moving. + if(controller.getSendQueueLength() < 2 && currentStage == ZWaveNodeInitStage.WAIT) { + logger.debug("NODE {}: Node advancer - WAIT: The WAIT is over!", node.getNodeId()); + + currentStage = currentStage.getNextStage(); + handleNodeQueue(null); + } + return; + } + + switch (serialMessage.getMessageClass()) { + case SendData: + case IdentifyNode: + case RequestNodeInfo: + case GetRoutingInfo: + case IsFailedNodeID: + logger.debug("NODE {}: Node advancer - {}: Transaction complete ({}:{}) success({})", + node.getNodeId(), currentStage.toString(), serialMessage.getMessageClass(), + serialMessage.getMessageType(), completeEvent.getState()); + + // If this frame was successfully sent, then handle the stage advancer + if (((ZWaveTransactionCompletedEvent) event).getState() == true) { + handleNodeQueue(serialMessage); + } + break; + default: + break; + } + } else if (event instanceof ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) { + // WAKEUP EVENT - only act if this is a wakeup notification + if (((ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) event).getEvent() != ZWaveWakeUpCommandClass.WAKE_UP_NOTIFICATION) { + return; + } + + // A wakeup event is received. Make sure it's for this node + if (node.getNodeId() != event.getNodeId()) { + return; + } + + logger.debug("NODE {}: Wakeup during initialisation.", node.getNodeId()); + + wakeupCount++; + advanceNodeStage(null); + } else if (event instanceof ZWaveNodeStatusEvent) { + ZWaveNodeStatusEvent statusEvent = (ZWaveNodeStatusEvent) event; + // A network status event is received. Make sure it's for this node. + if (node.getNodeId() != event.getNodeId()) { + return; + } + + logger.debug("NODE {}: Node Status event during initialisation - Node is {}", statusEvent.getNodeId(), + statusEvent.getState()); + + switch (statusEvent.getState()) { + case DEAD: + case FAILED: + break; + case ALIVE: + advanceNodeStage(null); + break; + } + logger.trace("NODE {}: Node Status event during initialisation processed", statusEvent.getNodeId()); + } + } + + // The following timer implements a re-triggerable timer. The timer is used to restart + // initialisation if it stalls using a log backoff + private class IdleTimerTask extends TimerTask { + @Override + public void run() { + // Increase the backoff + retryTimer *= 2; + if(retryTimer > BACKOFF_TIMER_MAX) { + retryTimer = BACKOFF_TIMER_MAX; + } + + // Timer has triggered, so log it! + logger.debug("NODE {}: Stage {}. Initialisation retry timer triggered. Increased to {}", + node.getNodeId(), currentStage.toString(), retryTimer); + + // Kickstart comms - clear the queue and run the advancer + msgQueue.clear(); + advanceNodeStage(null); + } + } + + private synchronized void resetIdleTimer() { + // Stop any existing timer + if(timerTask != null) { + timerTask.cancel(); + } + timerTask = null; + } + + private synchronized void startIdleTimer() { + // For nodes that aren't listening, don't start the timer + // We handle battery nodes differently - by counting the number of wakeups. + if(!node.isListening() && !node.isFrequentlyListening()) { + return; + } + + // Stop any existing timer + resetIdleTimer(); + + // Create the timer task + timerTask = new IdleTimerTask(); + + // Start the timer + timer.schedule(timerTask, retryTimer); + logger.debug("NODE {}: Initialisation retry timer started {}", node.getNodeId(), retryTimer); + } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AddNodeMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AddNodeMessageClass.java index 940578dd047..c8dd6edea08 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AddNodeMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AddNodeMessageClass.java @@ -69,11 +69,11 @@ public SerialMessage doRequestStop() { public boolean handleRequest(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) { switch(incomingMessage.getMessagePayloadByte(1)) { case ADD_NODE_STATUS_LEARN_READY: - logger.debug("Remove Node: Learn ready."); + logger.debug("Add Node: Learn ready."); zController.notifyEventListeners(new ZWaveInclusionEvent(ZWaveInclusionEvent.Type.IncludeStart)); break; case ADD_NODE_STATUS_NODE_FOUND: - logger.debug("Remove Node: New node found."); + logger.debug("Add Node: New node found."); break; case ADD_NODE_STATUS_ADDING_SLAVE: logger.debug("NODE {}: Adding slave.", incomingMessage.getMessagePayloadByte(2)); @@ -89,7 +89,7 @@ public boolean handleRequest(ZWaveController zController, SerialMessage lastSent case ADD_NODE_STATUS_DONE: logger.debug("Add Node: Done."); // If the node ID is 0, ignore! - if(incomingMessage.getMessagePayloadByte(2) != 0) { + if(incomingMessage.getMessagePayloadByte(2) > 0 && incomingMessage.getMessagePayloadByte(2) <= 232) { zController.notifyEventListeners(new ZWaveInclusionEvent(ZWaveInclusionEvent.Type.IncludeDone, incomingMessage.getMessagePayloadByte(2))); } break; diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ApplicationCommandMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ApplicationCommandMessageClass.java index 1b4669cea25..f48dc0acdca 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ApplicationCommandMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ApplicationCommandMessageClass.java @@ -11,6 +11,7 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; +import org.openhab.binding.zwave.internal.protocol.ZWaveNodeState; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass.CommandClass; import org.slf4j.Logger; @@ -34,53 +35,56 @@ public boolean handleRequest(ZWaveController zController, SerialMessage lastSen logger.warn("NODE {}: Not initialized yet, ignoring message.", nodeId); return false; } - logger.debug("NODE {}: Application Command Request (Stage {})", nodeId, node.getNodeStage().getLabel()); + logger.debug("NODE {}: Application Command Request ({}:{})", nodeId, + node.getNodeState().toString(), node.getNodeInitializationStage().toString()); // If the node is DEAD, but we've just received a message from it, then it's not dead! if(node.isDead()) { - node.setAlive(); - logger.debug("NODE {}: Node has risen from the DEAD. Set stage to {}.", nodeId, node.getNodeStage()); + node.setNodeState(ZWaveNodeState.ALIVE); } - + node.resetResendCount(); node.incrementReceiveCount(); int commandClassCode = incomingMessage.getMessagePayloadByte(3); CommandClass commandClass = CommandClass.getCommandClass(commandClassCode); - if (commandClass == null) { - logger.error(String.format("NODE %d: Unsupported command class 0x%02x", nodeId, commandClassCode)); + logger.error(String.format("NODE %d: Unknown command class 0x%02x", nodeId, commandClassCode)); return false; } - logger.debug(String.format("NODE %d: Incoming command class %s (0x%02x)", nodeId, commandClass.getLabel(), commandClass.getKey())); + logger.debug("NODE {}: Incoming command class {}", nodeId, commandClass.getLabel(), commandClass.getKey()); ZWaveCommandClass zwaveCommandClass = node.getCommandClass(commandClass); // Apparently, this node supports a command class that we did not get (yet) during initialization. // Let's add it now then to support handling this message. if (zwaveCommandClass == null) { - logger.debug(String.format("NODE %d: Command class %s (0x%02x) not found, trying to add it.", - nodeId, commandClass.getLabel(), commandClass.getKey())); + logger.debug("NODE {}: Command class {} not found, trying to add it.", + nodeId, commandClass.getLabel(), commandClass.getKey()); zwaveCommandClass = ZWaveCommandClass.getInstance(commandClass.getKey(), node, zController); if (zwaveCommandClass != null) { - logger.debug(String.format("NODE %d: Adding command class %s (0x%02x)", nodeId, commandClass.getLabel(), commandClass.getKey())); + logger.debug("NODE {}: Adding command class %s", nodeId, commandClass.getLabel()); node.addCommandClass(zwaveCommandClass); } } - + // We got an unsupported command class, return. if (zwaveCommandClass == null) { logger.error(String.format("NODE %d: Unsupported command class %s (0x%02x)", nodeId, commandClass.getLabel(), commandClassCode)); return false; } - + logger.trace("NODE {}: Found Command Class {}, passing to handleApplicationCommandRequest", nodeId, zwaveCommandClass.getCommandClass().getLabel()); zwaveCommandClass.handleApplicationCommandRequest(incomingMessage, 4, 0); - checkTransactionComplete(lastSentMessage, incomingMessage); - - return false; + if(node.getNodeId() == lastSentMessage.getMessageNode()) { + checkTransactionComplete(lastSentMessage, incomingMessage); + } else { + logger.debug("Transaction not completed: node address inconsistent."); + } + + return true; } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ApplicationUpdateMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ApplicationUpdateMessageClass.java index 83355d81b4a..094e5ee292d 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ApplicationUpdateMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ApplicationUpdateMessageClass.java @@ -8,25 +8,23 @@ */ package org.openhab.binding.zwave.internal.protocol.serialmessage; -import java.util.Collection; +import java.util.HashMap; +import java.util.Map; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.SerialMessage; -import org.openhab.binding.zwave.internal.protocol.UpdateState; import org.openhab.binding.zwave.internal.protocol.ZWaveController; -import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; -import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClassDynamicState; -import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveMultiInstanceCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass.CommandClass; +import org.openhab.binding.zwave.internal.protocol.event.ZWaveInclusionEvent; +import org.openhab.binding.zwave.internal.protocol.initialization.ZWaveNodeInitStage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * This class processes a serial message from the zwave controller + * This class processes a Node Information Frame (NIF) message from the zwave controller * @author Chris Jackson * @since 1.5.0 */ @@ -35,27 +33,44 @@ public class ApplicationUpdateMessageClass extends ZWaveCommandProcessor { @Override public boolean handleRequest(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) { - logger.trace("Handle Message Application Update Request"); - int nodeId = incomingMessage.getMessagePayloadByte(1); - - logger.trace("NODE {}: Application Update Request from Node ", nodeId); + int nodeId; + boolean result = true; UpdateState updateState = UpdateState.getUpdateState(incomingMessage.getMessagePayloadByte(0)); - + switch (updateState) { case NODE_INFO_RECEIVED: - logger.debug("NODE {}: Application update request, node information received.", nodeId); + // We've received a NIF, and this contains the node ID. + nodeId = incomingMessage.getMessagePayloadByte(1); + logger.debug("NODE {}: Application update request. Node information received.", nodeId); + int length = incomingMessage.getMessagePayloadByte(2); ZWaveNode node = zController.getNode(nodeId); - + if(node == null) { + logger.debug("NODE {}: Application update request. Node not known!", nodeId); + + // We've received a NIF from a node we don't know. + // This could happen if we add a new node using a different controller than OH. + // We handle this the same way as if included through an AddNode packet. + // This allows everyone to be notified. + if(nodeId > 0 && nodeId <= 232) { + zController.notifyEventListeners(new ZWaveInclusionEvent(ZWaveInclusionEvent.Type.IncludeDone, incomingMessage.getMessagePayloadByte(2))); + } + break; + } + node.resetResendCount(); - if(node.getNodeStage() == NodeStage.DONE) { + // Remember that we've received this so we can continue initialisation + node.setApplicationUpdateReceived(true); + + // If we're finished initialisation, then we can treat this like a HAIL + if(node.getNodeInitializationStage() == ZWaveNodeInitStage.DONE) { // If this node supports associations, then assume this should be handled through that mechanism if(node.getCommandClass(CommandClass.ASSOCIATION) == null) { // If we receive an Application Update Request and the node is already // fully initialised we assume this is a request to the controller to // re-get the current node values - logger.debug("NODE {}: Application update request, requesting node state.", nodeId); + logger.debug("NODE {}: Application update request. Requesting node state.", nodeId); zController.pollNode(node); } @@ -63,21 +78,17 @@ public boolean handleRequest(ZWaveController zController, SerialMessage lastSen else { for (int i = 6; i < length + 3; i++) { int data = incomingMessage.getMessagePayloadByte(i); - if(data == 0xef) { + if(data == 0xef) { // TODO: Implement control command classes break; } logger.trace(String.format("NODE %d: Command class 0x%02X is supported.", nodeId, data)); ZWaveCommandClass commandClass = ZWaveCommandClass.getInstance(data, node, zController); - if (commandClass != null) + if (commandClass != null) { node.addCommandClass(commandClass); + } } - - // advance node stage. - node.advanceNodeStage(NodeStage.MANSPEC01); } - - checkTransactionComplete(lastSentMessage, incomingMessage); // Treat the node information frame as a wakeup ZWaveWakeUpCommandClass wakeUp = (ZWaveWakeUpCommandClass)node.getCommandClass(ZWaveCommandClass.CommandClass.WAKE_UP); @@ -86,27 +97,100 @@ public boolean handleRequest(ZWaveController zController, SerialMessage lastSen } break; case NODE_INFO_REQ_FAILED: - logger.debug("NODE {}: Application update request, Node Info Request Failed, re-request node info.", nodeId); - - SerialMessage requestInfoMessage = lastSentMessage; - - if (requestInfoMessage.getMessageClass() != SerialMessageClass.RequestNodeInfo) { - logger.warn("NODE {}: Got application update request without node info request, ignoring.", nodeId); + // Make sure we can correlate the request before we use the nodeId + if (lastSentMessage.getMessageClass() != SerialMessageClass.RequestNodeInfo) { + logger.warn("Got ApplicationUpdateMessage without request, ignoring. Last message was {}.", lastSentMessage.getMessageClass()); return false; } - - if (--requestInfoMessage.attempts >= 0) { - logger.error("NODE {}: Got Node Info Request Failed while sending this serial message. Requeueing", nodeId); - zController.enqueue(requestInfoMessage); - } else - { + + // The failed message doesn't contain the node number, so use the info from the request. + nodeId = lastSentMessage.getMessageNode(); + logger.debug("NODE {}: Application update request. Node Info Request Failed.", nodeId); + + // Handle retries + if (--lastSentMessage.attempts >= 0) { + logger.error("NODE {}: Got Node Info Request Failed. Requeueing", nodeId); + zController.enqueue(lastSentMessage); + } + else { logger.warn("NODE {}: Node Info Request Failed 3x. Discarding message: {}", nodeId, lastSentMessage.toString()); } - transactionComplete = true; + + // Transaction is not successful + incomingMessage.setTransactionCanceled(); + result = false; break; default: - logger.warn(String.format("TODO: Implement Application Update Request Handling of %s (0x%02X).", updateState.getLabel(), updateState.getKey())); - } - return false; + logger.warn("TODO: Implement Application Update Request Handling of {} ({}).", updateState.getLabel(), updateState.getKey()); + } + + // Check if this completes the transaction + checkTransactionComplete(lastSentMessage, incomingMessage); + + return result; + } + + /** + * Update state enumeration. Indicates the type of application update state that was sent. + * @author Jan-Willem Spuij + * @ since 1.3.0 + */ + public enum UpdateState { + NODE_INFO_RECEIVED(0x84, "Node info received"), + NODE_INFO_REQ_DONE(0x82, "Node info request done"), + NODE_INFO_REQ_FAILED(0x81, "Node info request failed"), + ROUTING_PENDING(0x80, "Routing pending"), + NEW_ID_ASSIGNED(0x40, "New ID Assigned"), + DELETE_DONE(0x20, "Delete done"), + SUC_ID(0x10, "SUC ID"); + + /** + * A mapping between the integer code and its corresponding update state + * class to facilitate lookup by code. + */ + private static Map codeToUpdateStateMapping; + + private int key; + private String label; + + private UpdateState(int key, String label) { + this.key = key; + this.label = label; + } + + private static void initMapping() { + codeToUpdateStateMapping = new HashMap(); + for (UpdateState s : values()) { + codeToUpdateStateMapping.put(s.key, s); + } + } + + /** + * Lookup function based on the update state code. + * Returns null when there is no update state with code i. + * @param i the code to lookup + * @return enumeration value of the update state. + */ + public static UpdateState getUpdateState(int i) { + if (codeToUpdateStateMapping == null) { + initMapping(); + } + + return codeToUpdateStateMapping.get(i); + } + + /** + * @return the key + */ + public int getKey() { + return key; + } + + /** + * @return the label + */ + public String getLabel() { + return label; + } } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AssignReturnRouteMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AssignReturnRouteMessageClass.java index 34489328330..209f063530e 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AssignReturnRouteMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AssignReturnRouteMessageClass.java @@ -35,7 +35,7 @@ public SerialMessage doRequest(int nodeId, int destinationId, int callbackId) { newMessage.setMessagePayload(newPayload); return newMessage; } - + @Override public boolean handleResponse(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) { int nodeId = lastSentMessage.getMessagePayloadByte(0); @@ -48,9 +48,10 @@ public boolean handleResponse(ZWaveController zController, SerialMessage lastSen logger.error("NODE {}: AssignReturnRoute command failed.", nodeId); zController.notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.AssignReturnRoute, nodeId, ZWaveNetworkEvent.State.Failure)); + incomingMessage.setTransactionCanceled(); } - return false; + return true; } @Override @@ -59,7 +60,7 @@ public boolean handleRequest(ZWaveController zController, SerialMessage lastSent logger.debug("NODE {}: Got AssignReturnRoute request.", nodeId); if(incomingMessage.getMessagePayloadByte(1) != 0x00) { - logger.error("NODE {}: Assign return routes failed with error 0x{}.", nodeId, Integer.toHexString(incomingMessage.getMessagePayloadByte(1))); + logger.error("NODE {}: Assign return routes failed.", nodeId); zController.notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.AssignReturnRoute, nodeId, ZWaveNetworkEvent.State.Failure)); } @@ -67,7 +68,9 @@ public boolean handleRequest(ZWaveController zController, SerialMessage lastSent zController.notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.AssignReturnRoute, nodeId, ZWaveNetworkEvent.State.Success)); } - - return false; + + checkTransactionComplete(lastSentMessage, incomingMessage); + + return true; } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AssignSucReturnRouteMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AssignSucReturnRouteMessageClass.java index 07190f4349e..1dffbd63fe1 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AssignSucReturnRouteMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/AssignSucReturnRouteMessageClass.java @@ -54,7 +54,7 @@ public boolean handleResponse(ZWaveController zController, SerialMessage lastSen } checkTransactionComplete(lastSentMessage, incomingMessage); - return false; + return true; } @Override @@ -68,11 +68,13 @@ public boolean handleRequest(ZWaveController zController, SerialMessage lastSent Integer.toHexString(incomingMessage.getMessagePayloadByte(1))); zController.notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.AssignSucReturnRoute, nodeId, ZWaveNetworkEvent.State.Failure)); + + return false; } else { zController.notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.AssignSucReturnRoute, nodeId, ZWaveNetworkEvent.State.Success)); - } - return false; + return true; + } } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/DeleteReturnRouteMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/DeleteReturnRouteMessageClass.java index f90a50ed1bf..9d427a08dfe 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/DeleteReturnRouteMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/DeleteReturnRouteMessageClass.java @@ -45,12 +45,12 @@ public boolean handleResponse(ZWaveController zController, SerialMessage lastSen if(incomingMessage.getMessagePayloadByte(0) != 0x00) { logger.debug("NODE {}: DeleteReturnRoute command in progress.", nodeId); } else { - logger.error("NODE {}: DeleteReturnRoute command failed."); + logger.error("NODE {}: DeleteReturnRoute command failed.", nodeId); zController.notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.DeleteReturnRoute, nodeId, ZWaveNetworkEvent.State.Failure)); } - return false; + return true; } @Override @@ -69,6 +69,6 @@ public boolean handleRequest(ZWaveController zController, SerialMessage lastSent ZWaveNetworkEvent.State.Success)); } - return false; + return true; } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/EnableSucMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/EnableSucMessageClass.java index fc0266b9cde..02b8aaa074f 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/EnableSucMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/EnableSucMessageClass.java @@ -62,7 +62,7 @@ public boolean handleResponse(ZWaveController zController, SerialMessage lastSen } checkTransactionComplete(lastSentMessage, incomingMessage); - return false; + return true; } public enum SUCType { diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetControllerCapabilitiesMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetControllerCapabilitiesMessageClass.java index ff0bdd8e80c..06617876956 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetControllerCapabilitiesMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetControllerCapabilitiesMessageClass.java @@ -38,6 +38,7 @@ public class GetControllerCapabilitiesMessageClass extends ZWaveCommandProcessor private boolean isSUC = false; public SerialMessage doRequest() { + logger.debug("Creating GET_CONTROLLER_CAPABILITIES message"); return new SerialMessage(SerialMessageClass.GetControllerCapabilities, SerialMessageType.Request, SerialMessageClass.GetControllerCapabilities, SerialMessagePriority.High); } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetRoutingInfoMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetRoutingInfoMessageClass.java index 89cdb7df36f..10a44f5a6e4 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetRoutingInfoMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetRoutingInfoMessageClass.java @@ -50,7 +50,7 @@ public boolean handleResponse(ZWaveController zController, SerialMessage lastSen ZWaveNode node = zController.getNode(nodeId); if(node == null) { logger.error("NODE {}: Routing information for unknown node", nodeId); - transactionComplete = true; + incomingMessage.setTransactionCanceled(); return false; } @@ -75,13 +75,13 @@ public boolean handleResponse(ZWaveController zController, SerialMessage lastSen for (Integer neighborNode : node.getNeighbors()) { neighbors += " " + neighborNode; } - logger.debug("Node {}: {}", nodeId, neighbors); + logger.debug("NODE {}: {}", nodeId, neighbors); } zController.notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.NodeRoutingInfo, nodeId, ZWaveNetworkEvent.State.Success)); - transactionComplete = true; - return false; + checkTransactionComplete(lastSentMessage, incomingMessage); + return true; } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetSucNodeIdMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetSucNodeIdMessageClass.java index b8c72a29453..ad22ee4e8bd 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetSucNodeIdMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/GetSucNodeIdMessageClass.java @@ -48,7 +48,7 @@ public boolean handleResponse(ZWaveController zController, SerialMessage lastSen } checkTransactionComplete(lastSentMessage, incomingMessage); - return false; + return true; } public int getSucNodeId() { diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/IdentifyNodeMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/IdentifyNodeMessageClass.java index 8e474fb5a51..98dded76a64 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/IdentifyNodeMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/IdentifyNodeMessageClass.java @@ -8,7 +8,6 @@ */ package org.openhab.binding.zwave.internal.protocol.serialmessage; -import org.openhab.binding.zwave.internal.protocol.NodeStage; import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveDeviceClass; @@ -33,7 +32,7 @@ public class IdentifyNodeMessageClass extends ZWaveCommandProcessor { private static final Logger logger = LoggerFactory.getLogger(IdentifyNodeMessageClass.class); public SerialMessage doRequest(int nodeId) { - SerialMessage newMessage = new SerialMessage(nodeId, SerialMessageClass.IdentifyNode, SerialMessageType.Request, SerialMessageClass.IdentifyNode, SerialMessagePriority.High); + SerialMessage newMessage = new SerialMessage(SerialMessageClass.IdentifyNode, SerialMessageType.Request, SerialMessageClass.IdentifyNode, SerialMessagePriority.High); byte[] newPayload = { (byte) nodeId }; newMessage.setMessagePayload(newPayload); return newMessage; @@ -43,21 +42,27 @@ public SerialMessage doRequest(int nodeId) { public boolean handleResponse(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) { logger.trace("Handle Message Get Node ProtocolInfo Response"); + // Check that this request is consistent with the response + if(lastSentMessage.getMessageClass() != SerialMessageClass.IdentifyNode) { + logger.warn("Got IdentifyNodeMessage without request, ignoring. Last message was {}.", lastSentMessage.getMessageClass()); + return false; + } + int nodeId = lastSentMessage.getMessagePayloadByte(0); logger.debug("NODE {}: ProtocolInfo", nodeId); - + ZWaveNode node = zController.getNode(nodeId); - + boolean listening = (incomingMessage.getMessagePayloadByte(0) & 0x80)!=0 ? true : false; boolean routing = (incomingMessage.getMessagePayloadByte(0) & 0x40)!=0 ? true : false; int version = (incomingMessage.getMessagePayloadByte(0) & 0x07) + 1; boolean frequentlyListening = (incomingMessage.getMessagePayloadByte(1) & 0x60)!= 0 ? true : false; - + logger.debug("NODE {}: Listening = {}", nodeId, listening); logger.debug("NODE {}: Routing = {}", nodeId, routing); logger.debug("NODE {}: Version = {}", nodeId, version); - logger.debug("NODE {}: fLIRS = {}", nodeId, frequentlyListening); - + logger.debug("NODE {}: FLIRS = {}", nodeId, frequentlyListening); + node.setListening(listening); node.setRouting(routing); node.setVersion(version); @@ -68,21 +73,21 @@ public boolean handleResponse(ZWaveController zController, SerialMessage lastSen logger.error(String.format("NODE %d: Basic device class 0x%02x not found", nodeId, incomingMessage.getMessagePayloadByte(3))); return false; } - logger.debug(String.format("NODE %d: Basic = %s 0x%02x", nodeId, basic.getLabel(), basic.getKey())); + logger.debug("NODE {}: Basic = {}", nodeId, basic.getLabel()); Generic generic = Generic.getGeneric(incomingMessage.getMessagePayloadByte(4)); if (generic == null) { logger.error(String.format("NODE %d: Generic device class 0x%02x not found", nodeId, incomingMessage.getMessagePayloadByte(4))); return false; } - logger.debug(String.format("NODE %d: Generic = %s 0x%02x", nodeId, generic.getLabel(), generic.getKey())); + logger.debug("NODE {}: Generic = {}", nodeId, generic.getLabel()); Specific specific = Specific.getSpecific(generic, incomingMessage.getMessagePayloadByte(5)); if (specific == null) { logger.error(String.format("NODE %d: Specific device class 0x%02x not found", nodeId, incomingMessage.getMessagePayloadByte(5))); return false; } - logger.debug(String.format("NODE %d: Specific = %s 0x%02x", nodeId, specific.getLabel(), specific.getKey())); + logger.debug("NODE {}: Specific = {}", nodeId, specific.getLabel()); ZWaveDeviceClass deviceClass = node.getDeviceClass(); deviceClass.setBasicDeviceClass(basic); @@ -96,22 +101,21 @@ public boolean handleResponse(ZWaveController zController, SerialMessage lastSen // Add mandatory command classes as specified by it's generic device class. for (CommandClass commandClass : generic.getMandatoryCommandClasses()) { ZWaveCommandClass zwaveCommandClass = ZWaveCommandClass.getInstance(commandClass.getKey(), node, zController); - if (zwaveCommandClass != null) + if (zwaveCommandClass != null) { zController.getNode(nodeId).addCommandClass(zwaveCommandClass); + } } // Add mandatory command classes as specified by it's specific device class. for (CommandClass commandClass : specific.getMandatoryCommandClasses()) { ZWaveCommandClass zwaveCommandClass = ZWaveCommandClass.getInstance(commandClass.getKey(), node, zController); - if (zwaveCommandClass != null) + if (zwaveCommandClass != null) { node.addCommandClass(zwaveCommandClass); + } } - // advance node stage of the current node. - node.advanceNodeStage(NodeStage.PING); - checkTransactionComplete(lastSentMessage, incomingMessage); - return false; + return true; } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/IsFailedNodeMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/IsFailedNodeMessageClass.java index bec23020a66..80a077ef787 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/IsFailedNodeMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/IsFailedNodeMessageClass.java @@ -10,10 +10,11 @@ import org.openhab.binding.zwave.internal.protocol.SerialMessage; import org.openhab.binding.zwave.internal.protocol.ZWaveController; +import org.openhab.binding.zwave.internal.protocol.ZWaveNode; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; -import org.openhab.binding.zwave.internal.protocol.event.ZWaveNetworkEvent; +import org.openhab.binding.zwave.internal.protocol.ZWaveNodeState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,7 +29,7 @@ public class IsFailedNodeMessageClass extends ZWaveCommandProcessor { public SerialMessage doRequest(int nodeId) { logger.debug("NODE {}: Requesting IsFailedNode status from controller.", nodeId); - SerialMessage newMessage = new SerialMessage(nodeId, SerialMessageClass.IsFailedNodeID, SerialMessageType.Request, SerialMessageClass.IsFailedNodeID, SerialMessagePriority.High); + SerialMessage newMessage = new SerialMessage(SerialMessageClass.IsFailedNodeID, SerialMessageType.Request, SerialMessageClass.IsFailedNodeID, SerialMessagePriority.High); byte[] newPayload = { (byte) nodeId }; newMessage.setMessagePayload(newPayload); return newMessage; @@ -38,17 +39,22 @@ public SerialMessage doRequest(int nodeId) { public boolean handleResponse(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) { int nodeId = lastSentMessage.getMessagePayloadByte(0); - logger.trace("Handle IsFailedNode Response"); + ZWaveNode node = zController.getNode(nodeId); + if(node == null) { + logger.error("NODE {}: Failed node message for unknown node", nodeId); + incomingMessage.setTransactionCanceled(); + return false; + } if(incomingMessage.getMessagePayloadByte(0) != 0x00) { - zController.notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.FailedNode, nodeId, ZWaveNetworkEvent.State.Success)); logger.warn("NODE {}: Is currently marked as failed by the controller!", nodeId); + node.setNodeState(ZWaveNodeState.FAILED); } else { logger.debug("NODE {}: Is currently marked as healthy by the controller", nodeId); } - - transactionComplete = true; + + checkTransactionComplete(lastSentMessage, incomingMessage); return true; } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RemoveFailedNodeMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RemoveFailedNodeMessageClass.java index ec166f97cd4..94dc0a29183 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RemoveFailedNodeMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RemoveFailedNodeMessageClass.java @@ -43,7 +43,7 @@ public SerialMessage doRequest(int nodeId) { // Queue the request SerialMessage newMessage = new SerialMessage(SerialMessageClass.RemoveFailedNodeID, SerialMessageType.Request, SerialMessageClass.RemoveFailedNodeID, SerialMessagePriority.High); - byte[] newPayload = { (byte) nodeId }; + byte[] newPayload = { (byte) nodeId, (byte) 0xfe }; newMessage.setMessagePayload(newPayload); return newMessage; } @@ -52,11 +52,10 @@ public SerialMessage doRequest(int nodeId) { public boolean handleResponse(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) { logger.debug("Got RemoveFailedNode response."); int nodeId = lastSentMessage.getMessagePayloadByte(0); - + switch(incomingMessage.getMessagePayloadByte(0)) { case FAILED_NODE_REMOVE_STARTED: logger.debug("NODE {}: Remove failed node successfully placed on stack.", nodeId); - transactionComplete = true; break; case FAILED_NODE_NOT_PRIMARY_CONTROLLER: logger.error("NODE {}: Remove failed node failed as not Primary Controller for node!", nodeId); @@ -67,7 +66,7 @@ public boolean handleResponse(ZWaveController zController, SerialMessage lastSen transactionComplete = true; break; case FAILED_NODE_NOT_FOUND: - logger.error("NODE {}: Remove failed node failed as node not found on controllers failed list!", nodeId); + logger.error("NODE {}: Remove failed node failed as node not found!", nodeId); transactionComplete = true; break; case FAILED_NODE_REMOVE_PROCESS_BUSY: diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RequestNodeInfoMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RequestNodeInfoMessageClass.java index c05ecefba7a..fe09d335fa2 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RequestNodeInfoMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RequestNodeInfoMessageClass.java @@ -25,7 +25,7 @@ public class RequestNodeInfoMessageClass extends ZWaveCommandProcessor { private static final Logger logger = LoggerFactory.getLogger(RequestNodeInfoMessageClass.class); public SerialMessage doRequest(int nodeId) { - SerialMessage newMessage = new SerialMessage(nodeId, SerialMessageClass.RequestNodeInfo, SerialMessageType.Request, SerialMessageClass.ApplicationUpdate, SerialMessagePriority.High); + SerialMessage newMessage = new SerialMessage(SerialMessageClass.RequestNodeInfo, SerialMessageType.Request, SerialMessageClass.ApplicationUpdate, SerialMessagePriority.High); byte[] newPayload = { (byte) nodeId }; newMessage.setMessagePayload(newPayload); return newMessage; @@ -34,11 +34,13 @@ public SerialMessage doRequest(int nodeId) { @Override public boolean handleResponse(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) { logger.trace("Handle RequestNodeInfo Response"); - if(incomingMessage.getMessagePayloadByte(0) != 0x00) + if(incomingMessage.getMessagePayloadByte(0) != 0x00) { logger.debug("Request node info successfully placed on stack."); - else + } + else { logger.error("Request node info not placed on stack due to error."); - + } + checkTransactionComplete(lastSentMessage, incomingMessage); return true; diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RequestNodeNeighborUpdateMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RequestNodeNeighborUpdateMessageClass.java index caae1203584..2b802604b31 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RequestNodeNeighborUpdateMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RequestNodeNeighborUpdateMessageClass.java @@ -66,6 +66,6 @@ public boolean handleRequest(ZWaveController zController, SerialMessage lastSent transactionComplete = true; break; } - return false; + return true; } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SendDataMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SendDataMessageClass.java index f4b3b2875f7..a7506e2daa1 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SendDataMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SendDataMessageClass.java @@ -8,14 +8,16 @@ */ package org.openhab.binding.zwave.internal.protocol.serialmessage; -import org.openhab.binding.zwave.internal.protocol.NodeStage; +import java.util.HashMap; +import java.util.Map; + import org.openhab.binding.zwave.internal.protocol.SerialMessage; -import org.openhab.binding.zwave.internal.protocol.TransmissionState; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; -import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; -import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass; +import org.openhab.binding.zwave.internal.protocol.ZWaveNodeState; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass.CommandClass; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,10 +34,20 @@ public class SendDataMessageClass extends ZWaveCommandProcessor { public boolean handleResponse(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) { logger.trace("Handle Message Send Data Response"); - if (incomingMessage.getMessagePayloadByte(0) != 0x00) - logger.debug("Sent Data successfully placed on stack."); - else - logger.error("Sent Data was not placed on stack due to error {}.", incomingMessage.getMessagePayloadByte(0)); + if (incomingMessage.getMessagePayloadByte(0) != 0x00) { + logger.debug("NODE {}: Sent Data successfully placed on stack.", lastSentMessage.getMessageNode()); + } + else { + // This is an error. This means that the transaction is complete! + // Set the flag, and return false. + logger.error("NODE {}: Sent Data was not placed on stack due to error {}.", lastSentMessage.getMessageNode(), + incomingMessage.getMessagePayloadByte(0)); + + // We ought to cancel the transaction + lastSentMessage.setTransactionCanceled(); + + return false; + } return true; } @@ -47,56 +59,68 @@ public boolean handleRequest(ZWaveController zController, SerialMessage lastSent int callbackId = incomingMessage.getMessagePayloadByte(0); TransmissionState status = TransmissionState.getTransmissionState(incomingMessage.getMessagePayloadByte(1)); - SerialMessage originalMessage = lastSentMessage; if (status == null) { logger.warn("Transmission state not found, ignoring."); return false; } - logger.debug("CallBack ID = {}", callbackId); - logger.debug(String.format("Status = %s (0x%02x)", status.getLabel(), status.getKey())); + ZWaveNode node = zController.getNode(lastSentMessage.getMessageNode()); + if(node == null) { + logger.warn("Node not found!"); + return false; + } + + logger.debug("NODE {}: SendData Request. CallBack ID = {}, Status = {}({})", node.getNodeId(), callbackId, status.getLabel(), status.getKey()); - if (originalMessage == null || originalMessage.getCallbackId() != callbackId) { - logger.warn("Already processed another send data request for this callback Id, ignoring."); + if (lastSentMessage == null || lastSentMessage.getCallbackId() != callbackId) { + logger.warn("NODE {}: Already processed another send data request for this callback Id, ignoring.", node.getNodeId()); return false; } + // This response is our controller ACK + lastSentMessage.setAckRecieved(); + switch (status) { case COMPLETE_OK: - ZWaveNode node = zController.getNode(originalMessage.getMessageNode()); - if(node == null) - break; - // Consider this as a received frame since the controller did receive an ACK from the device. node.incrementReceiveCount(); - // If the node is DEAD, but we've just received a message from it, then it's not dead! + // If the node is DEAD, but we've just received an ACK from it, then it's not dead! if(node.isDead()) { - node.setAlive(); - logger.debug("NODE {}: Node has risen from the DEAD. Set stage to {}.", node.getNodeId(), node.getNodeStage()); + node.setNodeState(ZWaveNodeState.ALIVE);; } else { node.resetResendCount(); - // in case we received a ping response and the node is alive, we - // proceed with the next node stage for this node. - if (node.getNodeStage() == NodeStage.PING) { - node.advanceNodeStage(NodeStage.DETAILS); - } } checkTransactionComplete(lastSentMessage, incomingMessage); return true; case COMPLETE_NO_ACK: - // timeOutCount.incrementAndGet(); + // Handle WAKE_UP_NO_MORE_INFORMATION differently + // Since the system can time out if the node goes to sleep before + // we get the response, then don't treat this like a timeout + byte[] payload = lastSentMessage.getMessagePayload(); + if (payload.length >= 4 && + (payload[2] & 0xFF) == ZWaveCommandClass.CommandClass.WAKE_UP.getKey() && + (payload[3] & 0xFF) == ZWaveWakeUpCommandClass.WAKE_UP_NO_MORE_INFORMATION) { + checkTransactionComplete(lastSentMessage, incomingMessage); + + logger.debug("NODE {}: WAKE_UP_NO_MORE_INFORMATION. Treated as ACK.", node.getNodeId()); + + return true; + } + case COMPLETE_FAIL: case COMPLETE_NOT_IDLE: case COMPLETE_NOROUTE: try { - handleFailedSendDataRequest(zController, originalMessage); + handleFailedSendDataRequest(zController, lastSentMessage); } finally { transactionComplete = true; } + break; default: + break; } return false; @@ -106,14 +130,20 @@ public boolean handleFailedSendDataRequest(ZWaveController zController, SerialMe ZWaveNode node = zController.getNode(originalMessage.getMessageNode()); + logger.trace("NODE {}: Handling failed message.", node.getNodeId()); + + // Increment the resend count. + // This will set the node to DEAD if we've exceeded the retries. + node.incrementResendCount(); + // No retries if the node is DEAD or FAILED if (node.isDead()) { + logger.error("NODE {}: Node is DEAD. Dropping message.", node.getNodeId()); return false; } - // High priority messages get requeued, low priority get dropped - if (!node.isListening() && !node.isFrequentlyListening() - && originalMessage.getPriority() != SerialMessagePriority.Low) { + // If this device isn't listening, queue the message in the wakeup class + if (!node.isListening() && !node.isFrequentlyListening()) { ZWaveWakeUpCommandClass wakeUpCommandClass = (ZWaveWakeUpCommandClass) node .getCommandClass(CommandClass.WAKE_UP); @@ -123,14 +153,73 @@ public boolean handleFailedSendDataRequest(ZWaveController zController, SerialMe wakeUpCommandClass.processOutgoingWakeupMessage(originalMessage); return false; } - } else if (!node.isListening() && !node.isFrequentlyListening() - && originalMessage.getPriority() == SerialMessagePriority.Low) - return false; - - node.incrementResendCount(); + } logger.error("NODE {}: Got an error while sending data. Resending message.", node.getNodeId()); zController.sendData(originalMessage); return true; } + + /** + * Transmission state enumeration. Indicates the + * transmission state of the message to the node. + * @author Jan-Willem Spuij + * @ since 1.3.0 + */ + public enum TransmissionState { + COMPLETE_OK(0x00, "Transmission complete and ACK received"), + COMPLETE_NO_ACK(0x01, "Transmission complete, no ACK received"), + COMPLETE_FAIL(0x02, "Transmission failed"), + COMPLETE_NOT_IDLE(0x03, "Transmission failed, network busy"), + COMPLETE_NOROUTE(0x04, "Tranmission complete, no return route"); + + /** + * A mapping between the integer code and its corresponding transmission state + * class to facilitate lookup by code. + */ + private static Map codeToTransmissionStateMapping; + + private int key; + private String label; + + private TransmissionState(int key, String label) { + this.key = key; + this.label = label; + } + + private static void initMapping() { + codeToTransmissionStateMapping = new HashMap(); + for (TransmissionState s : values()) { + codeToTransmissionStateMapping.put(s.key, s); + } + } + + /** + * Lookup function based on the transmission state code. + * Returns null when there is no transmission state with code i. + * @param i the code to lookup + * @return enumeration value of the transmission state. + */ + public static TransmissionState getTransmissionState(int i) { + if (codeToTransmissionStateMapping == null) { + initMapping(); + } + + return codeToTransmissionStateMapping.get(i); + } + + /** + * @return the key + */ + public int getKey() { + return key; + } + + /** + * @return the label + */ + public String getLabel() { + return label; + } + } } diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SerialApiGetInitDataMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SerialApiGetInitDataMessageClass.java index f7f69595e79..f62fa7be5ec 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SerialApiGetInitDataMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SerialApiGetInitDataMessageClass.java @@ -36,7 +36,7 @@ public SerialMessage doRequest() { @Override public boolean handleResponse(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) { - logger.debug(String.format("Got MessageSerialApiGetInitData response.")); + logger.debug("Got MessageSerialApiGetInitData response."); int nodeBytes = incomingMessage.getMessagePayloadByte(2); if (nodeBytes != NODE_BYTES) { diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SerialApiSetTimeoutsMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SerialApiSetTimeoutsMessageClass.java new file mode 100644 index 00000000000..1d638ec51a6 --- /dev/null +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SerialApiSetTimeoutsMessageClass.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.zwave.internal.protocol.serialmessage; + +import org.openhab.binding.zwave.internal.protocol.SerialMessage; +import org.openhab.binding.zwave.internal.protocol.ZWaveController; +import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; +import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; +import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class processes a serial message from the zwave controller + * @author Chris Jackson + * @since 1.7.0 + */ +public class SerialApiSetTimeoutsMessageClass extends ZWaveCommandProcessor { + private static final Logger logger = LoggerFactory.getLogger(SerialApiSetTimeoutsMessageClass.class); + + public SerialMessage doRequest(int ackTimeout, int byteTimeout) { + // Queue the request + SerialMessage newMessage = new SerialMessage(SerialMessageClass.SerialApiSetTimeouts, + SerialMessageType.Request, SerialMessageClass.SerialApiSetTimeouts, SerialMessagePriority.High); + + byte[] newPayload = { (byte) ackTimeout, (byte)byteTimeout }; + + newMessage.setMessagePayload(newPayload); + return newMessage; + } + + @Override + public boolean handleResponse(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) { + logger.debug("Got SerialApiSetTimeouts response. ACK={}, BYTE={}", + incomingMessage.getMessagePayloadByte(0), + incomingMessage.getMessagePayloadByte(1)); + + checkTransactionComplete(lastSentMessage, incomingMessage); + + return true; + } +} diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SetSucNodeMessageClass.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SetSucNodeMessageClass.java index 0ae6c121897..1ea9283296b 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SetSucNodeMessageClass.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/SetSucNodeMessageClass.java @@ -66,7 +66,7 @@ public boolean handleResponse(ZWaveController zController, SerialMessage lastSen checkTransactionComplete(lastSentMessage, incomingMessage); } - return false; + return true; } @Override @@ -75,14 +75,16 @@ public boolean handleRequest(ZWaveController zController, SerialMessage lastSent logger.debug("NODE {}: SetSucNodeID node request.", nodeId); + checkTransactionComplete(lastSentMessage, incomingMessage); if (incomingMessage.getMessagePayloadByte(1) != 0x00) { logger.error("NODE {}: SetSucNodeID failed with error 0x{}.", nodeId, Integer.toHexString(incomingMessage.getMessagePayloadByte(1))); + + return false; } else { + + return true; } - - checkTransactionComplete(lastSentMessage, incomingMessage); - return false; } public enum SUCType { diff --git a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ZWaveCommandProcessor.java b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ZWaveCommandProcessor.java index 91e12cdf168..f5c6d1aa614 100644 --- a/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ZWaveCommandProcessor.java +++ b/bundles/binding/org.openhab.binding.zwave/src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/ZWaveCommandProcessor.java @@ -9,7 +9,6 @@ package org.openhab.binding.zwave.internal.protocol.serialmessage; import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import org.openhab.binding.zwave.internal.protocol.SerialMessage; @@ -53,8 +52,20 @@ public boolean isTransactionComplete() { * @param incomingMessage The response from the controller */ protected void checkTransactionComplete(SerialMessage lastSentMessage, SerialMessage incomingMessage) { - if (incomingMessage.getMessageClass() == lastSentMessage.getExpectedReply() && !incomingMessage.isTransActionCanceled()) { + // First, check if we're waiting for an ACK from the controller + // This is used for multi-stage transactions to ensure we get all parts of the + // transaction before completing. + if(lastSentMessage.isAckPending()) { + logger.trace("Message has Ack Pending"); + return; + } + + logger.debug("Sent message {}", lastSentMessage.toString()); + logger.debug("Recv message {}", incomingMessage.toString()); + logger.debug("Checking transaction complete: class={}, expected={}, cancelled={}", incomingMessage.getMessageClass(), lastSentMessage.getExpectedReply(), incomingMessage.isTransactionCanceled()); + if (incomingMessage.getMessageClass() == lastSentMessage.getExpectedReply() && !incomingMessage.isTransactionCanceled()) { transactionComplete = true; + logger.debug(" transaction complete!"); } } @@ -111,6 +122,7 @@ public static ZWaveCommandProcessor getMessageDispatcher(SerialMessage.SerialMes messageMap.put(SerialMessage.SerialMessageClass.SendData, SendDataMessageClass.class); messageMap.put(SerialMessage.SerialMessageClass.SerialApiGetCapabilities, SerialApiGetCapabilitiesMessageClass.class); messageMap.put(SerialMessage.SerialMessageClass.SerialApiGetInitData, SerialApiGetInitDataMessageClass.class); + messageMap.put(SerialMessage.SerialMessageClass.SerialApiSetTimeouts, SerialApiSetTimeoutsMessageClass.class); messageMap.put(SerialMessage.SerialMessageClass.SetSucNodeID, SetSucNodeMessageClass.class); } @@ -118,17 +130,7 @@ public static ZWaveCommandProcessor getMessageDispatcher(SerialMessage.SerialMes try { constructor = messageMap.get(serialMessage).getConstructor(); return constructor.newInstance(); - } catch (NoSuchMethodException e) { - logger.error("Command processor error: {}", e); - } catch (InvocationTargetException e) { - logger.error("Command processor error: {}", e); - } catch (InstantiationException e) { - logger.error("Command processor error: {}", e); - } catch (IllegalAccessException e) { - logger.error("Command processor error: {}", e); - } catch (SecurityException e) { - logger.error("Command processor error: {}", e); - } catch (IllegalArgumentException e) { + } catch (Exception e) { logger.error("Command processor error: {}", e); } diff --git a/bundles/binding/pom.xml b/bundles/binding/pom.xml index 9723839fc0f..33415462ef5 100644 --- a/bundles/binding/pom.xml +++ b/bundles/binding/pom.xml @@ -74,6 +74,7 @@ org.openhab.binding.systeminfo org.openhab.binding.piface org.openhab.binding.pilight + org.openhab.binding.pilight.test org.openhab.binding.fritzaha org.openhab.binding.tinkerforge org.openhab.binding.nibeheatpump @@ -137,6 +138,10 @@ org.openhab.binding.bticino org.openhab.binding.zibase org.openhab.binding.wago + org.openhab.binding.networkupstools + org.openhab.binding.ecobee + org.openhab.binding.nest + org.openhab.binding.satel diff --git a/bundles/config/org.openhab.config.core/.classpath b/bundles/config/org.openhab.config.core/.classpath index dd2af9bef84..6566c1e3a03 100644 --- a/bundles/config/org.openhab.config.core/.classpath +++ b/bundles/config/org.openhab.config.core/.classpath @@ -2,7 +2,6 @@ - diff --git a/bundles/core/org.openhab.core.drools/.classpath b/bundles/core/org.openhab.core.drools/.classpath deleted file mode 100644 index e35357ef51e..00000000000 --- a/bundles/core/org.openhab.core.drools/.classpath +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bundles/core/org.openhab.core.drools/META-INF/MANIFEST.MF b/bundles/core/org.openhab.core.drools/META-INF/MANIFEST.MF deleted file mode 100644 index edd755ccc77..00000000000 --- a/bundles/core/org.openhab.core.drools/META-INF/MANIFEST.MF +++ /dev/null @@ -1,51 +0,0 @@ -Manifest-Version: 1.0 -Private-Package: org.openhab.core.drools.internal -Ignore-Package: org.openhab.core.drools.internal -Bundle-Name: openHAB Drools Rule Engine -Bundle-Vendor: openHAB.org -Bundle-Version: 1.7.0.qualifier -Bundle-Activator: org.openhab.core.drools.internal.RulesActivator -Bundle-ManifestVersion: 2 -Eclipse-BuddyPolicy: registered -Bundle-License: http://www.eclipse.org/legal/epl-v10.html -Bundle-Description: This is the rule support of the open Home Aut - omation Bus (openHAB) -Import-Package: org.apache.commons.lang, - org.openhab.core.drools.actions, - org.openhab.core.events, - org.openhab.core.items, - org.openhab.core.library.items, - org.openhab.core.library.types, - org.openhab.core.service, - org.openhab.core.transform.actions, - org.openhab.core.types, - org.openhab.io.multimedia.actions, - org.openhab.io.net.actions, - org.osgi.framework, - org.osgi.service.cm, - org.osgi.service.event, - org.osgi.util.tracker, - org.slf4j -Bundle-SymbolicName: org.openhab.core.drools -Bundle-DocURL: http://www.openhab.org -Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Service-Component: OSGI-INF/ruleservice.xml -Bundle-ClassPath: ., - lib/antlr-runtime.jar, - lib/drools-api.jar, - lib/drools-bpmn2.jar, - lib/drools-compiler.jar, - lib/drools-core.jar, - lib/drools-decisiontables.jar, - lib/drools-ide-common.jar, - lib/drools-jsr94.jar, - lib/drools-templates.jar, - lib/jsr94.jar, - lib/jxl.jar, - lib/log4j.jar, - lib/mvel2.jar, - lib/xpp3_min.jar, - lib/xstream.jar -Require-Bundle: org.eclipse.jdt.core -Export-Package: org.openhab.core.drools.actions,org.openhab.core.drool - s.event diff --git a/bundles/core/org.openhab.core.drools/build.properties b/bundles/core/org.openhab.core.drools/build.properties deleted file mode 100644 index 4ba6dcbb424..00000000000 --- a/bundles/core/org.openhab.core.drools/build.properties +++ /dev/null @@ -1,21 +0,0 @@ -output.. = target/classes/ -bin.includes = META-INF/,\ - .,\ - lib/antlr-runtime.jar,\ - lib/drools-api.jar,\ - lib/drools-bpmn2.jar,\ - lib/drools-compiler.jar,\ - lib/drools-core.jar,\ - lib/drools-decisiontables.jar,\ - lib/drools-ide-common.jar,\ - lib/drools-jsr94.jar,\ - lib/drools-templates.jar,\ - lib/jsr94.jar,\ - lib/jxl.jar,\ - lib/log4j.jar,\ - lib/mvel2.jar,\ - lib/xpp3_min.jar,\ - lib/xstream.jar,\ - OSGI-INF/ -source.. = src/main/java/,\ - src/main/resources/ diff --git a/bundles/core/org.openhab.core.drools/lib/antlr-runtime.jar b/bundles/core/org.openhab.core.drools/lib/antlr-runtime.jar deleted file mode 100644 index b0a9ea69f5c..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/antlr-runtime.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/drools-api.jar b/bundles/core/org.openhab.core.drools/lib/drools-api.jar deleted file mode 100644 index b51b68ffd86..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/drools-api.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/drools-bpmn2.jar b/bundles/core/org.openhab.core.drools/lib/drools-bpmn2.jar deleted file mode 100644 index 71bc5ea00bb..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/drools-bpmn2.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/drools-compiler.jar b/bundles/core/org.openhab.core.drools/lib/drools-compiler.jar deleted file mode 100644 index bef6e67444c..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/drools-compiler.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/drools-core.jar b/bundles/core/org.openhab.core.drools/lib/drools-core.jar deleted file mode 100644 index 43bb6a96b1b..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/drools-core.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/drools-decisiontables.jar b/bundles/core/org.openhab.core.drools/lib/drools-decisiontables.jar deleted file mode 100644 index 2c6b1ac9849..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/drools-decisiontables.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/drools-ide-common.jar b/bundles/core/org.openhab.core.drools/lib/drools-ide-common.jar deleted file mode 100644 index e5f0f071be5..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/drools-ide-common.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/drools-jsr94.jar b/bundles/core/org.openhab.core.drools/lib/drools-jsr94.jar deleted file mode 100644 index 036fb2e9dbc..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/drools-jsr94.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/drools-templates.jar b/bundles/core/org.openhab.core.drools/lib/drools-templates.jar deleted file mode 100644 index 669af378ca3..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/drools-templates.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/jsr94.jar b/bundles/core/org.openhab.core.drools/lib/jsr94.jar deleted file mode 100644 index f01b9639dd2..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/jsr94.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/jxl.jar b/bundles/core/org.openhab.core.drools/lib/jxl.jar deleted file mode 100644 index a2eced557d0..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/jxl.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/log4j.jar b/bundles/core/org.openhab.core.drools/lib/log4j.jar deleted file mode 100644 index 62513071901..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/log4j.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/mvel2.jar b/bundles/core/org.openhab.core.drools/lib/mvel2.jar deleted file mode 100644 index 70ed89cb6c7..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/mvel2.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/xpp3_min.jar b/bundles/core/org.openhab.core.drools/lib/xpp3_min.jar deleted file mode 100644 index 813a9a830bd..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/xpp3_min.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/lib/xstream.jar b/bundles/core/org.openhab.core.drools/lib/xstream.jar deleted file mode 100644 index 4ef4219c6f6..00000000000 Binary files a/bundles/core/org.openhab.core.drools/lib/xstream.jar and /dev/null differ diff --git a/bundles/core/org.openhab.core.drools/pom.xml b/bundles/core/org.openhab.core.drools/pom.xml deleted file mode 100644 index a6ad4b49dc0..00000000000 --- a/bundles/core/org.openhab.core.drools/pom.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - org.openhab.bundles - core - 1.7.0-SNAPSHOT - - - - org.openhab.core.drools - org.openhab.core.drools - - - 4.0.0 - org.openhab.core - org.openhab.core.drools - - openHAB Drools Rule Engine - - eclipse-plugin - - diff --git a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/actions/BusEvent.java b/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/actions/BusEvent.java deleted file mode 100644 index 017ddf751dc..00000000000 --- a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/actions/BusEvent.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.core.drools.actions; - -import org.openhab.core.drools.internal.RulesActivator; -import org.openhab.core.events.EventPublisher; -import org.openhab.core.items.Item; -import org.openhab.core.items.ItemNotFoundException; -import org.openhab.core.items.ItemNotUniqueException; -import org.openhab.core.items.ItemRegistry; -import org.openhab.core.types.Command; -import org.openhab.core.types.State; -import org.openhab.core.types.TypeParser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The static methods of this class are imported as functions into the rules. - * This gives direct write access to the openHAB event bus from within the rules. - * Items should not be updated directly (through modify clauses), but updates should - * be sent to the bus, so that all interested bundles are notified. - * - * @author Kai Kreuzer - * @since 0.7.0 - * - */ -public class BusEvent { - - static private final Logger logger = LoggerFactory.getLogger(BusEvent.class); - - static public void sendCommand(String itemName, String commandString) { - ItemRegistry registry = (ItemRegistry) RulesActivator.itemRegistryTracker.getService(); - EventPublisher publisher = (EventPublisher) RulesActivator.eventPublisherTracker.getService(); - if(publisher!=null && registry!=null) { - try { - Item item = registry.getItem(itemName); - Command command = TypeParser.parseCommand(item.getAcceptedCommandTypes(), commandString); - publisher.sendCommand(itemName, command); - } catch (ItemNotFoundException e) { - logger.warn("Item '" + itemName + "' does not exist."); - } - } - } - - static public void postUpdate(String itemName, String stateString) { - ItemRegistry registry = (ItemRegistry) RulesActivator.itemRegistryTracker.getService(); - EventPublisher publisher = (EventPublisher) RulesActivator.eventPublisherTracker.getService(); - if(publisher!=null && registry!=null) { - try { - Item item = registry.getItem(itemName); - State state = TypeParser.parseState(item.getAcceptedDataTypes(), stateString); - publisher.postUpdate(itemName, state); - } catch (ItemNotFoundException e) { - logger.warn("Item '" + itemName + "' does not exist."); - } - } - } - -} diff --git a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/event/CommandEvent.java b/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/event/CommandEvent.java deleted file mode 100644 index f140f7b0412..00000000000 --- a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/event/CommandEvent.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.core.drools.event; - -import org.openhab.core.items.Item; -import org.openhab.core.types.Command; - -/** - * This class is used as a fact in rules to inform about received commands on the openHAB event bus. - * - * @author Kai Kreuzer - * @since 0.7.0 - * - */ -public class CommandEvent extends RuleEvent { - - protected Command command; - - public CommandEvent(Item item, Command command) { - super(item); - this.command = command; - } - - public Command getCommand() { - return command; - } -} diff --git a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/event/RuleEvent.java b/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/event/RuleEvent.java deleted file mode 100644 index 52e3c996081..00000000000 --- a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/event/RuleEvent.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.core.drools.event; - -import java.util.Calendar; -import java.util.GregorianCalendar; - -import org.openhab.core.items.Item; - -/** - * This is an abstract class that should be extended by all event classes that are used as facts in the rules. - * - * @author Kai Kreuzer - * @since 0.7.0 - * - */ -abstract public class RuleEvent { - - protected String itemName; - protected Item item; - protected Calendar timestamp; - - public RuleEvent(Item item) { - this.itemName = item.getName(); - this.item = item; - this.timestamp = GregorianCalendar.getInstance(); - } - - public String getItemName() { - return itemName; - } - - public void setItemName(String itemName) { - this.itemName = itemName; - } - - public Item getItem() { - return item; - } - - public void setItem(Item item) { - this.item = item; - } - - public Calendar getTimestamp() { - return timestamp; - } - - public void setTimestamp(Calendar timestamp) { - this.timestamp = timestamp; - } - -} diff --git a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/event/StateEvent.java b/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/event/StateEvent.java deleted file mode 100644 index d23436ad922..00000000000 --- a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/event/StateEvent.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.core.drools.event; - -import org.openhab.core.items.Item; -import org.openhab.core.types.State; - -/** - * This class is used as a fact in rules to inform about received status updates on the openHAB event bus. - * - * @author Kai Kreuzer - * @since 0.7.0 - * - */ -public class StateEvent extends RuleEvent { - - protected boolean changed; - protected State oldState; - protected State newState; - - public StateEvent(Item item, State oldState, State newState) { - super(item); - this.oldState = oldState; - this.newState = newState; - this.changed = !oldState.equals(newState); - } - - public StateEvent(Item item, State state) { - this(item, state, state); - } - - public boolean isChanged() { - return changed; - } - - public State getOldState() { - return oldState; - } - - public State getNewState() { - return newState; - } -} diff --git a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/internal/RuleService.java b/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/internal/RuleService.java deleted file mode 100644 index 02df8d1b770..00000000000 --- a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/internal/RuleService.java +++ /dev/null @@ -1,348 +0,0 @@ -/** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.core.drools.internal; - -import static org.openhab.core.events.EventConstants.TOPIC_PREFIX; -import static org.openhab.core.events.EventConstants.TOPIC_SEPERATOR; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Dictionary; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang.StringUtils; -import org.drools.KnowledgeBase; -import org.drools.KnowledgeBaseFactory; -import org.drools.ObjectFilter; -import org.drools.SystemEventListener; -import org.drools.SystemEventListenerFactory; -import org.drools.agent.KnowledgeAgent; -import org.drools.agent.KnowledgeAgentConfiguration; -import org.drools.agent.KnowledgeAgentFactory; -import org.drools.builder.KnowledgeBuilder; -import org.drools.builder.KnowledgeBuilderFactory; -import org.drools.builder.ResourceType; -import org.drools.io.ResourceChangeScannerConfiguration; -import org.drools.io.ResourceFactory; -import org.drools.runtime.StatefulKnowledgeSession; -import org.drools.runtime.rule.FactHandle; -import org.openhab.core.drools.event.CommandEvent; -import org.openhab.core.drools.event.RuleEvent; -import org.openhab.core.drools.event.StateEvent; -import org.openhab.core.items.GenericItem; -import org.openhab.core.items.Item; -import org.openhab.core.items.ItemNotFoundException; -import org.openhab.core.items.ItemRegistry; -import org.openhab.core.items.ItemRegistryChangeListener; -import org.openhab.core.items.StateChangeListener; -import org.openhab.core.service.AbstractActiveService; -import org.openhab.core.types.Command; -import org.openhab.core.types.EventType; -import org.openhab.core.types.State; -import org.osgi.service.cm.ConfigurationException; -import org.osgi.service.cm.ManagedService; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class RuleService extends AbstractActiveService implements ManagedService, EventHandler, ItemRegistryChangeListener, StateChangeListener { - - private static final String RULES_CHANGESET = "org/openhab/core/drools/changeset.xml"; - - static private final Logger logger = LoggerFactory.getLogger(RuleService.class); - - private ItemRegistry itemRegistry = null; - - private long refreshInterval = 200; - - private StatefulKnowledgeSession ksession = null; - - private Map factHandleMap = new HashMap(); - - private List eventQueue = Collections.synchronizedList(new ArrayList()); - - public void activate() { - - SystemEventListenerFactory.setSystemEventListener(new RuleEventListener()); - - KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); - kbuilder.add(ResourceFactory.newClassPathResource(RULES_CHANGESET, getClass()), ResourceType.CHANGE_SET); - - if(kbuilder.hasErrors()) { - logger.error("There are errors in the rules: " + kbuilder.getErrors()); - return; - } - - KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); - - KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration(); - aconf.setProperty("drools.agent.newInstance", "false"); - KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent("RuleAgent", kbase, aconf); - kagent.applyChangeSet(ResourceFactory.newClassPathResource(RULES_CHANGESET, getClass())); - kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); - ksession = kbase.newStatefulKnowledgeSession(); - - // activate notifications - ResourceFactory.getResourceChangeNotifierService().start(); - ResourceFactory.getResourceChangeScannerService().start(); - - // activate this for extensive logging - // KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession); - - // set the scan interval to 20 secs - ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration(); - sconf.setProperty( "drools.resource.scanner.interval", "20" ); - ResourceFactory.getResourceChangeScannerService().configure(sconf); - - // now add all registered items to the session - if(itemRegistry!=null) { - for(Item item : itemRegistry.getItems()) { - itemAdded(item); - } - } - - setProperlyConfigured(true); - } - - public void deactivate() { - if(ksession!=null) { - ksession.dispose(); - ksession = null; - } - factHandleMap.clear(); - shutdown(); - } - - public void setItemRegistry(ItemRegistry itemRegistry) { - this.itemRegistry = itemRegistry; - itemRegistry.addItemRegistryChangeListener(this); - } - - public void unsetItemRegistry(ItemRegistry itemRegistry) { - itemRegistry.removeItemRegistryChangeListener(this); - this.itemRegistry = null; - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("rawtypes") - public void updated(Dictionary config) throws ConfigurationException { - if (config != null) { - String evalIntervalString = (String) config.get("evalInterval"); - if (StringUtils.isNotBlank(evalIntervalString)) { - refreshInterval = Long.parseLong(evalIntervalString); - } - } - } - - /** - * {@inheritDoc} - */ - public void allItemsChanged(Collection oldItemNames) { - if(ksession!=null) { - // first remove all previous items from the session - for(String oldItemName : oldItemNames) { - internalItemRemoved(oldItemName); - } - - // then add the current ones again - Collection items = itemRegistry.getItems(); - for(Item item : items) { - internalItemAdded(item); - } - } - } - - /** - * {@inheritDoc} - */ - public void itemAdded(Item item) { - if(ksession!=null) { - internalItemAdded(item); - } - } - - /** - * {@inheritDoc} - */ - public void itemRemoved(Item item) { - if(ksession!=null) { - internalItemRemoved(item.getName()); - if (item instanceof GenericItem) { - GenericItem genericItem = (GenericItem) item; - genericItem.removeStateChangeListener(this); - } - } - } - - /** - * {@inheritDoc} - */ - public void stateChanged(Item item, State oldState, State newState) { - eventQueue.add(new StateEvent(item, oldState, newState)); - } - - /** - * {@inheritDoc} - */ - public void stateUpdated(Item item, State state) { - eventQueue.add(new StateEvent(item, state)); - } - - public void receiveCommand(String itemName, Command command) { - try { - Item item = itemRegistry.getItem(itemName); - eventQueue.add(new CommandEvent(item, command)); - } catch (ItemNotFoundException e) {} - } - - private void internalItemAdded(Item item) { - if(item==null) { - logger.debug("Item must not be null here!"); - return; - } - - FactHandle handle = factHandleMap.get(item.getName()); - if(handle!=null) { - // we already know this item - try { - ksession.update(handle, item); - } catch(NullPointerException e) { - // this can be thrown because of a bug in drools when closing down the system - } - } else { - // it is a new item - handle = ksession.insert(item); - factHandleMap.put(item.getName(), handle); - if (item instanceof GenericItem) { - GenericItem genericItem = (GenericItem) item; - genericItem.addStateChangeListener(this); - } - } - } - - private void internalItemRemoved(String itemName) { - FactHandle handle = factHandleMap.get(itemName); - if(handle!=null) { - factHandleMap.remove(itemName); - ksession.retract(handle); - } - } - - /** - * @{inheritDoc} - */ - @Override - protected synchronized void execute() { - // remove all previous events from the session - Collection handles = ksession.getFactHandles(new ObjectFilter() { - public boolean accept(Object obj) { - if (obj instanceof RuleEvent) { - return true; - } - return false; - } - }); - for(FactHandle handle : handles) { - ksession.retract(handle); - } - - ArrayList clonedQueue = new ArrayList(eventQueue); - eventQueue.clear(); - - // now add all recent events to the session - for(RuleEvent event : clonedQueue) { - Item item = event.getItem(); - if(ksession!=null && item!=null) { - FactHandle factHandle = factHandleMap.get(item.getName()); - if(factHandle!=null) { - ksession.update(factHandle, item); - } - ksession.insert(event); - } - } - - // run the rule evaluation - ksession.fireAllRules(); - - } - - @Override - protected long getRefreshInterval() { - return refreshInterval; - } - - @Override - protected String getName() { - return "Rule Evaluation Service"; - } - - /** - * {@inheritDoc} - */ - public void handleEvent(Event event) { - String itemName = (String) event.getProperty("item"); - - String topic = event.getTopic(); - String[] topicParts = topic.split(TOPIC_SEPERATOR); - - if(!(topicParts.length > 2) || !topicParts[0].equals(TOPIC_PREFIX)) { - return; // we have received an event with an invalid topic - } - String operation = topicParts[1]; - - if(operation.equals(EventType.COMMAND.toString())) { - Command command = (Command) event.getProperty("command"); - if(command!=null) receiveCommand(itemName, command); - } - } - - static private final class RuleEventListener implements SystemEventListener { - - private final Logger logger = LoggerFactory.getLogger(SystemEventListener.class); - - public void warning(String message, Object object) { - logger.warn(message); - } - - public void warning(String message) { - logger.warn(message); - } - - public void info(String message, Object object) { - logger.info(message); - } - - public void info(String message) { - logger.info(message); - } - - public void exception(String message, Throwable e) { - logger.error(message, e); - } - - public void exception(Throwable e) { - logger.error(e.getLocalizedMessage(), e); - } - - public void debug(String message, Object object) { - logger.debug(message); - } - - public void debug(String message) { - logger.debug(message); - } - } - -} diff --git a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/internal/RulesActivator.java b/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/internal/RulesActivator.java deleted file mode 100644 index 9204cd04497..00000000000 --- a/bundles/core/org.openhab.core.drools/src/main/java/org/openhab/core/drools/internal/RulesActivator.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2010-2015, openHAB.org and others. - * - * 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.core.drools.internal; - -import org.openhab.core.events.EventPublisher; -import org.openhab.core.items.ItemRegistry; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.util.tracker.ServiceTracker; - -/** - * Extension of the default OSGi bundle activator - */ -public final class RulesActivator implements BundleActivator { - - public static ServiceTracker itemRegistryTracker; - public static ServiceTracker eventPublisherTracker; - - /** - * Called whenever the OSGi framework starts our bundle - */ - public void start(BundleContext bc) throws Exception { - itemRegistryTracker = new ServiceTracker(bc, ItemRegistry.class, null); - itemRegistryTracker.open(); - - eventPublisherTracker = new ServiceTracker(bc, EventPublisher.class, null); - eventPublisherTracker.open(); -} - - /** - * Called whenever the OSGi framework stops our bundle - */ - public void stop(BundleContext bc) throws Exception { - itemRegistryTracker.close(); - eventPublisherTracker.close(); - } -} diff --git a/bundles/core/org.openhab.core.drools/src/main/resources/org/openhab/core/drools/changeset.xml b/bundles/core/org.openhab.core.drools/src/main/resources/org/openhab/core/drools/changeset.xml deleted file mode 100644 index d3555a94df8..00000000000 --- a/bundles/core/org.openhab.core.drools/src/main/resources/org/openhab/core/drools/changeset.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/bundles/core/org.openhab.core.library.test/src/test/java/org/openhab/core/library/types/LocationItemTest.java b/bundles/core/org.openhab.core.library.test/src/test/java/org/openhab/core/library/types/LocationItemTest.java new file mode 100644 index 00000000000..2081ea569e7 --- /dev/null +++ b/bundles/core/org.openhab.core.library.test/src/test/java/org/openhab/core/library/types/LocationItemTest.java @@ -0,0 +1,49 @@ +package org.openhab.core.library.types; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +import org.junit.Test; +import org.openhab.core.library.items.LocationItem; + +/** + * @author Gaël L'hopital + * @since 1.7.0 + */ +public class LocationItemTest { + + @Test + public void testDistance() { + PointType pointParis = new PointType("48.8566140,2.3522219"); + + assertEquals(pointParis.getLatitude().doubleValue(),48.856614,0.0000001); + assertEquals(pointParis.getLongitude().doubleValue(),2.3522219,0.0000001); + + PointType pointBerlin = new PointType("52.5200066,13.4049540"); + + LocationItem locationParis = new LocationItem("paris"); + locationParis.setState(pointParis); + LocationItem locationBerlin = new LocationItem("berlin"); + locationBerlin.setState(pointBerlin); + + DecimalType distance = locationParis.distanceFrom(pointParis); + assertEquals(distance.intValue(),0); + + double parisBerlin = locationParis.distanceFrom(pointBerlin).doubleValue(); + assertEquals(parisBerlin,878400,50); + + double gravParis = pointParis.getGravity().doubleValue(); + assertEquals(gravParis,9.809,0.001); + + // Check canonization of position + PointType point3 = new PointType("-100,200"); + double lat3 = point3.getLatitude().doubleValue(); + double lon3 = point3.getLongitude().doubleValue(); + assertTrue(lat3 > -90); + assertTrue(lat3 < 90); + assertTrue(lon3 < 180); + assertTrue(lon3 > -180); + + } + +} diff --git a/bundles/core/org.openhab.core.library/META-INF/MANIFEST.MF b/bundles/core/org.openhab.core.library/META-INF/MANIFEST.MF index ddbb9a516e0..c6e54780c3f 100644 --- a/bundles/core/org.openhab.core.library/META-INF/MANIFEST.MF +++ b/bundles/core/org.openhab.core.library/META-INF/MANIFEST.MF @@ -11,7 +11,8 @@ Bundle-License: http://www.eclipse.org/legal/epl-v10.html Bundle-SymbolicName: org.openhab.core.library Bundle-DocURL: http://www.openhab.org Originally-Created-By: Apache Maven Bundle Plugin -Import-Package: org.openhab.core.events, +Import-Package: org.apache.commons.lang, + org.openhab.core.events, org.openhab.core.items, org.openhab.core.types, org.osgi.framework diff --git a/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/CoreItemFactory.java b/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/CoreItemFactory.java index c839b858040..f448433e762 100644 --- a/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/CoreItemFactory.java +++ b/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/CoreItemFactory.java @@ -14,6 +14,7 @@ import org.openhab.core.library.items.ContactItem; import org.openhab.core.library.items.DateTimeItem; import org.openhab.core.library.items.DimmerItem; +import org.openhab.core.library.items.LocationItem; import org.openhab.core.library.items.NumberItem; import org.openhab.core.library.items.RollershutterItem; import org.openhab.core.library.items.StringItem; @@ -28,7 +29,7 @@ */ public class CoreItemFactory implements ItemFactory { - private static String[] ITEM_TYPES = new String[] { "Switch", "Rollershutter", "Contact", "String", "Number", "Dimmer", "DateTime", "Color" }; + private static String[] ITEM_TYPES = new String[] { "Switch", "Rollershutter", "Contact", "String", "Number", "Dimmer", "DateTime", "Color", "Point" }; /** * @{inheritDoc} @@ -42,6 +43,7 @@ public GenericItem createItem(String itemTypeName, String itemName) { if (itemTypeName.equals(ITEM_TYPES[5])) return new DimmerItem(itemName); if (itemTypeName.equals(ITEM_TYPES[6])) return new DateTimeItem(itemName); if (itemTypeName.equals(ITEM_TYPES[7])) return new ColorItem(itemName); + if (itemTypeName.equals(ITEM_TYPES[8])) return new LocationItem(itemName); else return null; } diff --git a/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/items/LocationItem.java b/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/items/LocationItem.java new file mode 100644 index 00000000000..6f2cbb9c905 --- /dev/null +++ b/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/items/LocationItem.java @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.core.library.items; + +import java.util.ArrayList; +import java.util.List; + +import org.openhab.core.items.GenericItem; +import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.PointType; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; + +/** + * A LocationItem can be used to store GPS related informations, addresses... + * This is useful for location awareness related functions + * + * @author Gaël L'hopital + * @since 1.7.0 + */ +public class LocationItem extends GenericItem { + private static List> acceptedDataTypes = new ArrayList>(); + private static List> acceptedCommandTypes = new ArrayList>(); + + static { + acceptedDataTypes.add(PointType.class); + acceptedDataTypes.add(UnDefType.class); + } + + public LocationItem(String name) { + super(name); + } + + public List> getAcceptedDataTypes() { + return acceptedDataTypes; + } + + public List> getAcceptedCommandTypes() { + return acceptedCommandTypes; + } + + /** + * Compute the distance with another Point type, + * http://stackoverflow.com/questions/837872/calculate-distance-in-meters-when-you-know-longitude-and-latitude-in-java + * @return distance between the two points in meters + */ + public DecimalType distanceFrom(PointType away){ + + double dist = -1; + + if ((away != null) && (this.state instanceof PointType)) { + + PointType me = (PointType) this.state; + + double dLat = Math.pow(Math.sin(Math.toRadians(away.getLatitude().doubleValue() - me.getLatitude().doubleValue()) / 2),2); + double dLng = Math.pow(Math.sin(Math.toRadians(away.getLongitude().doubleValue() - me.getLongitude().doubleValue()) / 2),2); + double a = dLat + Math.cos(Math.toRadians(me.getLatitude().doubleValue())) + * Math.cos(Math.toRadians(away.getLatitude().doubleValue())) * dLng; + + dist = PointType.WGS84_a * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + } + + return new DecimalType(dist); + } + +} diff --git a/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/types/ArithmeticGroupFunction.java b/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/types/ArithmeticGroupFunction.java index 1386084b520..a9c66123b01 100644 --- a/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/types/ArithmeticGroupFunction.java +++ b/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/types/ArithmeticGroupFunction.java @@ -11,6 +11,8 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.openhab.core.items.GroupFunction; import org.openhab.core.items.Item; @@ -262,6 +264,58 @@ public State getStateAs(List items, Class stateClass) { } } } + + /** + * This calculates the number of items in the group matching the + * regular expression passed in parameter + * Group:String:COUNT(".") will count all items having a string state of one character + * Group:String:COUNT("[5-9]") will count all items having a string state between 5 and 9 + * ... + * + * @author Gaël L'hopital + * @since 1.7.0 + * + */ + static class Count implements GroupFunction { + + protected final Pattern pattern; + + public Count(State regExpr) { + if(regExpr==null) { + throw new IllegalArgumentException("Parameter must not be null!"); + } + this.pattern = Pattern.compile(regExpr.toString()); + } + + /** + * @{inheritDoc + */ + public State calculate(List items) { + int count = 0; + if(items!=null) { + for(Item item : items) { + Matcher matcher = pattern.matcher(item.getState().toString()); + if (matcher.matches()) { + count++; + } + } + } + + return new DecimalType(count); + } + + /** + * @{inheritDoc + */ + public State getStateAs(List items, Class stateClass) { + State state = calculate(items); + if(stateClass.isInstance(state)) { + return state; + } else { + return null; + } + } + } /** * This calculates the numeric sum over all item states of decimal type. diff --git a/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/types/PointType.java b/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/types/PointType.java new file mode 100644 index 00000000000..fdb522ea6cb --- /dev/null +++ b/bundles/core/org.openhab.core.library/src/main/java/org/openhab/core/library/types/PointType.java @@ -0,0 +1,156 @@ +/** + * Copyright (c) 2010-2015, openHAB.org and others. + * + * 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.core.library.types; + +import java.util.Formatter; +import java.util.SortedMap; +import java.util.TreeMap; + + +import org.apache.commons.lang.StringUtils; +import org.openhab.core.types.Command; +import org.openhab.core.types.ComplexType; +import org.openhab.core.types.PrimitiveType; +import org.openhab.core.types.State; + + +/** + * This type can be used for items that are dealing with GPS functionality. + * + * @author Gaël L'hopital + * @since 1.7.0 + */ +public class PointType implements ComplexType, Command, State { + + public static final double EARTH_GRAVITATIONAL_CONSTANT = 3.986004418e14; + public static final double WGS84_a = 6378137; // The equatorial radius of WGS84 ellipsoid (6378137 m). + + private double latitude; // in decimal degrees + private double longitude; // in decimal degrees + private double altitude = 0; // in decimal meters + + // constants for the constituents + static final public String KEY_LATITUDE = "lat"; + static final public String KEY_LONGITUDE = "long"; + static final public String KEY_ALTITUDE = "alt"; + + public static final State EMPTY = new PointType(new DecimalType(0), new DecimalType(0)); + + public PointType(DecimalType latitude, DecimalType longitude) { + canonicalize(latitude.doubleValue(),longitude.doubleValue()); + } + + public PointType(DecimalType latitude, DecimalType longitude, DecimalType altitude) { + this(latitude, longitude); + this.altitude = altitude.doubleValue(); + } + + public PointType(StringType latitude, StringType longitude) { + this(new DecimalType(latitude.toString()), new DecimalType(longitude.toString())); + } + + public PointType(StringType latitude, StringType longitude, StringType altitude) { + this(new DecimalType(latitude.toString()), new DecimalType(longitude.toString()), new DecimalType(altitude.toString())); + } + + public PointType(String value) { + if (StringUtils.isNotBlank(value)) { + String[] elements = value.split(","); + if (elements.length >= 2) { + canonicalize(Double.parseDouble(elements[0]),Double.parseDouble(elements[1])); + if (elements.length == 3) { + this.altitude = Double.parseDouble(elements[2]); + } + } + } + } + + public DecimalType getLatitude() { + return new DecimalType(latitude); + } + + public DecimalType getLongitude() { + return new DecimalType(longitude); + } + + public DecimalType getAltitude() { + return new DecimalType(altitude); + } + + public void setAltitude(DecimalType altitude) { + this.altitude = altitude.doubleValue(); + } + + public DecimalType getGravity() { + double latRad = Math.toRadians(latitude); + double deltaG = -2000.0 * (altitude/1000) * EARTH_GRAVITATIONAL_CONSTANT / ( Math.pow(WGS84_a,3.0) ); + double sin2lat = Math.sin(latRad) * Math.sin(latRad); + double sin22lat = Math.sin(2.0*latRad) * Math.sin(2.0*latRad); + double result = (9.780327 * (1.0 + 5.3024e-3 * sin2lat - 5.8e-6 * sin22lat) + deltaG); + return new DecimalType(result); + } + + /** + *

      Formats the value of this type according to a pattern (@see + * {@link Formatter}). One single value of this type can be referenced + * by the pattern using an index. The item order is defined by the natural + * (alphabetical) order of their keys.

      + * + * @param pattern the pattern to use containing indexes to reference the + * single elements of this type. + */ + public String format(String pattern) { + return String.format(pattern, getConstituents().values().toArray()); + } + + public PointType valueOf(String value) { + return new PointType(value); + } + + @Override + public String toString() { + return String.format("%1$.2f°N, %2$.2f°W, %2$.2f m", latitude, longitude, altitude); + } + + @Override + public SortedMap getConstituents() { + SortedMap result = new TreeMap(); + result.put(KEY_LATITUDE, getLatitude()); + result.put(KEY_LONGITUDE, getLongitude()); + result.put(KEY_ALTITUDE, getAltitude()); + return result; + } + + /** + * Canonicalize the current latitude and longitude values such that: + * + *
      +	 * -90 <= latitude <= +90 - 180 < longitude <= +180
      +	 * 
      + */ + private void canonicalize(double aLat, double aLon) { + latitude = (aLat + 180) % 360; + longitude = aLon; + if (latitude < 0) this.latitude += 360; + + latitude -= 180; + if (latitude > 90) { + latitude = 180 - latitude; + longitude += 180; + } else if (latitude < -90) { + latitude = -180 - latitude; + longitude += 180; + } + + longitude = ((longitude + 180) % 360); + if (longitude <= 0) longitude += 360; + longitude -= 180; + } + +} diff --git a/bundles/core/org.openhab.core.transform/src/main/java/org/openhab/core/transform/internal/service/ScaleTransformationService.java b/bundles/core/org.openhab.core.transform/src/main/java/org/openhab/core/transform/internal/service/ScaleTransformationService.java index a6ffca7da51..181cc91c555 100644 --- a/bundles/core/org.openhab.core.transform/src/main/java/org/openhab/core/transform/internal/service/ScaleTransformationService.java +++ b/bundles/core/org.openhab.core.transform/src/main/java/org/openhab/core/transform/internal/service/ScaleTransformationService.java @@ -74,10 +74,14 @@ public String transform(String filename, String source) throws TransformationExc double maxLimit = Double.parseDouble(matcher.group(3)); // a bit of a trick to include/exclude limits of the segment - if (matcher.group(1).equals(']')) - minLimit = minLimit - 0.0000000001; - if (matcher.group(1).equals('[')) + if (matcher.group(1).equals("]")) minLimit = minLimit + 0.0000000001; + if (matcher.group(1).equals("[")) + minLimit = minLimit - 0.0000000001; + if (matcher.group(4).equals("]")) + maxLimit = maxLimit + 0.0000000001; + if (matcher.group(4).equals("[")) + maxLimit = maxLimit - 0.0000000001; if ((minLimit < value) && (value < maxLimit)) { result = matcher.group(5); diff --git a/bundles/core/org.openhab.core/.classpath b/bundles/core/org.openhab.core/.classpath index 9dda1ba495f..913a170d25e 100644 --- a/bundles/core/org.openhab.core/.classpath +++ b/bundles/core/org.openhab.core/.classpath @@ -4,6 +4,5 @@ - diff --git a/bundles/core/pom.xml b/bundles/core/pom.xml index f6b1ad29fc1..7b41cff7700 100644 --- a/bundles/core/pom.xml +++ b/bundles/core/pom.xml @@ -21,7 +21,6 @@ org.openhab.core.test org.openhab.core.library org.openhab.core.library.test - org.openhab.core.drools org.openhab.core.persistence org.openhab.core.persistence.test org.openhab.core.scheduler diff --git a/bundles/io/org.openhab.io.cv/.classpath b/bundles/io/org.openhab.io.cv/.classpath index 8974fd65022..b0b19b719c3 100644 --- a/bundles/io/org.openhab.io.cv/.classpath +++ b/bundles/io/org.openhab.io.cv/.classpath @@ -4,8 +4,8 @@ - - - + + + diff --git a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/CVApplication.java b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/CVApplication.java index bed08928714..e53abe83313 100644 --- a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/CVApplication.java +++ b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/CVApplication.java @@ -16,6 +16,7 @@ import javax.servlet.ServletException; import javax.ws.rs.ApplicationPath; +import org.apache.commons.lang.StringUtils; import org.atmosphere.cpr.AtmosphereServlet; import org.openhab.core.events.EventPublisher; import org.openhab.core.items.ItemRegistry; @@ -66,7 +67,7 @@ public class CVApplication extends PackagesResourceConfig { static private ItemUIRegistry itemUIRegistry; - static private ModelRepository modelRepository; + static public ModelRepository modelRepository; public CVApplication() { super("org.openhab.io.cv.internal.resources"); @@ -196,8 +197,15 @@ private Dictionary getJerseyServletParams() { jerseyServletParams.put("org.atmosphere.cpr.AtmosphereInterceptor.disableDefaults", "true"); // use the default interceptors without PaddingAtmosphereInterceptor // see: https://groups.google.com/forum/#!topic/openhab/Z-DVBXdNiYE - jerseyServletParams.put("org.atmosphere.cpr.AtmosphereInterceptor", "org.atmosphere.interceptor.DefaultHeadersInterceptor,org.atmosphere.interceptor.AndroidAtmosphereInterceptor,org.atmosphere.interceptor.SSEAtmosphereInterceptor,org.atmosphere.interceptor.JSONPAtmosphereInterceptor,org.atmosphere.interceptor.JavaScriptProtocol,org.atmosphere.interceptor.OnDisconnectInterceptor"); - + final String[] interceptors = { + "org.atmosphere.interceptor.CacheHeadersInterceptor", + "org.atmosphere.interceptor.AndroidAtmosphereInterceptor", + "org.atmosphere.interceptor.SSEAtmosphereInterceptor", + "org.atmosphere.interceptor.JSONPAtmosphereInterceptor", + "org.atmosphere.interceptor.JavaScriptProtocol", + "org.atmosphere.interceptor.OnDisconnectInterceptor" + }; + jerseyServletParams.put("org.atmosphere.cpr.AtmosphereInterceptor", StringUtils.join(interceptors, ",")); jerseyServletParams.put("org.atmosphere.cpr.broadcasterLifeCyclePolicy", "IDLE_DESTROY"); jerseyServletParams.put("org.atmosphere.cpr.CometSupport.maxInactiveActivity", "300000"); diff --git a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/broadcaster/CometVisuBroadcaster.java b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/broadcaster/CometVisuBroadcaster.java index 915ace5598d..93004108f54 100644 --- a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/broadcaster/CometVisuBroadcaster.java +++ b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/broadcaster/CometVisuBroadcaster.java @@ -8,13 +8,19 @@ */ package org.openhab.io.cv.internal.broadcaster; +import java.net.URI; import java.util.Collection; import java.util.Collections; import java.util.WeakHashMap; +import org.atmosphere.cpr.AtmosphereConfig; +import org.atmosphere.cpr.Broadcaster; import org.atmosphere.cpr.BroadcasterLifeCyclePolicyListener; import org.atmosphere.jersey.JerseyBroadcaster; +import org.openhab.io.cv.CVApplication; import org.openhab.io.cv.internal.listeners.ResourceStateChangeListener; +import org.openhab.model.core.EventType; +import org.openhab.model.core.ModelRepositoryChangeListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,12 +30,13 @@ * * @since 1.4.0 */ -public class CometVisuBroadcaster extends JerseyBroadcaster { +public class CometVisuBroadcaster extends JerseyBroadcaster implements ModelRepositoryChangeListener { private static final Logger logger = LoggerFactory.getLogger(CometVisuBroadcaster.class); protected Collection listeners = Collections.newSetFromMap(new WeakHashMap()); - public CometVisuBroadcaster(String id, org.atmosphere.cpr.AtmosphereConfig config) { - super(id, config); + @Override + public Broadcaster initialize(String name, URI uri, AtmosphereConfig config) { + super.initialize(name, uri, config); this.addBroadcasterLifeCyclePolicyListener(new BroadcasterLifeCyclePolicyListener() { @Override @@ -51,6 +58,8 @@ public void onDestroy() { } } }); + CVApplication.modelRepository.addModelRepositoryChangeListener(this); + return this; } public void addStateChangeListener(final ResourceStateChangeListener listener){ @@ -63,4 +72,13 @@ public void addStateChangeListener(final ResourceStateChangeListener listener){ } } + + @Override + public void modelChanged(String modelName, EventType type) { + for (ResourceStateChangeListener l : listeners) { + // Item Model has changed so the listener listen to non existent items and need to be registered again + l.setBroadcaster(this); + l.registerItems(); + } + } } diff --git a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/cache/CVBroadcasterCache.java b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/cache/CVBroadcasterCache.java index 7dcd285b33a..fa95b8e3462 100644 --- a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/cache/CVBroadcasterCache.java +++ b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/cache/CVBroadcasterCache.java @@ -37,11 +37,10 @@ public class CVBroadcasterCache extends UUIDBroadcasterCache { private final static Logger logger = LoggerFactory.getLogger(CVBroadcasterCache.class); @Override - public List retrieveFromCache(String broadcasterId, - AtmosphereResource r) { + public List retrieveFromCache(String broadcasterId, String uuid) { List result = new ArrayList(); ItemStateListBean response = new ItemStateListBean(new ItemListBean()); - for (Object cacheMessage : super.retrieveFromCache(broadcasterId, r)) { + for (Object cacheMessage : super.retrieveFromCache(broadcasterId, uuid)) { if (cacheMessage instanceof ItemStateListBean) { ItemStateListBean cachedStateList = (ItemStateListBean) cacheMessage; // add states to the response (maybe a comparison is needed here @@ -87,10 +86,8 @@ public List retrieveFromCache(String broadcasterId, } result.add(response); } - if (logger.isTraceEnabled()) { - logger.trace("Retrieved for AtmosphereResource {} cached messages {}", - r.uuid(), response.stateList.entries); - } + logger.trace("Retrieved for AtmosphereResource {} cached messages {}", + uuid, response.stateList.entries); return result; } diff --git a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/filter/ResponseObjectFilter.java b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/filter/ResponseObjectFilter.java index ecbdfc7c4e8..420c25aee9b 100644 --- a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/filter/ResponseObjectFilter.java +++ b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/filter/ResponseObjectFilter.java @@ -37,12 +37,12 @@ public class ResponseObjectFilter implements PerRequestBroadcastFilter { .getLogger(ResponseObjectFilter.class); @Override - public BroadcastAction filter(Object originalMessage, Object message) { - return new BroadcastAction(ACTION.CONTINUE, message); + public BroadcastAction filter(String broadcasterId, Object originalMessage, Object message) { + return new BroadcastAction(message); } @Override - public BroadcastAction filter(AtmosphereResource resource, + public BroadcastAction filter(String broadcasterId, AtmosphereResource resource, Object originalMessage, Object message) { final HttpServletRequest request = resource.getRequest(); try { diff --git a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/listeners/ResourceStateChangeListener.java b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/listeners/ResourceStateChangeListener.java index cc830440a81..34fa164dc8e 100644 --- a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/listeners/ResourceStateChangeListener.java +++ b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/listeners/ResourceStateChangeListener.java @@ -9,7 +9,6 @@ package org.openhab.io.cv.internal.listeners; import java.util.List; -import java.util.Set; import javax.servlet.http.HttpServletRequest; @@ -17,7 +16,6 @@ import org.atmosphere.cpr.BroadcastFilter.BroadcastAction.ACTION; import org.atmosphere.cpr.PerRequestBroadcastFilter; import org.openhab.core.items.GenericItem; -import org.openhab.core.items.GroupItem; import org.openhab.core.items.Item; import org.openhab.core.items.StateChangeListener; import org.openhab.core.types.State; @@ -26,8 +24,6 @@ import org.openhab.io.cv.internal.filter.ResponseObjectFilter; import org.openhab.io.cv.internal.resources.ReadResource; import org.openhab.io.cv.internal.resources.beans.ItemStateListBean; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** @@ -40,9 +36,6 @@ */ abstract public class ResourceStateChangeListener { - private static final Logger logger = LoggerFactory.getLogger(ResourceStateChangeListener.class); - - private Set relevantItems = null; private StateChangeListener stateChangeListener; private CometVisuBroadcaster broadcaster; @@ -69,12 +62,13 @@ public void registerItems(){ broadcaster.getBroadcasterConfig().addFilter(new PerRequestBroadcastFilter() { @Override - public BroadcastAction filter(Object originalMessage, Object message) { - return new BroadcastAction(ACTION.CONTINUE, message); + public BroadcastAction filter(String broadcasterId, Object originalMessage, Object message) { + return new BroadcastAction(message); } @Override - public BroadcastAction filter(AtmosphereResource resource, Object originalMessage, Object message) { + public BroadcastAction filter(String broadcasterId, AtmosphereResource resource, + Object originalMessage, Object message) { HttpServletRequest request = resource.getRequest(); Object responseObject; if (message instanceof Item) { @@ -99,18 +93,7 @@ public BroadcastAction filter(AtmosphereResource resource, Object originalMessag stateChangeListener = new StateChangeListener() { // don't react on update events public void stateUpdated(Item item, State state) { - // if the group has a base item and thus might calculate its state - // as a DecimalType or other, we also consider it to be necessary to - // send an update to the client as the label of the item might have changed, - // even though its state is yet the same. - if(item instanceof GroupItem) { - GroupItem gItem = (GroupItem) item; - if(gItem.getBaseItem()!=null) { - if(!broadcaster.getAtmosphereResources().isEmpty()) { - broadcaster.broadcast(item); - } - } - } + //updates can be ignored } @@ -134,11 +117,8 @@ protected void registerStateChangeListenerOnRelevantItems(String pathInfo, State } protected void unregisterStateChangeListenerOnRelevantItems() { - - if(relevantItems!=null) { - for(String itemName : relevantItems) { - unregisterChangeListenerOnItem(stateChangeListener, itemName); - } + for(String itemName : getRelevantItemNames()) { + unregisterChangeListenerOnItem(stateChangeListener, itemName); } } diff --git a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/ReadResource.java b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/ReadResource.java index 61d870dd480..97d6f5c6e68 100644 --- a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/ReadResource.java +++ b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/ReadResource.java @@ -15,7 +15,6 @@ import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; @@ -30,7 +29,6 @@ import org.atmosphere.cpr.AtmosphereResource; import org.atmosphere.cpr.Broadcaster; import org.atmosphere.cpr.BroadcasterFactory; -import org.atmosphere.cpr.HeaderConfig; import org.atmosphere.jersey.SuspendResponse; import org.openhab.core.items.GroupItem; import org.openhab.core.items.Item; @@ -83,12 +81,12 @@ public SuspendResponse getResults( @QueryParam("i") long index, @QueryParam("t") long time, @QueryParam("jsoncallback") @DefaultValue("callback") String callback, - @HeaderParam(HeaderConfig.X_ATMOSPHERE_TRANSPORT) String atmosphereTransport, - @HeaderParam(HeaderConfig.X_CACHE_DATE) long cacheDate, @Context AtmosphereResource resource) { - String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes()); - logger.debug("Received HTTP GET request at '{}' for {} items at index '{}', time '{}', ResponseType: '{}'.", - new String[] { uriInfo.getPath(), String.valueOf(itemNames.size()), String.valueOf(index), String.valueOf(cacheDate), responseType}); + final String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes()); + if (logger.isDebugEnabled()) { + logger.debug("Received HTTP GET request at '{}' for {} items at index '{}', ResponseType: '{}'.", + uriInfo.getPath(), itemNames.size(), index, responseType); + } if(index==0) { // first request => return all values if (responseType != null) { @@ -97,8 +95,11 @@ public SuspendResponse getResults( throw new WebApplicationException(Response.notAcceptable(null).build()); } } - CometVisuBroadcaster itemBroadcaster = (CometVisuBroadcaster) BroadcasterFactory.getDefault().lookup(CometVisuBroadcaster.class, resource.getRequest().getPathInfo(), true); + + BroadcasterFactory broadcasterFactory = resource.getAtmosphereConfig().getBroadcasterFactory(); + CometVisuBroadcaster itemBroadcaster = (CometVisuBroadcaster) broadcasterFactory.lookup(CometVisuBroadcaster.class, resource.getRequest().getPathInfo(), true); itemBroadcaster.addStateChangeListener(new ItemStateChangeListener(itemNames)); + return new SuspendResponse.SuspendResponseBuilder() .scope(SCOPE.REQUEST) .resumeOnBroadcast(!ResponseTypeHelper.isStreamingTransport(resource.getRequest())) diff --git a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/RrdResource.java b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/RrdResource.java index 053cb4bb5d4..2d57993aad9 100644 --- a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/RrdResource.java +++ b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/RrdResource.java @@ -76,8 +76,9 @@ public Response getRrd(@Context HttpHeaders headers, @QueryParam("start") String start, @QueryParam("end") String end, @QueryParam("res") long res) { - logger.debug("Received GET request at '{}' for rrd '{}'.", - new String[] { uriInfo.getPath(), rrdName }); + if (logger.isDebugEnabled()) + logger.debug("Received GET request at '{}' for rrd '{}'.", + uriInfo.getPath(), rrdName); String responseType = MediaTypeHelper.getResponseMediaType(headers .getAcceptableMediaTypes()); diff --git a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/WriteResource.java b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/WriteResource.java index fe52bdb0dd5..4806048a5cd 100644 --- a/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/WriteResource.java +++ b/bundles/io/org.openhab.io.cv/src/main/java/org/openhab/io/cv/internal/resources/WriteResource.java @@ -55,7 +55,7 @@ public Response getResults( @QueryParam("v") String value, @QueryParam("ts") long timestamp, @QueryParam("jsoncallback") @DefaultValue("callback") String callback) { - logger.debug("Received HTTP GET request at '{}' for item '{}'.", new String[] { uriInfo.getPath(), itemName }); + if (logger.isDebugEnabled()) logger.debug("Received HTTP GET request at '{}' for item '{}'.", uriInfo.getPath(), itemName); String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes()); if(responseType!=null) { Item item = ReadResource.getItem(itemName); diff --git a/bundles/io/org.openhab.io.dropbox/src/main/java/org/openhab/io/dropbox/internal/DropboxSynchronizer.java b/bundles/io/org.openhab.io.dropbox/src/main/java/org/openhab/io/dropbox/internal/DropboxSynchronizer.java index 83e16cf356e..7191b728abe 100644 --- a/bundles/io/org.openhab.io.dropbox/src/main/java/org/openhab/io/dropbox/internal/DropboxSynchronizer.java +++ b/bundles/io/org.openhab.io.dropbox/src/main/java/org/openhab/io/dropbox/internal/DropboxSynchronizer.java @@ -176,7 +176,7 @@ private void activateSynchronizer() { * @throws DbxException if there are technical or application level errors * in the Dropbox communication * - * @see openHAB Dropbox Wiki + * @see openHAB Dropbox IO Wiki */ public void startAuthentication() throws DbxException { DbxWebAuthNoRedirect webAuth = new DbxWebAuthNoRedirect(requestConfig, appInfo); @@ -198,7 +198,7 @@ public void startAuthentication() throws DbxException { * @throws DbxException if there are technical or application level errors * in the Dropbox communication * - * @see openHAB Dropbox Wiki + * @see openHAB Dropbox IO Wiki */ public void finishAuthentication(String code) throws DbxException { DbxWebAuthNoRedirect webAuth = new DbxWebAuthNoRedirect(requestConfig, appInfo); diff --git a/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/.classpath b/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/.classpath index 18476cf6bde..9cb66201d9b 100644 --- a/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/.classpath +++ b/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/.classpath @@ -1,8 +1,8 @@ + - diff --git a/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/META-INF/MANIFEST.MF b/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/META-INF/MANIFEST.MF index 532982bf16d..529bcdcc033 100644 --- a/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/META-INF/MANIFEST.MF +++ b/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/META-INF/MANIFEST.MF @@ -6,7 +6,7 @@ Bundle-Version: 1.7.0.qualifier Bundle-Vendor: openHAB.org Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ClassPath: ., - lib/opentts-0.1.jar + lib/opentts-0.2.jar Import-Package: org.openhab.io.multimedia.tts, org.osgi.framework, org.osgi.service.cm;version="1.4.0", diff --git a/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/build.properties b/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/build.properties index 537fe589118..28010a23f50 100644 --- a/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/build.properties +++ b/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/build.properties @@ -2,5 +2,5 @@ output.. = target/classes/ bin.includes = META-INF/,\ .,\ OSGI-INF/,\ - lib/opentts-0.1.jar + lib/opentts-0.2.jar source.. = src/main/java/ diff --git a/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/lib/opentts-0.1.jar b/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/lib/opentts-0.1.jar deleted file mode 100644 index 8f7d6f9fcc7..00000000000 Binary files a/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/lib/opentts-0.1.jar and /dev/null differ diff --git a/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/lib/opentts-0.2.jar b/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/lib/opentts-0.2.jar new file mode 100644 index 00000000000..874957a5338 Binary files /dev/null and b/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/lib/opentts-0.2.jar differ diff --git a/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/src/main/java/org/openhab/io/multimedia/internal/tts/SpeechDispatcherConnection.java b/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/src/main/java/org/openhab/io/multimedia/internal/tts/SpeechDispatcherConnection.java index 871ec0f5a7b..d3818514c11 100644 --- a/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/src/main/java/org/openhab/io/multimedia/internal/tts/SpeechDispatcherConnection.java +++ b/bundles/io/org.openhab.io.multimedia.tts.speechdispatcher/src/main/java/org/openhab/io/multimedia/internal/tts/SpeechDispatcherConnection.java @@ -16,31 +16,34 @@ import speechd.ssip.SSIPPriority; /** - * This class open a TCP/IP connection to the Speech Dispatcher service - * and can send messages to be announced + * This class open a TCP/IP connection to the Speech Dispatcher service and can + * send messages to be announced + * * @author Gaël L'hopital * @since 1.6.0 */ public class SpeechDispatcherConnection { - private static Logger logger = LoggerFactory.getLogger(SpeechDispatcherConnection.class); + private static Logger logger = LoggerFactory + .getLogger(SpeechDispatcherConnection.class); public String port; public String host; - private static SSIPClient speechDispatcherClient = null; - + private static SSIPClient speechDispatcherClient = null; + public SpeechDispatcherConnection() { } public void openConnection() { - // Close any existing connection first, if present - closeConnection(); + closeConnection(); try { - speechDispatcherClient = new SSIPClient("openhab", null, null, host, port); + speechDispatcherClient = new SSIPClient("openhab", null, null, + host, port); } catch (SSIPException e) { - logger.error("Error connecting to SpeechDispatcher Host {}: {}",host,e.getLocalizedMessage()); + logger.error("Error connecting to SpeechDispatcher Host {}: {}", + host, e.getLocalizedMessage()); } } @@ -48,37 +51,43 @@ public void closeConnection() { if (speechDispatcherClient != null) { try { speechDispatcherClient.close(); - speechDispatcherClient =null; + speechDispatcherClient = null; } catch (SSIPException e) { - logger.error("Error closing connection to SpeechDispatcher Host {}: {}",host,e.getLocalizedMessage()); - } + logger.error( + "Error closing connection to SpeechDispatcher Host {}: {}", + host, e.getLocalizedMessage()); + } } } - + /** * Speaks the text with a given voice - * - * @param text the text to speak - * @param voice the name of the voice to use or null, if the default voice should be used + * + * @param text + * the text to speak + * @param voice + * the name of the voice to use or null, if the default voice + * should be used */ public void say(String text, String voiceName) { - if (speechDispatcherClient==null || !speechDispatcherClient.getConnection().isConnected()) { - openConnection(); - } - if(text==null) { + if (text == null) { return; } + + openConnection(); try { if (voiceName != null) { speechDispatcherClient.setVoice(voiceName); } speechDispatcherClient.say(SSIPPriority.MESSAGE, text); } catch (SSIPException e) { - logger.error("Error sending text to SpeechDispatcher Host {}: {}",host,e.getLocalizedMessage()); + logger.error("Error sending text to SpeechDispatcher Host {}: {}", + host, e.getLocalizedMessage()); } + closeConnection(); } - + @Override public String toString() { return "Device [host=" + host + ", port=" + port + "]"; diff --git a/bundles/io/org.openhab.io.rest.lib/.classpath b/bundles/io/org.openhab.io.rest.lib/.classpath index 3b4dfa2826f..53f8d44f17b 100644 --- a/bundles/io/org.openhab.io.rest.lib/.classpath +++ b/bundles/io/org.openhab.io.rest.lib/.classpath @@ -1,15 +1,12 @@ - - - - + - - - - + + + + @@ -17,8 +14,8 @@ - - - + + + diff --git a/bundles/io/org.openhab.io.rest.lib/META-INF/MANIFEST.MF b/bundles/io/org.openhab.io.rest.lib/META-INF/MANIFEST.MF index 6b312b955c4..67b1ed1ad1a 100644 --- a/bundles/io/org.openhab.io.rest.lib/META-INF/MANIFEST.MF +++ b/bundles/io/org.openhab.io.rest.lib/META-INF/MANIFEST.MF @@ -10,19 +10,15 @@ Bundle-ClassPath: lib/jackson-core-asl-1.9.2.jar, lib/jackson-mapper-asl-1.9.2.jar, lib/jackson-xc-1.9.2.jar, lib/asm-3.1.jar, - lib/jersey-client-1.17.1.jar, - lib/jersey-json-1.17.1.jar, - lib/jersey-server-1.17.1.jar, - lib/jersey-servlet-1.17.1.jar, - lib/jettison-1.1.jar, - lib/jersey-core-1.17.1.jar, + lib/jersey-core-1.18.1.jar, + lib/jersey-json-1.18.1.jar, + lib/jersey-server-1.18.1.jar, + lib/jersey-servlet-1.18.1.jar, lib/jsr311-api-1.1.1.jar, - lib/atmosphere-compat-jbossweb-2.0.1.jar, - lib/atmosphere-compat-tomcat-2.0.1.jar, - lib/atmosphere-compat-tomcat7-2.0.1.jar, - lib/atmosphere-annotations-2.0.9.jar, - lib/atmosphere-jersey-2.0.9.jar, - lib/atmosphere-runtime-2.0.9.jar + lib/atmosphere-runtime-2.2.5.jar, + lib/atmosphere-annotations-2.2.5.jar, + lib/atmosphere-jersey-2.2.5.jar, + lib/jersey-client-1.18.1.jar Import-Package: com.sun.jersey.api.core, com.sun.jersey.api.json, com.sun.jersey.core.osgi, @@ -38,13 +34,119 @@ Import-Package: com.sun.jersey.api.core, org.osgi.framework, org.slf4j DynamicImport-Package: * -Export-Package: com.sun.jersey.api.client,com.sun.jersey.api.core,com. - sun.jersey.api.core.servlet,com.sun.jersey.api.json,com.sun.jersey.co - re.osgi,com.sun.jersey.core.util,com.sun.jersey.spi.container,javax.w - s.rs,javax.ws.rs.core,javax.ws.rs.ext,org.atmosphere,org.atmosphere.a - nnotation,org.atmosphere.cache,org.atmosphere.cpr,org.atmosphere.jers - ey,org.atmosphere.util,org.codehaus.jackson;version="1.9.2",org.codeh - aus.jackson.annotate;version="1.9.2",org.codehaus.jackson.map;version - ="1.9.2",org.codehaus.jackson.map.annotate;version="1.9.2",org.codeha - us.jackson.type;version="1.9.2" +Export-Package: com.sun.jersey.api.client; + uses:="com.sun.jersey.core.spi.component, + new com.sun.jersey.api.client, + com.sun.jersey.core.header, + com.sun.jersey.api.client.filter, + com.sun.jersey.api.client.async, + com.sun.jersey.core.util, + com.sun.jersey.core.spi.component.ioc, + com.sun.jersey.core.spi.factory, + com.sun.jersey.spi, + com.sun.jersey.client.proxy, + com.sun.jersey.api.client.config, + javax.ws.rs.ext, + javax.ws.rs.core, + com.sun.jersey.spi.inject, + com.sun.jersey.client.impl, + com.sun.jersey.client.impl.async", + com.sun.jersey.api.core; + uses:="com.sun.jersey.spi.container, + com.sun.jersey.server.impl.application, + javax.ws.rs.core, + com.sun.jersey.api.representation, + com.sun.jersey.core.spi.scanning, + com.sun.jersey.core.util, + com.sun.jersey.api.model", + com.sun.jersey.api.core.servlet;uses:="javax.servlet,com.sun.jersey.api.core", + com.sun.jersey.api.json; + uses:="org.codehaus.jackson.map, + org.codehaus.jackson, + new com.sun.jersey.api.json, + javax.xml.bind", + com.sun.jersey.core.osgi;uses:="org.osgi.framework,com.sun.jersey.core.spi.scanning", + com.sun.jersey.core.util;uses:="javax.ws.rs.core,javax.xml.parsers", + com.sun.jersey.spi.container; + uses:="com.sun.jersey.api.container, + com.sun.jersey.core.spi.component, + com.sun.jersey.spi, + com.sun.jersey.core.header, + javax.ws.rs.ext, + javax.ws.rs.core, + com.sun.jersey.api.representation, + javax.ws.rs, + com.sun.jersey.api.core, + com.sun.jersey.spi.monitoring, + com.sun.jersey.spi.dispatch, + com.sun.jersey.core.util, + com.sun.jersey.server.impl.inject, + com.sun.jersey.api.model, + com.sun.jersey.core.spi.component.ioc", + javax.ws.rs;uses:="javax.ws.rs.core", + javax.ws.rs.core, + javax.ws.rs.ext;uses:="javax.ws.rs.core", + org.atmosphere;uses:="org.atmosphere.cpr", + org.atmosphere.annotation; + uses:="javax.servlet, + org.slf4j, + org.atmosphere.cpr, + org.atmosphere.handler", + org.atmosphere.cache;uses:="org.atmosphere.cpr", + org.atmosphere.cpr; + uses:="org.slf4j, + org.atmosphere.interceptor, + javax.servlet.http, + org.atmosphere.websocket, + org.atmosphere.handler, + org.atmosphere.util.annotation, + javax.servlet, + org.atmosphere.di, + new org.atmosphere.cpr, + org.atmosphere.util, + org.atmosphere.cache", + org.atmosphere.jersey; + uses:="com.sun.jersey.core.spi.component, + org.atmosphere.annotation, + com.sun.jersey.spi, + org.slf4j, + com.sun.jersey.spi.container, + javax.servlet.http, + org.atmosphere.cpr, + javax.ws.rs.core, + com.sun.jersey.spi.inject, + com.sun.jersey.api.core, + com.sun.jersey.api, + new org.atmosphere.jersey, + com.sun.jersey.api.model", + org.atmosphere.util; + uses:="org.slf4j, + javax.servlet.http, + org.atmosphere.cpr, + javax.servlet", + org.codehaus.jackson;version="1.9.2"; + uses:="org.codehaus.jackson.io, + org.codehaus.jackson.type, + org.codehaus.jackson.format, + org.codehaus.jackson.sym, + org.codehaus.jackson.util", + org.codehaus.jackson.annotate;version="1.9.2", + org.codehaus.jackson.map;version="1.9.2"; + uses:="org.codehaus.jackson.io, + org.codehaus.jackson.map.introspect, + org.codehaus.jackson.type, + org.codehaus.jackson.map.type, + org.codehaus.jackson, + org.codehaus.jackson.annotate, + org.codehaus.jackson.map.annotate, + org.codehaus.jackson.map.ser, + org.codehaus.jackson.map.jsontype, + org.codehaus.jackson.map.util, + org.codehaus.jackson.node, + org.codehaus.jackson.map.jsontype.impl, + org.codehaus.jackson.schema, + org.codehaus.jackson.format, + org.codehaus.jackson.map.deser", + org.codehaus.jackson.map.annotate;version="1.9.2", + org.codehaus.jackson.type;version="1.9.2" Require-Bundle: javax.servlet diff --git a/bundles/io/org.openhab.io.rest.lib/build.properties b/bundles/io/org.openhab.io.rest.lib/build.properties index c57483a2ba5..ce36174973e 100644 --- a/bundles/io/org.openhab.io.rest.lib/build.properties +++ b/bundles/io/org.openhab.io.rest.lib/build.properties @@ -4,16 +4,14 @@ bin.includes = META-INF/,\ lib/jackson-mapper-asl-1.9.2.jar,\ lib/jackson-xc-1.9.2.jar,\ lib/asm-3.1.jar,\ - lib/jersey-client-1.17.1.jar,\ - lib/jersey-json-1.17.1.jar,\ - lib/jersey-server-1.17.1.jar,\ - lib/jersey-servlet-1.17.1.jar,\ + lib/jersey-core-1.18.1.jar,\ + lib/jersey-client-1.18.1.jar,\ + lib/jersey-json-1.18.1.jar,\ + lib/jersey-server-1.18.1.jar,\ + lib/jersey-servlet-1.18.1.jar,\ lib/jettison-1.1.jar,\ - lib/jersey-core-1.17.1.jar,\ lib/jsr311-api-1.1.1.jar,\ - lib/atmosphere-compat-jbossweb-2.0.1.jar,\ - lib/atmosphere-compat-tomcat-2.0.1.jar,\ - lib/atmosphere-compat-tomcat7-2.0.1.jar,\ - lib/atmosphere-annotations-2.0.9.jar,\ - lib/atmosphere-jersey-2.0.9.jar,\ - lib/atmosphere-runtime-2.0.9.jar + lib/atmosphere-annotations-2.2.5.jar,\ + lib/atmosphere-jersey-2.2.5.jar,\ + lib/atmosphere-runtime-2.2.5.jar + diff --git a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-annotations-2.0.9.jar b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-annotations-2.0.9.jar deleted file mode 100644 index 80157c76cee..00000000000 Binary files a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-annotations-2.0.9.jar and /dev/null differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-annotations-2.2.5.jar b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-annotations-2.2.5.jar new file mode 100644 index 00000000000..8312007beba Binary files /dev/null and b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-annotations-2.2.5.jar differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-compat-jbossweb-2.0.1.jar b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-compat-jbossweb-2.0.1.jar deleted file mode 100644 index 899b03f7e1e..00000000000 Binary files a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-compat-jbossweb-2.0.1.jar and /dev/null differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-compat-tomcat-2.0.1.jar b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-compat-tomcat-2.0.1.jar deleted file mode 100644 index 3df6f951ed3..00000000000 Binary files a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-compat-tomcat-2.0.1.jar and /dev/null differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-compat-tomcat7-2.0.1.jar b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-compat-tomcat7-2.0.1.jar deleted file mode 100644 index b1ef8cf4b3a..00000000000 Binary files a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-compat-tomcat7-2.0.1.jar and /dev/null differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-jersey-2.0.9.jar b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-jersey-2.0.9.jar deleted file mode 100644 index 07179911a75..00000000000 Binary files a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-jersey-2.0.9.jar and /dev/null differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-jersey-2.2.5.jar b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-jersey-2.2.5.jar new file mode 100644 index 00000000000..8af7c70a1ec Binary files /dev/null and b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-jersey-2.2.5.jar differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-runtime-2.0.9.jar b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-runtime-2.0.9.jar deleted file mode 100644 index 63dfc893841..00000000000 Binary files a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-runtime-2.0.9.jar and /dev/null differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-runtime-2.2.5.jar b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-runtime-2.2.5.jar new file mode 100644 index 00000000000..22536d4016c Binary files /dev/null and b/bundles/io/org.openhab.io.rest.lib/lib/atmosphere-runtime-2.2.5.jar differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/jersey-client-1.17.1.jar b/bundles/io/org.openhab.io.rest.lib/lib/jersey-client-1.17.1.jar deleted file mode 100644 index 898afb74ce3..00000000000 Binary files a/bundles/io/org.openhab.io.rest.lib/lib/jersey-client-1.17.1.jar and /dev/null differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/jersey-client-1.18.1.jar b/bundles/io/org.openhab.io.rest.lib/lib/jersey-client-1.18.1.jar new file mode 100644 index 00000000000..fec3718c54a Binary files /dev/null and b/bundles/io/org.openhab.io.rest.lib/lib/jersey-client-1.18.1.jar differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/jersey-core-1.17.1.jar b/bundles/io/org.openhab.io.rest.lib/lib/jersey-core-1.18.1.jar similarity index 64% rename from bundles/io/org.openhab.io.rest.lib/lib/jersey-core-1.17.1.jar rename to bundles/io/org.openhab.io.rest.lib/lib/jersey-core-1.18.1.jar index 8229c8d653e..31e49d34339 100644 Binary files a/bundles/io/org.openhab.io.rest.lib/lib/jersey-core-1.17.1.jar and b/bundles/io/org.openhab.io.rest.lib/lib/jersey-core-1.18.1.jar differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/jersey-json-1.17.1.jar b/bundles/io/org.openhab.io.rest.lib/lib/jersey-json-1.18.1.jar similarity index 77% rename from bundles/io/org.openhab.io.rest.lib/lib/jersey-json-1.17.1.jar rename to bundles/io/org.openhab.io.rest.lib/lib/jersey-json-1.18.1.jar index ae88856adca..64bf8c7e83e 100644 Binary files a/bundles/io/org.openhab.io.rest.lib/lib/jersey-json-1.17.1.jar and b/bundles/io/org.openhab.io.rest.lib/lib/jersey-json-1.18.1.jar differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/jersey-server-1.17.1.jar b/bundles/io/org.openhab.io.rest.lib/lib/jersey-server-1.18.1.jar similarity index 50% rename from bundles/io/org.openhab.io.rest.lib/lib/jersey-server-1.17.1.jar rename to bundles/io/org.openhab.io.rest.lib/lib/jersey-server-1.18.1.jar index ed6014488cf..b2c0440f6a3 100644 Binary files a/bundles/io/org.openhab.io.rest.lib/lib/jersey-server-1.17.1.jar and b/bundles/io/org.openhab.io.rest.lib/lib/jersey-server-1.18.1.jar differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/jersey-servlet-1.17.1.jar b/bundles/io/org.openhab.io.rest.lib/lib/jersey-servlet-1.17.1.jar deleted file mode 100644 index 676667497cc..00000000000 Binary files a/bundles/io/org.openhab.io.rest.lib/lib/jersey-servlet-1.17.1.jar and /dev/null differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/jersey-servlet-1.18.1.jar b/bundles/io/org.openhab.io.rest.lib/lib/jersey-servlet-1.18.1.jar new file mode 100644 index 00000000000..24f06f24474 Binary files /dev/null and b/bundles/io/org.openhab.io.rest.lib/lib/jersey-servlet-1.18.1.jar differ diff --git a/bundles/io/org.openhab.io.rest.lib/lib/slf4j-api-1.6.1.jar b/bundles/io/org.openhab.io.rest.lib/lib/slf4j-api-1.6.1.jar new file mode 100644 index 00000000000..f1f4fdd2149 Binary files /dev/null and b/bundles/io/org.openhab.io.rest.lib/lib/slf4j-api-1.6.1.jar differ diff --git a/bundles/io/org.openhab.io.rest/.classpath b/bundles/io/org.openhab.io.rest/.classpath index 25fba9f6b07..926a0e80153 100644 --- a/bundles/io/org.openhab.io.rest/.classpath +++ b/bundles/io/org.openhab.io.rest/.classpath @@ -3,8 +3,8 @@ - - - + + + diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/RESTApplication.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/RESTApplication.java index 7afab2780a6..4e6972f7bfb 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/RESTApplication.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/RESTApplication.java @@ -18,6 +18,7 @@ import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; +import org.apache.commons.lang.StringUtils; import org.atmosphere.cpr.AtmosphereServlet; import org.openhab.core.events.EventPublisher; import org.openhab.core.items.ItemRegistry; @@ -140,7 +141,7 @@ public void activate() { httpService.registerServlet(REST_SERVLET_ALIAS, atmosphereServlet, getJerseyServletParams(), createHttpContext()); - logger.info("Started REST API at /rest"); + logger.info("Started REST API at {}", REST_SERVLET_ALIAS); if (discoveryService != null) { discoveryService.registerService(getDefaultServiceDescription()); @@ -195,13 +196,24 @@ private Dictionary getJerseyServletParams() { jerseyServletParams.put("org.atmosphere.cpr.AtmosphereInterceptor.disableDefaults", "true"); // use the default interceptors without PaddingAtmosphereInterceptor // see: https://groups.google.com/forum/#!topic/openhab/Z-DVBXdNiYE - jerseyServletParams.put("org.atmosphere.cpr.AtmosphereInterceptor", "org.atmosphere.interceptor.DefaultHeadersInterceptor,org.atmosphere.interceptor.AndroidAtmosphereInterceptor,org.atmosphere.interceptor.SSEAtmosphereInterceptor,org.atmosphere.interceptor.JSONPAtmosphereInterceptor,org.atmosphere.interceptor.JavaScriptProtocol,org.atmosphere.interceptor.OnDisconnectInterceptor"); + final String[] interceptors = { + "org.atmosphere.interceptor.CacheHeadersInterceptor", + "org.atmosphere.interceptor.AndroidAtmosphereInterceptor", + "org.atmosphere.interceptor.SSEAtmosphereInterceptor", + "org.atmosphere.interceptor.JSONPAtmosphereInterceptor", + "org.atmosphere.interceptor.JavaScriptProtocol", + "org.atmosphere.interceptor.OnDisconnectInterceptor" + }; + jerseyServletParams.put("org.atmosphere.cpr.AtmosphereInterceptor", StringUtils.join(interceptors, ",")); // The BroadcasterCache is set in ResourceStateChangeListener.registerItems(), because otherwise // it gets somehow overridden by other registered servlets (e.g. the CV-bundle) //jerseyServletParams.put("org.atmosphere.cpr.broadcasterCacheClass", "org.atmosphere.cache.UUIDBroadcasterCache"); jerseyServletParams.put("org.atmosphere.cpr.broadcasterLifeCyclePolicy", "IDLE_DESTROY"); jerseyServletParams.put("org.atmosphere.cpr.CometSupport.maxInactiveActivity", "3000000"); + jerseyServletParams.put("org.atmosphere.cpr.broadcaster.maxProcessingThreads", "10"); // Default: unlimited! + jerseyServletParams.put("org.atmosphere.cpr.broadcaster.maxAsyncWriteThreads", "10"); // Default: 200 on atmos 2.2 + jerseyServletParams.put("com.sun.jersey.spi.container.ResourceFilter", "org.atmosphere.core.AtmosphereFilter"); // required because of bug http://java.net/jira/browse/JERSEY-361 diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/broadcaster/GeneralBroadcaster.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/broadcaster/GeneralBroadcaster.java index 610299ae9e9..23ac9e81237 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/broadcaster/GeneralBroadcaster.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/broadcaster/GeneralBroadcaster.java @@ -8,10 +8,13 @@ */ package org.openhab.io.rest.internal.broadcaster; +import java.net.URI; import java.util.Collection; import java.util.Collections; import java.util.WeakHashMap; +import org.atmosphere.cpr.AtmosphereConfig; +import org.atmosphere.cpr.Broadcaster; import org.atmosphere.cpr.BroadcasterLifeCyclePolicyListener; import org.atmosphere.jersey.JerseyBroadcaster; import org.openhab.io.rest.internal.listeners.ResourceStateChangeListener; @@ -27,8 +30,10 @@ public class GeneralBroadcaster extends JerseyBroadcaster { private static final Logger logger = LoggerFactory.getLogger(GeneralBroadcaster.class); protected Collection listeners = Collections.newSetFromMap(new WeakHashMap()); - public GeneralBroadcaster(String id, org.atmosphere.cpr.AtmosphereConfig config) { - super(id, config); + @Override + public Broadcaster initialize(String name, URI uri, AtmosphereConfig config) { + super.initialize(name, uri, config); + this.addBroadcasterLifeCyclePolicyListener(new BroadcasterLifeCyclePolicyListener() { @Override @@ -39,23 +44,21 @@ public void onIdle() { @Override public void onEmpty() { logger.debug("broadcaster '{}' is empty", this.toString()); - /* for (ResourceStateChangeListener l : listeners){ - l.unregisterItems(); - listeners.remove(l); - - } */ - } @Override public void onDestroy() { logger.debug("broadcaster '{}' destroyed", this.toString()); - for (ResourceStateChangeListener l : listeners){ - l.unregisterItems(); - listeners.remove(l); + logger.trace("broadcaster '{}' left {} {} instaces", this.toString(), listeners.size(), ResourceStateChangeListener.class.getName()); + for (ResourceStateChangeListener listener : listeners){ + listener.unregisterItems(); + boolean removed = listeners.remove(listener); + if (!removed) logger.warn("Could not remove event listener '{}', this may cause a memory leak.", listener.toString()); } } }); + + return this; } public void addStateChangeListener(final ResourceStateChangeListener listener){ diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/cache/SingleMessageBroadcastCache.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/cache/SingleMessageBroadcastCache.java new file mode 100644 index 00000000000..e1e5c562b29 --- /dev/null +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/cache/SingleMessageBroadcastCache.java @@ -0,0 +1,33 @@ +package org.openhab.io.rest.internal.cache; + +import org.atmosphere.cache.BroadcastMessage; +import org.atmosphere.cache.CacheMessage; +import org.atmosphere.cache.UUIDBroadcasterCache; +import org.openhab.io.rest.internal.resources.beans.PageBean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * UUIDBroadcasterCache that will enforce that only a single sitemap will exist + * in the cache for any given resource. This prevents leaks and other bad things + * from happening. + * @author Dan Cunningham + * @since 1.7.0 + */ +public class SingleMessageBroadcastCache extends UUIDBroadcasterCache { + + private final static Logger logger = LoggerFactory.getLogger(SingleMessageBroadcastCache.class); + + @Override + public CacheMessage addToCache(String broadcasterId, String uuid, BroadcastMessage message) { + if(uuid != null && message.message() instanceof PageBean){ + //remove previous message + retrieveFromCache(broadcasterId, uuid); + //add the new message + return super.addToCache(broadcasterId, uuid, message); + } else { + logger.trace("Not caching {}", message.message().getClass().getName()); + return null; + } + } +} \ No newline at end of file diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/DuplicateBroadcastProtectionFilter.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/DuplicateBroadcastProtectionFilter.java index 99550d906c4..d9812cea42b 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/DuplicateBroadcastProtectionFilter.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/DuplicateBroadcastProtectionFilter.java @@ -8,11 +8,16 @@ */ package org.openhab.io.rest.internal.filter; +import java.io.IOException; + import javax.servlet.http.HttpServletRequest; import org.atmosphere.cpr.AtmosphereResource; +import org.atmosphere.cpr.HeaderConfig; import org.atmosphere.cpr.BroadcastFilter.BroadcastAction.ACTION; import org.atmosphere.cpr.PerRequestBroadcastFilter; +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.openhab.io.rest.internal.listeners.ResourceStateChangeListener; import org.openhab.io.rest.internal.listeners.ResourceStateChangeListener.CacheEntry; @@ -33,12 +38,12 @@ public class DuplicateBroadcastProtectionFilter implements PerRequestBroadcastFi private static final Logger logger = LoggerFactory.getLogger(DuplicateBroadcastProtectionFilter.class); @Override - public BroadcastAction filter(Object arg0, Object message) { - return new BroadcastAction(ACTION.CONTINUE, message); + public BroadcastAction filter(String broadcasterId, Object originalMessage, Object message) { + return new BroadcastAction(message); } @Override - public BroadcastAction filter(AtmosphereResource resource, Object originalMessage, Object message) { + public BroadcastAction filter(String broadcasterId, AtmosphereResource resource, Object originalMessage, Object message) { final HttpServletRequest request = resource.getRequest(); try { @@ -50,36 +55,37 @@ public BroadcastAction filter(AtmosphereResource resource, Object originalMessag } } catch (Exception e) { - logger.error(e.getMessage()); + logger.error(e.getMessage(), e); return new BroadcastAction(ACTION.ABORT, message); } } - private boolean isDoubleBroadcast(HttpServletRequest request, Object responseEntity){ - String clientId = request.getHeader("X-Atmosphere-tracking-id"); - + private boolean isDoubleBroadcast(HttpServletRequest request, + Object responseEntity) throws JsonGenerationException, + JsonMappingException, IOException { + + String clientId = request.getHeader(HeaderConfig.X_ATMOSPHERE_TRACKING_ID); + // return false if the X-Atmosphere-tracking-id is not set - if(clientId == null || clientId.isEmpty()){ + if (clientId == null || clientId.isEmpty()) { return false; } - try{ - CacheEntry entry = ResourceStateChangeListener.getCachedEntries().put(clientId, new CacheEntry(responseEntity)); - //there was an existing cached entry, see if its the same - if(entry != null){ - ObjectMapper mapper = new ObjectMapper(); - //cached data - String firedResponse = mapper.writeValueAsString(entry.getData()); - //new data - String responseValue = mapper.writeValueAsString(responseEntity); - //the same ? - if(responseValue.equals(firedResponse)) { - return true; - } - } - } catch (Exception e) { - logger.error("Could not check if double broadcast",e); - } - return false; + + CacheEntry entry = ResourceStateChangeListener.getCachedEntries().put( + clientId, new CacheEntry(responseEntity)); + // there was an existing cached entry, see if its the same + if (entry != null) { + ObjectMapper mapper = new ObjectMapper(); + // cached data + final String firedResponse = mapper.writeValueAsString(entry.getData()); + // new data + final String responseValue = mapper.writeValueAsString(responseEntity); + // the same ? + return responseValue.equals(firedResponse); + } + + return false; } + } diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/MessageTypeFilter.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/MessageTypeFilter.java index a9277de5df0..e6e8511225b 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/MessageTypeFilter.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/MessageTypeFilter.java @@ -31,16 +31,16 @@ public class MessageTypeFilter implements PerRequestBroadcastFilter { private static final Logger logger = LoggerFactory.getLogger(MessageTypeFilter.class); @Override - public BroadcastAction filter(Object arg0, Object message) { - return new BroadcastAction(ACTION.CONTINUE, message); + public BroadcastAction filter(String broadcasterId, Object originalMessage, Object message) { + return new BroadcastAction(message); } @Override - public BroadcastAction filter(AtmosphereResource resource, Object originalMessage, Object message) { + public BroadcastAction filter(String broadcasterId, AtmosphereResource resource, Object originalMessage, Object message) { final HttpServletRequest request = resource.getRequest(); ResponseTypeHelper responseTypeHelper = new ResponseTypeHelper(); String responseType = responseTypeHelper.getResponseType(request); - try { + try { Object responseObject = responseType.equals(MediaTypeHelper.APPLICATION_X_JAVASCRIPT) ? new JSONWithPadding(message, responseTypeHelper.getQueryParam(request, "callback")) : message; return new BroadcastAction( diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/PollingDelayFilter.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/PollingDelayFilter.java index e079faf3ee8..8cc3b6bbb2a 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/PollingDelayFilter.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/PollingDelayFilter.java @@ -9,6 +9,8 @@ package org.openhab.io.rest.internal.filter; import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; @@ -34,48 +36,51 @@ public class PollingDelayFilter implements PerRequestBroadcastFilter { private static final Logger logger = LoggerFactory.getLogger(PollingDelayFilter.class); + ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + @Override - public BroadcastAction filter(Object arg0, Object message) { - return new BroadcastAction(ACTION.CONTINUE, message); + public BroadcastAction filter(String broadcasterId, Object originalMessage, Object message) { + return new BroadcastAction(message); } @Override - public BroadcastAction filter(final AtmosphereResource resource, Object originalMessage, final Object message) { + public BroadcastAction filter(String broadcasterId, final AtmosphereResource resource, Object originalMessage, final Object message) { final HttpServletRequest request = resource.getRequest(); try { // delay first broadcast for long-polling and other polling transports boolean isItemMessage = originalMessage instanceof Item || originalMessage instanceof GroupItem; - boolean isStreamingTransport = false; + boolean isStreamingTransport = ResponseTypeHelper.isStreamingTransport(request); + + //strange atmosphere bug, seems harmless, but pollutes the logs + //so lets see if this fails or not first before we call it again. try { - isStreamingTransport = ResponseTypeHelper.isStreamingTransport(request); + resource.getRequest().getPathInfo(); } catch (Exception e) { - logger.error(e.getMessage()); - return new BroadcastAction(ACTION.ABORT, message); + return new BroadcastAction(ACTION.ABORT, message); } if(!isStreamingTransport && message instanceof PageBean && isItemMessage) { final String delayedBroadcasterName = resource.getRequest().getPathInfo(); - Executors.newSingleThreadExecutor().submit(new Runnable() { + executor.schedule(new Runnable() { public void run() { try { - Thread.sleep(300); - GeneralBroadcaster delayedBroadcaster = (GeneralBroadcaster) BroadcasterFactory.getDefault().lookup(GeneralBroadcaster.class, delayedBroadcasterName); + BroadcasterFactory broadcasterFactory = resource.getAtmosphereConfig().getBroadcasterFactory(); + GeneralBroadcaster delayedBroadcaster = broadcasterFactory.lookup(GeneralBroadcaster.class, delayedBroadcasterName); if(delayedBroadcaster != null) delayedBroadcaster.broadcast(message, resource); } catch (Exception e) { - logger.error("Could not broadcast message",e); + logger.error("Could not broadcast message", e); } } - }); + }, 300, TimeUnit.MILLISECONDS); } else { //pass message to next filter - return new BroadcastAction(ACTION.CONTINUE, message); + return new BroadcastAction(ACTION.CONTINUE, message); } } catch (Exception e) { - logger.error(e.getMessage()); - return new BroadcastAction(ACTION.ABORT, message); + logger.error(e.getMessage(), e); } - return new BroadcastAction(ACTION.ABORT, message); + return new BroadcastAction(ACTION.ABORT, message); } -} +} \ No newline at end of file diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/ResponseObjectFilter.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/ResponseObjectFilter.java index 6be37a49643..4ba7321d9ec 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/ResponseObjectFilter.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/ResponseObjectFilter.java @@ -38,62 +38,60 @@ public class ResponseObjectFilter implements PerRequestBroadcastFilter { private static final Logger logger = LoggerFactory.getLogger(ResponseObjectFilter.class); @Override - public BroadcastAction filter(Object arg0, Object message) { - return new BroadcastAction(ACTION.CONTINUE, message); + public BroadcastAction filter(String broadcasterId, Object originalMessage, Object message) { + return new BroadcastAction(message); } @Override - public BroadcastAction filter(AtmosphereResource resource, Object originalMessage, Object message) { + public BroadcastAction filter(String broadcasterId, AtmosphereResource resource, Object originalMessage, Object message) { final HttpServletRequest request = resource.getRequest(); - try { - // websocket and HTTP streaming - if(ResponseTypeHelper.isStreamingTransport(request) && message instanceof PageBean && originalMessage instanceof Item) { - return new BroadcastAction(ACTION.CONTINUE, getSingleResponseObject((PageBean)message, (Item)originalMessage, request) ); - } + // websocket and HTTP streaming + if(ResponseTypeHelper.isStreamingTransport(request) && message instanceof PageBean && originalMessage instanceof Item) { + return new BroadcastAction(ACTION.CONTINUE, getSingleResponseObject((PageBean)message, (Item)originalMessage, request) ); + } - } catch (Exception e) { - logger.error(e.getMessage()); - return new BroadcastAction(ACTION.ABORT, message); - } // pass message to next filter return new BroadcastAction(ACTION.CONTINUE, message); } private Object getSingleResponseObject(PageBean pageBean, Item item, HttpServletRequest request) { - WidgetListBean responseBeam ; if(pageBean!=null) { - responseBeam = new WidgetListBean( getItemsOnPage(pageBean.widgets, item)); - return responseBeam; - + return new WidgetListBean( getItemsOnPage(pageBean.widgets, item)); } return null; } - private List getItemsOnPage(List widgets, Item searchItem){ - List foundWidgets = new ArrayList (); - try{ - for(WidgetBean widget : widgets) { - if(widget.item !=null && widget.item.name.equals(searchItem.getName())){ - foundWidgets.add(widget); - } - else{ - if (!widget.widgets.isEmpty()){ - List tmpWidgets = getItemsOnPage(widget.widgets, searchItem); - if(!tmpWidgets.isEmpty()) { - foundWidgets.addAll(tmpWidgets); } - + private List getItemsOnPage(List widgets, + Item searchItem) { + List foundWidgets = new ArrayList(); + try { + for (WidgetBean widget : widgets) { + if (widget.item != null + && widget.item.name.equals(searchItem.getName())) { + foundWidgets.add(widget); + } else { + if (!widget.widgets.isEmpty()) { + List tmpWidgets = getItemsOnPage( + widget.widgets, searchItem); + if (!tmpWidgets.isEmpty()) { + foundWidgets.addAll(tmpWidgets); + } + + } + } + + if (widget.linkedPage != null + && widget.linkedPage.widgets != null) { + List tmpWidgets = getItemsOnPage( + widget.linkedPage.widgets, searchItem); + if (!tmpWidgets.isEmpty()) { + foundWidgets.addAll(tmpWidgets); + } } } - - if (widget.linkedPage != null && widget.linkedPage.widgets != null) { - List tmpWidgets = getItemsOnPage(widget.linkedPage.widgets, searchItem); - if(!tmpWidgets.isEmpty()) { - foundWidgets.addAll(tmpWidgets); } - } - } - }catch (Exception e){ - logger.error(e.getMessage()); + } catch (Exception e) { + logger.error(e.getMessage(), e); } return foundWidgets; } diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/SendPageUpdateFilter.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/SendPageUpdateFilter.java index e5335e25404..9ae21e44ff4 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/SendPageUpdateFilter.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/filter/SendPageUpdateFilter.java @@ -15,6 +15,7 @@ import org.atmosphere.cpr.AtmosphereResource; import org.atmosphere.cpr.BroadcastFilter.BroadcastAction.ACTION; import org.atmosphere.cpr.BroadcasterFactory; +import org.atmosphere.cpr.HeaderConfig; import org.atmosphere.cpr.PerRequestBroadcastFilter; import org.openhab.core.items.Item; import org.openhab.io.rest.internal.broadcaster.GeneralBroadcaster; @@ -39,12 +40,12 @@ public class SendPageUpdateFilter implements PerRequestBroadcastFilter { private static final Logger logger = LoggerFactory.getLogger(SendPageUpdateFilter.class); @Override - public BroadcastAction filter(Object arg0, Object message) { - return new BroadcastAction(ACTION.CONTINUE, message); + public BroadcastAction filter(String broadcasterId, Object originalMessage, Object message) { + return new BroadcastAction(message); } @Override - public BroadcastAction filter(final AtmosphereResource resource, Object originalMessage, final Object message) { + public BroadcastAction filter(String broadcasterId, final AtmosphereResource resource, Object originalMessage, final Object message) { final HttpServletRequest request = resource.getRequest(); try { // broadcast page updates to streaming transports @@ -57,13 +58,13 @@ public BroadcastAction filter(final AtmosphereResource resource, Object original public void run() { try { Thread.sleep(300); - - GeneralBroadcaster delayedBroadcaster = (GeneralBroadcaster) BroadcasterFactory.getDefault().lookup(GeneralBroadcaster.class, delayedBroadcasterName); - delayedBroadcaster.broadcast(message, resource); - + + BroadcasterFactory broadcasterFactory = resource.getAtmosphereConfig().getBroadcasterFactory(); + GeneralBroadcaster delayedBroadcaster = broadcasterFactory.lookup(GeneralBroadcaster.class, delayedBroadcasterName); + delayedBroadcaster.broadcast(message, resource); } catch (Exception e) { - logger.error("Could not broadcast messages",e); + logger.error("Could not broadcast messages", e); } } }); @@ -71,42 +72,50 @@ public void run() { } // remove the widgets if (originalMessage instanceof PageBean){ - PageBean originalBean = (PageBean) message ; - PageBean responseBeam = new PageBean(); - responseBeam.icon = originalBean.icon; - responseBeam.id = originalBean.id; - responseBeam.link = originalBean.link; - responseBeam.parent = originalBean.parent; - responseBeam.title = originalBean.title; - return new BroadcastAction(ACTION.CONTINUE, responseBeam); + final PageBean responseBean = clonePageBeanWithoutWidgets((PageBean) message); + return new BroadcastAction(ACTION.CONTINUE, responseBean); } } //pass message to next filter - return new BroadcastAction(ACTION.CONTINUE, message); + return new BroadcastAction(ACTION.CONTINUE, message); } catch (Exception e) { - // TODO Auto-generated catch block - logger.error(e.getMessage()); - return new BroadcastAction(ACTION.ABORT, message); + logger.error(e.getMessage(), e); + return new BroadcastAction(ACTION.ABORT, message); } } + + private PageBean clonePageBeanWithoutWidgets(PageBean originalBean) { + final PageBean responseBean = new PageBean(); + responseBean.icon = originalBean.icon; + responseBean.id = originalBean.id; + responseBean.link = originalBean.link; + responseBean.parent = originalBean.parent; + responseBean.title = originalBean.title; + // TODO What to do with (the new) leaf attribute? + return responseBean; + } - private boolean isPageUpdated(HttpServletRequest request, Object responseEntity){ - String clientId = request.getHeader("X-Atmosphere-tracking-id"); + private boolean isPageUpdated(HttpServletRequest request, Object responseEntity) { + // TODO: Atmosphere docs say, the param can be a request param, too! + final String clientId = request.getHeader(HeaderConfig.X_ATMOSPHERE_TRACKING_ID); // return false if the X-Atmosphere-tracking-id is not set if(clientId == null || clientId.isEmpty()){ return false; } - CacheEntry entry = ResourceStateChangeListener.getCachedEntries().get(clientId); + final CacheEntry entry = ResourceStateChangeListener.getCachedEntries().get(clientId); if(entry != null && entry.getData() instanceof PageBean){ - Object firedEntity = entry.getData(); - if( firedEntity == null || ((PageBean)firedEntity).icon != ((PageBean)responseEntity).icon || ((PageBean)firedEntity).title != ((PageBean)responseEntity).title ) { + final PageBean firedEntity = (PageBean)entry.getData(); + final PageBean responsePageBean = (PageBean)responseEntity; + if( firedEntity == null || + firedEntity.icon != responsePageBean.icon || + firedEntity.title != responsePageBean.title ) { return true; } } diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/listeners/ResourceStateChangeListener.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/listeners/ResourceStateChangeListener.java index 1c3a7b600a8..122d74faf9b 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/listeners/ResourceStateChangeListener.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/listeners/ResourceStateChangeListener.java @@ -21,7 +21,9 @@ import org.atmosphere.cache.UUIDBroadcasterCache; import org.atmosphere.cpr.AtmosphereResource; +import org.atmosphere.cpr.BroadcastFilter; import org.atmosphere.cpr.BroadcastFilter.BroadcastAction.ACTION; +import org.atmosphere.cpr.BroadcasterConfig; import org.atmosphere.cpr.PerRequestBroadcastFilter; import org.openhab.core.items.GenericItem; import org.openhab.core.items.Item; @@ -33,6 +35,8 @@ import org.openhab.io.rest.internal.filter.ResponseObjectFilter; import org.openhab.io.rest.internal.filter.SendPageUpdateFilter; import org.openhab.io.rest.internal.resources.ItemResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This is an abstract super class which adds Broadcaster config, lifecycle and filters to its derived classes and registers listeners to subscribed resources. @@ -41,6 +45,8 @@ * @since 0.9.0 */ abstract public class ResourceStateChangeListener { + + private static final Logger logger = LoggerFactory.getLogger(ResourceStateChangeListener.class); final static long CACHE_TIME = 300 * 1000; // 5 mins @@ -73,43 +79,58 @@ public static ConcurrentMap getCachedEntries() { return cachedEntries; } + /** + * Configure what cache we want to use + * @param config + */ + public void configureCache(BroadcasterConfig config){ + config.setBroadcasterCache(new UUIDBroadcasterCache()); + config.getBroadcasterCache().configure(broadcaster.getBroadcasterConfig()); + config.getBroadcasterCache().start(); + } + public void registerItems(){ StartCacheExecutor(); - broadcaster.getBroadcasterConfig().setBroadcasterCache(new UUIDBroadcasterCache()); - broadcaster.getBroadcasterConfig().getBroadcasterCache().configure(broadcaster.getBroadcasterConfig()); - broadcaster.getBroadcasterConfig().getBroadcasterCache().start(); + BroadcasterConfig config = broadcaster.getBroadcasterConfig(); - broadcaster.getBroadcasterConfig().addFilter(new PerRequestBroadcastFilter() { - + configureCache(config); + + addBroadcastFilter(config, new PerRequestBroadcastFilter() { + @Override - public BroadcastAction filter(Object originalMessage, Object message) { - return new BroadcastAction(ACTION.CONTINUE, message); + public BroadcastAction filter(String broadcasterId, + Object originalMessage, Object message) { + return new BroadcastAction(message); } @Override - public BroadcastAction filter(AtmosphereResource resource, Object originalMessage, Object message) { + public BroadcastAction filter(String broadcasterId, + AtmosphereResource resource, Object originalMessage, + Object message) { HttpServletRequest request = null; BroadcastAction result = null; try { - request = resource.getRequest(); - Object responce = getResponseObject(request); - result = new BroadcastAction(ACTION.CONTINUE, responce); + request = resource.getRequest(); + Object response = getResponseObject(request); + result = new BroadcastAction(ACTION.CONTINUE, response); } catch (Exception e) { - result = new BroadcastAction(ACTION.ABORT, getResponseObject(request)); + result = new BroadcastAction(ACTION.ABORT, + getResponseObject(request)); } - return result; + return result; } + }); - broadcaster.getBroadcasterConfig().addFilter(new PollingDelayFilter()); - broadcaster.getBroadcasterConfig().addFilter(new SendPageUpdateFilter()); - broadcaster.getBroadcasterConfig().addFilter(new DuplicateBroadcastProtectionFilter()); - broadcaster.getBroadcasterConfig().addFilter(new ResponseObjectFilter()); - + addBroadcastFilter(config, new PollingDelayFilter()); + addBroadcastFilter(config, new SendPageUpdateFilter()); + addBroadcastFilter(config, new DuplicateBroadcastProtectionFilter()); + addBroadcastFilter(config, new ResponseObjectFilter()); + stateChangeListener = new StateChangeListener() { // don't react on update events public void stateUpdated(Item item, State state) { - broadcaster.broadcast(item); +// broadcaster.broadcast(item); // if the group has a base item and thus might calculate its state // as a DecimalType or other, we also consider it to be necessary to // send an update to the client as the label of the item might have changed, @@ -144,6 +165,14 @@ public void stateChanged(final Item item, State oldState, State newState) { registerStateChangeListenerOnRelevantItems(broadcaster.getID(), stateChangeListener); } + + + private void addBroadcastFilter(BroadcasterConfig config, + BroadcastFilter filter) { + if (!config.addFilter(filter) && logger.isDebugEnabled()) { + logger.debug("Could not add filter '{}'", filter.getClass().getName()); + } + } public void unregisterItems(){ unregisterStateChangeListenerOnRelevantItems(); diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/listeners/SitemapStateChangeListener.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/listeners/SitemapStateChangeListener.java index 2cd3c532f60..805f3896ec3 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/listeners/SitemapStateChangeListener.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/listeners/SitemapStateChangeListener.java @@ -17,13 +17,10 @@ import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.UriBuilder; -import org.atmosphere.cache.UUIDBroadcasterCache; -import org.atmosphere.cpr.AtmosphereResource; -import org.atmosphere.cpr.PerRequestBroadcastFilter; -import org.atmosphere.cpr.BroadcastFilter.BroadcastAction; -import org.atmosphere.cpr.BroadcastFilter.BroadcastAction.ACTION; +import org.atmosphere.cpr.BroadcasterConfig; import org.openhab.core.items.Item; import org.openhab.io.rest.RESTApplication; +import org.openhab.io.rest.internal.cache.SingleMessageBroadcastCache; import org.openhab.io.rest.internal.resources.ResponseTypeHelper; import org.openhab.io.rest.internal.resources.SitemapResource; import org.openhab.io.rest.internal.resources.beans.PageBean; @@ -51,27 +48,10 @@ public class SitemapStateChangeListener extends ResourceStateChangeListener { private static final Logger logger = LoggerFactory.getLogger(SitemapStateChangeListener.class); @Override - public void registerItems() { - super.registerItems(); - //if other filters have let this through then clear out any cached messages for the client. - //There should at most be only one message (version of the sitemap) in the cache for a client. - broadcaster.getBroadcasterConfig().addFilter(new PerRequestBroadcastFilter() { - - @Override - public BroadcastAction filter(Object originalMessage, Object message) { - return new BroadcastAction(ACTION.CONTINUE, message); - } - - @Override - public BroadcastAction filter(AtmosphereResource resource, Object originalMessage, Object message) { - //this will clear any cached messages before we add the new one - UUIDBroadcasterCache uuidCache = (UUIDBroadcasterCache)broadcaster.getBroadcasterConfig().getBroadcasterCache(); - List entries = uuidCache.retrieveFromCache(null,resource); - if(entries != null) - logger.trace("UUID {} had {} previous messages", resource.uuid(), entries.size()); - return new BroadcastAction(ACTION.CONTINUE, message); - } - }); + public void configureCache(BroadcasterConfig config){ + config.setBroadcasterCache(new SingleMessageBroadcastCache()); + config.getBroadcasterCache().configure(broadcaster.getBroadcasterConfig()); + config.getBroadcasterCache().start(); } @Override @@ -150,24 +130,23 @@ private Set getRelevantItemNamesForWidgets(List children) { private PageBean getPageBean(HttpServletRequest request){ try { - String query = request.getQueryString(); - String pathInfo = request.getPathInfo(); - - String responseType = (new ResponseTypeHelper()).getResponseType(request); - if(responseType!=null) { - URI basePath = UriBuilder.fromUri(request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+(request.getContextPath().equals("null")?"":request.getContextPath()) + RESTApplication.REST_SERVLET_ALIAS +"/").build(); - if (pathInfo.startsWith("/" + SitemapResource.PATH_SITEMAPS)) { - String[] pathSegments = pathInfo.substring(1).split("/"); - if(pathSegments.length>=3) { - String sitemapName = pathSegments[1]; - String pageId = pathSegments[2]; - Sitemap sitemap = (Sitemap) RESTApplication.getModelRepository().getModel(sitemapName + ".sitemap"); - if(sitemap!=null) { - return SitemapResource.getPageBean(sitemapName, pageId, basePath); - } - } - } - } + String pathInfo = request.getPathInfo(); + + String responseType = (new ResponseTypeHelper()).getResponseType(request); + if(responseType!=null) { + URI basePath = UriBuilder.fromUri(request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+(request.getContextPath().equals("null")?"":request.getContextPath()) + RESTApplication.REST_SERVLET_ALIAS +"/").build(); + if (pathInfo.startsWith("/" + SitemapResource.PATH_SITEMAPS)) { + String[] pathSegments = pathInfo.substring(1).split("/"); + if(pathSegments.length>=3) { + String sitemapName = pathSegments[1]; + String pageId = pathSegments[2]; + Sitemap sitemap = (Sitemap) RESTApplication.getModelRepository().getModel(sitemapName + ".sitemap"); + if(sitemap!=null) { + return SitemapResource.getPageBean(sitemapName, pageId, basePath); + } + } + } + } } catch (Exception e) { return null; } diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/ItemResource.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/ItemResource.java index 1fb5561acd9..94a6b4eda25 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/ItemResource.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/ItemResource.java @@ -16,7 +16,6 @@ import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; @@ -35,7 +34,7 @@ import org.atmosphere.annotation.Suspend.SCOPE; import org.atmosphere.cpr.AtmosphereResource; import org.atmosphere.cpr.BroadcasterFactory; -import org.atmosphere.cpr.HeaderConfig; +import org.atmosphere.cpr.AtmosphereResource.TRANSPORT; import org.atmosphere.jersey.SuspendResponse; import org.openhab.core.items.GroupItem; import org.openhab.core.items.Item; @@ -57,8 +56,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.sun.jersey.api.json.JSONWithPadding; - /** *

      This class acts as a REST resource for items and provides different methods to interact with them, * like retrieving lists of items, sending commands to them or checking a single status.

      @@ -86,12 +83,11 @@ public Response getItems( @Context HttpHeaders headers, @QueryParam("type") String type, @QueryParam("jsoncallback") @DefaultValue("callback") String callback) { - logger.debug("Received HTTP GET request at '{}' for media type '{}'.", new String[] { uriInfo.getPath(), type }); - - String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type); + if (logger.isDebugEnabled()) logger.debug("Received HTTP GET request at '{}' for media type '{}'.", uriInfo.getPath(), type); + final String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type); if(responseType!=null) { - Object responseObject = responseType.equals(MediaTypeHelper.APPLICATION_X_JAVASCRIPT) ? - new JSONWithPadding(new ItemListBean(getItemBeans()), callback) : new ItemListBean(getItemBeans()); + final ItemListBean content = new ItemListBean(getItemBeans()); + final Object responseObject = ResponseHelper.wrapContentIfNeccessary(callback, responseType, content); return Response.ok(responseObject, responseType).build(); } else { return Response.notAcceptable(null).build(); @@ -102,19 +98,20 @@ public Response getItems( @Produces( { MediaType.TEXT_PLAIN }) public SuspendResponse getPlainItemState( @PathParam("itemname") String itemname, - @HeaderParam(HeaderConfig.X_ATMOSPHERE_TRANSPORT) String atmosphereTransport, @Context AtmosphereResource resource) { - if(atmosphereTransport==null || atmosphereTransport.isEmpty()) { + if(TRANSPORT.UNDEFINED.equals(resource.transport())) { Item item = getItem(itemname); if(item!=null) { - logger.debug("Received HTTP GET request at '{}'.", uriInfo.getPath()); + if (logger.isDebugEnabled()) logger.debug("Received HTTP GET request at '{}'.", uriInfo.getPath()); throw new WebApplicationException(Response.ok(item.getState().toString()).build()); } else { - logger.info("Received HTTP GET request at '{}' for the unknown item '{}'.", uriInfo.getPath(), itemname); + if (logger.isDebugEnabled()) logger.info("Received HTTP GET request at '{}' for the unknown item '{}'.", uriInfo.getPath(), itemname); throw new WebApplicationException(404); } } - GeneralBroadcaster itemBroadcaster = (GeneralBroadcaster) BroadcasterFactory.getDefault().lookup(GeneralBroadcaster.class, resource.getRequest().getPathInfo(), true); + + BroadcasterFactory broadcasterFactory = resource.getAtmosphereConfig().getBroadcasterFactory(); + GeneralBroadcaster itemBroadcaster = (GeneralBroadcaster) broadcasterFactory.lookup(GeneralBroadcaster.class, resource.getRequest().getPathInfo(), true); itemBroadcaster.addStateChangeListener(new ItemStateChangeListener()); return new SuspendResponse.SuspendResponseBuilder() .scope(SCOPE.REQUEST) @@ -130,22 +127,21 @@ public SuspendResponse getItemData( @PathParam("itemname") String itemname, @QueryParam("type") String type, @QueryParam("jsoncallback") @DefaultValue("callback") String callback, - @HeaderParam(HeaderConfig.X_ATMOSPHERE_TRANSPORT) String atmosphereTransport, @Context AtmosphereResource resource) { - logger.debug("Received HTTP GET request at '{}' for media type '{}'.", new String[] { uriInfo.getPath(), type }); - if(atmosphereTransport==null || atmosphereTransport.isEmpty()) { + if (logger.isDebugEnabled()) logger.debug("Received HTTP GET request at '{}' for media type '{}'.", uriInfo.getPath(), type); + if(TRANSPORT.UNDEFINED.equals(resource.transport())) { final String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type); if(responseType!=null) { - final Object responseObject = responseType.equals(MediaTypeHelper.APPLICATION_X_JAVASCRIPT) ? - new JSONWithPadding(getItemDataBean(itemname), callback) : getItemDataBean(itemname); + final ItemBean content = getItemDataBean(itemname); + final Object responseObject = ResponseHelper.wrapContentIfNeccessary(callback, responseType, content); throw new WebApplicationException(Response.ok(responseObject, responseType).build()); - } else { throw new WebApplicationException(Response.notAcceptable(null).build()); } } - GeneralBroadcaster itemBroadcaster = (GeneralBroadcaster) BroadcasterFactory.getDefault().lookup(GeneralBroadcaster.class, resource.getRequest().getPathInfo(), true); + BroadcasterFactory broadcasterFactory = resource.getAtmosphereConfig().getBroadcasterFactory(); + GeneralBroadcaster itemBroadcaster = (GeneralBroadcaster) broadcasterFactory.lookup(GeneralBroadcaster.class, resource.getRequest().getPathInfo(), true); itemBroadcaster.addStateChangeListener(new ItemStateChangeListener()); return new SuspendResponse.SuspendResponseBuilder() @@ -158,15 +154,15 @@ public SuspendResponse getItemData( @PUT @Path("/{itemname: [a-zA-Z_0-9]*}/state") @Consumes(MediaType.TEXT_PLAIN) public Response putItemState(@PathParam("itemname") String itemname, String value) { - Item item = getItem(itemname); + final Item item = getItem(itemname); if(item!=null) { - State state = TypeParser.parseState(item.getAcceptedDataTypes(), value); + final State state = TypeParser.parseState(item.getAcceptedDataTypes(), value); if(state!=null) { - logger.debug("Received HTTP PUT request at '{}' with value '{}'.", uriInfo.getPath(), value); + if (logger.isDebugEnabled()) logger.debug("Received HTTP PUT request at '{}' with value '{}'.", uriInfo.getPath(), value); RESTApplication.getEventPublisher().postUpdate(itemname, state); return Response.ok().build(); } else { - logger.warn("Received HTTP PUT request at '{}' with an invalid status value '{}'.", uriInfo.getPath(), value); + if (logger.isDebugEnabled()) logger.warn("Received HTTP PUT request at '{}' with an invalid status value '{}'.", uriInfo.getPath(), value); return Response.status(Status.BAD_REQUEST).build(); } } else { @@ -179,7 +175,7 @@ public Response putItemState(@PathParam("itemname") String itemname, String valu @POST @Path("/{itemname: [a-zA-Z_0-9]*}") @Consumes(MediaType.TEXT_PLAIN) public Response postItemCommand(@PathParam("itemname") String itemname, String value) { - Item item = getItem(itemname); + final Item item = getItem(itemname); Command command = null; if(item!=null) { // support for TOGGLE, see https://code.google.com/p/openhab/issues/detail?id=336 @@ -252,7 +248,7 @@ private List getItemBeans() { } private ItemBean getItemDataBean(String itemname) { - Item item = getItem(itemname); + final Item item = getItem(itemname); if(item!=null) { return createItemBean(item, true, uriInfo.getBaseUri().toASCIIString()); } else { diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/ResponseHelper.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/ResponseHelper.java new file mode 100644 index 00000000000..1b2093d7b93 --- /dev/null +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/ResponseHelper.java @@ -0,0 +1,15 @@ +package org.openhab.io.rest.internal.resources; + +import com.sun.jersey.api.json.JSONWithPadding; + +public class ResponseHelper { + + public static Object wrapContentIfNeccessary(String callback, + final String responseType, final Object content) { + if (responseType.equals(MediaTypeHelper.APPLICATION_X_JAVASCRIPT)) { + return new JSONWithPadding(content, callback); + } + return content; + } + +} diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/ResponseTypeHelper.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/ResponseTypeHelper.java index 1483ec0048d..f5b25d6f3d6 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/ResponseTypeHelper.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/ResponseTypeHelper.java @@ -62,12 +62,14 @@ protected String getQueryParam(HttpServletRequest request, String paramName, Str * @return boolean */ public static boolean isStreamingTransport(HttpServletRequest request) { - String transport = request.getHeader(HeaderConfig.X_ATMOSPHERE_TRANSPORT); - String upgrade = request.getHeader(HeaderConfig.WEBSOCKET_UPGRADE); - if(HeaderConfig.WEBSOCKET_TRANSPORT.equalsIgnoreCase(transport) || HeaderConfig.STREAMING_TRANSPORT.equalsIgnoreCase(transport) || HeaderConfig.WEBSOCKET_TRANSPORT.equalsIgnoreCase(upgrade)) { - return true; + final String transport = request.getHeader(HeaderConfig.X_ATMOSPHERE_TRANSPORT); + final String upgrade = request.getHeader(HeaderConfig.WEBSOCKET_UPGRADE); + if (HeaderConfig.WEBSOCKET_TRANSPORT.equalsIgnoreCase(transport) + || HeaderConfig.STREAMING_TRANSPORT.equalsIgnoreCase(transport) + || HeaderConfig.WEBSOCKET_TRANSPORT.equalsIgnoreCase(upgrade)) { + return true; } else { - return false; + return false; } } diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/RootResource.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/RootResource.java index ffdb820aa8c..64517e80446 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/RootResource.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/RootResource.java @@ -21,8 +21,6 @@ import org.openhab.io.rest.internal.resources.beans.RootBean; -import com.sun.jersey.api.json.JSONWithPadding; - /** *

      This class acts as an entry point / root resource for the REST API.

      *

      In good HATEOAS manner, it provides links to other offered resources.

      @@ -45,10 +43,9 @@ public Response getRoot( @Context HttpHeaders headers, @QueryParam("type") String type, @QueryParam("jsoncallback") @DefaultValue("callback") String callback) { - String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type); + final String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type); if(responseType!=null) { - Object responseObject = responseType.equals(MediaTypeHelper.APPLICATION_X_JAVASCRIPT) ? - new JSONWithPadding(getRootBean(), callback) : getRootBean(); + final Object responseObject = ResponseHelper.wrapContentIfNeccessary(callback, responseType, getRootBean()); return Response.ok(responseObject, responseType).build(); } else { return Response.notAcceptable(null).build(); diff --git a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/SitemapResource.java b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/SitemapResource.java index eed0931d2e7..8cf98abb999 100644 --- a/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/SitemapResource.java +++ b/bundles/io/org.openhab.io.rest/src/main/java/org/openhab/io/rest/internal/resources/SitemapResource.java @@ -17,7 +17,6 @@ import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -34,9 +33,9 @@ import org.atmosphere.annotation.Suspend.SCOPE; import org.atmosphere.cpr.AtmosphereRequest; import org.atmosphere.cpr.AtmosphereResource; +import org.atmosphere.cpr.AtmosphereResource.TRANSPORT; import org.atmosphere.cpr.Broadcaster; import org.atmosphere.cpr.BroadcasterFactory; -import org.atmosphere.cpr.HeaderConfig; import org.atmosphere.jersey.SuspendResponse; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; @@ -68,7 +67,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.sun.jersey.api.json.JSONWithPadding; /** *

      This class acts as a REST resource for sitemaps and provides different methods to interact with them, @@ -104,11 +102,11 @@ public Response getSitemaps( @Context HttpHeaders headers, @QueryParam("type") String type, @QueryParam("jsoncallback") @DefaultValue("callback") String callback) { - logger.debug("Received HTTP GET request at '{}' for media type '{}'.", new String[] { uriInfo.getPath(), type }); - String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type); + if (logger.isDebugEnabled()) logger.debug("Received HTTP GET request at '{}' for media type '{}'.", uriInfo.getPath(), type); + final String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type); if(responseType!=null) { - Object responseObject = responseType.equals(MediaTypeHelper.APPLICATION_X_JAVASCRIPT) ? - new JSONWithPadding(new SitemapListBean(getSitemapBeans(uriInfo.getAbsolutePathBuilder().build())), callback) : new SitemapListBean(getSitemapBeans(uriInfo.getAbsolutePathBuilder().build())); + final SitemapListBean content = new SitemapListBean(getSitemapBeans(uriInfo.getAbsolutePathBuilder().build())); + final Object responseObject = ResponseHelper.wrapContentIfNeccessary(callback, responseType, content); return Response.ok(responseObject, responseType).build(); } else { return Response.notAcceptable(null).build(); @@ -122,17 +120,18 @@ public Response getSitemapData( @PathParam("sitemapname") String sitemapname, @QueryParam("type") String type, @QueryParam("jsoncallback") @DefaultValue("callback") String callback) { - logger.debug("Received HTTP GET request at '{}' for media type '{}'.", new String[] { uriInfo.getPath(), type }); - String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type); + if (logger.isDebugEnabled()) logger.debug("Received HTTP GET request at '{}' for media type '{}'.", uriInfo.getPath(), type); + final String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type); if(responseType!=null) { - Object responseObject = responseType.equals(MediaTypeHelper.APPLICATION_X_JAVASCRIPT) ? - new JSONWithPadding(getSitemapBean(sitemapname, uriInfo.getBaseUriBuilder().build()), callback) : getSitemapBean(sitemapname, uriInfo.getBaseUriBuilder().build()); + final SitemapBean content = getSitemapBean(sitemapname, uriInfo.getBaseUriBuilder().build()); + final Object responseObject = ResponseHelper.wrapContentIfNeccessary(callback, responseType, content); return Response.ok(responseObject, responseType).build(); } else { return Response.notAcceptable(null).build(); } } + @GET @Path("/{sitemapname: [a-zA-Z_0-9]*}/{pageid: [a-zA-Z_0-9]*}") @Produces( { MediaType.WILDCARD }) public SuspendResponse getPageData( @@ -141,29 +140,33 @@ public SuspendResponse getPageData( @PathParam("pageid") String pageId, @QueryParam("type") String type, @QueryParam("jsoncallback") @DefaultValue("callback") String callback, - @HeaderParam(HeaderConfig.X_ATMOSPHERE_TRANSPORT) String atmosphereTransport, @Context AtmosphereResource resource) { - logger.debug("Received HTTP GET request at '{}' for media type '{}'.", new String[] { uriInfo.getPath(), type }); - if(atmosphereTransport==null || atmosphereTransport.isEmpty()) { - String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type); + logger.debug("Received HTTP GET request at '{}' for media type '{}'.", uriInfo.getPath(), type); + + if(TRANSPORT.UNDEFINED.equals(resource.transport())) { + final String responseType = MediaTypeHelper.getResponseMediaType(headers.getAcceptableMediaTypes(), type); if(responseType!=null) { - Object responseObject = responseType.equals(MediaTypeHelper.APPLICATION_X_JAVASCRIPT) ? - new JSONWithPadding(getPageBean(sitemapname, pageId, uriInfo.getBaseUriBuilder().build()), callback) : getPageBean(sitemapname, pageId, uriInfo.getBaseUriBuilder().build()); - throw new WebApplicationException(Response.ok(responseObject, responseType).header(ATMOS_TIMEOUT_HEADER, DEFAULT_TIMEOUT_SECS + "").build()); + final PageBean content = getPageBean(sitemapname, pageId, uriInfo.getBaseUriBuilder().build()); + final Object responseObject = ResponseHelper.wrapContentIfNeccessary(callback, responseType, content); + throw new WebApplicationException( + Response.ok(responseObject, responseType) + .header(ATMOS_TIMEOUT_HEADER, DEFAULT_TIMEOUT_SECS + "") + .build()); } else { throw new WebApplicationException(Response.notAcceptable(null).build()); } } - GeneralBroadcaster sitemapBroadcaster = BroadcasterFactory.getDefault().lookup(GeneralBroadcaster.class, resource.getRequest().getPathInfo(), true); + BroadcasterFactory broadcasterFactory = resource.getAtmosphereConfig().getBroadcasterFactory(); + GeneralBroadcaster sitemapBroadcaster = broadcasterFactory.lookup(GeneralBroadcaster.class, resource.getRequest().getPathInfo(), true); sitemapBroadcaster.addStateChangeListener(new SitemapStateChangeListener()); boolean resume = false; try { - AtmosphereRequest request = resource.getRequest(); - resume = !ResponseTypeHelper.isStreamingTransport(request); + AtmosphereRequest request = resource.getRequest(); + resume = !ResponseTypeHelper.isStreamingTransport(request); } catch (Exception e) { - logger.debug(e.getMessage()); + logger.debug(e.getMessage(), e); } return new SuspendResponse.SuspendResponseBuilder() @@ -220,7 +223,7 @@ static public PageBean getPageBean(String sitemapName, String pageId, URI uri) { public Collection getSitemapBeans(URI uri) { Collection beans = new LinkedList(); - logger.debug("Received HTTP GET request at '{}'.", UriBuilder.fromUri(uri).build().toASCIIString()); + if (logger.isDebugEnabled()) logger.debug("Received HTTP GET request at '{}'.", UriBuilder.fromUri(uri).build().toASCIIString()); ModelRepository modelRepository = RESTApplication.getModelRepository(); for(String modelName : modelRepository.getAllModelNamesOfType("sitemap")) { Sitemap sitemap = (Sitemap) modelRepository.getModel(modelName); @@ -239,7 +242,7 @@ public Collection getSitemapBeans(URI uri) { } public SitemapBean getSitemapBean(String sitemapname, URI uri) { - Sitemap sitemap = getSitemap(sitemapname); + final Sitemap sitemap = getSitemap(sitemapname); if(sitemap!=null) { return createSitemapBean(sitemapname, sitemap, uri); } else { @@ -249,7 +252,7 @@ public SitemapBean getSitemapBean(String sitemapname, URI uri) { } private SitemapBean createSitemapBean(String sitemapName, Sitemap sitemap, URI uri) { - SitemapBean bean = new SitemapBean(); + final SitemapBean bean = new SitemapBean(); bean.name = sitemapName; bean.icon = sitemap.getIcon(); diff --git a/bundles/io/org.openhab.io.transport.cul/.classpath b/bundles/io/org.openhab.io.transport.cul/.classpath index 23d1fd829d7..4b153cdb5d5 100644 --- a/bundles/io/org.openhab.io.transport.cul/.classpath +++ b/bundles/io/org.openhab.io.transport.cul/.classpath @@ -3,6 +3,5 @@ - diff --git a/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/CULHandler.java b/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/CULHandler.java index c7809756805..2ab6b479b4a 100644 --- a/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/CULHandler.java +++ b/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/CULHandler.java @@ -8,6 +8,8 @@ */ package org.openhab.io.transport.cul; +import java.util.Map; + /** * An interface representing a culfw based device. Can only be obtained via * CULManager and has to be closed via CULManager. Classes implementing this @@ -57,4 +59,12 @@ public interface CULHandler { * @return number of 10ms transmit credits remaining */ public int getCredit10ms(); + + + /** + * Checks if all properties which are used by the CULHandler implementation are equal + * + * @return true if all are equal + */ + public boolean arePropertiesEqual(Map properties); } diff --git a/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/CULManager.java b/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/CULManager.java index 940211314b3..feb5a736b5a 100644 --- a/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/CULManager.java +++ b/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/CULManager.java @@ -77,7 +77,7 @@ public static CULHandler getOpenCULHandler(String deviceName, CULMode mode, Map< if (openDevices.containsKey(deviceName)) { CULHandler handler = openDevices.get(deviceName); - if (handler.getCULMode() == mode) { + if ((handler.getCULMode() == mode) && (handler.arePropertiesEqual(properties))){ logger.debug("Device " + deviceName + " is already open in mode " + mode.toString() + ", returning already openend handler"); return handler; diff --git a/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/AbstractCULHandler.java b/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/AbstractCULHandler.java index d02badbc4cb..727e75b769a 100644 --- a/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/AbstractCULHandler.java +++ b/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/AbstractCULHandler.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; @@ -26,7 +27,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** * Abstract base class for all CULHandler which brings some convenience * regarding registering listeners and detecting forbidden messages. @@ -34,9 +34,11 @@ * @author Till Klocke * @since 1.4.0 */ -public abstract class AbstractCULHandler implements CULHandler, CULHandlerInternal { +public abstract class AbstractCULHandler implements CULHandler, + CULHandlerInternal { - private final static Logger log = LoggerFactory.getLogger(AbstractCULHandler.class); + private final static Logger log = LoggerFactory + .getLogger(AbstractCULHandler.class); /** * Thread which sends all queued commands to the CUL. @@ -124,6 +126,9 @@ public CULMode getCULMode() { return mode; } + @Override + public abstract boolean arePropertiesEqual(Map properties); + @Override public void registerListener(CULListener listener) { if (listener != null) { @@ -175,11 +180,11 @@ public void send(String command) { } @Override - public void sendWithoutCheck(String message) throws CULCommunicationException { + public void sendWithoutCheck(String message) + throws CULCommunicationException { sendQueue.add(message); } - /** * Checks if the message would alter the RF mode of this device. * @@ -204,7 +209,8 @@ protected boolean isMessageAllowed(String message) { */ protected void notifyDataReceived(String data) { for (final CULListener listener : listeners) { - receiveExecutor.execute(new NotifyDataReceivedRunner(listener, data)); + receiveExecutor + .execute(new NotifyDataReceivedRunner(listener, data)); } } @@ -214,20 +220,21 @@ protected void notifyError(Exception e) { } } - /** * read and process next line from underlying transport. - * @throws CULCommunicationException if + * + * @throws CULCommunicationException + * if */ - protected void processNextLine() throws CULCommunicationException { + protected void processNextLine() throws CULCommunicationException { try { String data = br.readLine(); - if(data==null){ - String msg="EOF encountered for "+deviceName; + if (data == null) { + String msg = "EOF encountered for " + deviceName; log.error(msg); throw new CULCommunicationException(msg); } - + log.debug("Received raw message from CUL: " + data); if ("EOB".equals(data)) { log.warn("(EOB) End of Buffer. Last message lost. Try sending less messages per time slot to the CUL"); @@ -235,38 +242,38 @@ protected void processNextLine() throws CULCommunicationException { } else if ("LOVF".equals(data)) { log.warn("(LOVF) Limit Overflow: Last message lost. You are using more than 1% transmitting time. Reduce the number of rf messages"); return; - } else if (data.matches("^\\d+\\s+\\d+")) - { + } else if (data.matches("^\\d+\\s+\\d+")) { processCreditReport(data); return; } notifyDataReceived(data); requestCreditReport(); - + } catch (IOException e) { - log.error("Exception while reading from CUL port "+deviceName, e); + log.error("Exception while reading from CUL port " + deviceName, e); notifyError(e); - + throw new CULCommunicationException(e); - } + } } /** * process data received from credit report + * * @param data */ private void processCreditReport(String data) { // Credit report received - String[] report = data.split(" "); - credit10ms = Integer.parseInt(report[report.length-1]); - log.debug("credit10ms = "+credit10ms); + String[] report = data.split(" "); + credit10ms = Integer.parseInt(report[report.length - 1]); + log.debug("credit10ms = " + credit10ms); } - /** - * get the remaining send time on channel as seen at the last send/receive event. + * get the remaining send time on channel as seen at the last send/receive + * event. * - * @return remaining send time in 10ms units + * @return remaining send time in 10ms units */ public int getCredit10ms() { return credit10ms; @@ -292,8 +299,9 @@ private void requestCreditReport() { * @param message * @throws CULCommunicationException */ - private void writeMessage(String message) throws CULCommunicationException { - log.debug("Sending raw message to CUL "+deviceName+": '"+ message+"'"); + private void writeMessage(String message) throws CULCommunicationException { + log.debug("Sending raw message to CUL " + deviceName + ": '" + message + + "'"); if (bw == null) { log.error("Can't write message, BufferedWriter is NULL"); } @@ -302,11 +310,11 @@ private void writeMessage(String message) throws CULCommunicationException { bw.write(message); bw.flush(); } catch (IOException e) { - log.error("Can't write to CUL "+deviceName, e); + log.error("Can't write to CUL " + deviceName, e); } - + requestCreditReport(); } - + } } diff --git a/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/CULNetworkHandlerImpl.java b/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/CULNetworkHandlerImpl.java index 41bb1058995..93d5d16ca3c 100644 --- a/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/CULNetworkHandlerImpl.java +++ b/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/CULNetworkHandlerImpl.java @@ -26,7 +26,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** * Implementation for culfw based devices which communicate via network port * (CUN for example). @@ -37,6 +36,7 @@ public class CULNetworkHandlerImpl extends AbstractCULHandler { private static final int CUN_DEFAULT_PORT = 2323; + /** * Thread which receives all data from the CUL. * @@ -46,15 +46,16 @@ public class CULNetworkHandlerImpl extends AbstractCULHandler { */ private class ReceiveThread extends Thread { - private final Logger logger = LoggerFactory.getLogger(ReceiveThread.class); + private final Logger logger = LoggerFactory + .getLogger(ReceiveThread.class); /** * Mark this thread */ - ReceiveThread(){ + ReceiveThread() { super("CUL ReceiveThread"); } - + @Override public void run() { @@ -70,64 +71,70 @@ public void run() { } logger.debug("ReceiveThread exiting."); } catch (CULCommunicationException e) { - log.error("Connection to CUL broken, terminating receive thread for " + deviceName); + log.error("Connection to CUL broken, terminating receive thread for " + + deviceName); } } } - - final static Logger log = LoggerFactory.getLogger(CULNetworkHandlerImpl.class); + + final static Logger log = LoggerFactory + .getLogger(CULNetworkHandlerImpl.class); private ReceiveThread receiveThread; - + private Socket socket; private InputStream is; private OutputStream os; - - + public CULNetworkHandlerImpl(String deviceName, CULMode mode) { - super(deviceName, mode); + this(deviceName, mode, null); } /** - * Constructor including property map for specific configuration. Just for compatibility with CulSerialHandlerImpl + * Constructor including property map for specific configuration. Just for + * compatibility with CulSerialHandlerImpl + * * @param deviceName - * String representing the device. + * String representing the device. * @param mode - * The RF mode for which the device will be configured. + * The RF mode for which the device will be configured. * @param properties - * Properties are ignored + * Properties are ignored */ - public CULNetworkHandlerImpl(String deviceName, CULMode mode, Map properties){ - super(deviceName, mode); + public CULNetworkHandlerImpl(String deviceName, CULMode mode, + Map properties) { + super(deviceName, mode); } - + @Override protected void openHardware() throws CULDeviceException { log.debug("Opening network CUL connection for " + deviceName); try { - URI uri = new URI("cul://" + deviceName); - String host = uri.getHost(); - int port = uri.getPort()==-1?CUN_DEFAULT_PORT:uri.getPort(); - - if (uri.getHost() == null || uri.getPort() == -1) { - throw new CULDeviceException("Could not parse host:port from "+deviceName); - } - log.debug("Opening network CUL connection to " + host+":"+port); - socket=new Socket(host, port); - log.info("Connected network CUL connection to " + host+":"+port); + URI uri = new URI("cul://" + deviceName); + String host = uri.getHost(); + int port = uri.getPort() == -1 ? CUN_DEFAULT_PORT : uri.getPort(); + + if (uri.getHost() == null || uri.getPort() == -1) { + throw new CULDeviceException("Could not parse host:port from " + + deviceName); + } + log.debug("Opening network CUL connection to " + host + ":" + port); + socket = new Socket(host, port); + log.info("Connected network CUL connection to " + host + ":" + port); is = socket.getInputStream(); os = socket.getOutputStream(); br = new BufferedReader(new InputStreamReader(is)); bw = new BufferedWriter(new OutputStreamWriter(os)); log.debug("Starting network listener Thread"); - receiveThread=new ReceiveThread(); + receiveThread = new ReceiveThread(); receiveThread.start(); } catch (IOException e) { throw new CULDeviceException(e); } catch (URISyntaxException e) { - throw new CULDeviceException("Could not parse host:port from "+deviceName, e); + throw new CULDeviceException("Could not parse host:port from " + + deviceName, e); } } @@ -135,9 +142,9 @@ protected void openHardware() throws CULDeviceException { @Override protected void closeHardware() { receiveThread.interrupt(); - + log.debug("Closing network device " + deviceName); - + try { if (br != null) { br.close(); @@ -156,5 +163,14 @@ protected void closeHardware() { } } } - } + } + + /** + * Returns always true, because connection properties are ignored for a + * network connection. + */ + @Override + public boolean arePropertiesEqual(Map properties) { + return true; + } } diff --git a/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/CULSerialHandlerImpl.java b/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/CULSerialHandlerImpl.java index 1f470231f48..1d18c40d2ab 100644 --- a/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/CULSerialHandlerImpl.java +++ b/bundles/io/org.openhab.io.transport.cul/src/main/java/org/openhab/io/transport/cul/internal/CULSerialHandlerImpl.java @@ -24,16 +24,23 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.TooManyListenersException; +import org.apache.commons.lang.StringUtils; import org.openhab.io.transport.cul.CULCommunicationException; import org.openhab.io.transport.cul.CULDeviceException; import org.openhab.io.transport.cul.CULMode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** * Implementation for culfw based devices which communicate via serial port * (cullite for example). This is based on rxtx and assumes constant parameters @@ -42,55 +49,155 @@ * @author Till Klocke * @since 1.4.0 */ -public class CULSerialHandlerImpl extends AbstractCULHandler implements SerialPortEventListener { +public class CULSerialHandlerImpl extends AbstractCULHandler implements + SerialPortEventListener { + + private static final Map validParitiesMap; + static { + Map parities = new HashMap(); + parities.put("EVEN", SerialPort.PARITY_EVEN); + parities.put("ODD", SerialPort.PARITY_ODD); + parities.put("MARK", SerialPort.PARITY_MARK); + parities.put("NONE", SerialPort.PARITY_NONE); + parities.put("SPACE", SerialPort.PARITY_SPACE); + validParitiesMap = Collections.unmodifiableMap(parities); + } - final static Logger log = LoggerFactory.getLogger(CULSerialHandlerImpl.class); + private static final List validBaudrateMap; + static { + Integer baudrates[] = {75, 110, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}; + validBaudrateMap = Collections.unmodifiableList(Arrays.asList(baudrates)); + } + + private final static Logger log = LoggerFactory + .getLogger(CULSerialHandlerImpl.class); + + private final static String KEY_BAUDRATE = "baudrate"; + private final static String KEY_PARITY = "parity"; private SerialPort serialPort; private Integer baudRate = 9600; private Integer parityMode = SerialPort.PARITY_EVEN; private InputStream is; private OutputStream os; + /** * Default Constructor + * * @param deviceName - * String representing the device. + * String representing the device. * @param mode - * The RF mode for which the device will be configured. + * The RF mode for which the device will be configured. */ public CULSerialHandlerImpl(String deviceName, CULMode mode) { - super(deviceName, mode); + this(deviceName, mode, null); } - - + /** * Constructor including property map for specific configuration. + * * @param deviceName - * String representing the device. + * String representing the device. * @param mode - * The RF mode for which the device will be configured. + * The RF mode for which the device will be configured. * @param properties - * Property Map containing specific configuration for serial device connection. - *

        - *
      • "baudrate" (Integer) Setup baudrate
      • - *
      • "parity" (Integer) Setup parity bit handling. (http://show.docjava.com/book/cgij/code/data/j4pDoc/constant-values.html#serialPort.rxtx.SerialPortInterface.PARITY_NONE) - *
      + * Property Map containing specific configuration for serial + * device connection. + *
        + *
      • "baudrate" (Integer) Setup baudrate
      • + *
      • "parity" (Integer) Setup parity bit handling. + * (http://show. + * docjava.com/book/cgij/code/data/j4pDoc/constant-values + * .html#serialPort.rxtx.SerialPortInterface.PARITY_NONE) + *
      */ - public CULSerialHandlerImpl(String deviceName, CULMode mode, Map properties){ + public CULSerialHandlerImpl(String deviceName, CULMode mode, + Map properties) { super(deviceName, mode); - - if(properties.get("baudrate") != null){ - baudRate = (Integer) properties.get("baudrate"); - log.debug("Set baudrate to " + baudRate); + + final String configuredBaudRate = (String) properties.get(KEY_BAUDRATE); + if (StringUtils.isNotBlank(configuredBaudRate)) { + try { + int tmpBaudRate = Integer.parseInt(configuredBaudRate); + if(validBaudrateMap.contains(tmpBaudRate)) { + baudRate = tmpBaudRate; + } else { + log.error( + "Error parsing config parameter '{}'. Value = {} is not a valid baudrate. Value must be in [75, 110, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200]", + KEY_BAUDRATE, tmpBaudRate); + } + log.info("Update config, {} = {}", KEY_BAUDRATE, baudRate); + } catch (NumberFormatException e) { + log.error( + "Error parsing config parameter '{}' to integer. Value = {}", + KEY_BAUDRATE, configuredBaudRate); + } + } + + final String configuredParity = (String) properties.get(KEY_PARITY); + if (StringUtils.isNotBlank(configuredParity)) { + try { + if (isValidParity(configuredParity)) { + parityMode = validParitiesMap.get(configuredParity + .toUpperCase()); + } else { + int parsedParityNumber = Integer.parseInt(configuredParity); + if (isValidParity(parsedParityNumber)) { + parityMode = parsedParityNumber; + } else { + log.error( + "The configured '{}' value is invalid. The value '{}' has to be one of {}.", + KEY_PARITY, parsedParityNumber, + validParitiesMap.keySet()); + } + } + log.info("Update config, {} = {} ({})", KEY_PARITY, + convertParityModeToString(parityMode), parityMode); + } catch (NumberFormatException e) { + log.error("Error parsing config key '{}'. Use one of {}.", + KEY_PARITY, validParitiesMap.keySet()); + } } - - if(properties.get("parity") != null){ - parityMode = (Integer) properties.get("parity"); - log.debug("Set parity to " + parityMode); + + } + + /** + * Checks if mode is a valid input for 'SerialPort' - class + * + * @param mode + * @return true if valid + */ + private boolean isValidParity(int mode) { + return validParitiesMap.containsValue(mode); + } + + /** + * Checks if mode is a valid input for 'SerialPort' - class + * + * @param mode + * @return true if valid + */ + private boolean isValidParity(String mode) { + return validParitiesMap.containsKey(mode.toUpperCase()); + } + + /** + * converts modes integer representation into a readable sting + * + * @param mode + * @return text if mode was valid, otherwise "invalid mode" + */ + private String convertParityModeToString(int mode) { + if (validParitiesMap.containsValue(mode)) { + for (Entry parity : validParitiesMap.entrySet()) { + if (parity.getValue().equals(mode)) { + return parity.getKey(); + } + } } - + return "invalid mode"; } - + @Override public void serialEvent(SerialPortEvent event) { if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) { @@ -106,17 +213,23 @@ public void serialEvent(SerialPortEvent event) { protected void openHardware() throws CULDeviceException { log.debug("Opening serial CUL connection for " + deviceName); try { - CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(deviceName); + CommPortIdentifier portIdentifier = CommPortIdentifier + .getPortIdentifier(deviceName); if (portIdentifier.isCurrentlyOwned()) { - throw new CULDeviceException("The port " + deviceName + " is currenty used by " + throw new CULDeviceException("The port " + deviceName + + " is currenty used by " + portIdentifier.getCurrentOwner()); } - CommPort port = portIdentifier.open(this.getClass().getName(), 2000); + CommPort port = portIdentifier + .open(this.getClass().getName(), 2000); if (!(port instanceof SerialPort)) { - throw new CULDeviceException("The device " + deviceName + " is not a serial port"); + throw new CULDeviceException("The device " + deviceName + + " is not a serial port"); } serialPort = (SerialPort) port; - serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, parityMode); + + serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, + SerialPort.STOPBITS_1, parityMode); is = serialPort.getInputStream(); os = serialPort.getOutputStream(); br = new BufferedReader(new InputStreamReader(is)); @@ -161,4 +274,48 @@ protected void closeHardware() { } } + + /** + * Compares KEY_BAUDRATE and KEY_PARITY to equality in properties map. The + * values are not required, so if they're not present, they're handled as + * equal, too! + */ + @Override + public boolean arePropertiesEqual(Map properties) { + + if (properties == null) { + return false; + } + + boolean baudRateEquals = mapContainsEqualValueByKey(properties, + KEY_BAUDRATE, baudRate); + boolean parityEquals = mapContainsEqualValueByKey(properties, + KEY_PARITY, parityMode); + + return baudRateEquals && parityEquals; + } + + /** + * Check if a key in a map is present and in that case check equality of the + * value to {value}. + * + * @param properties + * @param key + * The key of the given properties + * @param value + * Has to equal the properties value of key + */ + private boolean mapContainsEqualValueByKey(Map properties, + String key, Integer value) { + boolean result = true; + if (properties.containsKey(key)) { + try { + int mapValue = Integer.parseInt((String) properties.get(key)); + result = (value == mapValue); + } catch (NumberFormatException e) { + result = false; + } + } + return result; + } } diff --git a/bundles/io/org.openhab.io.transport.serial/.classpath b/bundles/io/org.openhab.io.transport.serial/.classpath index e5b1c31ae69..88b0b119f94 100644 --- a/bundles/io/org.openhab.io.transport.serial/.classpath +++ b/bundles/io/org.openhab.io.transport.serial/.classpath @@ -2,6 +2,6 @@ - + diff --git a/bundles/io/org.openhab.io.transport.serial/META-INF/MANIFEST.MF b/bundles/io/org.openhab.io.transport.serial/META-INF/MANIFEST.MF index 94d7ebcd44b..b3bf9a1e97b 100644 --- a/bundles/io/org.openhab.io.transport.serial/META-INF/MANIFEST.MF +++ b/bundles/io/org.openhab.io.transport.serial/META-INF/MANIFEST.MF @@ -5,6 +5,6 @@ Bundle-SymbolicName: org.openhab.io.transport.serial Bundle-Version: 1.7.0.qualifier Bundle-Vendor: openHAB.org Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Bundle-ClassPath: lib/nrjavaserial-3.8.8.jar +Bundle-ClassPath: lib/nrjavaserial-3.9.3.jar Export-Package: gnu.io Import-Package: gnu.io diff --git a/bundles/io/org.openhab.io.transport.serial/build.properties b/bundles/io/org.openhab.io.transport.serial/build.properties index 583517109f9..7af7ddea74a 100644 --- a/bundles/io/org.openhab.io.transport.serial/build.properties +++ b/bundles/io/org.openhab.io.transport.serial/build.properties @@ -1,2 +1,2 @@ bin.includes = META-INF/,\ - lib/nrjavaserial-3.8.8.jar + lib/nrjavaserial-3.9.3.jar diff --git a/bundles/io/org.openhab.io.transport.serial/lib/nrjavaserial-3.8.8.jar b/bundles/io/org.openhab.io.transport.serial/lib/nrjavaserial-3.8.8.jar deleted file mode 100644 index 13e0405396c..00000000000 Binary files a/bundles/io/org.openhab.io.transport.serial/lib/nrjavaserial-3.8.8.jar and /dev/null differ diff --git a/bundles/io/org.openhab.io.transport.serial/lib/nrjavaserial-3.9.3.jar b/bundles/io/org.openhab.io.transport.serial/lib/nrjavaserial-3.9.3.jar new file mode 100644 index 00000000000..467797599b7 Binary files /dev/null and b/bundles/io/org.openhab.io.transport.serial/lib/nrjavaserial-3.9.3.jar differ diff --git a/bundles/model/org.openhab.model.item.ui/src/org/openhab/model/ui/contentassist/ItemsProposalProvider.java b/bundles/model/org.openhab.model.item.ui/src/org/openhab/model/ui/contentassist/ItemsProposalProvider.java index c9ef300ba04..3afeea79090 100644 --- a/bundles/model/org.openhab.model.item.ui/src/org/openhab/model/ui/contentassist/ItemsProposalProvider.java +++ b/bundles/model/org.openhab.model.item.ui/src/org/openhab/model/ui/contentassist/ItemsProposalProvider.java @@ -40,6 +40,7 @@ public class ItemsProposalProvider extends AbstractItemsProposalProvider { ITEMTYPES.add("Contact"); ITEMTYPES.add("Rollershutter"); ITEMTYPES.add("DateTime"); + ITEMTYPES.add("Point"); } @Override diff --git a/bundles/model/org.openhab.model.item/src/org/openhab/model/Items.xtext b/bundles/model/org.openhab.model.item/src/org/openhab/model/Items.xtext index 36f1327f413..9154f4a1214 100644 --- a/bundles/model/org.openhab.model.item/src/org/openhab/model/Items.xtext +++ b/bundles/model/org.openhab.model.item/src/org/openhab/model/Items.xtext @@ -19,7 +19,7 @@ ModelGroupItem : ; enum ModelGroupFunction : - AND='AND' | OR='OR' | NAND='NAND' | NOR='NOR' | AVG='AVG' | SUM='SUM' | MAX='MAX' | MIN='MIN' + AND='AND' | OR='OR' | NAND='NAND' | NOR='NOR' | AVG='AVG' | SUM='SUM' | MAX='MAX' | MIN='MIN' | COUNT='COUNT' ; ModelNormalItem : @@ -27,7 +27,7 @@ ModelNormalItem : ; ModelItemType : - 'Switch' | 'Rollershutter' | 'Number' | 'String' | 'Dimmer' | 'Contact' | 'DateTime' | 'Color' | ID + 'Switch' | 'Rollershutter' | 'Number' | 'String' | 'Dimmer' | 'Contact' | 'DateTime' | 'Color' | 'Point' | ID ; ModelBinding: diff --git a/bundles/model/org.openhab.model.item/src/org/openhab/model/item/internal/GenericItemProvider.java b/bundles/model/org.openhab.model.item/src/org/openhab/model/item/internal/GenericItemProvider.java index 09d30d8f851..71746fd6394 100644 --- a/bundles/model/org.openhab.model.item/src/org/openhab/model/item/internal/GenericItemProvider.java +++ b/bundles/model/org.openhab.model.item/src/org/openhab/model/item/internal/GenericItemProvider.java @@ -243,6 +243,13 @@ private GroupItem applyGroupFunction(GenericItem baseItem, ModelGroupItem modelG } else { logger.error("Group function 'NOT OR' requires two arguments. Using Equality instead."); } + case COUNT: + if (args.size() == 1) { + groupFunction = new ArithmeticGroupFunction.Count(args.get(0)); + break; + } else { + logger.error("Group function 'COUNT' requires one argument. Using Equality instead."); + } case AVG: groupFunction = new ArithmeticGroupFunction.Avg(); break; diff --git a/bundles/model/org.openhab.model.rule.tests/META-INF/MANIFEST.MF b/bundles/model/org.openhab.model.rule.tests/META-INF/MANIFEST.MF deleted file mode 100644 index d3f5a12faa9..00000000000 --- a/bundles/model/org.openhab.model.rule.tests/META-INF/MANIFEST.MF +++ /dev/null @@ -1 +0,0 @@ - diff --git a/bundles/model/org.openhab.model.rule/.classpath b/bundles/model/org.openhab.model.rule/.classpath index f7845a1a3fa..ff72560041b 100644 --- a/bundles/model/org.openhab.model.rule/.classpath +++ b/bundles/model/org.openhab.model.rule/.classpath @@ -5,6 +5,5 @@ - diff --git a/bundles/model/org.openhab.model.script.tests/META-INF/MANIFEST.MF b/bundles/model/org.openhab.model.script.tests/META-INF/MANIFEST.MF deleted file mode 100644 index d3f5a12faa9..00000000000 --- a/bundles/model/org.openhab.model.script.tests/META-INF/MANIFEST.MF +++ /dev/null @@ -1 +0,0 @@ - diff --git a/bundles/model/org.openhab.model.script/.classpath b/bundles/model/org.openhab.model.script/.classpath index 7931e0d51fb..ff72560041b 100644 --- a/bundles/model/org.openhab.model.script/.classpath +++ b/bundles/model/org.openhab.model.script/.classpath @@ -4,8 +4,6 @@ - - diff --git a/bundles/model/org.openhab.model.sitemap/src/org/openhab/model/Sitemap.xtext b/bundles/model/org.openhab.model.sitemap/src/org/openhab/model/Sitemap.xtext index 4bd3908ba02..e605cb3fec2 100644 --- a/bundles/model/org.openhab.model.sitemap/src/org/openhab/model/Sitemap.xtext +++ b/bundles/model/org.openhab.model.sitemap/src/org/openhab/model/Sitemap.xtext @@ -143,5 +143,5 @@ terminal ID: (('0'..'9')+ ('a'..'z' | 'A'..'Z' | '_') ('0'..'9' | 'a'..'z' | 'A'..'Z' | '_')*); terminal FLOAT returns ecore::EBigDecimal: - INT '.' INT; + '-'? INT '.' INT; \ No newline at end of file diff --git a/bundles/persistence/org.openhab.persistence.db4o/pom.xml b/bundles/persistence/org.openhab.persistence.db4o/pom.xml index f26ac0c44f9..b35337f5e67 100644 --- a/bundles/persistence/org.openhab.persistence.db4o/pom.xml +++ b/bundles/persistence/org.openhab.persistence.db4o/pom.xml @@ -30,60 +30,6 @@ org.vafer jdeb - - - package - - jdeb - - - ${basedir}/src/deb/control - - - ${basedir}/src/deb/etc/openhab/configurations/persistence/db4o.persist - file - - perm - /etc/openhab/configurations/persistence - root - root - 644 - - - - ${basedir}/target/${project.artifactId}-${project.version}.jar - file - - perm - /usr/share/openhab/addons - root - root - 644 - - - - directory - ${basedir}/src/deb/var/lib/openhab/persistence - **/.gitignore - - perm - /var/lib/openhab/persistence - root - openhab - 2775 - - - - - link - /etc/openhab/jetty/etc/db4o - /var/lib/openhab/persistence/db4o - true - - - - - diff --git a/bundles/persistence/org.openhab.persistence.db4o/src/deb/control/conffiles b/bundles/persistence/org.openhab.persistence.db4o/src/deb/control/conffiles deleted file mode 100644 index 8d42f373553..00000000000 --- a/bundles/persistence/org.openhab.persistence.db4o/src/deb/control/conffiles +++ /dev/null @@ -1 +0,0 @@ -/etc/openhab/configurations/persistence/db4o.persist diff --git a/bundles/persistence/org.openhab.persistence.db4o/src/deb/control/control b/bundles/persistence/org.openhab.persistence.db4o/src/deb/control/control deleted file mode 100644 index 89d4486570f..00000000000 --- a/bundles/persistence/org.openhab.persistence.db4o/src/deb/control/control +++ /dev/null @@ -1,9 +0,0 @@ -Package: [[deb.name]] -Version: [[version]] -Section: [[deb.section]] -Priority: optional -Architecture: all -Maintainer: [[deb.maintainer]] -Description: [[deb.description]] -Distribution: [[deb.distribution]] -Depends: [[deb.depends]] diff --git a/bundles/persistence/org.openhab.persistence.db4o/src/deb/etc/openhab/configurations/persistence/db4o.persist b/bundles/persistence/org.openhab.persistence.db4o/src/deb/etc/openhab/configurations/persistence/db4o.persist deleted file mode 100644 index 2d9f91a7bcf..00000000000 --- a/bundles/persistence/org.openhab.persistence.db4o/src/deb/etc/openhab/configurations/persistence/db4o.persist +++ /dev/null @@ -1 +0,0 @@ -// Configuration file for "db4o" persistence module diff --git a/bundles/persistence/org.openhab.persistence.db4o/src/deb/var/lib/openhab/persistence/db4o/.gitignore b/bundles/persistence/org.openhab.persistence.db4o/src/deb/var/lib/openhab/persistence/db4o/.gitignore deleted file mode 100644 index 44c5ea8fa75..00000000000 --- a/bundles/persistence/org.openhab.persistence.db4o/src/deb/var/lib/openhab/persistence/db4o/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore \ No newline at end of file diff --git a/bundles/persistence/org.openhab.persistence.db4o/src/main/java/org/openhab/persistence/db4o/internal/Db4oPersistenceService.java b/bundles/persistence/org.openhab.persistence.db4o/src/main/java/org/openhab/persistence/db4o/internal/Db4oPersistenceService.java index a21024a4250..4996576c930 100644 --- a/bundles/persistence/org.openhab.persistence.db4o/src/main/java/org/openhab/persistence/db4o/internal/Db4oPersistenceService.java +++ b/bundles/persistence/org.openhab.persistence.db4o/src/main/java/org/openhab/persistence/db4o/internal/Db4oPersistenceService.java @@ -58,7 +58,8 @@ /** * This is a {@link PersistenceService} implementation using the db4o database. * - * @author Kai Kreuzer + * @author Kai Kreuzer - Initial Contribution + * @author Theo Weiss - get DB_FOLDER from property * @since 1.0.0 */ public class Db4oPersistenceService implements QueryablePersistenceService { @@ -67,7 +68,7 @@ public class Db4oPersistenceService implements QueryablePersistenceService { private static final String SERVICE_NAME = "db4o"; - private static final String DB_FOLDER_NAME = "etc/db4o"; + private static final String DB_FOLDER = getUserPersistenceDataFolder() + File.separator + "db4o"; private static final String DB_FILE_NAME = "store.db4o"; private static final String SCHEDULER_GROUP = "DB4O_SchedulerGroup"; @@ -80,9 +81,9 @@ public String getName() { } public void activate() { - File folder = new File(DB_FOLDER_NAME); + File folder = new File(DB_FOLDER); if(!folder.exists()) { - folder.mkdir(); + folder.mkdirs(); } openDbFile(); Db4oItem.configure(db.ext().configure()); @@ -191,7 +192,7 @@ private Query queryWithReconnect() { } private static void openDbFile() { - db = Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(), DB_FOLDER_NAME + File.separator + DB_FILE_NAME); + db = Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(), DB_FOLDER + File.separator + DB_FILE_NAME); } @@ -295,10 +296,10 @@ public static class BackupJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { long startTime = System.currentTimeMillis(); - String backupFileName = DB_FOLDER_NAME + File.separator + + String backupFileName = DB_FOLDER + File.separator + DATE_FORMATTER.format(System.currentTimeMillis()) + "_" + DB_FILE_NAME + ".bak"; - removeObsoleteBackupFiles(DB_FOLDER_NAME); + removeObsoleteBackupFiles(DB_FOLDER); try { ExtObjectContainer extDb = db.ext(); if (!extDb.isClosed()) { @@ -346,6 +347,14 @@ public boolean accept(File dir, String name) { } } - + + static private String getUserPersistenceDataFolder() { + String progArg = System.getProperty("smarthome.userdata"); + if (progArg != null) { + return progArg + File.separator + "persistence"; + } else { + return "etc"; + } + } } diff --git a/bundles/persistence/org.openhab.persistence.influxdb/java/org/openhab/persistence/influxdb/internal/InfluxDBPersistenceService.java b/bundles/persistence/org.openhab.persistence.influxdb/java/org/openhab/persistence/influxdb/internal/InfluxDBPersistenceService.java index 9b86925ca1f..2e434be14e0 100644 --- a/bundles/persistence/org.openhab.persistence.influxdb/java/org/openhab/persistence/influxdb/internal/InfluxDBPersistenceService.java +++ b/bundles/persistence/org.openhab.persistence.influxdb/java/org/openhab/persistence/influxdb/internal/InfluxDBPersistenceService.java @@ -473,9 +473,13 @@ private State objectToState(Object value, String itemName) { try { Item item = itemRegistry.getItem(itemName); if (item instanceof SwitchItem && !(item instanceof DimmerItem)) { - return valueStr.equals(DIGITAL_VALUE_OFF) ? OnOffType.OFF : OnOffType.ON; + return string2DigitalValue(valueStr).equals(DIGITAL_VALUE_OFF) + ? OnOffType.OFF + : OnOffType.ON; } else if (item instanceof ContactItem) { - return valueStr.equals(DIGITAL_VALUE_OFF) ? OpenClosedType.CLOSED : OpenClosedType.OPEN; + return string2DigitalValue(valueStr).equals(DIGITAL_VALUE_OFF) + ? OpenClosedType.CLOSED + : OpenClosedType.OPEN; } } catch (ItemNotFoundException e) { logger.warn("Could not find item '{}' in registry", itemName); @@ -485,4 +489,22 @@ private State objectToState(Object value, String itemName) { return new DecimalType(valueStr); } + /** + * Maps a string value which expresses a {@link BigDecimal.ZERO } to DIGITAL_VALUE_OFF, all others + * to DIGITAL_VALUE_ON + * + * @param value to be mapped + * @return + */ + private String string2DigitalValue(String value) { + BigDecimal num = new BigDecimal(value); + if (num.compareTo(BigDecimal.ZERO) == 0) { + logger.trace("digitalvalue {}", DIGITAL_VALUE_OFF); + return DIGITAL_VALUE_OFF; + } else { + logger.trace("digitalvalue {}", DIGITAL_VALUE_ON); + return DIGITAL_VALUE_ON; + } + } + } diff --git a/bundles/persistence/org.openhab.persistence.mysql/java/org/openhab/persistence/mysql/internal/MysqlPersistenceService.java b/bundles/persistence/org.openhab.persistence.mysql/java/org/openhab/persistence/mysql/internal/MysqlPersistenceService.java index 225cd1a924c..e5b4f605a2d 100644 --- a/bundles/persistence/org.openhab.persistence.mysql/java/org/openhab/persistence/mysql/internal/MysqlPersistenceService.java +++ b/bundles/persistence/org.openhab.persistence.mysql/java/org/openhab/persistence/mysql/internal/MysqlPersistenceService.java @@ -113,9 +113,9 @@ public class MysqlPersistenceService implements QueryablePersistenceService, Man public void activate() { // Initialise the type array - sqlTypes.put("COLORITEM", "CHAR(25)"); + sqlTypes.put("COLORITEM", "VARCHAR(70)"); sqlTypes.put("CONTACTITEM", "VARCHAR(6)"); - sqlTypes.put("DATETIMEITEM", "DATETIME(3)"); + sqlTypes.put("DATETIMEITEM", "DATETIME"); sqlTypes.put("DIMMERITEM", "TINYINT"); sqlTypes.put("GROUPITEM", "DOUBLE"); sqlTypes.put("NUMBERITEM", "DOUBLE"); diff --git a/bundles/persistence/org.openhab.persistence.rrd4j/pom.xml b/bundles/persistence/org.openhab.persistence.rrd4j/pom.xml index 90621bae808..da2b0e7ce66 100644 --- a/bundles/persistence/org.openhab.persistence.rrd4j/pom.xml +++ b/bundles/persistence/org.openhab.persistence.rrd4j/pom.xml @@ -30,60 +30,6 @@ org.vafer jdeb - - - package - - jdeb - - - ${basedir}/src/deb/control - - - ${basedir}/src/deb/etc/openhab/configurations/persistence/rrd4j.persist - file - - perm - /etc/openhab/configurations/persistence - root - root - 644 - - - - ${basedir}/target/${project.artifactId}-${project.version}.jar - file - - perm - /usr/share/openhab/addons - root - root - 644 - - - - directory - ${basedir}/src/deb/var/lib/openhab/persistence - **/.gitignore - - perm - /var/lib/openhab/persistence - root - openhab - 2775 - - - - - link - /etc/openhab/jetty/etc/rrd4j - /var/lib/openhab/persistence/rrd4j - true - - - - - diff --git a/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/control/conffiles b/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/control/conffiles deleted file mode 100644 index 00af54877fd..00000000000 --- a/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/control/conffiles +++ /dev/null @@ -1 +0,0 @@ -/etc/openhab/configurations/persistence/rrd4j.persist diff --git a/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/control/control b/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/control/control deleted file mode 100644 index 89d4486570f..00000000000 --- a/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/control/control +++ /dev/null @@ -1,9 +0,0 @@ -Package: [[deb.name]] -Version: [[version]] -Section: [[deb.section]] -Priority: optional -Architecture: all -Maintainer: [[deb.maintainer]] -Description: [[deb.description]] -Distribution: [[deb.distribution]] -Depends: [[deb.depends]] diff --git a/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/etc/openhab/configurations/persistence/rrd4j.persist b/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/etc/openhab/configurations/persistence/rrd4j.persist deleted file mode 100644 index 2447d12152e..00000000000 --- a/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/etc/openhab/configurations/persistence/rrd4j.persist +++ /dev/null @@ -1 +0,0 @@ -// Configuration file for "rrd4j" persistence module diff --git a/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/var/lib/openhab/persistence/rrd4j/.gitignore b/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/var/lib/openhab/persistence/rrd4j/.gitignore deleted file mode 100644 index 44c5ea8fa75..00000000000 --- a/bundles/persistence/org.openhab.persistence.rrd4j/src/deb/var/lib/openhab/persistence/rrd4j/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore \ No newline at end of file diff --git a/bundles/persistence/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/RRD4jService.java b/bundles/persistence/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/RRD4jService.java index 59ad23466fc..94575af3629 100644 --- a/bundles/persistence/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/RRD4jService.java +++ b/bundles/persistence/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/RRD4jService.java @@ -58,7 +58,7 @@ public class RRD4jService implements QueryablePersistenceService { private static final String DATASOURCE_STATE = "state"; - protected final static String DB_FOLDER = getUserDataFolder() + File.separator + "rrd4j"; + public final static String DB_FOLDER = getUserPersistenceDataFolder() + File.separator + "rrd4j"; private static final Logger logger = LoggerFactory.getLogger(RRD4jService.class); @@ -165,7 +165,7 @@ public Iterable query(FilterCriteria filter) { RrdDb db = getDB(itemName, consolidationFunction); if(db!=null) { long start = 0L; - long end = filter.getEndDate()==null ? System.currentTimeMillis()/1000 - 1 : filter.getEndDate().getTime()/1000; + long end = filter.getEndDate()==null ? System.currentTimeMillis()/1000 : filter.getEndDate().getTime()/1000; try { if(filter.getBeginDate()==null) { @@ -223,7 +223,7 @@ protected synchronized RrdDb getDB(String alias, ConsolFun function) { } else { File folder = new File(DB_FOLDER); if(!folder.exists()) { - folder.mkdir(); + folder.mkdirs(); } // create a new database file db = new RrdDb(getRrdDef(function, file)); @@ -304,10 +304,10 @@ private State mapToState(double value, String itemName) { return new DecimalType(value); } - static private String getUserDataFolder() { + static private String getUserPersistenceDataFolder() { String progArg = System.getProperty("smarthome.userdata"); if (progArg != null) { - return progArg; + return progArg + File.separator + "persistence"; } else { return "etc"; } diff --git a/bundles/persistence/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/charts/RRD4jChartServlet.java b/bundles/persistence/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/charts/RRD4jChartServlet.java index ff98852bc7e..d5d7f58e72d 100644 --- a/bundles/persistence/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/charts/RRD4jChartServlet.java +++ b/bundles/persistence/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/charts/RRD4jChartServlet.java @@ -11,6 +11,7 @@ import java.awt.Color; import java.awt.Font; import java.awt.image.BufferedImage; +import java.io.File; import java.io.IOException; import java.util.Date; import java.util.HashMap; @@ -177,11 +178,11 @@ protected void addLine(RrdGraphDef graphDef, Item item, int counter) { } if(item instanceof NumberItem) { // we only draw a line - graphDef.datasource(Integer.toString(counter), "./etc/rrd4j/" + item.getName() + ".rrd", "state", RRD4jService.getConsolidationFunction(item)); + graphDef.datasource(Integer.toString(counter), RRD4jService.DB_FOLDER + File.separator + item.getName() + ".rrd", "state", RRD4jService.getConsolidationFunction(item)); graphDef.line(Integer.toString(counter), color, label, 2); } else { // we draw a line and fill the area beneath it with a transparent color - graphDef.datasource(Integer.toString(counter), "./etc/rrd4j/" + item.getName() + ".rrd", "state", RRD4jService.getConsolidationFunction(item)); + graphDef.datasource(Integer.toString(counter), RRD4jService.DB_FOLDER + File.separator + item.getName() + ".rrd", "state", RRD4jService.getConsolidationFunction(item)); Color areaColor = AREACOLORS[counter%LINECOLORS.length]; graphDef.area(Integer.toString(counter), areaColor); diff --git a/bundles/ui/org.openhab.ui.webapp/minify-webapp.sh b/bundles/ui/org.openhab.ui.webapp/minify-webapp.sh new file mode 100755 index 00000000000..2351a57934e --- /dev/null +++ b/bundles/ui/org.openhab.ui.webapp/minify-webapp.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Use defaults +COMPRESS_OPTIONS="" + +# Extend list for more scripts +declare -a files=( + "web/WebApp/Action/Logic.js" +) + +# Check uglify installation +command -v uglifyjs >/dev/null 2>&1 || { echo >&2 "You need to have nodejs and uglifyjs2 (https://github.com/mishoo/UglifyJS2) installed!"; exit 1; } + +echo "Minifying JavaScript" + +for file in "${files[@]}"; do + minFile=${file//.js/.min.js} + echo "$file -> $minFile: " + uglifyjs --compress $COMPRESS_OPTIONS --output $minFile -- $file +done diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/button.html b/bundles/ui/org.openhab.ui.webapp/snippets/button.html index fcc647604a1..4a63049699f 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/button.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/button.html @@ -1 +1 @@ -%label% +%label% diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/buttons.html b/bundles/ui/org.openhab.ui.webapp/snippets/buttons.html index 306cc4d823a..0cd87a2b503 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/buttons.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/buttons.html @@ -1 +1 @@ -
    • %buttons%
    • +
    • %buttons%
    • diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/colorpicker.html b/bundles/ui/org.openhab.ui.webapp/snippets/colorpicker.html index c4fbfc5872e..7d1fe025538 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/colorpicker.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/colorpicker.html @@ -1,3 +1,3 @@ -
    • - -%label%
    • +
    • + +%label%
    • diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/group.html b/bundles/ui/org.openhab.ui.webapp/snippets/group.html index 081c2c8b221..e321e53bfde 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/group.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/group.html @@ -1 +1 @@ -
    • %label%
    • +
    • %label%
    • diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/image_link.html b/bundles/ui/org.openhab.ui.webapp/snippets/image_link.html index f6d628fbfc3..a4e88896b64 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/image_link.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/image_link.html @@ -1 +1 @@ -%setrefresh%

      +%setrefresh%

      diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/main.html b/bundles/ui/org.openhab.ui.webapp/snippets/main.html index 7445a04f677..f3d2eadef33 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/main.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/main.html @@ -1,176 +1,199 @@ - - - - %label% - - - - - - - - - - - - - - - - - - - - - - - - - - -
      -
      -
      Loading...
      - -
      - Back - Home - %label% -
      - -
      -
      - %children% -
      ©2010-2014 openHAB.org
      -
      -
      -

      -
        -

        -
      -
      -
      -
      -
      -
      - + + + + %label% + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      Loading...
      + +
      + Back + Home + %label% +
      + +
      +
      + %children% +
      ©2010-2014 openHAB.org
      +
      +
      +

      +
        +

        +
      +
      +
      +
      +
      +
      + \ No newline at end of file diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/rollerblind.html b/bundles/ui/org.openhab.ui.webapp/snippets/rollerblind.html index 3a42279043a..8c4eb82f583 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/rollerblind.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/rollerblind.html @@ -1,2 +1,2 @@ -
    • %label%
    • +
    • %label%
    • diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/selection.html b/bundles/ui/org.openhab.ui.webapp/snippets/selection.html index 6bb2b04465e..40705ebdca6 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/selection.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/selection.html @@ -1 +1 @@ -
    • %label_header%%rows%
    • +
    • %label_header%%rows%
    • diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/selection_row.html b/bundles/ui/org.openhab.ui.webapp/snippets/selection_row.html index b7c132962af..2bd1213cb0b 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/selection_row.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/selection_row.html @@ -1 +1 @@ - + diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/setpoint.html b/bundles/ui/org.openhab.ui.webapp/snippets/setpoint.html index f71434246c6..90607047bfb 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/setpoint.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/setpoint.html @@ -1,2 +1,2 @@ -
    • %label%
    • +
    • %label%
    • diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/slider.html b/bundles/ui/org.openhab.ui.webapp/snippets/slider.html index 9d1477ef181..48c35848695 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/slider.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/slider.html @@ -1,2 +1,2 @@ -
    • %label%
    • +
    • %label%
    • diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/switch.html b/bundles/ui/org.openhab.ui.webapp/snippets/switch.html index af84d8745bb..6fa4f7ebbce 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/switch.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/switch.html @@ -1 +1 @@ -
    • \ No newline at end of file +
    • \ No newline at end of file diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/text.html b/bundles/ui/org.openhab.ui.webapp/snippets/text.html index c44bf5acaae..f0c52bad133 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/text.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/text.html @@ -1 +1 @@ -
    • %label%
    • +
    • %label%
    • diff --git a/bundles/ui/org.openhab.ui.webapp/snippets/text_link.html b/bundles/ui/org.openhab.ui.webapp/snippets/text_link.html index 09cedd679e8..f8abb43a9a6 100644 --- a/bundles/ui/org.openhab.ui.webapp/snippets/text_link.html +++ b/bundles/ui/org.openhab.ui.webapp/snippets/text_link.html @@ -1 +1 @@ -
    • %label%
    • +
    • %label%
    • diff --git a/bundles/ui/org.openhab.ui.webapp/src/main/java/org/openhab/ui/webapp/internal/render/AbstractWidgetRenderer.java b/bundles/ui/org.openhab.ui.webapp/src/main/java/org/openhab/ui/webapp/internal/render/AbstractWidgetRenderer.java index 447e3040038..13bf7acde7d 100644 --- a/bundles/ui/org.openhab.ui.webapp/src/main/java/org/openhab/ui/webapp/internal/render/AbstractWidgetRenderer.java +++ b/bundles/ui/org.openhab.ui.webapp/src/main/java/org/openhab/ui/webapp/internal/render/AbstractWidgetRenderer.java @@ -51,7 +51,9 @@ abstract public class AbstractWidgetRenderer implements WidgetRenderer { protected static final String SNIPPET_LOCATION = "snippets/"; /* a local cache so we do not have to read the snippets over and over again from the bundle */ - protected static final Map snippetCache = new HashMap(); + protected static final Map snippetCache = new HashMap(); + + protected boolean useSnippetCache = true; public void setItemUIRegistry(ItemUIRegistry itemUIRegistry) { this.itemUIRegistry = itemUIRegistry; @@ -66,6 +68,7 @@ public ItemUIRegistry getItemUIRegistry() { } protected void activate(ComponentContext context) { + useSnippetCache = !Boolean.valueOf(System.getProperty("disableHtmlCache", "false")); } protected void deactivate(ComponentContext context) { @@ -87,7 +90,9 @@ protected synchronized String getSnippet(String elementType) throws RenderExcept if(entry!=null) { try { snippet = IOUtils.toString(entry.openStream()); - snippetCache.put(elementType, snippet); + if (useSnippetCache) { + snippetCache.put(elementType, snippet); + } } catch (IOException e) { logger.warn("Cannot load snippet for element type '{}'", elementType, e); } diff --git a/bundles/ui/org.openhab.ui.webapp/web/WebApp/Action/Logic.js b/bundles/ui/org.openhab.ui.webapp/web/WebApp/Action/Logic.js index edbcd2e9734..269ebccc906 100644 --- a/bundles/ui/org.openhab.ui.webapp/web/WebApp/Action/Logic.js +++ b/bundles/ui/org.openhab.ui.webapp/web/WebApp/Action/Logic.js @@ -1,226 +1,1810 @@ -var WebApp=(function(){var A_=setTimeout;var B_=setInterval;var _ll,_mm,_nn,_nner;var _pp,_qq,_rr,_ss,_tt;var _uu,_vv;var _ww,_xx,_yy;var _zz,_00;var _11=-1;var _22=-1;var _33=[];var _44=[];var _55=[];var _66=[];var _77=history.length;var _88=0;var _99=0;var _AAA="";var _BBB="";var _CCC=0;var _DDD=0;var _EEE=1;var _FFF=null;var _GGG=1;var _HHH="";var _III=0;var _JJJ=B_(_f,250);var _KKK=null;var _LLL=window;var _MMM="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";var _wkt;var _NNN=!!document.getElementsByClassName&&UA("WebKit");var _OOO=!!navigator.standalone;var _PPP=_N(_LLL.ontouchstart)&&!UA("Android");var _QQQ=_PPP?_2:_3;var _RRR={} -_RRR.load=[];_RRR.beginslide=[];_RRR.endslide=[];_RRR.beginasync=[];_RRR.willasync=[];_RRR.endasync=[];_RRR.orientationchange=[];_RRR.tabchange=[];var _SSS=false;var d=document;var $h={get HEAD(){return 0},get BACK(){return 1},get HOME(){return 2},get LEFT(){return 3},get RIGHT(){return 4},get TITLE(){return 5}} -var $d={get L2R(){return+1},get R2L(){return-1}} -d.wa={get auto_GG(){return _SSS},set auto_GG(v){_SSS=(v=="true"||v=="yes"||v===true)},get header(){return $h},get direction(){return $d}} -d.webapp=d.wa;var $pc={get Version(){return 'v0.6.0 WIP'},Proxy:function(url){_HHH=url},Progressive:function(enable){_III=enable},Opener:function(func){_zz=func?func:function(u){location=u}},Refresh:function(id){if(id!==false){var o=$(id);if(!o){_ee()}else if(o.type=="radio"){_XX([o])}else if(o.type=="checkbox"){_CC(o.previousSibling,1)}} -_9();_0();_q()},HideBar:function(){if(_GGG&&_p()){_GGG=0;_A(1);A_(_A,0)}return false},Header:function(show,what,keep){_BB();if(keep!=-1){_D(!show,keep)} -_h(_mm,0);_mm=$(what);_h(_mm,show);_nner[$h.HEAD].style.zIndex=!show?2:"";return false},Tab:function(id,active){var o=$(id);_u(o,$$("li",o)[active])},AddEventListener:function(evt,handler){if(_N(_RRR[evt])){with(_RRR[evt]){if(indexOf(handler)==-1){push(handler)}} -}},RemoveEventListener:function(evt,handler){if(_N(_RRR[evt])){with(_RRR[evt]){splice(lastIndexOf(handler),1)}} -},Back:function(){if(_99){return(_99=0)} -_00=null;if(history.length-_77==_22){history.back()}else{_zz(_33[_22-1][1])}return false},Home:function(){if(history.length-_77==_22){history.go(-_22)}else{_zz("#")}return(_99=0)},Form:function(frm){var s,a,b,c,o,k,f,t;a=$(frm);b=$(_33[_22][0]);s=(a.style.display!="block");f=_T(a);with(_nner[$h.HEAD]){t=offsetTop+offsetHeight}if(s){a.style.top=t+"px"}if(f){k=f.onsubmit;if(!s){f.onsubmit=f.onsubmit(0,1)}else{f.onsubmit=function(e,b){if(b){return k}if(e){_K(e)}if(!(k&&k(e)===false)){$pc.Submit(this,null,e)}} -}} -_h(a,s);_k(s,t+a.offsetHeight);o=$$("legend",a)[0];_9(s&&o?o.innerHTML:null);_FFF=(s)?a:null;if(s){c=a;a=b;b=c} -_F(a);_E(b,s);if(s){$pc.Header()}else{_D(!s)}return false},Submit:function(frm){var f=_T(frm);if(f){var a=arguments[1];var _=function(i,f){var q="";for(var n=0;n=0){url=_LL(url,"__source",_33[_22][0])} -url=_JJ(url);o.open(m,url,async);if(prms){o.setRequestHeader("Content-Type","application/x-www-form-urlencoded")} -_s("willasync",a,o);o.onreadystatechange=(async)?c:null;o.send(prms);if(!async){c()}} -},Loader:function(obj,show){var o,h,f;if(o=$(obj)){h=_X(o,"__lod");_C(o);if(show){if(h){$pc.Loader(obj,0)} -_Z(o,"__lod");_44.push([o,_H(o)])}else if(h){_a(o,"__lod");f=_44.filter(function(f){return f[0]==o} -)[0];_d(_44,f);if(f=f[1]){f[0]._=0;clearInterval(f[1]);f[0].style.backgroundImage=""}} -}return h},Player:function(src){if(!_p()){_LLL.open(src)}else{if(_NNN){location="#"+Math.random()} -var w=$("__wa_media");var o=_R("iframe");o.id="__wa_media";o.src=src;_pp.appendChild(o);_S(w)}return false},toString:function(){return "[WebApp.Net Framework]"}} -function _A(h){h=h?h:0;_pp.style.minHeight=(_DDD+h)+"px";_LLL.scrollTo(0,h)} -function _B(s,w,dir,step,mn){s+=Math.max((w-s)/step,mn||4);return[s,(w+w*dir)/2-Math.min(s,w)*dir]} -function _C(o){if(_X(o,"iMore")){var a=$$("a",o)[0];if(a&&a.title){var s=$$("span",a)[0]||a;o=s.innerHTML;s.innerHTML=a.title;a.title=o}} -} -function _D(s,k){if(_nn){var h=_nner;k=(s)?[]:k||[];for(var i=1;i1)}} -}} -function _E(lay,ignore){if(_nn){var a=$$("a",lay);var p=$h.RIGHT;for(var i=0;i=$h.LEFT;i++){if(_nner[p]&&!ignore){i--;p--;continue}if(_W(a[i].rel,"action")||_W(a[i].rel,"back")){_Z(a[i],p==$h.RIGHT?"iRightButton":"iLeftButton");_h(a[i],1);_nner[p--]=a[i];_nn.appendChild(a[i--])}} -}} -function _F(lay){if(_nn){with($h){for(var i=LEFT;i<=RIGHT;i++){var a=_nner[i];if(a&&(_W(a.rel,"action")||_W(a.rel,"back"))){_h(a,0);_a(a,i==RIGHT?"iRightButton":"iLeftButton");lay.insertBefore(a,lay.firstChild)}} -_nner[RIGHT]=$("waRightButton");_nner[LEFT]=$("waLeftButton")}} -} -function _G(o){var u;if(u=getComputedStyle(o,null).backgroundImage){o._=1;return/(.+?(\d+)x(\d+)x)(\d+)(.*)/.exec(u)}} -function _H(o){var d,c,i;if(!(d=_G(o))){c=$$("*",o);for(i=0;i/g,"").replace(/^\s+|\s+$/g,"").replace(/\s{2,}/," ")} -function _K(e){e.preventDefault();e.stopPropagation()} -function _L(o){return _W(o.rev,"async")||_W(o.rev,"async:np")} -function _M(o){return _W(o.rev,"media")} -function _N(o){return(typeof o!="undefined")} -function _O(o,a){return a.indexOf(o)!=-1} -function $(i){return typeof i=="string"?document.getElementById(i):i} -function $$(t,o){return(o||document).getElementsByTagName(t)} -function $A(o,a){return o.getAttribute(a)||""} -function XY(e){var x=0;var y=0;while(e){x+=e.offsetLeft;y+=e.offsetTop;e=e.offsetParent}return{x:x,y:y}} -function _P(){with(_LLL)return{x:pageXOffset,y:pageYOffset,w:innerWidth,h:innerHeight}} -function _Q(c){var s,h=$$("head")[0];s=_R("script");s.type="text/javascript";s.textContent=c;h.appendChild(s)} -function _R(t,c){var o=document.createElement(t);if(c){o.innerHTML=c}return o} -function _S(p,c){if(p){if(!c){c=p;p=c.parentNode} -p.removeChild(c)}} -function _T(o){o=$(o);if(o&&_V(o)!="form"){o=_b(o,"form")}return o} -function _U(o){return _V(o)=="a"?o:_b(o,"a")} -function _V(o){return o.localName.toLowerCase()} -function _W(o,t){return o&&_O(t,o.toLowerCase().split(" "))} -function _X(o,c){return o&&_O(c,_Y(o))} -function _Y(o){return o.className.split(" ")} -function _Z(o,c){var h=_X(o,c);if(!h){o.className+=" "+c}return h} -function _a(o){var c=_Y(o);var a=arguments;for(var i=1;i=_vv)?_vv:_uu;if(w!=_CCC){_CCC=w;_pp.className=(w==_uu)?"portrait":"landscape";_s("orientationchange")}if(o=_II()){h=XY(o).y+o.offsetHeight} -m=_CCC==_uu?416:268;w=_P().h;h=h0){return}else{act=_33[0][0]} -var cur=_33[_22][0];if(act!=cur){var i,pos=-1;for(i in _33){if(_33[i][0]==act){pos=parseInt(i);break}}if(pos!=-1&&pos<_22){_z(cur,act,$d.L2R)}else{_y(act)}} -} -function _s(evt,ctx,obj){var l=_RRR[evt].length;if(l==0){return true} -var e={type:evt,target:obj||null,context:ctx||_EE(_33[_22][1]),windowWidth:_CCC,windowHeight:_DDD} -var k=true;for(var i=0;i_vv){var l=_vv;_vv=_uu;_uu=l} -_ll=_FF()[0].id;_l(_ll,1);var a=(_II()||"").id;if(a!=_ll){_l(a)}if(!a){a=_ll;_zz("#")} -_ff(_qq);_i(a,1);_E($(a));with($h){var h=_nner;_h(h[BACK],(!h[LEFT]&&_22));_h(h[HOME],(!h[RIGHT]&&_22>1&&a!=_ll));if(h[BACK]){_BBB=h[BACK].innerHTML}if(h[TITLE]){_AAA=h[TITLE].innerHTML;_9()}} -B_(_r,250);_s("load");_pp.addEventListener("touchstart",new Function(),false);(_PPP?_qq:document).addEventListener(_PPP?"touchmove":"scroll",_ii,false);_q();_hh();_kk("DOMSubtreeModified");_kk("resize");$pc.HideBar()} -function _u(ul,li,h,ev){if(!(_X(li,"__dis")||_W($$("a",li)[0].rel,"action"))){var c,s,al=$$("li",ul);for(var i=0;ix22||x12y22||y12= 0) { + url = AddParam(url, "__source", _history[_historyPos][0]); + } + url = SetURL(url); + + o.open(m, url, async); + if (prms) { o.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); } + CallListeners("willasync", a, o); + o.onreadystatechange = (async) ? c : null; + o.send(prms); + + if (!async) { c(); } + } + }, + + Loader: function(obj, show) { + var o, h, f; + + if (o = $(obj)) { + h = HasClass(o, "__lod"); + ApplyMore(o); + + if (show) { + // If already running remove it to make the new loader image work if style has change + if (h) { $pc.Loader(obj, 0); } + AddClass(o, "__lod"); + _loader.push([o, AnimPrepare(o)]); + + } else if (h) { + DelClass(o, "__lod"); + f = _loader.filter(function(f) { return f[0] == o })[0]; + Remove(_loader, f); + if (f = f[1]) { + f[0]._ = 0; + clearInterval(f[1]); + f[0].style.backgroundImage = ""; + } + } + } + return h; + }, + + Player: function(src) { + if (!IsMobile()) { + _win.open(src); + } else { + + // prevent the back request sent by the internal player + if (_v2) { location = "#" + Math.random(); } + + var w = $("__wa_media"); + var o = NewItem("iframe"); + o.id = "__wa_media"; + o.src = src; // must be before appendChild to prevent Safari weird behavior + + _webapp.appendChild(o); + DelItem(w); + } + return false; + }, + + toString: function() { return "[WebApp.Net Framework]"; } + } + + function ToTop(h) { + h = h ? h : 0; + _webapp.style.minHeight = (_height + h) + "px"; + _win.scrollTo(0, h); + } + + function CalcEaseOut(s, w, dir, step, mn) { + s += Math.max((w - s) / step, mn || 4); + return [s, (w + w * dir) / 2 - Math.min(s, w) * dir]; + } + + function ApplyMore(o) { + if (HasClass(o, "iMore")) { + var a = $$("a", o)[0]; + if (a && a.title) { + var s = $$("span", a)[0] || a; + o = s.innerHTML; + s.innerHTML = a.title; + a.title = o; + } + } + } + + function Buttons(s, k) { + if (_head) { + var h = _header; + k = (s) ? [] : k || []; // if have to show header, ignore k parameter + + for (var i = 1; i < h.length; i++) { // don't hide HEAD, just hide content + if (!Contains(i, k)) { + Display(h[i], s); + } + } + + with ($h) { + if (!Contains(BACK, k)) { + Display(h[BACK], s && !h[LEFT] && _historyPos); + } + if (!Contains(HOME, k)) { + Display(h[HOME], s && !h[RIGHT] && !_hold && _historyPos > 1); + } + } + } + } + + function AddLayerButtons(lay, ignore) { + if (_head) { + var a = $$("a", lay); + var p = $h.RIGHT; + + for (var i = 0; i < a.length && p >= $h.LEFT; i++) { + if (_header[p] && !ignore) { i--; p--; continue; } + + if (HasToken(a[i].rel, "action") || + HasToken(a[i].rel, "back")) { + + AddClass(a[i], p == $h.RIGHT ? "iRightButton" : "iLeftButton"); + Display(a[i], 1); + _header[p--] = a[i]; + _head.appendChild(a[i--]); + } + } + } + } + + function DelLayerButtons(lay) { + if (_head) { + with ($h) { + for (var i = LEFT; i <= RIGHT; i++) { + var a = _header[i]; + if (a && ( HasToken(a.rel, "action") || + HasToken(a.rel, "back")) ) { + + Display(a, 0); + DelClass(a, i == RIGHT ? "iRightButton" : "iLeftButton"); + lay.insertBefore(a, lay.firstChild); + } + } + _header[RIGHT] = $("waRightButton"); + _header[LEFT] = $("waLeftButton"); + } + } + } + + function AnimData(o) { + var u; +/* + [1] = first part of the filename + [2] = delay + [3] = frame count + [4] = frame index + [5] = end part of the filename +*/ + if (u = getComputedStyle(o).backgroundImage) { + o._ = 1; // To track if loading animation is still active + return /(.+?(\d+)x(\d+)x)(\d+)(.*)/.exec(u); + } + } + + function AnimPrepare(o) { + var d, c, i; + + // if the object has no background with anim definition, search any child + if (!(d = AnimData(o))) { + c = $$("*", o); + for (i = 0; i < c.length; i++) { + o = c[i]; + if (d = AnimData(o)) { + break; + } + } + } + // return the animator or nothing + return (d) ? [o, setInterval(AnimRun, d[2], [o, d[4], d[3], (d[1] + "*" + d[5]), new Image() ])] : d; + } + + function AnimRun(a) { + if (!a[5]) { + a[1] = parseInt(a[1]) % parseInt(a[2]) + 1; + var b = a[3].replace("*", a[1]); + a[4].onload = function() { if (a[0]._) a[0].style.backgroundImage = b; a[5] = 0 }; + a[5] = a[4].src = b.substr(4, b.length - 5); + } + } + +/* Private */ + function NoTag(s) { return s.replace(/<.+?>/g, "").replace(/^\s+|\s+$/g, "").replace(/\s{2,}/, " "); } + function NoEvent(e) { e.preventDefault(); e.stopPropagation(); } + function IsAsync(o) { return HasToken(o.rev, "async") || HasToken(o.rev, "async:np"); } + function IsMedia(o) { return HasToken(o.rev, "media") /*|| HasToken(o.rev, "media:audio") || HasToken(o.rev, "media:video");*/ } + function IsDefined(o) { return (typeof o != "undefined"); } + function Contains(o, a) { return a.indexOf(o) != -1 } + + function $(i) { return typeof i == "string" ? document.getElementById(i) : i; } + function $$(t, o) { return (o || document).getElementsByTagName(t); } + function $A(o, a) { return o.getAttribute(a) || ""; } + + function XY(e) { + var x = 0; + var y = 0; + + while (e) { + x += e.offsetLeft; + y += e.offsetTop; + e = e.offsetParent; + } + + return {x:x, y:y}; + } + + function WIN() { + with (_win) return { x:pageXOffset, y:pageYOffset, w:innerWidth, h:innerHeight }; + } + + function NewScript(c) { + var s, h = $$("head")[0]; + s = NewItem("script"); + s.type = "text/javascript"; // should be application/x-javascript see RFC4329 + s.textContent = c; + h.appendChild(s); + } + + function NewItem(t, c) { + var o = document.createElement(t); + if (c) { o.innerHTML = c; } + return o; + } + function DelItem(p, c) { + if (p) { + if (!c) { + c = p; + p = c.parentNode; + } + p.removeChild(c); + } + } + function GetForm(o) { + o = $(o); + if (o && GetName(o) != "form") { + o = GetParent(o, "form"); + } + return o; + } + function GetLink(o) { return GetName(o) == "a" ? o : GetParent(o, "a") } + function GetName(o) { return o.localName.toLowerCase() } + function HasToken(o, t) { return o && Contains(t, o.toLowerCase().split(" ")); } + + function HasClass(o, c) { return o && Contains(c, GetClass(o)); } + function GetClass(o) { return o.className.split(" "); } + function AddClass(o, c) { + var h = HasClass(o, c); + if (!h) { o.className += " " + c; } + return h; + } + function DelClass(o) { + var c = GetClass(o); + var a = arguments; + for (var i = 1; i < a.length; i++) { + Remove(c, a[i]); + } + o.className = c.join(" "); + } + function GetParent(o, t) { + while ((o = o.parentNode) && (o.nodeType != 1 || GetName(o) != t)){}; + return o; + } + function AnyOf(o, c) { + while ((o = o.parentNode) && (o.nodeType != 1 || !HasClass(o, c))){}; + return o; + } + + function Remove(a, e) { + var p = a.indexOf(e); + if (p != -1) { a.splice(p, 1); } + } + + function GetText(o) { + o = o.childNodes; + for (var i = 0; i < o.length; i++) { + if (o[i].nodeType == 3) { + return o[i].nodeValue.replace(/^\s+|\s+$/g, ""); + } + } + return null; + } + + function InitBlocks() { + if (!_webapp) { _webapp = $("WebApp"); } + if (!_group) { _group = $("iGroup"); } + + var i = $("iLoader"); + if (i && !HasClass(i, "__lod")) { + $pc.Loader(i, 1); + } + } + + function InitVars() { + _header = [ + $("iHeader"), + $("waBackButton"), + $("waHomeButton"), + $("waLeftButton"), + $("waRightButton"), + $("waHeadTitle") + ]; + + _bdy = document.body; + _bdo = (_bdy.dir == "rtl") ? -1 : +1; + _wkt = IsDefined(_bdy.style.webkitTransform); + } + + function Display(o, s) { if (o = $(o)) { o.style.display = s ? "block" : "none"; } } + function Layer(o, s) { + if (o = $(o)) { + o.style[_bdo == 1 ? "left" : "right"] = s ? 0 : ""; + o.style.display = s ? "block" : ""; + } + } + + // TODO: any way to do this with CSS?? + function AdjustLayer(o) { + if (o = o || GetActive()) { + var z = $$("div", o); z = z[z.length -1]; + if (z && (HasClass(z, "iList") || HasClass(z, "iFull"))) { + z.style.minHeight = parseInt(_webapp.style.minHeight) - XY(z).y + "px"; + } + } + } + + function Shadow(s, p) { + var o = $("__wa_shadow"); + o.style.top = p + "px"; + // display:relative may slow down webkit effect, use it only when required + _webapp.style.position = s ? "relative" : ""; + Display(o, s); + } + + function Historize(o, l) { // l = isDefault + if (o) { + //TODO: fix endless toggle when using same layer in different level of navigation + + _history.splice(++_historyPos, _history.length); + _history.push([o, !l ? location.hash : ("#_" + _def.substr(2)), _lastScroll]); + + } + } + + // We need to remove scripts from the clone to prevent execution + function PrepareClone(o) { + // prevent execution of script tag + var s = $$("script", o); + while(s.length) { + DelItem(s[0]); + } + return o; + } + + function Cleanup() { + var s, i, c; + +// FIXME: may cancel some unwanted visual loaders + + while (_loader.length) { + $pc.Loader(_loader[0][0], 0); + } + s = $$("li"); + for (i = 0; i < s.length; i++) { + DelClass(s[i], "__sel", "__tap"); + } + } + + function ParseParams(s, np) { + var ed = s.indexOf("#_"); + if (ed == -1) { + return null; + } + var rs = ""; + var bs = SplitURL(s); + if (!np) { + for (var i = 0; i < bs[1].length; i++) { + rs += "/" + bs[1][i].split("=").pop(); + } + } + return bs[2] + rs; + } + + function IsMobile() { + return (UA("iPhone") || UA("iPod") || UA("Aspen")); + } + + function UA(s) { + return Contains(s, navigator.userAgent); + } + + function Resizer() { + if (_sliding) { + return; + } + var m, h, o, w = (WIN().w >= _maxh) ? _maxh : _maxw; + if (w != _width) { + _width = w; + _webapp.className = (w == _maxw) ? "portrait" : "landscape"; + CallListeners("orientationchange"); + } + + if (o = GetActive()) { + h = XY(o).y + o.offsetHeight; + } + + m = _width == _maxw ? 416 : 268; // minimum height values for Safari iPhone + w = WIN().h; + h = h < w ? w : h; + h = h < m ? m : h; + + _height = h; + _webapp.style.minHeight = h + "px"; + AdjustLayer(); + + } + + function Locator() { + if (_sliding || _hold == location.href) { + return; + } + _hold = 0; + + var act = GetActive(); + if (act) { + act = act.id; + } else if (location.hash.length > 0) { // there is a simple anchor, jump to it + return; + } else { // No? should slide back to home + act = _history[0][0]; + } + + var cur = _history[_historyPos][0]; + if (act != cur) { + var i, pos = -1; + for (i in _history) { + if (_history[i][0] == act) { + pos = parseInt(i); + break; + } + } + if (pos != -1 && pos < _historyPos) { +// TODO: check this, seems it is useless and make URL based change to an invalid history position, should fix back madness +// Locator redefini _historyPos ? = erreur de position quand # (_historyPos = pos + 1) +// _historyPos = pos + 1; + InitSlide(cur, act, $d.L2R); + } else { + SlideTo(act); + } + } + } + + function CallListeners(evt, ctx, obj) { + // Do not waste time and memory if no handler have been defined for the given event + var l = _handler[evt].length; + if (l == 0) { + return true; + } + var e = { + type: evt, + target: obj || null, + context: ctx || Explode(_history[_historyPos][1]), + windowWidth: _width, + windowHeight: _height + } + + var k = true; + for (var i = 0; i < l; i++) { + k = k && (_handler[evt][i](e) == false ? false : true); + } + return k; + } + + function Init() { + + clearInterval(_tmp); + + InitBlocks(); + InitVars(); + InitForms(); + InitTab(); + InitHeader(); + InitObj("__wa_shadow"); + + var i = $("iLoader"); + $pc.Loader(i, 0); + DelItem(i); + + $pc.Opener(_opener); + + // get screen size + _maxw = screen.width; + _maxh = screen.height; + if (_maxw > _maxh) { var l = _maxh; _maxh = _maxw; _maxw = l; } + + // Get the default layer + _def = GetLayers()[0].id; + Historize(_def, 1); + + var a = (GetActive() || "").id; + if (a != _def) { Historize(a); } // FIXME: should historize extra params too if any (?) + if (!a) { a = _def; _opener("#"); } + + Layer(a, 1); + AddLayerButtons($(a)); + + with ($h) { + var h = _header; + Display(h[BACK], (!h[LEFT] && _historyPos)); + Display(h[HOME], (!h[RIGHT] && _historyPos > 1 && a != _def)); + + if (h[BACK]) { + _baseBack = h[BACK].innerHTML; + } + if (h[TITLE]) { + _baseTitle = h[TITLE].innerHTML; + SetTitle(); + } + } + + /* start common jobs + */ + setInterval(Locator, 250); + + /* call load listener in blocking mode to allow loading of destination layer + */ + CallListeners("load"); + + _webapp.addEventListener("touchstart", new Function(), false); // active state + (_touch ? _group : document).addEventListener(_touch ? "touchmove" : "scroll", ImagesListener, false); + + Resizer(); + ImagesShow(); + DocumentTracker("DOMSubtreeModified"); + DocumentTracker("resize"); + $pc.HideBar(); + } + +/* Event */ + function ShowTab(ul, li, h, ev) { // TODO: load async content here? + if (!( HasClass(li, "__dis") || + HasToken($$("a", li)[0].rel, "action"))) { + + var c, s, al = $$("li", ul); + for (var i = 0; i < al.length; i++) { + c = (al[i] == li); + if (c) { s = i; } // check which has been selected + + Display(ul.id + i, (!h && c)); // display/hide the panel if no override (h) + DelClass(al[i], "__act"); // unselected any tabs + } + + AddClass(li, "__act"); + if (ev) { CallListeners("tabchange", [s], ul); } + } + } + + function ClearTransform(o) { + if (o) o.style.webkitTransform = ""; + } + + function ListenClick(e) { + if (_sliding) { + return NoEvent(e); + } + /* Checkbox label */ + var o = e.target; + var n = GetName(o); + if (n == "label") { + var f = $($A(o, "for")); + if (HasClass(f, "iToggle")) { + setTimeout(FlipCheck, 1, f.previousSibling, 1); + } + return; + } + + /* Radio parent */ + var li = GetParent(o, "li"); + if (li && HasClass(li, "iRadio")) { + AddClass(li, "__sel"); + ShowRadio(li); + _hold = location.href; + SlideTo("wa__radio"); + return NoEvent(e); + } + + /* handle onclick event on links */ + var a = GetLink(o); + if (a && li && HasClass(li, "__dis")) { + return NoEvent(e); + } + /* Warning: if onclick="return false" and do not call any other code, + a.onclick will be null and the following code will not be executed. + */ + if (a && a.onclick) { + var old = a.onclick; + a.onclick = null; // prevent double execution + var val = old.call(a, e); + setTimeout(function() { a.onclick = old }, 0); + if (val === false) { + if (li) { + AddClass(li, HasClass(a, "iSide") ? "__tap" : "__sel"); + Unselect(li); + } + return NoEvent(e); + } + } + + /* Tab */ + var ul = GetParent(o, "ul"); + var pr = !ul ? null : ul.parentNode; + var ax = a && IsAsync(a); + + if (a && ul && HasClass(pr, "iTab")) { + var h, t; + + t = HasToken(a.rel, "action"); // allows classic link on tab + h = $(ul.id + "-loader"); + Display(h, 0); + + if (!t && ax) { + Display(h, 1); + $pc.Loader(h, 1); + BasicAsync(a, function(o) { + Display(h, 0); + $pc.Loader(h, 0); + Display(ShowAsync(o)[0], 1); + ShowTab(ul, li, 0, 1); + }); + } else { h = t } // activation only if loader doesn't exists or disabled (!ax) + ShowTab(ul, li, !!h, !ax); // !ax = event will be raised by async callback + + if (!t) { return NoEvent(e); } // will be processed as classic link + } + + /* Common button */ + if (a && Contains(a.id, ["waBackButton", "waHomeButton"])) { + if (a.id == "waBackButton") { $pc.Back(); } + else { $pc.Home(); } + return NoEvent(e); + } + + /* Radio list */ + if (ul && HasClass(ul, "iCheck")) { + if (ClickRadio(a, ul) !== false) { + var al = $$("li", ul); + for (var i = 0; i < al.length; i++) { + DelClass(al[i], "__act", "__sel"); + } + AddClass(li, "__act __sel"); + setTimeout(DelClass, 1000, li, "__sel"); + } + return NoEvent(e); + } + + /* Menu and list */ + if (ul && !HasClass(li, "iMore") && + ((HasClass(ul, "iMenu") || HasClass(pr, "iMenu")) || + (HasClass(ul, "iList") || HasClass(pr, "iList"))) ) { + + if (a && !HasClass(a, "iButton")) { + var c = AddClass(li, HasClass(a, "iSide") ? "__tap" : "__sel"); + if (ax) { + if (!c) { BasicAsync(a); } + return NoEvent(e); + } + } + } + + /* More */ + var dv = AnyOf(o, "iMore"); + if (dv) { + if (!HasClass(dv, "__lod")) { + $pc.Loader(dv, 1); + if (ax) { BasicAsync(a); } + } + return NoEvent(e); + } + + /* Top form button */ + if (a && _dialog) { + if (HasToken(a.rel, "back")) { + $pc.Form(_dialog, a); + return NoEvent(e); + } + if (HasToken(a.rel, "action")) { + var f = GetForm(_dialog); + if (f) { + f.onsubmit(e); + return; + } + } + } + + /* Media player */ + if (a && IsMedia(a)) { + Unselect(li); + /*if (!d)*/ $pc.Player(a.href, a); + return NoEvent(e); + } + + /* Basic async link */ + if (ax) { + BasicAsync(a); + NoEvent(e); + + } else if (a && !a.target) { + /* Basic go layer */ + if (startsWith(a.href, "http:", "https:", "file:")) { // file: for local testing + Forward(a.href); + NoEvent(e); + } + Unselect(li); + } + } + + function Unselect(li) { + if (li) { setTimeout(DelClass, 1000, li, "__sel", "__tap"); } + } + + function startsWith(s1) { + var r, i, a = arguments; + for (i = 1; i < a.length; i++) { + if (s1.toLowerCase().indexOf(a[i]) == 0) { + return 1; + } + } + } + +/* Animate */ + + function SlideTo(to) { + var h = _history[_historyPos][0]; + if (h != to) { + InitSlide(h, to); + } + } + + function InitSlide(src, dst, dir) { + if (_sliding) { + return; + } + _sliding = 1; + + AdjustView(); + if (dst == _history[0][0]) { + _initialNav = history.length; + } + dir = dir || $d.R2L; + src = $(src); + dst = $(dst); + + var h; + + if (_wkt && _head) { + h = PrepareClone(_head.cloneNode(true)); + } + + _prev = _historyPos; + if (dir == $d.R2L) { + Historize(dst.id); + } else { + while (_historyPos && _history[--_historyPos][0] != dst.id){}; + } + +// New title bar + HideHeader(); + DelLayerButtons(src); + AddLayerButtons(dst); + ShowHeader(); + + if (h) { _header[$h.HEAD].appendChild(h); } + SetBackButton((dir != $d.R2L) ? "" : (_hold ? "" : NoTag(src.title)) || _baseBack); + + SetTitle(_hold ? dst.title : null); + DoSlide(src, dst, dir); + } + + function SetBackButton(txt) { + if (_header[$h.BACK]) { + if (!txt && _historyPos) { + txt = NoTag($(_history[_historyPos - 1][0]).title) || _baseBack; + } + if (txt) { _header[$h.BACK].innerHTML = txt; } + } + } + + function SlideInfo(m) { + var s = Explode(_history[_prev][1]); + var d = Explode(_history[_historyPos][1]); + var r = (m < 0 && !!_hold) ? ["wa__radio"] : d; + return [s, d, m, r]; + } + + function tr_iphone(t) { return "translate3d(" + t + ",0,0)"; } + function tr_others(t) { return "translateX(" + t + ")"; } + + function TranslateX(o, t, i) { + if (o) { + if (t) { t = _translator(t); } + o.style.webkitTransitionProperty = (i) ? "none" : ""; + o.style.webkitTransform = t; + } + } + + function GetTiming(o) { + return o ? getComputedStyle(o, null).webkitTransitionDuration : "0s"; + } + + function GetHigherOf() { + var r, t, i, j, a = arguments; + r = 0; + for (i = 0; i < a.length; i++) { + t = GetTiming(a[i]).split(','); + for (j = 0; j < t.length; j++) { + r = Math.max(r, parseFloat(t[j]) * 1000); + } + } + return r; + } + + function DoSlide(src, dst, dir) { + CallListeners("beginslide", SlideInfo(dir)); + + InitForms(dst); + Layer(src, 1); + Layer(dst, 1); + + // default effect if not webkit + if (!_wkt) { + EndSlide(src, dst, dir); + return; + } + + var b = _group; + var w = _webapp; + var g = dir * _bdo; + + // set the height of iGroup to match the real height of the effect + b.style.height = (_height - b.offsetTop) + "px"; + + // layer anim + AddClass(w, "__ani"); + TranslateX(src, "0", 1); + TranslateX(dst, (g * -100) + "%", 1); + + // header anim + var h, hcs, hos, tim = GetHigherOf(src, dst, _head, _header[$h.TITLE]); + if (_head) { + h = _header[$h.HEAD].lastChild; + hcs = h.style; + hos = _head.style; + + hcs.opacity = 1; + hos.opacity = 0; + TranslateX(h, "0", 1); + TranslateX(_head, (g * -20) + "%", 1); + TranslateX(_header[$h.TITLE], (g == $d.R2L ? 60 : -20) + "%", 1); + } + + setTimeout(function() { + AdjustLayer(dst); + + TranslateX(dst, "0"); + TranslateX(src, (g * 100) + "%"); + + if (h) { + hcs.opacity = 0; + hos.opacity = 1; + TranslateX(h, (g * 30) + "%"); + TranslateX(_head, "0"); + TranslateX(_header[$h.TITLE], "0"); + } + + setTimeout(function() { + if (h) { DelItem(_header[$h.HEAD], h); } + DelClass(w, "__ani"); + b.style.height = ""; + + EndSlide(src, dst, dir); + }, tim); + }, 0); + } + + function EndSlide(src, dst, dir) { + Cleanup(); + Layer(src, 0); + + if (_wkt) { + ClearTransform(dst); + ClearTransform(src); + ClearTransform(_head); + ClearTransform(_header[$h.TITLE]); + } + + CallListeners("endslide", SlideInfo(dir)); + + _sliding = 0; + _prev = -1; + + Resizer(); + setTimeout(AdjustView, 0, dir == $d.L2R ? _history[_historyPos + 1][2] : null); + setTimeout(ImagesShow, 0); + } + + function SetTitle(title) { + var o; + if (o = _header[$h.TITLE]) { + o.innerHTML = title || GetTitle(GetActive()) || _baseTitle; + } + } + + function HideHeader() { + if (_dialog) { $pc.Form(_dialog); } + Display(_headView, 0); + } + + function ShowHeader() { + Buttons(1); + } + +// OFF +// o +// o + + function FlipCheck(o, dontChange) { + var c = o, i = $(c.title); + var txt = i.title.split("|"); + + if (!dontChange) { + i.click(); + } + (i.disabled ? AddClass : DelClass)(c, "__dis"); + + o = c.firstChild.nextSibling; + with (c.lastChild) { + innerHTML = txt[i.checked ? 0 : 1]; + if (i.checked) { + o.style.left = ""; + o.style.right = "-1px"; + AddClass(c, "__sel"); + style.left = 0; + style.right = ""; + } else { + o.style.left = "-1px"; + o.style.right = ""; + DelClass(c, "__sel"); + style.left = ""; + style.right = 0; + } + } + } + + function AdjustView(to) { + var h = to ? to : Math.min(50, WIN().y); + var s = to ? Math.max(1, to - 50) : 1; + var d = to ? -1 : +1; + + while (s <= h) { + var z = CalcEaseOut(s, h, d, 6, 2); + s = z[0]; _win.scrollTo(0, z[1]); + } + if (!to) { $pc.HideBar(); } + } + + function Explode(loc) { + // WARNING: with classic anchors the returned value of this function will be wrong + if (loc) { + var p = loc.indexOf("#_"); + + if (p != -1) { + loc = loc.substring(p + 2).split("/"); + var id = "wa" + loc[0]; + for (var i in loc) { + loc[i] = decodeURIComponent(loc[i]); + } + loc[0] = id; + + if (_o_acl && !$(id)) { + CreateLayer(id); + } + return $(id) ? loc : []; + } + } + return []; + } + + function GetLayers() { + var lay = []; + var src = _group.childNodes; + for (var i in src) { + if (src[i].nodeType == 1 && HasClass(src[i], "iLayer")) { + lay.push(src[i]); + } + } + return lay; + } + + function CreateLayer(i) { + var n = NewItem("div"); + n.id = i; + n.className = "iLayer"; + _group.appendChild(n); + return n; + } + + function GetTitle(o) { + return (!_historyPos && _baseTitle) ? _baseTitle : o.title; + } + + function GetActive() { +// FIXME: should always return the active layer even if the hash is incorrect or use a classic anchor? + var h = location.hash; + return $(!h ? _def : Explode(h)[0]); + } + + function SetURL(url) { + var d = url.match(/[a-z]+:\/\/(.+:.*@)?([a-z0-9-\.]+)((:\d+)?\/.*)?/i); + return (!_proxy || !d || d[2] == location.hostname) + ? url : AddParam(_proxy, "__url", url); // FIXME??? was __url=? + } + + function SplitURL(u) { + var s, q, d; + + s = u.replace(/&/g, "&"); + d = s.indexOf("#"); + d = s.substr(d != -1 ? d : s.length); + s = s.substr(0, s.length - d.length); + q = s.indexOf("?"); + q = s.substr(q != -1 ? q : s.length); + s = s.substr(0, s.length - q.length); + q = !q ? [] : q.substr(1).split("&"); + + return [s, q, d]; + } + + function AddParam(u, k, v) { + u = SplitURL(u); + var q = u[1].filter( + function(o) { return o && o.indexOf(k + "=") != 0 }); // != 0 => any parameter not starting with (k + "=") no multiple name allowed!!! FIXME? + q.push(k + "=" + encodeURIComponent(v)); + return u[0] + "?" + q.join("&") + u[2]; + } + + function AddParams(u, q) { + u = SplitURL(u); + u[1].push(q); + + return u[0] + "?" + u[1].join("&") + u[2]; + } + + function BasicAsync(item, cb, q) { + var h, o, u, i; + + i = (typeof item == "object"); + u = (i ? item.href : item); + o = GetParent(item, "li"); // get loader + + if (!cb) { cb = DefaultCallback(u, HasToken(item.rev, "async:np")); } + $pc.Request(u, q, cb, true, o, (i ? item : null)); + } + + +// TODO: optimize this!!!! + function DefaultCallback(i, np) { + return function(o) { + var u = i ? ParseParams(i, np) : null; + var g = ShowAsync(o); + + if (g && (g[1] || u)) { + Forward(g[1] || u); + } else { + Cleanup(); //setTimeout(Cleanup, 250); + } + return null; + }; + } + + function ReadTextNodes(o) { + var nds = o.childNodes; + var txt = ""; + for (var y = 0; y < nds.length; y++) { + txt += nds[y].nodeValue; + } + return txt; + } + + function Forward(l) { + _lastScroll = WIN().y; + AdjustView(); + _opener(l); + } + + function Go(g) { + return "#_" + g.substr(2); + } + + function ResetScroll(i) { + if (i.substr(0, 2) == "wa") { + var p = _historyPos; + + if (p && i == _history[0][0]) { + _history[1][2] = 0; + } + while (p && _history[--p][0] != i){}; + if (p) { _history[p + 1][2] = 0; } + } + } + + function ShowAsync(o) { + if (o.responseXML) { + o = o.responseXML.documentElement; + + var s, t, k, a = GetActive(); + + /* force jump to a given layer */ + var g = $$("go", o); + g = (g.length != 1) ? null : $A(g[0], "to"); + + /* get all parts to update */ + var f, p = $$("part", o); + if (p.length == 0) { p = [o]; } + + for (var z = 0; z < p.length; z++) { + var dst = $$("destination", p[z])[0]; + if (!dst) { break; } + + var mod = $A(dst, "mode"); + var txt = ReadTextNodes($$("data", p[z])[0]); + + var i = $A(dst, "zone"); + if (($A(dst, "create") == "true" || _o_acl) && + i.substr(0, 2) == "wa" && !$(i)) { + + CreateLayer(i); + } + + f = f || i; + g = g || $A(dst, "go"); // For compatibility with older version + i = $(i || dst.firstChild.nodeValue); // For compatibility with older version + + // Skip this part if the target el does not exist + if (!i) break; + + /* if we target the active layer, remove buttons */ + if (!k && a && a.id == i.id) { + HideHeader(); + DelLayerButtons(i); + k = i; + } + + /* Rset scroll if we modify a previous layer */ + ResetScroll(i.id); + + /* update content */ + SetContent(i, txt, mod); + } + + /* Custom title for the given layer */ + t = $$("title", o); + for (var n = 0; n < t.length; n++) { + var s = $($A(t[n], "set")); + s.title = ReadTextNodes(t[n]); + if (a == s) { SetTitle(); } + } + + /* active layer is targeted? show new header */ + if (k) { + AddLayerButtons(k); + ShowHeader(); + } + + /* script to execute */ + var e = $$("script", o)[0]; + if (e) { NewScript(ReadTextNodes(e)); } + + /* initialize stuff if required */ + InitForms(a); + SetBackButton(); + + if (g == a) { g = null; } // let ImagesShow work properly + if (!g) { ImagesShow(); } + + return [f, g ? Go(g) : null]; + } + + throw "Invalid asynchronous response received."; + } + + function SetContent(o, c, m) { + c = ImagesParse(c); + // Store content in a temp
      to prepare script execution and prepare images + c = NewItem("div", c); + // Clone the
      so that Safari properly recognize