Skip to content
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

[mielecloud] Initial contribution of the Miele Cloud binding #9146

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
0a9ed5b
Initial contribution of the Miele Cloud binding
Nov 27, 2020
98f90ac
Removed references to Paper UI from README
Dec 1, 2020
892ca3f
Move property extraction to own class
Dec 2, 2020
07a04d0
Remove plate_is_present channels
Dec 3, 2020
e89cf43
Add plateCount property to hob discovery results
Dec 3, 2020
0a181a7
Refactorings to improve code quality
Dec 3, 2020
e61005d
Fix compile errors in integration tests
Dec 3, 2020
fceb1fc
Update thing properties on device status update
Dec 3, 2020
364402b
Fix spotless checks
Dec 3, 2020
0394f28
Remove accessToken from documentation images
Dec 4, 2020
0f36349
plateCount property changes for README
Dec 4, 2020
7f0f469
Corrected capitalization in feature.xml
Dec 4, 2020
d866dee
Fixed build warnings for README
Dec 4, 2020
5c8aeeb
Remove unnecessary @NonNullByDefault annotations
Dec 4, 2020
b527daf
Use constructor instead of method injection
Dec 4, 2020
72272d9
Lists instead of tables for channel IDs in README
Dec 9, 2020
9c8a840
Use UoM for temperatures
Dec 9, 2020
b01fdae
Corrected binding name in pom.xml
Dec 9, 2020
a546148
Use constructor injection for handler factory
Dec 9, 2020
185175c
Catch specific exceptions
Dec 9, 2020
d3343af
Adapted logging according to guidelines
Dec 11, 2020
e2cd6d4
Replace fixed delay with check of inbox
Dec 11, 2020
f30dd1e
Use Set.of
Dec 11, 2020
11814dd
Apply review comments in AbstractMieleThingHandler
Dec 11, 2020
8111513
Use execute rather than schedule
Dec 11, 2020
046772b
No immediate loading of handler factory
Dec 11, 2020
546c21a
Use ThingHandlerService for thing discovery
Dec 11, 2020
8ebd0a7
Remove obsolete OptionalUtils
Dec 11, 2020
82d120e
Remove deprecated author tag
Dec 11, 2020
ae14209
Removed obsolete config description
Dec 11, 2020
2eb9762
Capitalize and shorten labels
Dec 11, 2020
39d26bd
Use required attribute instead of tag
Dec 11, 2020
7e54fef
Use Number instead of Number:Time
Dec 11, 2020
84b365c
Use Number:Temperature type for temperatures
Dec 11, 2020
3ff53fc
Error message for transient HTTP errors
Dec 18, 2020
79a4026
Remove minified js and css files
Dec 18, 2020
c429eab
Fix some build warnings
Dec 18, 2020
c2cd6d1
Remove access token from auto pairing
Dec 21, 2020
4ab527d
Fix typo in README
Dec 21, 2020
4241bad
Added acknowledgement note to README
Dec 22, 2020
1825e14
Use DEBUG/WARN rather than INFO log level
Dec 24, 2020
5894439
Additional logging for Retry-After parsing
Feb 1, 2021
1b895b5
Limit retry connect interval in all cases
Feb 1, 2021
81ff50d
Add test for Retry-After header exceeding maximum SSE reconnect wait …
Feb 1, 2021
d5c9d14
Remove outdated information from README
Feb 3, 2021
65e80aa
Upgrade to openHAB 3.1.0
Feb 15, 2021
b9d1a64
Conditional logging on enabled debug
Feb 15, 2021
bd29b93
Use static final Gson
Feb 15, 2021
4b54d7e
Nullable annotation as part of the type
Feb 15, 2021
16273c3
Consistent use of StringBuilder in ThingsTemplateGenerator
Feb 15, 2021
543538e
Include cause exception
Feb 15, 2021
f5154e6
Include cause message
Feb 15, 2021
687408e
More nullable annotations on types
Feb 15, 2021
e9058d6
Fix unit tests broken by logging adaption
Apr 12, 2021
dbe2886
Fix logging performance warning
Apr 12, 2021
da95ff1
Update integration test run configuration
Apr 12, 2021
dde3d3c
Remove logo from README
Apr 23, 2021
0254fe5
Remove example thing file in favor of full example
Apr 23, 2021
abf4247
Remove outdated note about locale parameter
Apr 23, 2021
f9ab516
Remove other ithings file example
Apr 23, 2021
e183560
Add table with technical thing types
Apr 23, 2021
3ca02d4
Remove warning logs when account is not authorized
Apr 23, 2021
46bb587
Things use just OFFLINE if the reason is unclear
Apr 23, 2021
ce10358
Remove updateStatus workaround
Apr 28, 2021
5198874
handleConfigurationUpdate reinitializes the bridge
Apr 30, 2021
594c940
Locale parameter is not required
Apr 30, 2021
7389bf9
Add required e-mail address config param
May 21, 2021
ffcb467
Add device identifier config param
May 21, 2021
2bd65a6
Do not call framework methods for reinit
May 21, 2021
9d52296
Add integration test for e-mail address validity
May 25, 2021
2f3d31b
Update documentation
May 25, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
/bundles/org.openhab.binding.meteoblue/ @9037568
/bundles/org.openhab.binding.meteostick/ @cdjackson
/bundles/org.openhab.binding.miele/ @kgoderis
/bundles/org.openhab.binding.mielecloud/ @BjoernLange
/bundles/org.openhab.binding.mihome/ @pboos
/bundles/org.openhab.binding.miio/ @marcelrv
/bundles/org.openhab.binding.milight/ @davidgraeff
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 @@ -811,6 +811,11 @@
<artifactId>org.openhab.binding.miele</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.mielecloud</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.mihome</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.binding.mielecloud/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
623 changes: 623 additions & 0 deletions bundles/org.openhab.binding.mielecloud/README.md

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions bundles/org.openhab.binding.mielecloud/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.1.0-SNAPSHOT</version>
</parent>

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

