Skip to content

Commit

Permalink
Initital commit of the MyQ binding for OH3
Browse files Browse the repository at this point in the history
Signed-off-by: Dan Cunningham <[email protected]>
  • Loading branch information
digitaldan committed Dec 12, 2020
1 parent 941189a commit e41b32b
Show file tree
Hide file tree
Showing 30 changed files with 1,853 additions and 13 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
/bundles/org.openhab.binding.mqtt.generic/ @davidgraeff
/bundles/org.openhab.binding.mqtt.homeassistant/ @davidgraeff
/bundles/org.openhab.binding.mqtt.homie/ @davidgraeff
/bundles/org.openhab.binding.myq/ @[email protected]
/bundles/org.openhab.binding.mystrom/ @pail23
/bundles/org.openhab.binding.nanoleaf/ @raepple
/bundles/org.openhab.binding.neato/ @jjlauterbach
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,11 @@
<artifactId>org.openhab.binding.mqtt.homie</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.myq</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.mystrom</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.binding.myq/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code

https://github.com/openhab/openhab-addons
35 changes: 35 additions & 0 deletions bundles/org.openhab.binding.myq/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# MyQ Binding

This is the MyQ binding for openHAB. It allows monitoring and control over garage doors manufactured by LiftMaster, Chamberlain and Craftsman who are compatible with the MyQ cloud service.

## Supported Things

### Account

### Garage Door

### Light

## Discovery

Once an account has been added, garage doors and lights will automatically be discovered and added to the inbox.


## Thing Configuration

_Describe what is needed to manually configure a thing, either through the (Paper) UI or via a thing-file. This should be mainly about its mandatory and optional configuration parameters. A short example entry for a thing file can help!_

_Note that it is planned to generate some part of this based on the XML files within ```src/main/resources/OH-INF/thing``` of your binding._

## Channels

| channel | type | description |
|---------------|---------------|--------------------------|
| status | String | Status of the device |
| switch | Switch | Opens (on), Closes (off) |
| contact | contact | |
| rollershutter | rollershutter | |

## Full Example


17 changes: 17 additions & 0 deletions bundles/org.openhab.binding.myq/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>3.0.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.binding.myq</artifactId>

<name>openHAB Add-ons :: Bundles :: MyQ Binding</name>

</project>
23 changes: 23 additions & 0 deletions bundles/org.openhab.binding.myq/src/main/feature/feature.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2010-2020 Contributors to the openHAB project
See the NOTICE file(s) distributed with this work for additional
information.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License 2.0 which is available at
http://www.eclipse.org/legal/epl-2.0
SPDX-License-Identifier: EPL-2.0
-->
<features name="org.openhab.binding.myq-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>

<feature name="openhab-binding-myq" description="MyQ Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.myq/${project.version}</bundle>
</feature>
</features>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.myq.internal;

import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;

/**
* The {@link MyQBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Dan Cunningham - Initial contribution
*/
@NonNullByDefault
public class MyQBindingConstants {

public static final String BINDING_ID = "myq";

// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_ACCOUNT = new ThingTypeUID(BINDING_ID, "account");
public static final ThingTypeUID THING_TYPE_GARAGEDOOR = new ThingTypeUID(BINDING_ID, "garagedoor");
public static final ThingTypeUID THING_TYPE_LIGHT = new ThingTypeUID(BINDING_ID, "light");
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ACCOUNT, THING_TYPE_GARAGEDOOR,
THING_TYPE_LIGHT);
public static final Set<ThingTypeUID> SUPPORTED_DISCOVERY_THING_TYPES_UIDS = Set.of(THING_TYPE_GARAGEDOOR,
THING_TYPE_LIGHT);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.myq.internal;

