···
1
1
-
{ config, lib, pkgs, ... }:
1
1
+
{ pkgs, ... }:
2
2
{
3
3
imports = [
4
4
-
./pyscript
5
4
./zigbee.nix
6
6
-
./rooms/bett.nix
7
7
-
./rooms/essen.nix
8
8
-
./rooms/nass.nix
9
5
];
10
6
11
7
krebs.iptables.tables.filter.INPUT.rules = [
···
1
1
-
{ lib, ... }:
2
2
-
rec {
3
3
-
lights = {
4
4
-
bett = "l_bett";
5
5
-
essen = "l_essen";
6
6
-
arbeit = "l_arbeit";
7
7
-
nass = "l_nass";
8
8
-
};
9
9
-
10
10
-
switches = {
11
11
-
dimmer = {
12
12
-
bett = "i_bett";
13
13
-
essen = "i_essen";
14
14
-
nass = "i_nass";
15
15
-
};
16
16
-
};
17
17
-
18
18
-
sensors = {
19
19
-
movement = {
20
20
-
essen = "s_essen";
21
21
-
nass = "s_nass";
22
22
-
};
23
23
-
};
24
24
-
25
25
-
friendly_names =
26
26
-
lib.mapAttrs' (n: v: lib.nameValuePair "light.${v}" { friendly_name = "l.${n}"; }) lights //
27
27
-
lib.mapAttrs' (n: v: lib.nameValuePair "binary_sensor.${v}_update_available" { friendly_name = "s.${n}_up"; }) switches.dimmer //
28
28
-
lib.mapAttrs' (n: v: lib.nameValuePair "binary_sensor.${v}_update_available" { friendly_name = "i.${n}_up"; }) sensors.movement //
29
29
-
lib.mapAttrs' (n: v: lib.nameValuePair "binary_sensor.${v}_update_available" { friendly_name = "l.${n}_up"; }) lights //
30
30
-
lib.mapAttrs' (n: v: lib.nameValuePair "sensor.${v}_linkquality" { friendly_name = "s.${n}_link"; }) switches.dimmer //
31
31
-
lib.mapAttrs' (n: v: lib.nameValuePair "sensor.${v}_linkquality" { friendly_name = "i.${n}_link"; }) sensors.movement //
32
32
-
lib.mapAttrs' (n: v: lib.nameValuePair "sensor.${v}_linkquality" { friendly_name = "l.${n}_link"; }) lights //
33
33
-
lib.mapAttrs' (n: v: lib.nameValuePair "sensor.${v}_battery" { friendly_name = "s.${n}_bat"; }) switches.dimmer //
34
34
-
lib.mapAttrs' (n: v: lib.nameValuePair "sensor.${v}_battery" { friendly_name = "i.${n}_bat"; }) sensors.movement //
35
35
-
lib.mapAttrs' (n: v: lib.nameValuePair "sensor.${v}_action" { friendly_name = "s.${n}_act"; }) switches.dimmer //
36
36
-
lib.mapAttrs' (n: v: lib.nameValuePair "binary_sensor.${v}_occupancy" { friendly_name = "i.${n}_move"; }) sensors.movement //
37
37
-
lib.mapAttrs' (n: v: lib.nameValuePair "binary_sensor.${v}_occupancy" { friendly_name = "i.${n}_move"; }) sensors.movement //
38
38
-
lib.mapAttrs' (n: v: lib.nameValuePair "sensor.${v}_temperature" { friendly_name = "i.${n}_heat"; }) sensors.movement //
39
39
-
lib.mapAttrs' (n: v: lib.nameValuePair "sensor.${v}_temperature" { friendly_name = "i.${n}_heat"; }) sensors.movement //
40
40
-
lib.mapAttrs' (n: v: lib.nameValuePair "sensor.${v}_illuminance" { friendly_name = "i.${n}_lux"; }) sensors.movement //
41
41
-
lib.mapAttrs' (n: v: lib.nameValuePair "sensor.${v}_illuminance" { friendly_name = "i.${n}_lux"; }) sensors.movement //
42
42
-
{};
43
43
-
44
44
-
detect_movement = name: sensor: light: delay:
45
45
-
let
46
46
-
id = name;
47
47
-
sensor_ = "binary_sensor.${sensor}_occupancy";
48
48
-
light_ = "light.${light}";
49
49
-
in {
50
50
-
input_boolean."${id}" = {
51
51
-
};
52
52
-
timer."${id}" = {
53
53
-
duration = delay;
54
54
-
};
55
55
-
automation = [
56
56
-
# {
57
57
-
# alias = "debug detect_movement";
58
58
-
# trigger = {
59
59
-
# platform = "state";
60
60
-
# entity_id = sensor_;
61
61
-
# };
62
62
-
# action = [
63
63
-
# {
64
64
-
# service = "system_log.write";
65
65
-
# data_template = {
66
66
-
# message = "XXXXXXXXXXXXXXXXXXXXXX {{ states('input_boolean.${sensor}_${light}_triggered') == 'on' }}";
67
67
-
# #message = "XXXXXXXXXXXXXXXXXXXXXX {{ state_attr('trigger.to_state.state', 'illuminance') }}";
68
68
-
# };
69
69
-
# }
70
70
-
# ];
71
71
-
# }
72
72
-
{
73
73
-
alias = "movement reset timer ${id}";
74
74
-
trigger = {
75
75
-
platform = "state";
76
76
-
entity_id = sensor_;
77
77
-
from = "off";
78
78
-
to = "on";
79
79
-
};
80
80
-
action = [
81
81
-
{
82
82
-
service = "timer.cancel";
83
83
-
data_template.entity_id = "timer.${id}";
84
84
-
}
85
85
-
];
86
86
-
}
87
87
-
{
88
88
-
alias = "movement on ${id}";
89
89
-
trigger = {
90
90
-
platform = "state";
91
91
-
entity_id = "binary_sensor.${sensor}_occupancy";
92
92
-
from = "off";
93
93
-
to = "on";
94
94
-
};
95
95
-
condition = {
96
96
-
condition = "and";
97
97
-
conditions = [
98
98
-
{
99
99
-
condition = "template";
100
100
-
value_template = "{{ trigger.to_state.attributes.illuminance < 7500 }}";
101
101
-
}
102
102
-
{
103
103
-
condition = "template";
104
104
-
value_template = "{{ states('${light_}') == 'off' }}";
105
105
-
}
106
106
-
];
107
107
-
};
108
108
-
action = [
109
109
-
{
110
110
-
service = "light.turn_on";
111
111
-
data_template = {
112
112
-
entity_id = light_;
113
113
-
brightness = "100";
114
114
-
};
115
115
-
}
116
116
-
{ delay = "0:00:02"; }
117
117
-
{
118
118
-
service = "input_boolean.turn_on";
119
119
-
data_template.entity_id = "input_boolean.${id}";
120
120
-
}
121
121
-
];
122
122
-
}
123
123
-
{
124
124
-
alias = "movement off ${id}";
125
125
-
trigger = {
126
126
-
platform = "state";
127
127
-
entity_id = sensor_;
128
128
-
from = "on";
129
129
-
to = "off";
130
130
-
};
131
131
-
condition = {
132
132
-
condition = "template";
133
133
-
value_template = "{{ states('input_boolean.${id}') == 'on' }}";
134
134
-
};
135
135
-
action = [
136
136
-
{
137
137
-
service = "timer.start";
138
138
-
entity_id = "timer.${id}";
139
139
-
}
140
140
-
];
141
141
-
}
142
142
-
{
143
143
-
alias = "movement override ${id}";
144
144
-
trigger = {
145
145
-
platform = "state";
146
146
-
entity_id = light_;
147
147
-
};
148
148
-
action = [
149
149
-
{
150
150
-
service = "input_boolean.turn_off";
151
151
-
data_template.entity_id = "input_boolean.${id}";
152
152
-
}
153
153
-
{
154
154
-
service = "system_log.write";
155
155
-
data_template = {
156
156
-
message = "XXXXXXXXXXXXXXXXXXXXXX {{ trigger }}";
157
157
-
};
158
158
-
}
159
159
-
];
160
160
-
}
161
161
-
{
162
162
-
alias = "movement expired ${id}";
163
163
-
trigger = {
164
164
-
platform = "event";
165
165
-
event_type = "timer.finished";
166
166
-
event_data.entity_id = "timer.${id}";
167
167
-
};
168
168
-
action = [
169
169
-
{
170
170
-
service = "light.turn_off";
171
171
-
data_template = {
172
172
-
entity_id = light_;
173
173
-
};
174
174
-
}
175
175
-
{
176
176
-
service = "input_boolean.turn_off";
177
177
-
data_template.entity_id = "input_boolean.${id}";
178
178
-
}
179
179
-
];
180
180
-
}
181
181
-
];
182
182
-
};
183
183
-
184
184
-
lightswitch = name: switch: light: {
185
185
-
automation = [
186
186
-
{
187
187
-
alias = "lightswitch ${name} turn on";
188
188
-
trigger = {
189
189
-
platform = "mqtt";
190
190
-
topic = "zigbee/${switch}";
191
191
-
};
192
192
-
condition = {
193
193
-
condition = "or";
194
194
-
conditions = [
195
195
-
{
196
196
-
condition = "template";
197
197
-
value_template = "{{ trigger.payload_json.action == 'on-press' }}";
198
198
-
}
199
199
-
{
200
200
-
condition = "template";
201
201
-
value_template = "{{ trigger.payload_json.action == 'up-press' }}";
202
202
-
}
203
203
-
{
204
204
-
condition = "and";
205
205
-
conditions = [
206
206
-
{
207
207
-
condition = "template";
208
208
-
value_template = "{{ trigger.payload_json.action == 'down-press' }}";
209
209
-
}
210
210
-
{
211
211
-
condition = "template";
212
212
-
value_template = "{{ trigger.payload_json.brightness > 30 }}";
213
213
-
}
214
214
-
];
215
215
-
}
216
216
-
];
217
217
-
};
218
218
-
action = [
219
219
-
{
220
220
-
service = "light.turn_on";
221
221
-
data_template = {
222
222
-
entity_id = "light.${light}";
223
223
-
brightness = "{{ trigger.payload_json.brightness }}";
224
224
-
};
225
225
-
}
226
226
-
];
227
227
-
}
228
228
-
{
229
229
-
alias = "lightswitch ${name} turn off";
230
230
-
trigger = {
231
231
-
platform = "mqtt";
232
232
-
topic = "zigbee/${switch}";
233
233
-
};
234
234
-
condition = {
235
235
-
condition = "or";
236
236
-
conditions = [
237
237
-
{
238
238
-
condition = "template";
239
239
-
value_template = "{{ trigger.payload_json.action == 'off-press' }}";
240
240
-
}
241
241
-
{
242
242
-
condition = "template";
243
243
-
value_template = "{{ trigger.payload_json.brightness < 30 }}";
244
244
-
}
245
245
-
];
246
246
-
};
247
247
-
action = {
248
248
-
service = "light.turn_off";
249
249
-
data_template = {
250
250
-
entity_id = "light.${light}";
251
251
-
};
252
252
-
};
253
253
-
}
254
254
-
];
255
255
-
};
256
256
-
}
···
1
1
-
{ config, lib, pkgs, ... }:
2
2
-
{
3
3
-
systemd.tmpfiles.rules = [
4
4
-
"L+ /var/lib/hass/custom_components/pyscript - - - - ${pkgs.fetchzip {
5
5
-
url = "https://github.com/custom-components/pyscript/releases/download/1.3.2/hass-custom-pyscript.zip";
6
6
-
sha256 = "0cqdjj46s5xp4mqxb0ic790jm1xp3z0zr2n9f7bsfl5zpvdshl8z";
7
7
-
stripRoot = false;
8
8
-
}}"
9
9
-
];
10
10
-
11
11
-
services.home-assistant = {
12
12
-
package = (pkgs.home-assistant.overrideAttrs (old: {
13
13
-
doInstallCheck = false;
14
14
-
})).override {
15
15
-
extraPackages = pp: [ pp.croniter ];
16
16
-
};
17
17
-
config.pyscript = {
18
18
-
allow_all_imports = true;
19
19
-
hass_is_global = true;
20
20
-
};
21
21
-
};
22
22
-
23
23
-
networking.firewall.interfaces.retiolum.allowedTCPPortRanges = [
24
24
-
{ from = 50321; to = 50341; } # for ipython interactive debugging
25
25
-
];
26
26
-
}
···
1
1
-
{ pkgs ? import <nixpkgs> {} }: let
2
2
-
3
3
-
hass_host = "styx.r";
4
4
-
hass_token = builtins.readFile ./hass_token;
5
5
-
6
6
-
mach-nix = import (builtins.fetchGit {
7
7
-
url = "https://github.com/DavHau/mach-nix/";
8
8
-
ref = "refs/tags/3.4.0";
9
9
-
}) {
10
10
-
pkgs = pkgs;
11
11
-
};
12
12
-
pyenv = mach-nix.mkPython {
13
13
-
requirements = ''
14
14
-
hass_pyscript_kernel
15
15
-
'';
16
16
-
};
17
17
-
jupyter = import (builtins.fetchGit {
18
18
-
url = https://github.com/tweag/jupyterWith;
19
19
-
ref = "master";
20
20
-
}) {};
21
21
-
22
22
-
pyscriptKernel = {
23
23
-
spec = pkgs.runCommand "pyscript" {} ''
24
24
-
mkdir -p $out/kernels/pyscript
25
25
-
cp ${kernel_json} $out/kernels/pyscript/kernel.json
26
26
-
cp ${pyscript_conf} $out/kernels/pyscript/pyscript.conf
27
27
-
'';
28
28
-
runtimePackages = [ pyenv ];
29
29
-
};
30
30
-
31
31
-
kernel_json = pkgs.writeText "kernel.json" (builtins.toJSON {
32
32
-
argv = [
33
33
-
"${pyenv}/bin/python3" "-m" "hass_pyscript_kernel"
34
34
-
"-f" "{connection_file}"
35
35
-
];
36
36
-
display_name = "hass_pyscript";
37
37
-
language = "python";
38
38
-
});
39
39
-
40
40
-
pyscript_conf = pkgs.writeText "pyscript.conf" ''
41
41
-
[homeassistant]
42
42
-
hass_host = ${hass_host}
43
43
-
hass_url = http://''${hass_host}:8123
44
44
-
hass_token = ${hass_token}
45
45
-
'';
46
46
-
47
47
-
jupyterEnvironment = jupyter.jupyterlabWith {
48
48
-
kernels = [ pyscriptKernel ];
49
49
-
};
50
50
-
51
51
-
in jupyterEnvironment.env
···
1
1
-
{ lib, ... }:
2
2
-
with import ../lib.nix { inherit lib; };
3
3
-
4
4
-
{
5
5
-
services.home-assistant.config = lib.mkMerge [
6
6
-
(lightswitch "bett" switches.dimmer.bett lights.bett)
7
7
-
];
8
8
-
9
9
-
# lass.hass.love = {
10
10
-
# resources = [{
11
11
-
# url = "https://raw.githubusercontent.com/ljmerza/light-entity-card/master/dist/light-entity-card.js.map";
12
12
-
# type = "js";
13
13
-
# }];
14
14
-
# views = [{
15
15
-
# title = "bett";
16
16
-
# cards = [
17
17
-
# {
18
18
-
# type = "markdown";
19
19
-
# title = "hello world";
20
20
-
# content = "This is just a test";
21
21
-
# }
22
22
-
# {
23
23
-
# type = "light";
24
24
-
# entity = "light.${lights.bett}";
25
25
-
# }
26
26
-
# {
27
27
-
# type = "custom:light-entity-card";
28
28
-
# entity = "light.${lights.bett}";
29
29
-
# }
30
30
-
# {
31
31
-
# type = "history-graph";
32
32
-
# entities = [
33
33
-
# "light.${lights.bett}"
34
34
-
# ];
35
35
-
# }
36
36
-
# ];
37
37
-
# }];
38
38
-
# };
39
39
-
}
···
1
1
-
{ lib, ... }:
2
2
-
with import ../lib.nix { inherit lib; };
3
3
-
4
4
-
{
5
5
-
services.home-assistant.config = lib.mkMerge [
6
6
-
(detect_movement "essen" sensors.movement.essen lights.essen 70)
7
7
-
(lightswitch "essen" switches.dimmer.essen lights.essen)
8
8
-
];
9
9
-
}
···
1
1
-
{ lib, ... }:
2
2
-
with import ../lib.nix { inherit lib; };
3
3
-
4
4
-
{
5
5
-
services.home-assistant.config = lib.mkMerge [
6
6
-
(detect_movement "nass" sensors.movement.nass lights.nass 100)
7
7
-
(lightswitch "nass" switches.dimmer.nass lights.nass)
8
8
-
];
9
9
-
}
10
10
-