homebridge-blinds
is a plugin for Homebridge.
Control your http
-based blinds via Homebridge (also works for command-line scripts as well)!
If you are new to Homebridge, please first read the Homebridge documentation.If you are running on a Raspberry, you will find a tutorial in the homebridge-punt Wiki.
Install Homebridge:
sudo npm install -g homebridge
Install homebridge-blinds:
sudo npm install -g homebridge-blinds
Add the accessory in config.json
in your home directory inside .homebridge
.
{
"accessory": "BlindsHTTP",
"name": "Window",
"up_url": "http://1.2.3.4/window/up",
"down_url": "http://1.2.3.4/window/down",
"stop_url": "http://1.2.3.4/window/stop",
"http_options": {
"method": "GET"
},
"success_codes": [200],
"motion_time": 10000,
"response_lag": 0
}
{
"accessory": "BlindsHTTP",
"name": "Window",
"up_url": "http://1.2.3.4/window/up",
"down_url": "http://1.2.3.4/window/down",
"position_url": "http://1.2.3.4/window/position",
"position_interval": 15000,
"position_jsonata": "ShutterPosition1",
"stop_url": "http://1.2.3.4/window/stop",
"map_send_jsonata": "$round( ( 100 - $number($) ) * 255 / 100 )",
"http_options": {
"body": "{}",
"headers": {
"API-Token": "aaabbbcccddd"
},
"method": "PUT"
},
"success_codes": [200, 204],
"max_http_attempts": 5,
"retry_delay": 2000,
"unique_serial": false,
"use_same_url_for_stop": false,
"show_stop_button": false,
"show_toggle_button": false,
"webhook_port": 51828,
"webhook_http_auth_user": "username",
"webhook_http_auth_pass": "password",
"webhook_https": false,
"webhook_https_keyfile": "/path/to/https.key",
"webhook_https_certfile": "/path/to/https.crt",
"motion_up_time": 11000,
"motion_down_time": 10000,
"response_lag": 0,
"trigger_stop_at_boundaries": false,
"verbose": false
}
You can omit any of the up_url
, down_url
, stop_url
if you don't want these to send a command, and position_url
if you want the blinds to only emulate the position (using a timer).
You can omit http_options
, it defaults to { method: 'POST' }
. Note that it can also be configured to accept any number of additional arguments (headers, body, form, etc.) that request or requestretry supports.
success_codes
allows you to define which HTTP response codes indicate a successful server response. If omitted, it defaults to 200.
max_http_attempts
allows you to define a maximum number of retries on a failed or timed out request (retry on 5xx or network errors). If omitted, it defaults to 5. If no retries are desired, set this value to 1.
retry_delay
allows you to define the number of ms between HTTP retries (max_http_attempts
> 1). If omitted, it defaults to 2000 (2 seconds). The minimum number of ms has been set to 100 to avoid excessive requests.
Any of the url config parameters (up_url
, down_url
, stop_url
, etc.) can be used to trigger command-line scripts instead. To use this feature, simply add the file://
prefix to the command. The command should be specified in full without URL encoding. This could be used to trigger external blinds commands via serial connection or MQTT.
For example:
"up_url": "file://python /home/pi/run_script.py",
If file://
is found as the prefix, it is removed and the remaining string is executed directly. Use caution when defining scripts as they are submitted to the system as received.
See the Wiki for examples of user-written scripts. Setting verbose
to true
in the config may also be useful for troubleshooting.
Alternatively, for more advanced configuration of URL's, each URL can be set to a complete request
/requestretry
object, e.g.:
"up_url": {
"url": "http://1.2.3.4/window/up",
"body": "{}",
"headers": {
"API-Token": "aaabbbcccddd"
},
"method": "PUT",
"maxAttempts": 5,
"retryDelay": 2000,
"time": false
},
If an object is used for the configuration, http_options
, max_http_attempts
, and retry_delay
are ignored, and these values must be instead specified directly inside the object. success_codes
are still used globally.
If time
is set to true, a full request timing profile (wait, dns, tcp, firstByte, download, total) will be logged (see timingPhases).
The plugin emulates the blinds position (it saves it in a variable) using an understanding of how long the blinds take to move and the relative position, but it can be used with position_url
for real time feedback.
For up_url
and down_url
, the variable %%POS%%
can be included in the URL, which will be replaced with the desired target before the URL is requested. For example, use of http://1.2.3.4/window/up?pos=%%POS%%
would be modified to http://1.2.3.4/window/up?pos=100
if the position 100 was requested. This is useful for cases where blinds offer the ability to directly specify the value.
When %%POS%%
is used, note that stop_url
will not be sent. (Because the blinds can receive a specific position, there is no need to send an additional stop command.)
NOTE: In scenarios where %%POS%%
is part of a body object and required to be sent as an integer instead of a string, { pos: "%%POSINT%%" }
can be used. In this case, it will be replaced with the target position as an integer value, e.g., { pos: 5 }
.
If transforming %%POS%%
or %%POSINT%%
values before sending is desired (e.g., the endpoint uses a different numerical scheme), map_send_jsonata
can be defined. This allows a JSONata expression to be used to pre-parse the value instead of the default HomeKit 0-100 values.
So, map_send_jsonata
could be set to a custom expression like $round( ( 100 - $number($) ) * 255 / 100 )
where $
represents the target position value.The JSONata Exerciser can be a helpful tool for developing custom expressions.
If the following parameters are defined, the position can be updated using a webhook. At a minimum, webhook_port
must be defined. webhook_http_auth_user
/ webhook_http_auth_pass
are used for basic authentication. If webhook_https
is true, then an SSL connection is used instead. If webhook_https_keyfile
/ webhook_https_keyfile
are not defined, a self-signed certificate will be used instead.
Once defined, this can be updated as follows: http://homebridgeip:port/?pos=##
, where pos=
any integer between 0-100. A simple JSON where success
is true or false is returned. Additional information is returned in the logs.
For example, http://192.168.1.40:51828/?pos=30
.
This implementation does take into account whether or not the blinds are moving, but will be most reliable in cases when blinds are stationary.
"webhook_port": 51828,
"webhook_http_auth_user": "username",
"webhook_http_auth_pass": "password",
"webhook_https": false,
"webhook_https_keyfile": "/path/to/https.key",
"webhook_https_certfile": "/path/to/https.crt",
position_url
must report the current state of the blinds as an integer (0-100) in either plain text or JSON format, e.g. {"current_position": 40}
. If JSON is used, JSON keys are filtered to look for a single numeric response, but the JSON handling is not very robust and will cause unexpected results if multiple numeric keys are present.
position_url
defaults to a simple GET request, ignoring headers or other methods specified in http_options
. If more robust handling is required, position_url
can be defined as a complete request
/requestretry
object as specified in Advanced URL
above.
If more robust handling of position_url
responses in JSON format is needed, position_jsonata
can be defined. This allows a JSONata expression to be set to parse the result. For example, considering the following JSON response:
{
"example": { "value": 4 }
}
So, position_jsonata
could be set to example.value
(as below) to produce the value of 4
.
"position_jsonata": "example.value",
Also, note that if the returned value is not in JSON format, $
can be used in some instances. For example, the expression below could be used to replace "
in the case of a simple string response like "25"
.
"position_jsonata": "$replace($, '\"', '')",
The JSONata Exerciser can be a helpful tool for developing custom expressions.
Ensure that the motion time is configured properly, even when position_url
is set, as it is used to obtain an estimate of blind position to avoid multiple web requests to the position_url
. (After the estimated position is reached, the position will be confirmed).
position_interval
is specified in ms, and defaults to 15000 ms (15 s). It can be used to set the polling frequency, particularly useful in cases where the blinds can also be controlled externally.
motion_time
is the time, in milliseconds, for your blinds to move from up to down. This should only include the time the motor is running. Filming this with your phone to determine the time may be easier than trying to do it with a timer. NOTE: If you are performing multiple blind requests simultaneously and are getting network timeouts due to your configuration, try using non-identical motion_time
(e.g., 9800, 10000, 10200 vs. 10000 for each) it may help.
For cases where motion_time
varies based on the direction of shutter movement (i.e., due to gravity), motion_down_time
and motion_up_time
may be used for more fine-tuning.
motion_down_time
is the time, in milliseconds, for your blinds to move from up to down.motion_up_time
is the time, in milliseconds, for your blinds to move from down to up.motion_time
above.Ideally, a better approach would be using some kind of equation for calculating the exact time. This would be a nice-to-have feature in the future.
motion_down_time
and motion_up_time
have a higher priority over motion_time
. This means, that if all three are explicitly provided in the configuration file, the value set in motion_time
will be ignored.
Steps:
success_codes
) = HTTP request delay (measured)
response_lag
current_position
- target_position
) / 100 * motion_time
Total motion time
- HTTP request delay
- response_lag
Total motion time
The HTTP request delay is in the logs, i.e., Move request sent (484 ms)
indicates the HTTP request took 484 ms.
Using response_lag
also helps ensure that if a move event is interrupted early, the position of the blinds will still be correct.
Because the HTTP request delay
in Step 1 can vary significantly (e.g., in the event of a failed request, it could be a few seconds), it is not included in the equation for Step 4. This is also shown in the Example below.
The optional stop request needs to be sent before the blinds will actually reach the target position. This is because there is a delay (i.e., Steps 1 and 2) before a request is sent, received, and the corresponding signal sent.
Therefore, to calibrate your blinds, you will need to set response_lag
. This can be a second or more in some cases. The simplest way to do this is to determine the time from initiating an open/close event via HomeKit to the time you can see/hear movement, and subtract the HTTP request delay
(from the logs). This is only relevant when trigger_stop_at_boundaries
is required, or, a value of 1-99 is used for the blinds (not just fully open or closed).
motion_time
= 10000, response_lag
= 750):Open
command sentHTTP request
successful (Move request sent (250 ms)
)Stop
request sentHTTP request
successfulHTTP request delay
was ignored as mentioned above)Stop
command received by blinds, blinds stopped movingThese can be set to true
or false
, but the default is false
.
show_stop_button
will expose a HomeKit button for the stop command. Some logic has also been added to smoothly abort any currently running functions.
show_toggle_button
will expose a HomeKit button that allows the blinds position to be toggled based on the last command sent. For example, if the last command sent to the blinds was up
, it will send the command down
. Note that on start up, toggle
will have no effect unless either 1) the initial blinds position on start up is either 0 or 100, or, 2) at least one command (up
or down
) is sent.
These can be set to true
or false
, but the default is false
.
unique_serial
will use a uuid-based serial/model number instead of the default BlindsHTTPAccessory
. This should only be required for specific external integrations (such as Eve) that may have problems with identical serial numbers for multiple devices.
use_same_url_for_stop
will send the previously sent url (either, up_url
or down_url
) again. This is for specific blind types that don't use a standard stop URL.
trigger_stop_at_boundaries
sends an additional stop command when moving the blinds to position 0 or 100. Most blinds don't require this command and will stop by themselves.
verbose
adds additional logging capabilities.
Have an idea? Found a bug? Contributions and pull requests are welcome.
I try to reply to everyone needing help using these projects. Obviously, this takes time. However, if you get some profit from this or just want to encourage me to continue creating stuff, there are few ways you can do it:
33sT6xw3tZWAdP2oL4ygbH5TVpVMfk9VW7
Sample config.json
, noting that you need to replace 1.2.3.4
with your Bond IP address, <deviceId>
with your deviceId, and <BondToken>
with your Bond token.
These values can be obtained from the Bond app, under Device settings
for any individual shades.
{
"accessory": "BlindsHTTP",
"name": "Dining Room Shades",
"up_url": "http://1.2.3.4/v2/devices/<deviceId>/actions/Open",
"down_url": "http://1.2.3.4/v2/devices/<deviceId>/actions/Close",
"stop_url": "http://1.2.3.4/v2/devices/<deviceId>/actions/Hold",
"http_options": {
"body": "{}",
"headers": {
"BOND-Token": "<BondToken>"
},
"method": "PUT"
},
"success_codes": [204],
"motion_time": 11000,
"response_lag": 1000,
"trigger_stop_at_boundaries": false
}
If you are having difficulty finding the settings, you can test your Bond device from the command line directly first (substituting your IP address, BOND-Token, and deviceId, e.g.:
curl -H "BOND-Token: f074b61f628018fd" -i http://1.2.3.4/v2/devices/79135791/actions/Open -X PUT -d "{}"
Alternatively, sample shell script to retrieve the list of Bond deviceId's using the local API, replacing 1.2.3.4
with your Bond IP address, and <BondToken>
with your Bond token:
#!/bin/sh
# CONFIGURE BOND_IP AND BOND_TOKEN TO MATCH YOUR CONFIGURATION
BOND_IP="1.2.3.4"
BOND_TOKEN="<BondToken>"
if ! [ -x "$(command -v jq)" ]; then
echo 'Error: jq is not installed.' >&2
exit 1
fi
BOND_DEVICES=$( curl -s "http://${BOND_IP}/v2/devices" -X GET -d "{\"_token\": \"${BOND_TOKEN}\"}" | jq -r 'keys[]' | grep -v '_' )
while read -r line; do
DEVICE_DETAILS=$( curl -sH "BOND-Token: ${BOND_TOKEN}" "http://${BOND_IP}/v2/devices/${line}" | jq '.name' )
echo "${DEVICE_DETAILS} ${line}"
done <<< "${BOND_DEVICES}"
Sample config.json
, noting that you need to replace 1.2.3.4
with your Tasmota IP address. As described above, %%POS%%
is used to supply the target position (0-100) to the plugin.
{
"accessory": "BlindsHTTP",
"name": "Window",
"up_url": "http://1.2.3.4/cm?cmnd=ShutterPosition%20%%POS%%",
"down_url": "http://1.2.3.4/cm?cmnd=ShutterPosition%20%%POS%%",
"stop_url": "http://1.2.3.4/cm?cmnd=Power3%20ON",
"http_options": {
"method": "GET"
},
"success_codes": [200],
"max_http_attempts": 5,
"retry_delay": 2000,
"use_same_url_for_stop": false,
"show_stop_button": true,
"show_toggle_button": false,
"motion_time": 20000,
"response_lag": 0,
"trigger_stop_at_boundaries": false,
"verbose": false
}
Louvolite's smart home system seems to be build on top of Neo Smart Blinds platform, so this configuration is likely to work with other manufacturers utilising Neo. You will need the following values for the config:
<controller_ip>
is the IP address of Louvolite's One Touch (or other Neo-based hub), e.g. 1.2.3.4;<controller_id>
is the controller identifier, which you can find in the Neo app on the controller page, this is a long alphanumeric identifier;<blind_code>
you can also find in the Neo app at the bottom of the blind page — it looks something like 123.456-01.{
"accessory": "BlindsHTTP",
"name": "Louvolite Blind",
"up_url": "http://<controller_ip>:8838/neo/v1/transmit?id=<controller_id>&command=<blind_code>-up",
"down_url": "http://<controller_ip>:8838/neo/v1/transmit?id=<controller_id>&command=<blind_code>-dn",
"stop_url": "http://<controller_ip>:8838/neo/v1/transmit?id=<controller_id>&command=<blind_code>-sp",
"http_options": {
"method": "GET"
}
}
Homebridge 是一个轻量级 NodeJS 服务器,它模拟 iOS HomeKit API,提供从 HomeKit 到“智能家居”设备制造商提供的各种第三方 API 的基本桥接。通过 Homebridge 的桥接,可以让 Siri 控制完全不支持 HomeKit 的设备。 此外 Homebridge 支持插件。
Homebridge Blinds Command HomeKit support for non-smart motorized blinds through command-line scripts. homebridge-blinds-cmd is a Homebridge plugin that allows you to raise, lower, and get the current
homebridge-mqtt-blinds This is a homebridge plugin to control blinds/shutters via mqtt. �� �� It can be used with DIY systems or retrofit solutions like Shelly2 andShelly2.5. Installation If you are n
homebridge-vsx homebridge-vsx is a plugin made for homebridge,which allows switching on and off your Pioneer AV receiver. All AV receivers (VSX and SC),which work with the iControl AV5 App are support
homebridge-sesame Control and monitor your Sesame smart lock with HomeKit integration. Prerequisites Installation of Homebridge iOS 11 or later Sesame lock with enabled cloud integration Sesame Wifi A
homebridge-panasonictv A homebridge plugin for turning on and off your Panasonic Viera TV. The plugin also has experimental support for changing the volume and channel. These characteristics are not r