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

[surepetcare] added waterstation Felaqua #18114

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
508 changes: 363 additions & 145 deletions bundles/org.openhab.binding.surepetcare/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ public class SurePetcareConstants {
public static final ThingTypeUID THING_TYPE_HUB_DEVICE = new ThingTypeUID(BINDING_ID, "hubDevice");
public static final ThingTypeUID THING_TYPE_FLAP_DEVICE = new ThingTypeUID(BINDING_ID, "flapDevice");
public static final ThingTypeUID THING_TYPE_FEEDER_DEVICE = new ThingTypeUID(BINDING_ID, "feederDevice");
public static final ThingTypeUID THING_TYPE_WATER_DEVICE = new ThingTypeUID(BINDING_ID, "waterDevice");

public static final Set<ThingTypeUID> BRIDGE_THING_TYPES_UIDS = Set.of(THING_TYPE_BRIDGE);
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = new HashSet<>(Arrays.asList(THING_TYPE_HOUSEHOLD,
THING_TYPE_PET, THING_TYPE_HUB_DEVICE, THING_TYPE_FLAP_DEVICE, THING_TYPE_FEEDER_DEVICE));
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = new HashSet<>(
Arrays.asList(THING_TYPE_HOUSEHOLD, THING_TYPE_PET, THING_TYPE_HUB_DEVICE, THING_TYPE_FLAP_DEVICE,
THING_TYPE_FEEDER_DEVICE, THING_TYPE_WATER_DEVICE));

public static final long DEFAULT_REFRESH_INTERVAL_TOPOLOGY = 36000; // 10 hours
public static final long DEFAULT_REFRESH_INTERVAL_STATUS = 300; // 5 mins
Expand Down Expand Up @@ -122,4 +124,7 @@ public class SurePetcareConstants {
public static final String PET_CHANNEL_FEEDER_LAST_CHANGE = "feederLastChange";
public static final String PET_CHANNEL_FEEDER_LAST_CHANGE_LEFT = "feederLastChangeLeft";
public static final String PET_CHANNEL_FEEDER_LAST_CHANGE_RIGHT = "feederLastChangeRight";
public static final String PET_CHANNEL_WATER_DEVICE = "waterDevice";
public static final String PET_CHANNEL_WATER_LASTDRINKING = "waterLastDrinking";
public static final String PET_CHANNEL_WATER_LAST_CHANGE = "waterLastChange";
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return new SurePetcareDeviceHandler(thing, petcareAPI);
} else if (thingTypeUID.equals(THING_TYPE_FEEDER_DEVICE)) {
return new SurePetcareDeviceHandler(thing, petcareAPI);
} else if (thingTypeUID.equals(THING_TYPE_WATER_DEVICE)) {
return new SurePetcareDeviceHandler(thing, petcareAPI);
} else if (thingTypeUID.equals(THING_TYPE_PET)) {
return new SurePetcarePetHandler(thing, petcareAPI);
} else if (thingTypeUID.equals(THING_TYPE_BRIDGE)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ private void deviceDiscovered(SurePetcareDevice device) {
case PET_FEEDER:
typeUID = THING_TYPE_FEEDER_DEVICE;
break;
case PET_WATER:
typeUID = THING_TYPE_WATER_DEVICE;
break;
case UNKNOWN:
default:
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public enum ProductType {
HUB(1, "Hub"),
PET_FLAP(3, "Pet Flap"),
PET_FEEDER(4, "Pet Feeder"),
CAT_FLAP(6, "Cat Flap");
CAT_FLAP(6, "Cat Flap"),
PET_WATER(8, "Waterstation");

public final Integer id;
public final String name;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.surepetcare.internal.dto;

import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.annotations.SerializedName;

/**
* The {@link SurePetcarePetDrinking} is the Java class used to represent the
* status of a pet. It's used to deserialize JSON API results.
*
* @author Rene Scherer - Initial contribution
* @author Holger Eisold - Added pet feeder status, waterstation
*/
public class SurePetcarePetDrinking {

public Long tagId;
public Long deviceId;
@SerializedName("change")
public List<Float> drinkChange = new ArrayList<>();
@SerializedName("at")
public ZonedDateTime drinkChangeAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ public class SurePetcarePetStatus {

public SurePetcarePetActivity activity;
public SurePetcarePetFeeding feeding;
public SurePetcarePetDrinking drinking;
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,17 @@ protected void updateThing() {
updateState(DEVICE_CHANNEL_PAIRING_MODE, new StringType(device.status.pairingModeId.toString()));
} else {
float batVol = device.status.battery;
updateState(DEVICE_CHANNEL_BATTERY_VOLTAGE, new DecimalType(batVol));
updateState(DEVICE_CHANNEL_BATTERY_LEVEL, new DecimalType(Math.min(
(batVol - BATTERY_EMPTY_VOLTAGE) / (BATTERY_FULL_VOLTAGE - BATTERY_EMPTY_VOLTAGE) * 100.0f,
100.0f)));
updateState(DEVICE_CHANNEL_BATTERY_VOLTAGE, new QuantityType<>(batVol, Units.VOLT));
updateState(DEVICE_CHANNEL_BATTERY_LEVEL,
new QuantityType<>(
Math.min((batVol - BATTERY_EMPTY_VOLTAGE)
/ (BATTERY_FULL_VOLTAGE - BATTERY_EMPTY_VOLTAGE) * 100.0f, 100.0f),
Units.PERCENT));
updateState(DEVICE_CHANNEL_LOW_BATTERY, OnOffType.from(batVol < LOW_BATTERY_THRESHOLD));
updateState(DEVICE_CHANNEL_DEVICE_RSSI,
QuantityType.valueOf(device.status.signal.deviceRssi, Units.DECIBEL_MILLIWATTS));
new QuantityType<>(device.status.signal.deviceRssi, Units.DECIBEL_MILLIWATTS));
updateState(DEVICE_CHANNEL_HUB_RSSI,
QuantityType.valueOf(device.status.signal.hubRssi, Units.DECIBEL_MILLIWATTS));
new QuantityType<>(device.status.signal.hubRssi, Units.DECIBEL_MILLIWATTS));

if (thing.getThingTypeUID().equals(THING_TYPE_FLAP_DEVICE)) {
updateThingCurfews(device);
Expand Down Expand Up @@ -175,6 +177,8 @@ protected void updateThing() {
new StringType(device.control.lid.closeDelayId.toString()));
updateState(DEVICE_CHANNEL_BOWLS_TRAINING_MODE,
new StringType(device.control.trainingModeId.toString()));
} else if (thing.getThingTypeUID().equals(THING_TYPE_WATER_DEVICE)) {
// TODO
} else {
logger.warn("Unknown product type for device {}", thing.getUID().getAsString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.openhab.binding.surepetcare.internal.dto.SurePetcareHousehold;
import org.openhab.binding.surepetcare.internal.dto.SurePetcarePet;
import org.openhab.binding.surepetcare.internal.dto.SurePetcarePetActivity;
import org.openhab.binding.surepetcare.internal.dto.SurePetcarePetDrinking;
import org.openhab.binding.surepetcare.internal.dto.SurePetcarePetFeeding;
import org.openhab.binding.surepetcare.internal.dto.SurePetcareTag;
import org.openhab.core.cache.ByteArrayFileCache;
Expand All @@ -35,7 +36,9 @@
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.types.RawType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.library.unit.MetricPrefix;
import org.openhab.core.library.unit.SIUnits;
import org.openhab.core.library.unit.Units;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.types.Command;
Expand Down Expand Up @@ -211,6 +214,16 @@ protected void updateThing() {
updateState(PET_CHANNEL_FEEDER_LASTFEEDING, new DateTimeType(feeding.feedChangeAt));
}
}
SurePetcarePetDrinking drinking = pet.status.drinking;
if (drinking != null) {
SurePetcareDevice device = petcareAPI.getDevice(drinking.deviceId.toString());
if (device != null) {
updateState(PET_CHANNEL_WATER_DEVICE, new StringType(device.name));
updateState(PET_CHANNEL_WATER_LAST_CHANGE,
new QuantityType<>(drinking.drinkChange.get(0), MetricPrefix.MILLI(Units.LITRE)));
updateState(PET_CHANNEL_WATER_LASTDRINKING, new DateTimeType(drinking.drinkChangeAt));
}
}
} else {
logger.debug("Trying to update unknown pet: {}", thing.getUID().getId());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<type>binding</type>
<name>Sure Petcare Binding</name>
<description>This binding interacts with the Sure Petcare Connect range of cat flaps and feeders</description>
<description>This binding interacts with the Sure Petcare Connect range of pet/cat flaps, feeders and waterstations</description>
<connection>cloud</connection>

</addon:addon>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
addon.surepetcare.name = Sure Petcare Binding
addon.surepetcare.description = This binding interacts with the Sure Petcare Connect range of cat/pet flaps and feeders
addon.surepetcare.description = This binding interacts with the Sure Petcare Connect range of cat/pet flaps, feeders and waterstations

# bridge-types
thing-type.surepetcare.bridge.label = Sure Petcare API Bridge
Expand Down Expand Up @@ -31,6 +31,9 @@ thing-type.surepetcare.flapDevice.description = A Sure Petcare cat or pet flap d
thing-type.surepetcare.feederDevice.label = Sure Petcare Pet Feeder
thing-type.surepetcare.feederDevice.description = A Sure Petcare pet feeder device.

thing-type.surepetcare.waterDevice.label = Sure Petcare Pet Waterstation
thing-type.surepetcare.waterDevice.description = A Sure Petcare pet waterstation device.

thing-type.surepetcare.pet.label = Sure Petcare Pet
thing-type.surepetcare.pet.description = A Sure Petcare pet.

Expand All @@ -51,12 +54,13 @@ channel-type.surepetcare.timezoneIdType.label = Timezone ID
channel-type.surepetcare.timezoneIdType.description = The identifier of the timezone.

channel-type.surepetcare.productType.label = Product Type
channel-type.surepetcare.productType.description = The type of product this device represents. (0=Unknown, 1=Hub, 3=Pet Flap, 4=Feeder, 6=Cat Flap)
channel-type.surepetcare.productType.description = The type of product this device represents. (0=Unknown, 1=Hub, 3=Pet Flap, 4=Feeder, 6=Cat Flap, 8=Waterstation)
channel-type.surepetcare.productType.state.option.0 = Unknown
channel-type.surepetcare.productType.state.option.1 = Hub
channel-type.surepetcare.productType.state.option.3 = Pet Flap
channel-type.surepetcare.productType.state.option.4 = Pet Feeder
channel-type.surepetcare.productType.state.option.6 = Cat Flap
channel-type.surepetcare.productType.state.option.8 = Waterstation

channel-type.surepetcare.shareCodeType.label = Share Code
channel-type.surepetcare.shareCodeType.description = A unique code provided by Sure Petcare to access photos of pets.
Expand Down Expand Up @@ -195,6 +199,15 @@ channel-type.surepetcare.feederLastChangeLeftType.description = The pet feeding
channel-type.surepetcare.feederLastChangeRightType.label = Pet Feeding Last Change Right
channel-type.surepetcare.feederLastChangeRightType.description = The pet feeding last change right.

channel-type.surepetcare.waterDeviceType.label = Pet Waterstation Device Name
channel-type.surepetcare.waterDeviceType.description = The pet waterstation device name.

channel-type.surepetcare.waterLastDrinkingType.label = Pet Last Drinking
channel-type.surepetcare.waterLastDrinkingType.description = The last pet drinking.

channel-type.surepetcare.waterLastChangeType.label = Pet Drinking Last Change
channel-type.surepetcare.waterLastChangeType.description = The pet drinking last change.

channel-type.surepetcare.lockingModeType.label = Locking Mode
channel-type.surepetcare.lockingModeType.description = The id of the locking mode the flap is currently set to (e.g. in/out, in only, out only, locked)
channel-type.surepetcare.lockingModeType.state.option.0 = Unlocked
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ thing-type.config.surepetcare.bridge.password.label = Sure Petcare Passwort
thing-type.config.surepetcare.bridge.password.description = Sure Petcare Passwort.

thing-type.config.surepetcare.bridge.refreshIntervalStatus.label = Aktualisierungsintervall Haustier Status
thing-type.config.surepetcare.bridge.refreshIntervalStatus.description = Intervall zur Abfrage des Haustier Status (in Sekunden) (mind. 300 / standard 36000).
thing-type.config.surepetcare.bridge.refreshIntervalStatus.description = Intervall zur Abfrage des Haustier Status (in Sekunden) (mind. 300 / standard 300).

thing-type.config.surepetcare.bridge.refreshIntervalTopology.label = Aktualisierungsintervall Topology
thing-type.config.surepetcare.bridge.refreshIntervalTopology.description = Intervall zur Abfrage der Geräte und Haustier Daten (in Sekunden) (mind. 300 / standard 300).
thing-type.config.surepetcare.bridge.refreshIntervalTopology.description = Intervall zur Abfrage der Geräte und Haustier Daten (in Sekunden) (mind. 300 / standard 36000).

# thing-types
thing-type.surepetcare.household.label = Sure Petcare Haushalt
Expand All @@ -31,6 +31,9 @@ thing-type.surepetcare.flapDevice.description = Ein Sure Petcare Gerät (Haustie
thing-type.surepetcare.feederDevice.label = Sure Petcare Gerät (Futterautomat)
thing-type.surepetcare.feederDevice.description = Sure Petcare Gerät (Futterautomat).

thing-type.surepetcare.waterDevice.label = Sure Petcare Gerät (Felaqua - Wasserstation)
thing-type.surepetcare.waterDevice.description = Sure Petcare Gerät (Felaqua - Wasserstation).

thing-type.surepetcare.pet.label = Sure Petcare Haustier
thing-type.surepetcare.pet.description = Ein Sure Petcare Haustier.

Expand All @@ -51,12 +54,13 @@ channel-type.surepetcare.timezoneIdType.label = Zeitzone ID
channel-type.surepetcare.timezoneIdType.description = Zeigt die ID der Zeitzone an.

channel-type.surepetcare.productType.label = Produkt Typ
channel-type.surepetcare.productType.description = Zeigt den Produkt Namen an. \#(0\=unbekannt, 1\=Hub, 3\=Haustierklappe, 4\=Futterautomat, 6\=Katzenklappe)
channel-type.surepetcare.productType.description = Zeigt den Produkt Namen an. \#(0\=unbekannt, 1\=Hub, 3\=Haustierklappe, 4\=Futterautomat, 6\=Katzenklappe, 8\=Wasserstation)
channel-type.surepetcare.productType.state.option.0 = unbekannt
channel-type.surepetcare.productType.state.option.1 = Hub
channel-type.surepetcare.productType.state.option.3 = Haustierklappe
channel-type.surepetcare.productType.state.option.4 = Futterautomat
channel-type.surepetcare.productType.state.option.6 = Katzenklappe
channel-type.surepetcare.productType.state.option.8 = Wasserstation

channel-type.surepetcare.shareCodeType.label = Share Code
channel-type.surepetcare.shareCodeType.description = A unique code provided by Sure Petcare to access photos of pets
Expand Down Expand Up @@ -195,6 +199,15 @@ channel-type.surepetcare.feederLastChangeLeftType.description = Die letzte Futte
channel-type.surepetcare.feederLastChangeRightType.label = Letzte Futteraufnahme Änderung (Rechts)
channel-type.surepetcare.feederLastChangeRightType.description = Die letzte Futteraufnahme Änderung (rechts).

channel-type.surepetcare.waterDeviceType.label = Wasserstation Name
channel-type.surepetcare.waterDeviceType.description = Der Name der Wasserstation.

channel-type.surepetcare.waterLastDrinkingType.label = Letzte Wasseraufnahme
channel-type.surepetcare.waterLastDrinkingType.description = Die letzte Wasseraufnahme.

channel-type.surepetcare.waterLastChangeType.label = Letzte Wasseraufnahme Änderung
channel-type.surepetcare.waterLastChangeType.description = Die letzte Wasseraufnahme Änderung.

channel-type.surepetcare.lockingModeType.label = Sperrmodus
channel-type.surepetcare.lockingModeType.description = Zeigt des Sperrmodus des Gerätes an.
channel-type.surepetcare.lockingModeType.state.option.0 = Entriegelt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
</supported-bridge-type-refs>

<label>Sure Petcare Hub Device</label>
<description>A Sure Petcare hub device (connects cat flaps, feeders etc. to a network)</description>
<description>A Sure Petcare hub device (connects pet/cat flaps, feeders and waterstations to a network)</description>

<channels>
<channel id="id" typeId="idType"/>
Expand Down Expand Up @@ -192,6 +192,40 @@
<representation-property>id</representation-property>
</thing-type>

<thing-type id="waterDevice">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>

<label>Sure Petcare Waterstation Device</label>
<description>A Sure Petcare pet waterstation device</description>

<channels>
<channel id="id" typeId="idType"/>
<channel id="name" typeId="nameType"/>
<channel id="product" typeId="productType"/>
<channel id="lowBattery" typeId="system.low-battery"/>
<channel id="batteryLevel" typeId="system.battery-level"/>
<channel id="batteryVoltage" typeId="batteryVoltageType"/>
<channel id="online" typeId="onlineType"/>
<channel id="deviceRSSI" typeId="rssiDeviceType"/>
<channel id="hubRSSI" typeId="rssiHubType"/>
</channels>

<properties>
<property name="id"/>
<property name="version"/>
<property name="createdAt"/>
<property name="updatedAt"/>
<property name="householdId"/>
<property name="productType"/>
<property name="productName"/>
<property name="pairingAt"/>
<property name="thingTypeVersion">1</property>
</properties>
<representation-property>id</representation-property>
</thing-type>

<thing-type id="pet">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
Expand Down Expand Up @@ -220,6 +254,9 @@
<channel id="feederLastChange" typeId="feederLastChangeType"/>
<channel id="feederLastChangeLeft" typeId="feederLastChangeLeftType"/>
<channel id="feederLastChangeRight" typeId="feederLastChangeRightType"/>
<channel id="waterDevice" typeId="waterDeviceType"/>
<channel id="waterLastDrinking" typeId="waterLastDrinkingType"/>
<channel id="waterLastChange" typeId="waterLastChangeType"/>
</channels>

<properties>
Expand Down Expand Up @@ -272,6 +309,7 @@
<option value="3">Pet Flap</option>
<option value="4">Pet Feeder</option>
<option value="6">Cat Flap</option>
<option value="8">Waterstation</option>
</options>
</state>
</channel-type>
Expand Down Expand Up @@ -527,6 +565,27 @@
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>

<channel-type id="waterDeviceType">
<item-type>String</item-type>
<label>Pet Waterstation Device Name</label>
<description>The pet waterstation device name</description>
<state readOnly="true" pattern="%s"/>
</channel-type>

<channel-type id="waterLastDrinkingType">
<item-type>DateTime</item-type>
<label>Pet Last Drinking</label>
<description>The last pet drinking</description>
<state readOnly="true" pattern="%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS"/>
</channel-type>

<channel-type id="waterLastChangeType">
<item-type>Number:Volume</item-type>
<label>Pet Drinking Last Change</label>
<description>The pet drinking last change</description>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>

<channel-type id="lockingModeType">
<item-type>String</item-type>
<label>Locking Mode</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@
</instruction-set>
</thing-type>

<thing-type uid="surepetcare:waterDevice">
<instruction-set targetVersion="1">
<update-channel id="deviceRSSI">
<type>surepetcare:rssiDeviceType</type>
</update-channel>
<update-channel id="hubRSSI">
<type>surepetcare:rssiHubType</type>
</update-channel>
</instruction-set>
</thing-type>

<thing-type uid="surepetcare:flapDevice">
<instruction-set targetVersion="1">
<update-channel id="deviceRSSI">
Expand Down
Loading