Skip to content

Commit

Permalink
Add support for newer WaterMeterController devices as a HomeKit valve
Browse files Browse the repository at this point in the history
  • Loading branch information
dkerr64 committed Aug 10, 2024
1 parent 5ce8688 commit 300f28e
Show file tree
Hide file tree
Showing 8 changed files with 395 additions and 68 deletions.
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Currently supports the following devices:
* Switch
* Temperature and Humidity Sensor
* Vibration Sensor (as a motion sensor)
* Water Meter Controller (as a valve)

The plugin registers as a MQTT client and subscribes to reports published by YoLink for real time alerts and status updates.

Expand Down Expand Up @@ -103,6 +104,7 @@ If you see an error message in the log similar to the following then you are lik
"doublePress": 800,
"powerFailureSensorAs": "Outlet",
"deviceTemperatures": false,
"useWaterFlowing": false,
"devices": [
{
"deviceId": "0123456789abcdef",
Expand All @@ -113,6 +115,7 @@ If you see an error message in the log similar to the following then you are lik
"doublePress": 800,
"nOutlets": 5,
"temperature": false,
"useWaterFlowing": false,
"enableExperimental": false
}
}
Expand Down Expand Up @@ -147,6 +150,7 @@ If you see an error message in the log similar to the following then you are lik
* **doublePress** *(optional)*: Duration in milliseconds to trigger a double-press event on two button presses on a stateless device. Defaults to 800ms and a value of zero disables double-press feature. See notes below for YoLink FlexFob remote.
* **powerFailureSensorAs** *(optional)*: How to represent the YoLink power failure alarm sensor in HomeKit, can be either *Outlet* or *Contact*, defaults to Outlet.
* **deviceTemperatures** *(optional)*: If set to true then create a temperature service for those devices that report temperature in addition to their main function. See Device Notes below.
* **useWaterFlowing** *(optional)*: If set to true then the plugin will use the *waterFlowing* status from YoLink *WaterMeterController* valves to report the *InUse* status to HomeKit. See Device Notes below.
* **devices** *(optional)*: Optional array of device settings, see below.
* **garageDoors** *(optional)*: Optional array of sensor/controller pairs, see below.

Expand All @@ -158,7 +162,8 @@ If you see an error message in the log similar to the following then you are lik
* **refreshAfter** *(optional)*: Device specific override of global *refreshAfter*, see above. Defaults to global setting.
* **doublePress** *(optional)*: Device specific override of global *doublePress*, see above. Defaults to global setting.
* **nOutlets** *(optional)*: For power strip or multi-outlet devices, number of controllable outlets. See device notes below.
* **temperature** *(optional)*: If set to true then create a temperature service in addition to the main function. See device notes below.
* **temperature** *(optional)*: If set to true then create a temperature service in addition to the main function. See Device Notes below.
* **useWaterFlowing** *(optional)*: Device specific override of global *useWaterFlowing*, see above. Defaults to global setting.
* **enableExperimental** *(optional)*: Device specific override of global *enableExperimental*, see above. Defaults to global setting.

* **garageDoors** are an array of objects that allow you to pair two devices, either a *GarageDoor* or *Finger* controller with a *DoorSensor* that together represent a single garage door. The garage door inherits properties of the individual devices. The garage door *name* is taken from the controller device. See device notes below.
Expand Down Expand Up @@ -232,9 +237,7 @@ The YoLink Smart Lock M1 can be locked and unlocked from Homebridge/HomeKit and

### Manipulator / Water Valve Controller

YoLink water valve controllers report as a *Manipulator* device, the plugin registers this as a HomeKit generic valve. HomeKit has the concept of both open/close and in use where in use means that fluid is actually flowing through the device. Presumably this allows for a valve to be open, but no fluid to flow. YoLink only reports open/close and so the plugin uses this state for both valve position and in use (fluid flowing). Normal status reporting occurs every 4 hours. If you want to check on device status more frequently then set *refreshAfter* to desired interval.

I have observed *Can't connect to Device* errors from YoLink when trying to retrieve device status. When these occur the plugin attempts to connect again, up to 5 times, before giving up.
YoLink water valve controllers report as a *Manipulator* device, the plugin registers this as a HomeKit generic valve. HomeKit has the concept of both open/close and in-use where in-use means that fluid is actually flowing through the device. Presumably this allows for a valve to be open, but no fluid to flow. YoLink only reports open/close and so the plugin uses this state for both valve position and in-use (fluid flowing). Normal status reporting occurs every 4 hours. If you want to check on device status more frequently then set *refreshAfter* to desired interval.

### Motion Sensor

Expand Down Expand Up @@ -283,6 +286,16 @@ HomeKit does not have a vibration sensor device type so this plugin registers th

YoLink vibration sensors also report device temperature. If you set the *temperature* configuration setting to true then a Homebridge/HomeKit service is created to make this visible to the app. The name has "Temperature" appended to the end.

