-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathnotifier
More file actions
executable file
·135 lines (117 loc) · 4.3 KB
/
notifier
File metadata and controls
executable file
·135 lines (117 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env php
<?php
require_once(__DIR__.'/lib/common.php');
require_once(__DIR__.'/lib/visitors.php');
// Getopt is super lousy compared to what you have in modern libraries
// nowadays. This is best we have in PHP and sticking with it
$opts = getopt("hc:s", ["help", "conf:", "ssh"], $rest);
if ($argc !== $rest) {
print("Invalid number of arguments, see --help\n");
exit(1);
}
if (array_key_exists('h', $opts) || array_key_exists('help', $opts)) {
printf("Usage: %s: [--conf=CONFIG_FILE] [--ssh]\n", $argv[0]);
exit(0);
}
// Create new notifier, defaulting to configuration file option
$conffile = @$opts['conf'] ?: @$opts['c'] ?: __DIR__.'/notifier.conf';
$conf = parse_ini_file($conffile, TRUE);
if ($conf === FALSE) {
print("Configuration file invalid\n");
exit(1);
}
// Load localization (premises specific handlers)
require_once(__DIR__.'/lib/localizations/'.$conf['localization'].'.php');
$notifier = new Localization();
// Remote triggering via ssh
if (array_key_exists('s', $opts) || array_key_exists('ssh', $opts)) {
// Remove procedure is in the env as JSON
$rpc_json = getenv('SSH_ORIGINAL_COMMAND');
if ($rpc_json === false) {
print("SSH_ORIGINAL_COMMAND required\n");
exit(2);
}
$rpc = json_decode($rpc_json);
if ($rpc === null) {
printf("Invalid JSON in SSH_ORIGINAL_COMMAND\n");
exit(2);
}
$method = 'ssh_'.$rpc->method;
if (!method_exists($notifier, $method)) {
print("Unsupported method name in selected localization: ".$method."\n");
exit(2);
}
$notifier->$method($rpc);
exit(0);
}
$find_user_by_id = $db->prepare("SELECT * from user WHERE id=?");
$pipe = popen("exec journalctl -n0 -ojson -f -u visitors -u rtl_433 -u hackbus", "r");
$last_press = 0;
while (true) {
$raw = fgets($pipe);
if ($raw === FALSE) {
// EOF
break;
}
$e = json_decode($raw);
if ($e === NULL) {
print("Panic: Not systemd log export format\n");
exit(1);
}
// Try decoding the message as well.
$e->json = json_decode($e->MESSAGE);
switch ($e->_SYSTEMD_UNIT) {
case 'rtl_433.service':
// Radio controlled buttons parsed by rtl_433
// Remove timestamps to identify duplicates
if ($e->json !== NULL) $e->json->time = NULL;
// Name some common RTL error cases
if (strpos($e->MESSAGE, 'rtlsdr_demod_write_reg failed') === 0) {
$e->json = "rtl_error";
} else if (strpos($e->MESSAGE, 'Using device ') === 0) {
$e->json = "rtl_ok";
} else if ($e->json === NULL) {
// Ignore garbage
break;
} else {
if ($e->json->model === 'Generic Remote') {
$e->json->released = $e->json->tristate[11] === '1';
$e->json->chan = strpos($e->json->tristate, '0');
$e->json->button = strpos($e->json->tristate, '0', 4)-4;
$e->json->on = $e->json->tristate[11] === 'F';
$e->json->tristate = NULL; // Not needed anymore
}
}
// If the same state comes soon enough
if (time() < $last_press + 20 && $rtl_433_state === (array)$e->json) break;
// Localize
if ($notifier->radio_button($e->json)) {
// Save last state if successful
$rtl_433_state = (array)$e->json;
$last_press = time();
}
break;
case 'hackbus.service':
// MODBUS controller messages.
// Call handler if there is any payload
if ($e->json === NULL) break;
$notifier->hackbus($e->json->method, $e->json->params);
break;
case 'visitors.service':
// Visitors via DHCP parsed by follow_dhcp.
// Skip if not containing JSON payload
if ($e->json === NULL) break;
// Matrix native visitor information
$notifier->visitors_change($e->json->nicks);
if ($e->json->ids === []) {
// Lab is now empty
$notifier->last_leave(find_leavers($e->json->occupied));
}
if ($e->json->occupied === $e->json->ts) {
// Lab got first visitor
$user = db_execute($find_user_by_id, [$e->json->ids[0]])->fetchArray(SQLITE3_ASSOC);
$notifier->first_join($user);
}
break;
}
}