@uncaught/gpio-shutter-bridge 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -5
- package/dist/example.js +1 -1
- package/dist/src/Gpio.js +12 -2
- package/dist/src/mqtt/mqtt.d.ts +3 -2
- package/dist/src/mqtt/mqtt.js +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ Just to give you an insight, you can pobably use this project with any other har
|
|
|
45
45
|
- 1 Schellenberg shutter motor in my balcony door
|
|
46
46
|
- 1 Schellenberg remote control
|
|
47
47
|
- Which I opened up and soldered contacts to all three buttons (up/stop/down) as well as the power supply.
|
|
48
|
-
- This way I can supply power directly via the 3V
|
|
48
|
+
- This way I can supply power directly via the 3V output pin of the raspberry pi without needing batteries.
|
|
49
49
|
- I'm trusting you with this [definitely professional piece of art](docs/schellenberg.png).
|
|
50
50
|
- 3 Velux covers/shutters on my roof windows
|
|
51
51
|
- Velux KLF 150 gateway
|
|
@@ -69,7 +69,7 @@ Just to give you an insight, you can pobably use this project with any other har
|
|
|
69
69
|
|
|
70
70
|

|
|
71
71
|
|
|
72
|
-
- Connect all **VCC** pins of the relays to a 3V
|
|
72
|
+
- Connect all **VCC** pins of the relays to a 3V pin of the Raspberry Pi.
|
|
73
73
|
- I have daisy chained them together. Only the most left relay is connected to the Pi.
|
|
74
74
|
- Connect all **GND** pins of the relays to a GND pin of the Raspberry Pi.
|
|
75
75
|
- Again daisy chained.
|
|
@@ -95,21 +95,59 @@ This is for the default configuration as described in the Velux KLF 150 manual.
|
|
|
95
95
|
|
|
96
96
|
# Software
|
|
97
97
|
|
|
98
|
-
-
|
|
98
|
+
- Make sure you have either `raspi-gpio` or `pinctrl` (newer) installed. Check with `raspi-gpio get` or `pinctrl get`.
|
|
99
|
+
- Either one is used to set the GPIO input pins to the "pull up" mode. This is not handled in the `onoff`-library I'm using.
|
|
100
|
+
- `pinctrl` is newer, but requires permissions. So you either need to be root, or make sure you have access to all `/dev/gpio*` devices:
|
|
101
|
+
- E.g. use the `gpio` group:
|
|
102
|
+
- Check `ll /dev/gpio*` and see that every device is owned by the `gpio` group and has `g+rw` permissions.
|
|
103
|
+
- If not, use `sudo chgrp gpio /dev/gpio*` and/or `sudo chmod g+rw /dev/gpio*`.
|
|
104
|
+
- You can add yourself to the `gpio` group with `sudo usermod -a -G gpio $USER`.
|
|
105
|
+
- Verify with `pinctrl get` that you can use the tool without further permissions.
|
|
106
|
+
- Go into a folder where you wish to install this project.
|
|
107
|
+
- Install the library with `npm install @uncaught/gpio-shutter-bridge`
|
|
108
|
+
- Create a javascript file (e.g. `run.js`), require my library and call it with your shutter-pin-layout:
|
|
99
109
|
|
|
100
110
|
```js
|
|
101
111
|
import {createVeluxShutters, initRuntime, initMqtt} from '@uncaught/gpio-shutter-bridge';
|
|
102
112
|
|
|
103
113
|
const {onDispose} = initRuntime();
|
|
104
114
|
|
|
105
|
-
|
|
115
|
+
initMqtt(createVeluxShutters([
|
|
106
116
|
{ident: 'Velux_A', up: 2, down: 3, input: 14},
|
|
107
117
|
{ident: 'Velux_B', up: 4, down: 17, input: 15},
|
|
108
118
|
{ident: 'Velux_C', up: 27, down: 22, input: 18},
|
|
109
119
|
{ident: 'Velux_D', up: 10, down: 9, input: 23},
|
|
110
120
|
{ident: 'Velux_E', up: 11, down: 8, input: 24}, //same row!
|
|
111
|
-
], onDispose), {url: 'mqtt://your-mqtt-or-home-assistant'})
|
|
121
|
+
], onDispose), onDispose, {url: 'mqtt://your-mqtt-or-home-assistant'});
|
|
112
122
|
```
|
|
113
123
|
|
|
114
124
|
- The ident should match `/[a-zA-Z][a-zA-Z0-9_-]*/`.
|
|
115
125
|
- See [my personal example](./example.ts) for a few more details.
|
|
126
|
+
|
|
127
|
+
## Dockerizing
|
|
128
|
+
|
|
129
|
+
I tried to dockerize this project, but I was not able to get it to work with only specific mapped devices. The `pinctrl` kept saying "No GPIO chips found". I've only managed to get it working with the `--privileged` flag, which for me, kind of defeats the purpose of running this inside docker.
|
|
130
|
+
|
|
131
|
+
If you find a way to get it working, please let me know, I'll add it as an example.
|
|
132
|
+
|
|
133
|
+
<details>
|
|
134
|
+
<summary>My attempts</summary>
|
|
135
|
+
|
|
136
|
+
I tried based off of this:
|
|
137
|
+
|
|
138
|
+
```Dockerfile
|
|
139
|
+
FROM node:25.0.0-trixie-slim
|
|
140
|
+
|
|
141
|
+
RUN apt update && apt install -y git build-essential cmake \
|
|
142
|
+
&& git clone https://github.com/raspberrypi/utils.git \
|
|
143
|
+
&& cd utils/pinctrl \
|
|
144
|
+
&& cmake . \
|
|
145
|
+
&& make \
|
|
146
|
+
&& make install
|
|
147
|
+
|
|
148
|
+
ENTRYPOINT ["bash"]
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Building with `docker build -t gpio .` and running with `docker run --rm -it --device /dev/gpiochip0 --device /dev/gpiochip1 --device /dev/gpiochip2 --device /dev/gpiomem --cap-add SYS_RAWIO gpio`
|
|
152
|
+
|
|
153
|
+
</details>
|
package/dist/example.js
CHANGED
|
@@ -30,4 +30,4 @@ const shutters = [
|
|
|
30
30
|
...createVeluxShutters(veluxKlf150CDE, onDispose),
|
|
31
31
|
createThreeButtonShutter('Balkon', 10, 9, 11, onDispose),
|
|
32
32
|
];
|
|
33
|
-
|
|
33
|
+
initMqtt(shutters, onDispose, { url: 'mqtts://mosquitto.local.correnz.net', rejectUnauthorized: false });
|
package/dist/src/Gpio.js
CHANGED
|
@@ -20,13 +20,23 @@ export function mkInput(pin, onDispose) {
|
|
|
20
20
|
//Setting to pull-up - the `onoff`-library doesn't do that.
|
|
21
21
|
// I'm doing this because the inputs were floating high without any pull, so I just stick with it.
|
|
22
22
|
// We assume the input pin is closed to ground, causing it to change to low.
|
|
23
|
-
|
|
23
|
+
try {
|
|
24
|
+
execSync(`raspi-gpio set ${pin} pu`);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
try {
|
|
28
|
+
execSync(`pinctrl set ${pin} pu`); //newer tool, replacing raspi-gpio, might need root though
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
console.error('Unable to set pull-up on GPIO input');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
24
34
|
const gpio = new Gpio(pin, 'in', 'both');
|
|
25
35
|
onDispose(() => gpio.unexport());
|
|
26
36
|
//Double check that the input is high:
|
|
27
37
|
const value = gpio.readSync();
|
|
28
38
|
if (value !== Gpio.HIGH) {
|
|
29
|
-
console.error(`Expected GPIO ${pin} to be high, but it was
|
|
39
|
+
console.error(`Expected GPIO ${pin} to be high (3V), but it was low (0V)`);
|
|
30
40
|
}
|
|
31
41
|
return gpio;
|
|
32
42
|
}
|
package/dist/src/mqtt/mqtt.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type IClientOptions } from 'mqtt';
|
|
2
2
|
import { ShutterInterface } from '../Shutter/Shutter.js';
|
|
3
|
-
|
|
3
|
+
import type { OnDispose } from '../runtime.js';
|
|
4
|
+
export declare function initMqtt(shutters: readonly ShutterInterface[], onDispose: OnDispose, { url, ...mqttOpts }: {
|
|
4
5
|
url: string;
|
|
5
|
-
} & IClientOptions, namespace?: string):
|
|
6
|
+
} & IClientOptions, namespace?: string): void;
|
package/dist/src/mqtt/mqtt.js
CHANGED
|
@@ -9,7 +9,7 @@ function validateNamespacePart(str) {
|
|
|
9
9
|
throw new Error(`Invalid string for namespace: ${str}`);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
export function initMqtt(shutters, { url, ...mqttOpts }, namespace = 'shutter') {
|
|
12
|
+
export function initMqtt(shutters, onDispose, { url, ...mqttOpts }, namespace = 'shutter') {
|
|
13
13
|
const shuttersById = new Map(shutters.map((s) => [s.ident, s]));
|
|
14
14
|
validateNamespacePart(namespace);
|
|
15
15
|
const ns1 = namespace;
|
|
@@ -66,7 +66,7 @@ export function initMqtt(shutters, { url, ...mqttOpts }, namespace = 'shutter')
|
|
|
66
66
|
},
|
|
67
67
|
origin: {
|
|
68
68
|
name: ns0,
|
|
69
|
-
sw_version: '1.
|
|
69
|
+
sw_version: '1.1.0',
|
|
70
70
|
support_url: 'https://github.com/uncaught/gpio-shutter-bridge',
|
|
71
71
|
},
|
|
72
72
|
payload_available: 'online',
|
|
@@ -127,8 +127,8 @@ export function initMqtt(shutters, { url, ...mqttOpts }, namespace = 'shutter')
|
|
|
127
127
|
publish(`homeassistant/device/${deviceId}/config`, JSON.stringify(autoDiscoveryPayload), { retain: true });
|
|
128
128
|
publish(deviceAvailabilityTopic, 'online', { retain: true });
|
|
129
129
|
});
|
|
130
|
-
|
|
130
|
+
onDispose(async () => {
|
|
131
131
|
publish(deviceAvailabilityTopic, 'offline', { retain: true });
|
|
132
132
|
await client.endAsync();
|
|
133
|
-
};
|
|
133
|
+
});
|
|
134
134
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@uncaught/gpio-shutter-bridge",
|
|
3
3
|
"author": "uncaught <uncaught42@gmail.com>",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.1.0",
|
|
6
6
|
"description": "MQTT shutter bridge for home assistant with Velux KLF 150 support",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|