### Water Meter Controller

YoLink water meter and valve controllers report as a *WaterMeterController* device, the plugin registers this as a HomeKit generic valve. HomeKit has the concept of both open/close and in-use where in-use means that fluid is actually flowing through the device. This allows for a valve to be open, but no fluid to flow.

The *YS-5008-UC* valve does report whether water is flowing. However these devices currently do not update this status in real time and this can confuse Apple Home which will repport "Waiting..." after you open the valve -- as it waits for the in-use characteristic to indicate water flowing. Therefore, by default, this plugin will report in-use based on whether the value is open or closed. You can set the config *useWaterFlowing* setting to change this to use the water flowing status from the device.

This plugin expects to receive status updates from YoLink devices when status changes. As this device is not currently doing this for *waterFlowing*, an alternative would be to change the *refreshAfter* config setting for this device only (do not change it globally) and the plugin will poll the device for status more regularly. The minimum time you can set this to is 60 seconds. However this is *not recommended* as it places additional load on the LoRa protocol and the affects on device battery life are unknown.

A Leak Sensor and, if supported, a Temperature Sensor service is added with this device. The name of each has "Leak" and "Temperature" appended to the end. *YS-5006-UC* is known not to report temperature.

### Unsupported Devices

If you have a device not supported by the plugin then useful information will be logged as warnings, including callback messages received for any alerts or status changes triggered by the device. Please capture these logs and report to the author by opening a [issue](https://github.com/dkerr64/homebridge-yolink/issues).
Expand Down Expand Up @@ -324,7 +337,7 @@ Many log messages carry two timestamps. The first is current time and is logged

## License

(c) Copyright 2022-2023 David A. Kerr
(c) Copyright 2022-2024 David A. Kerr

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this program except in compliance with the License. You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)

