Skip to content

Commit

Permalink
new sensor types
Browse files Browse the repository at this point in the history
  • Loading branch information
nitaybz committed Feb 6, 2022
1 parent f883cc9 commit 8a837af
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 46 deletions.
46 changes: 23 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins) [![Homebridge Discord](https://img.shields.io/discord/432663330281226270?color=728ED5&logo=discord&label=discord)](https://discord.gg/HWUKH9C)<br>
[![certified-hoobs-plugin](https://badgen.net/badge/HOOBS/Certified/yellow)](https://plugins.hoobs.org?ref=10876) [![hoobs-support](https://badgen.net/badge/HOOBS/Support/yellow)](https://support.hoobs.org?ref=10876)

With this plugin, you can create any number of fake switches that will start a timer when turned ON, when the delay time is reached the switch will automatically turn OFF and trigger a dedicated motion sensor for 3 seconds. This can be very useful for advanced automation with HomeKit scenes - when delayed actions are required.
With this plugin, you can create any number of fake switches that will start a timer when turned ON, when the delay time is reached the switch will automatically turn OFF and trigger a dedicated sensor (motion/contact/occupancy) for 3 seconds. This can be very useful for advanced automation with HomeKit scenes - when delayed actions are required.

## Installations

Expand All @@ -27,7 +27,8 @@ If you don't use Homebridge UI or HOOBS, keep reading:
"accessory": "DelaySwitch",
"name": "DelaySwitch",
"delay": 5000,
"disableSensor": false,
"sensorType": "motion",
"flipSensorState": false,
"startOnReboot": false
}
]
Expand All @@ -38,42 +39,41 @@ If you don't use Homebridge UI or HOOBS, keep reading:
| -------------------------------- | --------------------------- |:--------:|:--------:|:--------:|
| `accessory` | always `"DelaySwitch"` || - | String |
| `name` | Name for your accessory || - | String |
| `delay` | Delay/Timer in milliseconds |     ✓ | - | Integer |
| `disableSensor` | Remove the Motion Sensor | | `false` | Boolean |
| `startOnReboot`       | When set to `true`, the switch will be turned ON and start the timer when HomeBridge restarts |       | `false` | Boolean |
| `delay` | Delay/Timer in milliseconds || - | Integer |
| `sensorType` | The sensor type that will trigger when the time has ended (`null` for no sensor) | | `"motion"` | Integer |
| `flipSensorState` | Flips the trigger sensor state (close/open, detected/not detected) | | `false` | Boolean |
| `startOnReboot` | When set to `true`, the switch will be turned ON and start the timer when HomeBridge restarts | | `false` | Boolean |

## Why do we need this Plugin?

## Why do we need this plugin?
The most common use of this plugin is to turn ON/OFF lights based on a motion/door sensor. This can be achieved by setting an automation to turn ON a light and the delay switch when motion is detected and turn OFF the light when the dedicated delay sensor is triggered (or delay switch is turned OFF).

The most common use of this plugin is to turn ON/OFF lights based on a motion/door sensor. This can be achieved by setting an automation to turn ON a light and the delay switch when motion is detected and turn OFF the light when the dedicated delay motion sensor is triggered (or delay switch is turned OFF).
Another great example, when using a smart wall switch (to turn ON) and RGB light bulb (to switch color) together on the same scene can cause no action on the bulb since the bulb might not even be ON when the command is sent from Homebridge.
To fix this, we can set an automation to change the bulb color a few seconds after the wall switch ON command.

Also it can be use with any device that requires a certain delay time after other devices (TV + RPi-Kodi / PC + SSH / etc...)

Another great example, when using smart wall switch (to turn ON) and RGB light bulb (to switch color) together on the same scene can cause no action on the bulb since the bulb might not even be ON when the command has been sent from homebridge.
For that, we need to set an automation to change the bulb color a few seconds after the wall switch ON command.

Also it can be use with any device that require a certain delay time from other devices (TV + RPi-Kodi / PC + SSH / etc...)


## How it works
## How it Works

Basically, all you need to do is:

1. Set the desired delay time in the config file (in milliseconds).
2. The plugin will create one switch and one motion sensor for this plugin.
1. Set the desired `delay` time in the config file (in milliseconds).
2. The plugin will create one switch and optional sensor (motion/contact/occupancy).
3. Use this switch in any scene or automation.
4. Set an automation to trigger when this switch is turned OFF or the motion sensor is triggers - "EVE" app is very recommended to set this automation.
4. Set an automation to trigger when this switch is turned OFF or the sensor is triggered, using the Home app or another app such as the Eve app.

## Why Add a Motion Sensor?
## Why Add a Trigger Sensor?

A Motion sensor is created for each accessory in order to be able to cancel the timer and the attached automations.
How does it works? You can set the automation to be triggered from the motion sensor instead of the switch OFF command and therefore you can turn OFF the switch and prevent the motion sensor from being triggered or any attached automations.
If you have no use of the sensor you can remove it by adding `"disableSensor": true` to your config.
A sensor (motion/contact/occupancy) is created for each accessory in order to be able to cancel the timer and the attached automations.
How does it works? You can set the automation to be triggered from the attached "trigger" sensor instead of the switch OFF command and therefore you can turn OFF the switch and prevent the sensor from triggering or any attached automations from executing.
If you have no use of the sensor you can remove it by setting `"sensorType": null` to your config.

## Good to know
## Good to Know

* **When manualy turning OFF the switch, the timer will stop and the motion sensor will NOT be triggered.**
* **When manualy turning OFF the switch, the timer will stop and the sensor will NOT be triggered.**

* **When the delay switch is getting ON command while it's already ON, the timer will restart and the motion sensor trigger will be delayed.**
* **When the delay switch receives ON command while it's already ON, the timer will restart and the sensor trigger will be delayed.**

_________________________________________

Expand Down
18 changes: 15 additions & 3 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,21 @@
"default": 5000,
"required": true
},
"disableSensor": {
"title": "Disable Extra Motion Sensor",
"description": "Enable if you have no use of the sensor and you're interested to use the switch only",
"sensorType": {
"title": "Trigger Sensor Type",
"description": "The sensor type that will trigger when the time has ended (\"None\" for no sensor, \"Motion Sensor\" is default)",
"type": "string",
"default": "motion",
"required": false,
"oneOf": [
{ "title": "Motion Sensor", "enum": ["motion"] },
{ "title": "Contact Sensor", "enum": ["contact"] },
{ "title": "Occupancy Sensor", "enum": ["occupancy"] }
]
},
"flipSensorState": {
"title": "Flip Sensor State",
"description": "Enable to flip the trigger sensor state (close/open, detected/not detected)",
"type": "boolean",
"default": false,
"required": false
Expand Down
65 changes: 45 additions & 20 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,25 @@ function delaySwitch(log, config, api) {
this.log = log;
this.name = config['name'];
this.delay = config['delay'];
this.disableSensor = config['disableSensor'] || false;
this.startOnReboot = config['startOnReboot'] || false;
this.sensorType = config['sensorType'];
this.flipSensor = config['flipSensorState'];
this.disableSensor = config['disableSensor'] || !config['sensorType'];
this.startOnReboot = config['startOnReboot'];
this.timer;
this.switchOn = false;
this.motionTriggered = false;
this.sensorTriggered = 0;
this.uuid = UUIDGen.generate(this.name)

this.getSensorState = () => {
state = this.sensorTriggered
if (this.flipSensor && sensorType === 'motion')
return !state
if (this.sensorType === 'motion')
return !!state
if (this.flipSensor)
return state^1
return state
}
}

delaySwitch.prototype.getServices = function () {
Expand All @@ -45,12 +58,28 @@ delaySwitch.prototype.getServices = function () {
var services = [informationService, this.switchService]

if (!this.disableSensor){
this.motionService = new Service.MotionSensor(this.name + ' Trigger');

this.motionService
.getCharacteristic(Characteristic.MotionDetected)
.on('get', this.getMotion.bind(this));
services.push(this.motionService)
switch (this.sensorType) {
case 'contact':
this.sensorService = new Service.ContactSensor(this.name + ' Trigger');
this.sensorCharacteristic = Characteristic.ContactSensorState
break;
case 'occupancy':
this.sensorService = new Service.OccupancySensor(this.name + ' Trigger');
this.sensorCharacteristic = Characteristic.OccupancyDetected
break;
default:
this.sensorService = new Service.MotionSensor(this.name + ' Trigger');
this.sensorCharacteristic = Characteristic.MotionDetected
break;
}

this.sensorService
.getCharacteristic(this.sensorCharacteristic)
.on('get', (callback) => {
callback(null, this.getSensorState())
});

services.push(this.sensorService)
}

return services;
Expand All @@ -65,8 +94,8 @@ delaySwitch.prototype.setOn = function (on, callback) {

this.switchOn = false;
clearTimeout(this.timer);
this.motionTriggered = false;
if (!this.disableSensor) this.motionService.getCharacteristic(Characteristic.MotionDetected).updateValue(false);
this.sensorTriggered = 0;
if (!this.disableSensor) this.sensorService.getCharacteristic(this.sensorCharacteristic).updateValue(this.getSensorState());


} else {
Expand All @@ -80,12 +109,12 @@ delaySwitch.prototype.setOn = function (on, callback) {
this.switchOn = false;

if (!this.disableSensor) {
this.motionTriggered = true;
this.motionService.getCharacteristic(Characteristic.MotionDetected).updateValue(true);
this.log('Triggering Motion Sensor');
this.sensorTriggered = 1;
this.sensorService.getCharacteristic(this.sensorCharacteristic).updateValue(this.getSensorState());
this.log('Triggering Sensor');
setTimeout(function() {
this.motionService.getCharacteristic(Characteristic.MotionDetected).updateValue(false);
this.motionTriggered = false;
this.sensorTriggered = 0;
this.sensorService.getCharacteristic(this.sensorCharacteristic).updateValue(this.getSensorState());
}.bind(this), 3000);
}

Expand All @@ -100,7 +129,3 @@ delaySwitch.prototype.setOn = function (on, callback) {
delaySwitch.prototype.getOn = function (callback) {
callback(null, this.switchOn);
}

delaySwitch.prototype.getMotion = function(callback) {
callback(null, this.motionTriggered);
}

0 comments on commit 8a837af

Please sign in to comment.