Compare commits

...

2 Commits

Author SHA1 Message Date
Aaska Black Wolf 7da503ce68 completed monitor queries and added option for test messages 2026-06-03 20:14:56 +02:00
Aaska Black Wolf e3424352d9 added information regarding test messages to README.md 2026-06-03 20:13:51 +02:00
2 changed files with 116 additions and 29 deletions
+12 -2
View File
@@ -11,7 +11,7 @@ The file is structured by directives controlling the various aspects of the prog
### service ### service
In this directive you define the notification service to use. VE.Direct-notify is tested and proofed working with the OpenSource notification service ntfy. In this directive you define the notification service to use. VE.Direct-notify is tested and proofed working with the OpenSource notification service ntfy.
The topic URL to use is derived from the parameters url and topic combined. the parameter url is to be given *without a trailing slash*. The topic URL to use is derived from the parameters url and topic combined. the parameter url is to be given **without a trailing slash**.
VE.Direct-notify supports conneting to notification services with and without authentication. Authentication can be by Username/Password or Authentication Token. VE.Direct-notify supports conneting to notification services with and without authentication. Authentication can be by Username/Password or Authentication Token.
example without authentication: example without authentication:
@@ -23,7 +23,7 @@ example without authentication:
``` ```
examaple with authentication using a username and password: example with authentication using a username and password:
``` ```
"service": { "service": {
"url": "https://ntfy.yourdomain.com", "url": "https://ntfy.yourdomain.com",
@@ -117,6 +117,16 @@ Once tested successfully, it can be set up as a cron-job:
In the cron table fill in a line like this: In the cron table fill in a line like this:
`0 * * * * php /path/to/your/VE.Direct-ntfy-instance/worker.php` `0 * * * * php /path/to/your/VE.Direct-ntfy-instance/worker.php`
### send test message to notification server
VE.Direct-notify is able to send test messages to the notification serivce to check whether it can use the configured service properly.
To send a test message the following command can be used on the command line:
```
$ cd /path/to/your/VE.Direct-ntfy-instance
$ php worker.php test <notificationType>
```
<notificationType> shall be replaced by either warning or error.
## Troubleshooting ## Troubleshooting
## Contributing ## Contributing
+102 -25
View File
@@ -8,38 +8,52 @@
* You should have received a copy of the license with this software * You should have received a copy of the license with this software
*/ */
// read configuration
$config = readConfig(); $config = readConfig();
if( !isset($config) )
exit("Error reading configuration! Exit!\r\n");
// check whether test message shall be delivered to notification service
if( $argc >= 3 && $argv[1] == "test" && isset($argv[2]) ) {
sendMessage($argv[2] . ": Testmessage");
exit();
}
queryMonitors(); queryMonitors();
function readConfig() { function checkCondition($value, $condition) {
return json_decode( file_get_contents('config.json') ); switch($condition[0]) {
} case "e": // equal
if($value == $condition[1])
function sendMessage($message) { return ' equals ' . $condition[1];
global $config; break;
$authorization = ""; case "gt": // greater than
if( floatval($value) > floatval($condition[1]) )
if( defined($config->service->username) && defined($config->service->password) ) return ' = ' . $value . ' and greater than ' . $condition[1];
$authorization = 'Basic ' + base64_encode($config->service->username + ':' + $config->service->password); break;
elseif( defined($config->service->token) ) case "gte": // greater than or equal
$authorization = 'Bearer ' + $config->service->token; if( floatval($value) >= floatval($condition[1]) )
return ' = ' . $value . ' and greater than or equal ' . $condition[1];
$result = file_get_contents( $config->service->url + '/' + $config->service->topic, false, stream_context_create([ break;
'http' => [ case "lt": // lower than
'method' => 'POST', if( floatval($value) < floatval($condition[1]) )
'header' => return ' = ' . $value . ' and lower than ' . $condition[1];
'Content-Type: text/plain\r\n' . break;
'Authorization: ' + $authorization, case "lte": // lower than or equal
'content' => $message if( floatval($value) <= floatval($condition[1]) )
] return ' = ' . $value . ' and lower than or equal ' . $condition[1];
])); break;
case "ne": // not equal
return true; if($value != $condition[1])
return ' = ' . $value . ' and not equal to ' . $condition[1];
break;
}
return false;
} }
function queryMonitors() { function queryMonitors() {
global $config; global $config;
// establish database connection // establish database connection
$dbPath = (str_starts_with($config->database, '/')) ? $config->database : dirname(__FILE__) . '/' . $config->database; $dbPath = (str_starts_with($config->database, '/')) ? $config->database : dirname(__FILE__) . '/' . $config->database;
try { try {
@@ -49,6 +63,7 @@ function queryMonitors() {
print ('error detected: ' . $e->getMessage() . "\r\n"); print ('error detected: ' . $e->getMessage() . "\r\n");
return false; return false;
} }
// query devices from database // query devices from database
$sql = "SELECT name FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%' AND name <> 'meta' ORDER BY name ASC;"; $sql = "SELECT name FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%' AND name <> 'meta' ORDER BY name ASC;";
$data = $db->query($sql); $data = $db->query($sql);
@@ -59,12 +74,74 @@ function queryMonitors() {
$sql = "SELECT * FROM '" . $device['name'] . "' ORDER BY date DESC, time DESC LIMIT 1;"; $sql = "SELECT * FROM '" . $device['name'] . "' ORDER BY date DESC, time DESC LIMIT 1;";
$res = $db->query($sql)->fetchArray(SQLITE3_NUM); $res = $db->query($sql)->fetchArray(SQLITE3_NUM);
$dataset = json_decode($res[2]); $dataset = json_decode($res[2]);
print_r($dataset);
// read last status of warnings and errors for comparison to avoid double sending of notifications
$statusFile = __DIR__ . '/status/' . $device['name'];
$lastStatus = [];
if( is_file($statusFile) )
$lastStatus = json_decode( file_get_contents( $statusFile ), true );
// process configured monitors // process configured monitors
foreach($config->monitors as $monitor) { foreach($config->monitors as $monitor) {
if( !empty($monitor->warning) ) {
if( !isset( $lastStatus[$monitor->parameter]['warning'] ) )
$lastStatus[$monitor->parameter]['warning'] = 0;
$status = checkCondition($dataset->{$monitor->parameter}, $monitor->warning);
if( $status && $lastStatus[$monitor->parameter]['warning'] == 0 ) { // new warning
sendMessage('Warning from ' . $device['name'] . ': ' . $monitor->parameter . $status);
$lastStatus[$monitor->parameter]['warning'] = 1;
} }
else if( !$status && $lastStatus[$monitor->parameter]['warning'] == 1) { // warning cleared
sendMessage( 'Warning cleared on ' . $device['name'] . '. ' . $monitor->parameter . ' = ' . $dataset->{$monitor->parameter} . ' and back to normal.');
$lastStatus[$monitor->parameter]['warning'] = 0;
}
}
if( !empty($monitor->error) ) {
if( !isset( $lastStatus[$monitor->parameter]['error'] ) )
$lastStatus[$monitor->parameter]['error'] = 0;
$status = checkCondition($dataset->{$monitor->parameter}, $monitor->error);
if( $status && $lastStatus[$monitor->parameter]['error'] == 0 ) { // new error!
sendMessage('Error from ' . $device['name'] . ': ' . $monitor->parameter . $status);
$lastStatus[$monitor->parameter]['error'] = 1;
}
else if( !$status && $lastStatus[$monitor->parameter]['error'] == 1 ) { // error cleared
sendMessage('Error cleared on ' . $device['name'] . '. ' . $monitor->parameter . ' = ' . $dataset->{$monitor->parameter} . ' and out of critical range.');
$lastStatus[$monitor->parameter]['error'] = 0;
}
}
}
file_put_contents( $statusFile, json_encode($lastStatus) );
} }
} }
function readConfig() {
return json_decode( file_get_contents(__DIR__ . '/config.json') );
}
function sendMessage($message) {
global $config;
$authorization = "Authorization: ";
if( !empty($config->service->username) && !empty($config->service->password) )
$authorization .= 'Basic ' . base64_encode($config->service->username . ':' . $config->service->password);
elseif( !empty($config->service->auth_token) )
$authorization .= 'Bearer ' . $config->service->auth_token;
else
$authorization = '';
$result = file_get_contents( $config->service->url . '/' . $config->service->topic, false, stream_context_create([
'http' => [
'method' => 'POST',
'header' =>
"Content-Type: text/plain\r\n" .
$authorization,
'content' => $message
]
]));
return true;
}
?> ?>