Expand Down
89 changes: 72 additions & 17 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"required": true,
"default": "YoLink"
},
"tokenURL": {
"tokenURL": {
"title": "YoLink authentication server URL address",
"type": "string",
"required": true,
Expand Down Expand Up @@ -124,7 +124,8 @@
"SmartRemoter",
"Switch",
"THSensor",
"VibrationSensor"
"VibrationSensor",
"WaterMeterController"
]
},
"default": [
Expand Down Expand Up @@ -160,7 +161,8 @@
"SmartRemoter",
"Switch",
"THSensor",
"VibrationSensor"
"VibrationSensor",
"WaterMeterController"
]
}
},
Expand All @@ -185,15 +187,30 @@
"type": "boolean",
"required": false,
"description": "Some YoLink devices report temperature in addition to their main function. Currently these are LeakSensors, Vibration & Motion Sensors, Flex Fob and Smoke & CO Alarms. This will create a temperature sensor for those."

},
"useWaterFlowing": {
"title": "Use waterFlowing status from YoLink water valves",
"type": "boolean",
"required": false,
"description": "YoLink water meter controller valves can report whether water is flowing. This sets whether to use this when informing HomeKit that a valve is InUse. Default is to assume InUse if valve is open."
},
"powerFailureSensorAs": {
"title": "Represent YoLink Power Failure Alarm as",
"type": "string",
"required": false,
"oneOf": [
{ "title": "Outlet device", "enum": ["Outlet"] },
{ "title": "Contact sensor", "enum": ["Contact"] }
{
"title": "Outlet device",
"enum": [
"Outlet"
]
},
{
"title": "Contact sensor",
"enum": [
"Contact"
]
}
],
"description": "HomeKit does not have the concept of a power failure sensor so we much choose either an Outlet or Contact sensor to represent the YoLink device."
},
Expand All @@ -216,7 +233,7 @@
"type": "string",
"required": true,
"default": "",
"description":"You can find the Device ID in the Homebridge log, in the YoLink mobile app (as Device EUI) or in the Homebridge Config UI by clicking on an accessory's settings and copying the Serial Number field."
"description": "You can find the Device ID in the Homebridge log, in the YoLink mobile app (as Device EUI) or in the Homebridge Config UI by clicking on an accessory's settings and copying the Serial Number field."
},
"config": {
"title": "Device Configuration",
Expand All @@ -227,12 +244,42 @@
"type": "string",
"required": false,
"oneOf": [
{ "title": "false", "enum": ["false"] },
{ "title": "true", "enum": ["true"] },
{ "title": "Hydrometer", "enum": ["hydro"] },
{ "title": "Thermometer", "enum": ["thermo"] },
{ "title": "CO Sensor", "enum": ["co"] },
{ "title": "Smoke Sensor", "enum": ["smoke"] }
{
"title": "false",
"enum": [
"false"
]
},
{
"title": "true",
"enum": [
"true"
]
},
{
"title": "Hydrometer",
"enum": [
"hydro"
]
},
{
"title": "Thermometer",
"enum": [
"thermo"
]
},
{
"title": "CO Sensor",
"enum": [
"co"
]
},
{
"title": "Smoke Sensor",
"enum": [
"smoke"
]
}
],
"description": "Hide this device from Homebridge / HomeKit. You might want to do this to suppress the 'device not supported' warning message in the log. As there is no accessory type in HomeKit for a hub, you can set this to true for the YoLink hub."
},
Expand All @@ -241,7 +288,7 @@
"type": "string",
"required": false,
"default": "",
"description":"This will override the device name returned by YoLink for display in the Homebridge accessories page"
"description": "This will override the device name returned by YoLink for display in the Homebridge accessories page"
},
"refreshAfter": {
"title": "Refresh time for data from YoLink server (override global setting)",
Expand Down Expand Up @@ -269,8 +316,14 @@
"type": "boolean",
"required": false,
"description": "Some YoLink devices report temperature in addition to their main function. Currently these are LeakSensors, Vibration & Motion Sensors, Flex Fob and Smoke & CO Alarms. This will create a temperature sensor for those."
},
"useWaterFlowing": {
"title": "Use waterFlowing status from YoLink water valves",
"type": "boolean",
"required": false,
"description": "YoLink water meter controller valves can report whether water is flowing. This sets whether to use this when informing HomeKit that a valve is InUse. Default is to assume InUse if valve is open."
}
}
}
}
}
}
Expand Down Expand Up @@ -304,7 +357,7 @@
}
}
},
"description":"Pair two devices together into a single Garage Door accessory. You can find the Device ID in the Homebridge log, in the YoLink mobile app (as Device EUI) or in the Homebridge Config UI by clicking on an accessory's settings and copying the Serial Number field."
"description": "Pair two devices together into a single Garage Door accessory. You can find the Device ID in the Homebridge log, in the YoLink mobile app (as Device EUI) or in the Homebridge Config UI by clicking on an accessory's settings and copying the Serial Number field."
}
}
},
Expand Down Expand Up @@ -337,6 +390,7 @@
"refreshAfter",
"doublePress",
"deviceTemperatures",
"useWaterFlowing",
"powerFailureSensorAs",
"verboseLog",
"liteLog",
Expand Down Expand Up @@ -373,7 +427,8 @@
"devices[].config.refreshAfter",
"devices[].config.doublePress",
"devices[].config.nOutlets",
"devices[].config.temperature"
"devices[].config.temperature",
"devices[].config.useWaterFlowing"
]
}
]
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"displayName": "Homebridge YoLink",
"name": "homebridge-yolink",
"version": "1.5.7",
"version": "1.6.0",
"description": "Connect to YoLink.",
"license": "Apache-2.0",
"repository": {
Expand Down
5 changes: 4 additions & 1 deletion src/deviceHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/***********************************************************************
* YoLink device list
*
* Copyright (c) 2022 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/
import { initUnknownDevice, mqttUnknownDevice } from './unknownDevice';
Expand Down Expand Up @@ -47,6 +47,7 @@ export const deviceFeatures = {
Dimmer: { hasBattery: false },
InfraredRemoter: { hasBattery: true },
COSmokeSensor: { hasBattery: true },
WaterMeterController: { hasBattery: true },
};

export const initDeviceService = {
Expand All @@ -72,6 +73,7 @@ export const initDeviceService = {
Dimmer(this: YoLinkPlatformAccessory) { initLightbulb.bind(this)('open', 'open', 'close'); },
InfraredRemoter(this: YoLinkPlatformAccessory) { initInfraredRemoter.bind(this)(); },
COSmokeSensor(this: YoLinkPlatformAccessory) { initCoSmokeDetector.bind(this)(); },
WaterMeterController(this: YoLinkPlatformAccessory) { initValveDevice.bind(this)(); },
};

export const mqttHandler = {
Expand All @@ -97,4 +99,5 @@ export const mqttHandler = {
Dimmer(this: YoLinkPlatformAccessory, data) { mqttLightbulb.bind(this)(data); },
InfraredRemoter(this: YoLinkPlatformAccessory, data) { mqttInfraredRemoter.bind(this)(data); },
COSmokeSensor(this: YoLinkPlatformAccessory, data) { mqttCoSmokeDetector.bind(this)(data); },
WaterMeterController(this: YoLinkPlatformAccessory, data) { mqttValveDevice.bind(this)(data); },
};
2 changes: 1 addition & 1 deletion src/garageDoor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink Garage Door device support
*
* Copyright (c) 2022-2023 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down
2 changes: 2 additions & 0 deletions src/platformAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ export class YoLinkPlatformAccessory {
device.timeout ??= 45;
// targetState used to track if garage door has been requested to open or close
device.targetState = '';
// Use waterFlowing status from waterMeterControllers?
device.config.useWaterFlowing = platform.makeBoolean(device.config.useWaterFlowing, platform.config.useWaterFlowing);
}

/*********************************************************************
Expand Down
Loading

0 comments on commit 300f28e

Please sign in to comment.