/**
* The {@link MyQConfiguration} class contains fields mapping thing configuration parameters.
*
* @author Dan Cunningham - Initial contribution
*/
public class MyQConfiguration {

/**
* Sample configuration parameter. Replace with your own.
*/
public String username;
public String password;
public Integer refreshInterval;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.myq.internal;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.config.discovery.DiscoveryListener;
import org.openhab.core.config.discovery.DiscoveryResult;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.config.discovery.ScanListener;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The {@link MyQDiscoveryService} is responsible for discovering MyQ things
*
* @author Dan Cunningham - Initial contribution
*/
@NonNullByDefault
public class MyQDiscoveryService implements DiscoveryService {
private final Logger logger = LoggerFactory.getLogger(MyQDiscoveryService.class);
private static final Set<ThingTypeUID> SUPPORTED_DISCOVERY_THING_TYPES_UIDS = Set
.of(MyQBindingConstants.THING_TYPE_GARAGEDOOR);
private final Map<ThingUID, DiscoveryResult> cachedResults = new HashMap<>();
private final Set<DiscoveryListener> discoveryListeners = new CopyOnWriteArraySet<>();

public void deviceDiscovered(DiscoveryResult result) {

for (DiscoveryListener discoveryListener : discoveryListeners) {
try {
discoveryListener.thingDiscovered(this, result);
} catch (Exception e) {
logger.error("An error occurred while calling the discovery listener {}.",
discoveryListener.getClass().getName(), e);
}
}
synchronized (cachedResults) {
cachedResults.put(result.getThingUID(), result);
}
}

@Override
public Collection<ThingTypeUID> getSupportedThingTypes() {
return SUPPORTED_DISCOVERY_THING_TYPES_UIDS;
}

@Override
public int getScanTimeout() {
return 0;
}

@Override
public boolean isBackgroundDiscoveryEnabled() {
return false;
}

@Override
public void startScan(@Nullable ScanListener listener) {
if (listener != null) {
listener.onFinished();
}
}

@Override
public void abortScan() {
}

@Override
public void addDiscoveryListener(@Nullable DiscoveryListener listener) {
logger.trace("Adding discovery listener");
if (listener == null) {
return;
}
synchronized (cachedResults) {
for (DiscoveryResult cachedResult : cachedResults.values()) {
listener.thingDiscovered(this, cachedResult);
}
}
discoveryListeners.add(listener);
}

@Override
public void removeDiscoveryListener(@Nullable DiscoveryListener listener) {
discoveryListeners.remove(listener);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.myq.internal;

import static org.openhab.binding.myq.internal.MyQBindingConstants.*;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.myq.internal.handler.MyQAccountHandler;
import org.openhab.binding.myq.internal.handler.MyQGarageDoorHandler;
import org.openhab.binding.myq.internal.handler.MyQLightHandler;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
* The {@link MyQHandlerFactory} is responsible for creating things and thing
* handlers.
*
* @author Dan Cunningham - Initial contribution
*/
@NonNullByDefault
@Component(configurationPid = "binding.myq", service = ThingHandlerFactory.class)
public class MyQHandlerFactory extends BaseThingHandlerFactory {
private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
private final HttpClient httpClient;

@Activate
public MyQHandlerFactory(final @Reference HttpClientFactory httpClientFactory) {
this.httpClient = httpClientFactory.getCommonHttpClient();
}

@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
}

@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();

if (THING_TYPE_ACCOUNT.equals(thingTypeUID)) {
MyQDiscoveryService discoveryService = new MyQDiscoveryService();
MyQAccountHandler accountHandler = new MyQAccountHandler((Bridge) thing, httpClient, discoveryService);
discoveryServiceRegs.put(accountHandler.getThing().getUID(), bundleContext
.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
return accountHandler;
}

if (THING_TYPE_GARAGEDOOR.equals(thingTypeUID)) {
return new MyQGarageDoorHandler(thing);
}

if (THING_TYPE_LIGHT.equals(thingTypeUID)) {
return new MyQLightHandler(thing);
}

return null;
}

@Override
protected synchronized void removeHandler(ThingHandler thingHandler) {
if (thingHandler instanceof MyQAccountHandler) {
ServiceRegistration<?> serviceReg = discoveryServiceRegs.remove(thingHandler.getThing().getUID());
if (serviceReg != null) {
serviceReg.unregister();
}
}
}
}
Loading

0 comments on commit e41b32b

Please sign in to comment.