[robonect] Add blade status channel (#15061)

* Add blade status channel in Robonect binding

Signed-off-by: Christian Jonak-Möchel <christian@jonak.org>
Signed-off-by: Leo Siepel <leosiepel@gmail.com>
This commit is contained in:
Christian Jonak-Möchel 2024-10-16 20:58:02 +02:00 committed by GitHub
parent 926f680622
commit 896abdbf5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 171 additions and 38 deletions

View File

@ -45,7 +45,7 @@ Thing robonect:mower:automower "Mower" @ "Garden" [ host="192.168.2.1", pollInte
## Channels
| Channel ID | Item Type | Description |
|------------------------------|-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|---------------------------|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name` | String | Retrieves or sets the name of the mower |
| `battery` | Number | Retrieves the current battery status in percent |
| `status-duration` | Number | Retrieves the duration of the current status (see `status`) of the mower |
@ -66,6 +66,9 @@ Thing robonect:mower:automower "Mower" @ "Garden" [ host="192.168.2.1", pollInte
| `last-error-date` | DateTime | The date and time of the last error happened |
| `health-temperature` | Number | The temperature of the mower (just available for robonect firmware >= 1.0) |
| `health-humidity` | Number | The humidity of the mower (just available for robonect firmware >= 1.0) |
| `blades-quality` | Number:Dimensionless | The quality of the blades |
| `blades-replacement-days` | Number:Time | The number of days since the blades have been changed |
| `blades-usage-hours` | Number:Time | The usage time in hours of the blades |
### Offline Trigger Channel
@ -97,6 +100,9 @@ Switch mowerOneHourJob "Start mowing for one hour from now" {
Number mowerErrorCode "Error code" {channel="robonect:mower:automower:error-code"}
String mowerErrorMessage "Error message" {channel="robonect:mower:automower:error-message"}
DateTime mowerErrorDate "Error date [%1$td/%1$tm %1$tH:%1$tM]" {channel="robonect:mower:automower:error-date"}
Number:Dimensionless mowerBladesQuality "Blades quality [%d %%]" {channel="robonect:mower:automower:blades-quality"}
Number:Time mowerBladesDays "Days since last blade change [%d d]" {channel="robonect:mower:automower:blades-replacement-days"}
Number:Time mowerBladesHours "Blades usage in hours [%d h]" {channel="robonect:mower:automower:blades-usage-hours"}
```
Map transformation for mower status (`robonect_status.map`)

View File

@ -54,6 +54,10 @@ public class RobonectBindingConstants {
public static final String CHANNEL_HEALTH_TEMP = "health-temperature";
public static final String CHANNEL_HEALTH_HUM = "health-humidity";
public static final String CHANNEL_BLADES_QUALITY = "blades-quality";
public static final String CHANNEL_BLADES_REPL_DAYS = "blades-replacement-days";
public static final String CHANNEL_BLADES_USAGE_HOURS = "blades-usage-hours";
public static final String PROPERTY_COMPILED = "compiled";
public static final String PROPERTY_COMMENT = "comment";
}

View File

@ -248,6 +248,11 @@ public class RobonectHandler extends BaseThingHandler {
new QuantityType<>(info.getHealth().getTemperature(), SIUnits.CELSIUS));
updateState(CHANNEL_HEALTH_HUM, new QuantityType<>(info.getHealth().getHumidity(), Units.PERCENT));
}
if (info.getBlades() != null) {
updateState(CHANNEL_BLADES_QUALITY, new QuantityType<>(info.getBlades().getQuality(), Units.PERCENT));
updateState(CHANNEL_BLADES_REPL_DAYS, new QuantityType<>(info.getBlades().getDays(), Units.DAY));
updateState(CHANNEL_BLADES_USAGE_HOURS, new QuantityType<>(info.getBlades().getHours(), Units.HOUR));
}
if (info.getTimer() != null) {
if (info.getTimer().getNext() != null) {
updateNextTimer(info);

View File

@ -0,0 +1,51 @@
/**
* Copyright (c) 2010-2024 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.robonect.internal.model;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* Blade information from the mower.
*
* @author Christian Jonak-Moechel - Initial contribution
*/
@NonNullByDefault
public class Blades {
private int quality;
private int hours;
private int days;
/**
* @return - the quality of the blades in %.
*/
public int getQuality() {
return quality;
}
/**
* @return - the hours of how many days the blades have been actively in use
*/
public int getHours() {
return hours;
}
/**
* @return - the days since the blades have been changed the last time
*/
public int getDays() {
return days;
}
}

View File

@ -25,6 +25,7 @@ public class MowerInfo extends RobonectAnswer {
private Timer timer;
private Wlan wlan;
private Health health;
private Blades blades;
private ErrorEntry error;
/**
@ -69,6 +70,13 @@ public class MowerInfo extends RobonectAnswer {
return health;
}
/**
* @return - the blades status information.
*/
public Blades getBlades() {
return blades;
}
public void setName(String name) {
this.name = name;
}
@ -89,6 +97,10 @@ public class MowerInfo extends RobonectAnswer {
this.health = health;
}
public void setBlades(Blades blades) {
this.blades = blades;
}
public void setError(ErrorEntry error) {
this.error = error;
}

View File

@ -31,6 +31,12 @@ thing-type.config.robonect.mower.user.description = The user id if authenticatio
# channel types
channel-type.robonect.blades-quality.label = Blade Quality
channel-type.robonect.blades-quality.description = The quality of the blades
channel-type.robonect.blades-replacement-days.label = Blade In Use Days
channel-type.robonect.blades-replacement-days.description = The number of days since the blades have been replaced
channel-type.robonect.blades-usage-hours.label = Blade Usage Hours
channel-type.robonect.blades-usage-hours.description = The usage time in hours of the blades
channel-type.robonect.commentType.label = Robonect Firmware Comment
channel-type.robonect.compiledType.label = Robonect Version
channel-type.robonect.distanceType.label = Status Distance

View File

@ -45,6 +45,10 @@
<channel id="health-temperature" typeId="temperatureType"/>
<channel id="health-humidity" typeId="humidityType"/>
<channel id="blades-quality" typeId="blades-quality"/>
<channel id="blades-replacement-days" typeId="blades-replacement-days"/>
<channel id="blades-usage-hours" typeId="blades-usage-hours"/>
</channels>
<properties>
@ -52,6 +56,7 @@
<property name="firmwareVersion">N/A</property>
<property name="compiled">N/A</property>
<property name="serialNumber">N/A</property>
<property name="thingTypeVersion">1</property>
</properties>
<config-description>
@ -155,6 +160,27 @@
<state readOnly="true" pattern="%d %%"/>
</channel-type>
<channel-type id="blades-quality">
<item-type unitHint="%">Number:Dimensionless</item-type>
<label>Blade Quality</label>
<description>The quality of the blades</description>
<state readOnly="true" pattern="%d %%"/>
</channel-type>
<channel-type id="blades-usage-hours">
<item-type unitHint="h">Number:Time</item-type>
<label>Blade Usage Hours</label>
<description>The usage time in hours of the blades</description>
<state readOnly="true" pattern="%d %unit%"/>
</channel-type>
<channel-type id="blades-replacement-days">
<item-type unitHint="d">Number:Time</item-type>
<label>Blade In Use Days</label>
<description>The number of days since the blades have been replaced</description>
<state readOnly="true" pattern="%d %unit%"/>
</channel-type>
<channel-type id="modeType">
<item-type>String</item-type>
<label>Mower Mode</label>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
<thing-type uid="robonect:mower">
<instruction-set targetVersion="1">
<add-channel id="blades-quality">
<type>robonect:blades-quality</type>
</add-channel>
<add-channel id="blades-usage-hours">
<type>robonect:blades-usage-hours</type>
</add-channel>
<add-channel id="blades-replacement-days">
<type>robonect:blades-replacement-days</type>
</add-channel>
</instruction-set>
</thing-type>
</update:update-descriptions>

View File

@ -79,7 +79,7 @@ public class ModelParserTest {
@Test
public void shouldParseCorrectStatusModelWithHealth() {
String correctModel = "{ \"successful\": true, \"name\": \"Rosenlund Automower\", \"status\": { \"status\": 4, \"stopped\": false, \"duration\": 47493, \"mode\": 0, \"battery\": 20, \"hours\": 991 }, \"timer\": { \"status\": 2, \"next\": { \"date\": \"30.07.2017\", \"time\": \"13:00:00\", \"unix\": 1501419600 } }, \"wlan\": { \"signal\": -66 }, \"health\": { \"temperature\": 28, \"humidity\": 32 } }";
String correctModel = "{ \"successful\": true, \"name\": \"Rosenlund Automower\", \"status\": { \"status\": 4, \"stopped\": false, \"duration\": 47493, \"mode\": 0, \"battery\": 20, \"hours\": 991 }, \"timer\": { \"status\": 2, \"next\": { \"date\": \"30.07.2017\", \"time\": \"13:00:00\", \"unix\": 1501419600 } }, \"blades\": {\"quality\": 9, \"hours\": 183, \"days\": 76}, \"wlan\": { \"signal\": -66 }, \"health\": { \"temperature\": 28, \"humidity\": 32 } }";
MowerInfo mowerInfo = subject.parse(correctModel, MowerInfo.class);
assertTrue(mowerInfo.isSuccessful());
assertEquals("Rosenlund Automower", mowerInfo.getName());
@ -98,6 +98,9 @@ public class ModelParserTest {
assertNotNull(mowerInfo.getHealth());
assertEquals(28, mowerInfo.getHealth().getTemperature());
assertEquals(32, mowerInfo.getHealth().getHumidity());
assertEquals(9, mowerInfo.getBlades().getQuality());
assertEquals(76, mowerInfo.getBlades().getDays());
assertEquals(183, mowerInfo.getBlades().getHours());
// "health": { "temperature": 28, "humidity": 32 }
}