-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[Worxlandroid] Initial contribution #16893
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 19 commits
7948d21
c72a4ab
de635ea
3ae5a65
c73c363
ed0170e
77bb4cd
30b58ac
c090241
cfe369c
f9d88a7
afad02b
39bdf9f
38a8098
de4ea46
d3bbd17
898fa75
a4fe63a
18d657a
586b348
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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 |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 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>5.1.0-SNAPSHOT</version> | ||
| </parent> | ||
|
|
||
| <artifactId>org.openhab.binding.worxlandroid</artifactId> | ||
|
|
||
| <name>openHAB Add-ons :: Bundles :: Worx Landroid Binding</name> | ||
|
|
||
| <dependencies> | ||
| <dependency> | ||
| <groupId>software.amazon.awssdk.iotdevicesdk</groupId> | ||
| <artifactId>aws-iot-device-sdk</artifactId> | ||
| <version>1.15.0</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>software.amazon.awssdk.crt</groupId> | ||
| <artifactId>aws-crt</artifactId> | ||
| <version>0.25.1</version> | ||
lsiepel marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| </dependency> | ||
| </dependencies> | ||
|
Comment on lines
19
to
30
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This binding performs some similar requests/response, so it should be possible to create them without these SDK's.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you be more explicit ? I'm afraid I did not get the meaning of your comment.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant to say that the SDK should not be used. Instead the httpclient can be used to perform the same api request/responses. You could look at the salus binding that also holds a very light weight base class doing much of the SDK work without needing the actual SDK. Due to problems of the past with size, upgrades and other issues we try to keep these SDK’s out of the codebase.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lsiepel : This is for Mqtt client of AWS IoT, I remember I failed to switch to another MQTT client (because of the need of a websocket for the authentication IIRW that was not available with available one). I'll have another look at it to be sure.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have not looked in depth on how the MQTT client and websocket / authentication work together. I just know that we tent not to accept these SDK's. For the salus binding we had a similar issue with the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't find any problems so far with the URL encoder in the HiveMQ implementation, is that still a problem and why? What I found after looking at the code:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried HiveMQ client in my eatly tentative. I do not find back what blocked me at the time but the result is I did not suceed in that way.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Did you read the linked comment? As that also points to: hivemq/hivemq-mqtt-client#643
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That issue is not very detailed as it doesn't tell exactly where the issue occurs. Also I couldn't relate the code in that issue to actual HiveMQ Client APIs. 🤔
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I filed that issue quite a while ago. I have just tried to dig through this as I had originally come to the same conclusion as you, but could not make it work. I've managed to reduce it to the following code: In the above it creates a URI just like hivemq, then passes it on to Netty which extracts the raw query as you pointed out. The challenge is to get the string that Netty uses (and is returned by |
||
|
|
||
| </project> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <features name="org.openhab.binding.worxlandroid-${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-worxlandroid" description="Worx Landroid Binding" version="${project.version}"> | ||
| <feature>openhab-runtime-base</feature> | ||
| <bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.worxlandroid/${project.version}</bundle> | ||
lsiepel marked this conversation as resolved.
Show resolved
Hide resolved
lsiepel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <bundle dependency="true">mvn:org.openhab.osgiify/software.amazon.awssdk.iotdevicesdk.aws-iot-device-sdk/1.27.4</bundle> | ||
| </feature> | ||
| </features> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| /* | ||
| * Copyright (c) 2010-2025 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.worxlandroid.internal; | ||
|
|
||
| import java.util.Set; | ||
|
|
||
| import org.eclipse.jdt.annotation.NonNullByDefault; | ||
| import org.openhab.core.thing.ThingTypeUID; | ||
|
|
||
| /** | ||
| * The {@link WorxLandroidBindingConstants} class defines datCommon constants, which are | ||
| * used across the whole binding. | ||
| * | ||
| * @author Nils Billing - Initial contribution | ||
| */ | ||
| @NonNullByDefault | ||
| public class WorxLandroidBindingConstants { | ||
|
|
||
| public static final String BINDING_ID = "worxlandroid"; | ||
|
|
||
| // List of all Thing Type UIDs | ||
| public static final ThingTypeUID THING_TYPE_BRIDGE = new ThingTypeUID(BINDING_ID, "bridge"); | ||
| public static final ThingTypeUID THING_TYPE_MOWER = new ThingTypeUID(BINDING_ID, "mower"); | ||
|
|
||
| public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_MOWER); | ||
|
|
||
| // Channel group ids | ||
| public static final String GROUP_COMMON = "common"; | ||
| public static final String GROUP_CONFIG = "config"; | ||
| public static final String GROUP_MULTI_ZONES = "multi-zones"; | ||
| public static final String GROUP_SCHEDULE = "schedule"; | ||
| public static final String GROUP_ONE_TIME = "one-time"; | ||
| public static final String GROUP_BATTERY = "battery"; | ||
| public static final String GROUP_ORIENTATION = "orientation"; | ||
| public static final String GROUP_METRICS = "metrics"; | ||
| public static final String GROUP_RAIN = "rain"; | ||
| public static final String GROUP_WIFI = "wifi"; | ||
| public static final String GROUP_AWS = "aws"; | ||
|
|
||
| // List channel ids | ||
| // common | ||
| public static final String CHANNEL_ONLINE_TIMESTAMP = "online-timestamp"; | ||
| public static final String CHANNEL_ACTION = "action"; | ||
| public static final String CHANNEL_ENABLE = "enable"; | ||
| public static final String CHANNEL_ONLINE = "online"; | ||
| public static final String CHANNEL_LOCK = "lock"; | ||
| public static final String CHANNEL_RSSI = "rssi"; | ||
|
|
||
| // AWS | ||
| public static final String CHANNEL_POLL = "poll"; | ||
| public static final String CHANNEL_CONNECTED = "connected"; | ||
|
|
||
| // cfgCommon | ||
| public static final String CHANNEL_TIMESTAMP = "timestamp"; | ||
| public static final String CHANNEL_COMMAND = "command"; | ||
| public static final String CHANNEL_DELAY = "delay"; | ||
|
|
||
| // cfgSc | ||
| public static final String CHANNEL_TIME_EXTENSION = "time-extension"; | ||
| public static final String CHANNEL_MODE = "mode"; | ||
| public static final String CHANNEL_START = "next-start"; | ||
| public static final String CHANNEL_STOP = "next-stop"; | ||
|
|
||
| // cfgScXXXday | ||
| public static final String CHANNEL_DURATION = "duration"; | ||
| public static final String CHANNEL_EDGECUT = "edgecut"; | ||
| public static final String CHANNEL_TIME = "time"; | ||
|
|
||
| // datCommon | ||
| public static final String CHANNEL_WIFI_QUALITY = "wifi-quality"; | ||
| public static final String CHANNEL_LAST_ZONE = "last-zone"; | ||
| public static final String CHANNEL_STATUS_CODE = "status"; | ||
| public static final String CHANNEL_ERROR_CODE = "error"; | ||
|
|
||
| // datBattery | ||
| public static final String CHANNEL_TEMPERATURE = "temperature"; | ||
| public static final String CHANNEL_VOLTAGE = "voltage"; | ||
| public static final String CHANNEL_LEVEL = "level"; | ||
| public static final String CHANNEL_CHARGE_CYCLES = "charge-cycles"; | ||
| public static final String CHANNEL_CHARGE_CYCLES_TOTAL = "charge-cycles-total"; | ||
| public static final String CHANNEL_CHARGING = "charging"; | ||
|
|
||
| // datDmp | ||
| public static final String CHANNEL_PITCH = "pitch"; | ||
| public static final String CHANNEL_ROLL = "roll"; | ||
| public static final String CHANNEL_YAW = "yaw"; | ||
|
|
||
| // datSt | ||
| public static final String CHANNEL_BLADE_TIME = "blade-time"; | ||
| public static final String CHANNEL_BLADE_TIME_TOTAL = "blade-time-total"; | ||
| public static final String CHANNEL_DISTANCE = "distance"; | ||
| public static final String CHANNEL_TOTAL_TIME = "total-time"; | ||
|
|
||
| // datRain | ||
| public static final String CHANNEL_RAIN_STATE = "state"; | ||
| public static final String CHANNEL_RAIN_COUNTER = "counter"; | ||
|
|
||
| public static final String CHANNEL_PREFIX_ALLOCATION = "allocation-%d"; | ||
| public static final String CHANNEL_PREFIX_ZONE = "zone-%d"; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| /* | ||
| * Copyright (c) 2010-2025 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.worxlandroid.internal; | ||
|
|
||
| import static org.openhab.binding.worxlandroid.internal.WorxLandroidBindingConstants.*; | ||
|
|
||
| import java.util.HashMap; | ||
| import java.util.Hashtable; | ||
| import java.util.Map; | ||
| import java.util.Set; | ||
|
|
||
| import org.eclipse.jdt.annotation.NonNullByDefault; | ||
| import org.eclipse.jdt.annotation.Nullable; | ||
| import org.openhab.binding.worxlandroid.internal.api.WorxApiHandler; | ||
| import org.openhab.binding.worxlandroid.internal.discovery.MowerDiscoveryService; | ||
| import org.openhab.binding.worxlandroid.internal.handler.WorxLandroidBridgeHandler; | ||
| import org.openhab.binding.worxlandroid.internal.handler.WorxLandroidMowerHandler; | ||
| import org.openhab.core.auth.client.oauth2.OAuthFactory; | ||
| import org.openhab.core.config.discovery.DiscoveryService; | ||
| 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 WorxLandroidHandlerFactory} is responsible for creating things and thing | ||
| * handlers. | ||
| * | ||
| * @author Nils Billing - Initial contribution | ||
| * @author Gaël L'hopital - Added oAuthFactory | ||
| */ | ||
| @NonNullByDefault | ||
| @Component(configurationPid = "binding.worxlandroid", service = ThingHandlerFactory.class) | ||
| public class WorxLandroidHandlerFactory extends BaseThingHandlerFactory { | ||
| private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_MOWER, THING_TYPE_BRIDGE); | ||
|
|
||
| private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>(); | ||
| private final OAuthFactory oAuthFactory; | ||
| private final WorxApiHandler worxApiHandler; | ||
|
|
||
| @Activate | ||
| public WorxLandroidHandlerFactory(final @Reference OAuthFactory oAuthFactory, | ||
| final @Reference WorxApiHandler worxApiHandler) { | ||
| this.oAuthFactory = oAuthFactory; | ||
| this.worxApiHandler = worxApiHandler; | ||
| } | ||
|
|
||
| @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_BRIDGE.equals(thingTypeUID)) { | ||
| WorxLandroidBridgeHandler bridgeHandler = new WorxLandroidBridgeHandler((Bridge) thing, worxApiHandler, | ||
| oAuthFactory); | ||
| MowerDiscoveryService discoveryService = new MowerDiscoveryService(bridgeHandler); | ||
| discoveryServiceRegs.put(thing.getUID(), bundleContext.registerService(DiscoveryService.class.getName(), | ||
| discoveryService, new Hashtable<>())); | ||
|
|
||
| return bridgeHandler; | ||
| } else if (THING_TYPE_MOWER.equals(thingTypeUID)) { | ||
| return new WorxLandroidMowerHandler(thing, worxApiHandler.getDeserializer()); | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| @Override | ||
| protected void removeHandler(ThingHandler handler) { | ||
| if (handler instanceof WorxLandroidBridgeHandler) { | ||
| ServiceRegistration<?> serviceReg = discoveryServiceRegs.remove(handler.getThing().getUID()); | ||
| if (serviceReg != null) { | ||
| serviceReg.unregister(); | ||
| } | ||
| } | ||
| super.removeHandler(handler); | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.