<name>openHAB Add-ons :: Bundles :: Miele Cloud Binding</name>

</project>
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.mielecloud-${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-mielecloud" description="Miele Cloud Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.mielecloud/${project.version}</bundle>
</feature>
</features>
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
/**
* Copyright (c) 2010-2021 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.mielecloud.internal;

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

/**
* The {@link MieleCloudBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Roland Edelhoff - Initial contribution
* @author Björn Lange - Added locale config parameter, added i18n key collection
* @author Benjamin Bolte - Add pre-heat finished and plate step channels, door state and door alarm channels, info
* state channel and map signal flags from API
* @author Björn Lange - Add elapsed time channel, dish warmer thing
*/
@NonNullByDefault
public final class MieleCloudBindingConstants {

private MieleCloudBindingConstants() {
}

/**
* ID of the binding.
*/
public static final String BINDING_ID = "mielecloud";

/**
* Thing type ID of Miele cloud bridges / accounts.
*/
public static final String BRIDGE_TYPE_ID = "account";

/**
* The {@link ThingTypeUID} of Miele cloud bridges / accounts.
*/
public static final ThingTypeUID THING_TYPE_BRIDGE = new ThingTypeUID(BINDING_ID, BRIDGE_TYPE_ID);

/**
* The {@link ThingTypeUID} of Miele washing machines.
*/
public static final ThingTypeUID THING_TYPE_WASHING_MACHINE = new ThingTypeUID(BINDING_ID, "washing_machine");

/**
* The {@link ThingTypeUID} of Miele washer-dryers.
*/
public static final ThingTypeUID THING_TYPE_WASHER_DRYER = new ThingTypeUID(BINDING_ID, "washer_dryer");

/**
* The {@link ThingTypeUID} of Miele coffee machines.
*/
public static final ThingTypeUID THING_TYPE_COFFEE_SYSTEM = new ThingTypeUID(BINDING_ID, "coffee_system");

/**
* The {@link ThingTypeUID} of Miele fridge-freezers.
*/
public static final ThingTypeUID THING_TYPE_FRIDGE_FREEZER = new ThingTypeUID(BINDING_ID, "fridge_freezer");

/**
* The {@link ThingTypeUID} of Miele fridges.
*/
public static final ThingTypeUID THING_TYPE_FRIDGE = new ThingTypeUID(BINDING_ID, "fridge");

/**
* The {@link ThingTypeUID} of Miele freezers.
*/
public static final ThingTypeUID THING_TYPE_FREEZER = new ThingTypeUID(BINDING_ID, "freezer");

/**
* The {@link ThingTypeUID} of Miele ovens.
*/
public static final ThingTypeUID THING_TYPE_OVEN = new ThingTypeUID(BINDING_ID, "oven");

/**
* The {@link ThingTypeUID} of Miele hobs.
*/
public static final ThingTypeUID THING_TYPE_HOB = new ThingTypeUID(BINDING_ID, "hob");

/**
* The {@link ThingTypeUID} of Miele wine storages.
*/
public static final ThingTypeUID THING_TYPE_WINE_STORAGE = new ThingTypeUID(BINDING_ID, "wine_storage");

/**
* The {@link ThingTypeUID} of Miele dishwashers.
*/
public static final ThingTypeUID THING_TYPE_DISHWASHER = new ThingTypeUID(BINDING_ID, "dishwasher");

/**
* The {@link ThingTypeUID} of Miele dryers.
*/
public static final ThingTypeUID THING_TYPE_DRYER = new ThingTypeUID(BINDING_ID, "dryer");

/**
* The {@link ThingTypeUID} of Miele hoods.
*/
public static final ThingTypeUID THING_TYPE_HOOD = new ThingTypeUID(BINDING_ID, "hood");

/**
* The {@link ThingTypeUID} of Miele dish warmers.
*/
public static final ThingTypeUID THING_TYPE_DISH_WARMER = new ThingTypeUID(BINDING_ID, "dish_warmer");

/**
* The {@link ThingTypeUID} of Miele robotic vacuum cleaners.
*/
public static final ThingTypeUID THING_TYPE_ROBOTIC_VACUUM_CLEANER = new ThingTypeUID(BINDING_ID,
"robotic_vacuum_cleaner");

/**
* Name of the property storing the OAuth2 access token.
*/
public static final String PROPERTY_ACCESS_TOKEN = "accessToken";

/**
* Name of the configuration parameter for the e-mail address.
*/
public static final String CONFIG_PARAM_EMAIL = "email";

/**
* Name of the configuration parameter for the device identifier uniquely identifying a Miele device.
*/
public static final String CONFIG_PARAM_DEVICE_IDENTIFIER = "deviceIdentifier";

/**
* Name of the configuration parameter for the locale. The locale is stored as a 2-letter language code.
*/
public static final String CONFIG_PARAM_LOCALE = "locale";

/**
* Name of the property storing the number of plates for hobs.
*/
public static final String PROPERTY_PLATE_COUNT = "plateCount";

/**
* Constants for all channels.
*/
public static final class Channels {
private Channels() {
}

public static final String REMOTE_CONTROL_CAN_BE_STARTED = "remote_control_can_be_started";
public static final String REMOTE_CONTROL_CAN_BE_STOPPED = "remote_control_can_be_stopped";
public static final String REMOTE_CONTROL_CAN_BE_PAUSED = "remote_control_can_be_paused";
public static final String REMOTE_CONTROL_CAN_BE_SWITCHED_ON = "remote_control_can_be_switched_on";
public static final String REMOTE_CONTROL_CAN_BE_SWITCHED_OFF = "remote_control_can_be_switched_off";
public static final String REMOTE_CONTROL_CAN_SET_PROGRAM_ACTIVE = "remote_control_can_set_program_active";
public static final String SPINNING_SPEED = "spinning_speed";
public static final String SPINNING_SPEED_RAW = "spinning_speed_raw";
public static final String PROGRAM_ACTIVE = "program_active";
public static final String PROGRAM_ACTIVE_RAW = "program_active_raw";
public static final String DISH_WARMER_PROGRAM_ACTIVE = "dish_warmer_program_active";
public static final String VACUUM_CLEANER_PROGRAM_ACTIVE = "vacuum_cleaner_program_active";
public static final String PROGRAM_PHASE = "program_phase";
public static final String PROGRAM_PHASE_RAW = "program_phase_raw";
public static final String OPERATION_STATE = "operation_state";
public static final String OPERATION_STATE_RAW = "operation_state_raw";
public static final String PROGRAM_START_STOP = "program_start_stop";
public static final String PROGRAM_START_STOP_PAUSE = "program_start_stop_pause";
public static final String POWER_ON_OFF = "power_state_on_off";
public static final String FINISH_STATE = "finish_state";
public static final String DELAYED_START_TIME = "delayed_start_time";
public static final String PROGRAM_REMAINING_TIME = "program_remaining_time";
public static final String PROGRAM_ELAPSED_TIME = "program_elapsed_time";
public static final String PROGRAM_PROGRESS = "program_progress";
public static final String DRYING_TARGET = "drying_target";
public static final String DRYING_TARGET_RAW = "drying_target_raw";
public static final String PRE_HEAT_FINISHED = "pre_heat_finished";
public static final String TEMPERATURE_TARGET = "temperature_target";
public static final String TEMPERATURE_CURRENT = "temperature_current";
public static final String TEMPERATURE_CORE_TARGET = "temperature_core_target";
public static final String TEMPERATURE_CORE_CURRENT = "temperature_core_current";
public static final String VENTILATION_POWER = "ventilation_power";
public static final String VENTILATION_POWER_RAW = "ventilation_power_raw";
public static final String ERROR_STATE = "error_state";
public static final String INFO_STATE = "info_state";
public static final String FRIDGE_SUPER_COOL = "fridge_super_cool";
public static final String FREEZER_SUPER_FREEZE = "freezer_super_freeze";
public static final String SUPER_COOL_CAN_BE_CONTROLLED = "super_cool_can_be_controlled";
public static final String SUPER_FREEZE_CAN_BE_CONTROLLED = "super_freeze_can_be_controlled";
public static final String FRIDGE_TEMPERATURE_TARGET = "fridge_temperature_target";
public static final String FRIDGE_TEMPERATURE_CURRENT = "fridge_temperature_current";
public static final String FREEZER_TEMPERATURE_TARGET = "freezer_temperature_target";
public static final String FREEZER_TEMPERATURE_CURRENT = "freezer_temperature_current";
public static final String TOP_TEMPERATURE_TARGET = "top_temperature_target";
public static final String TOP_TEMPERATURE_CURRENT = "top_temperature_current";
public static final String MIDDLE_TEMPERATURE_TARGET = "middle_temperature_target";
public static final String MIDDLE_TEMPERATURE_CURRENT = "middle_temperature_current";
public static final String BOTTOM_TEMPERATURE_TARGET = "bottom_temperature_target";
public static final String BOTTOM_TEMPERATURE_CURRENT = "bottom_temperature_current";
public static final String LIGHT_SWITCH = "light_switch";
public static final String LIGHT_CAN_BE_CONTROLLED = "light_can_be_controlled";
public static final String PLATE_1_POWER_STEP = "plate_1_power_step";
public static final String PLATE_1_POWER_STEP_RAW = "plate_1_power_step_raw";
public static final String PLATE_2_POWER_STEP = "plate_2_power_step";
public static final String PLATE_2_POWER_STEP_RAW = "plate_2_power_step_raw";
public static final String PLATE_3_POWER_STEP = "plate_3_power_step";
public static final String PLATE_3_POWER_STEP_RAW = "plate_3_power_step_raw";
public static final String PLATE_4_POWER_STEP = "plate_4_power_step";
public static final String PLATE_4_POWER_STEP_RAW = "plate_4_power_step_raw";
public static final String PLATE_5_POWER_STEP = "plate_5_power_step";
public static final String PLATE_5_POWER_STEP_RAW = "plate_5_power_step_raw";
public static final String PLATE_6_POWER_STEP = "plate_6_power_step";
public static final String PLATE_6_POWER_STEP_RAW = "plate_6_power_step_raw";
public static final String DOOR_STATE = "door_state";
public static final String DOOR_ALARM = "door_alarm";
public static final String BATTERY_LEVEL = "battery_level";
}

/**
* Constants for i18n keys.
*/
public static final class I18NKeys {
private I18NKeys() {
}

public static final String BRIDGE_STATUS_DESCRIPTION_ACCESS_TOKEN_NOT_CONFIGURED = "@text/mielecloud.bridge.status.access.token.not.configured";
public static final String BRIDGE_STATUS_DESCRIPTION_ACCOUNT_NOT_AUTHORIZED = "@text/mielecloud.bridge.status.account.not.authorized";
public static final String BRIDGE_STATUS_DESCRIPTION_ACCESS_TOKEN_REFRESH_FAILED = "@text/mielecloud.bridge.status.access.token.refresh.failed";
public static final String BRIDGE_STATUS_DESCRIPTION_INVALID_EMAIL = "@text/mielecloud.bridge.status.invalid.email";
public static final String BRIDGE_STATUS_DESCRIPTION_TRANSIENT_HTTP_ERROR = "@text/mielecloud.bridge.status.transient.http.error";

public static final String THING_STATUS_DESCRIPTION_WEBSERVICE_MISSING = "@text/mielecloud.thing.status.webservice.missing";
public static final String THING_STATUS_DESCRIPTION_REMOVED = "@text/mielecloud.thing.status.removed";
public static final String THING_STATUS_DESCRIPTION_RATELIMIT = "@text/mielecloud.thing.status.ratelimit";
public static final String THING_STATUS_DESCRIPTION_DISCONNECTED = "@text/mielecloud.thing.status.disconnected";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2010-2021 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.mielecloud.internal.auth;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Indicates an error in the OAuth2 authorization process.
*
* @author Roland Edelhoff - Initial contribution
*/
@NonNullByDefault
public class OAuthException extends RuntimeException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you make this an unchecked exception by intention?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we actually prefer unchecked exceptions. Shall we change it to a checked one?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would fit better to the other code in this repo, but I won't insist on it. As you're using many lambdas converting could be painful.

private static final long serialVersionUID = -1863609233382694104L;

public OAuthException(final String message) {
super(message);
}

public OAuthException(final String message, final Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright (c) 2010-2021 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.mielecloud.internal.auth;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Listener that is invoked when an OAuth 2 access token was refreshed.
*
* @author Björn Lange - Initial contribution
*/
@NonNullByDefault
public interface OAuthTokenRefreshListener {
/**
* Invoked when a new access token becomes available.
*
* @param accessToken The new access token.
*/
public void onNewAccessToken(String accessToken);
}
Loading