Add module.nix
This commit is contained in:
parent
ff0822d1bc
commit
08f8d721fa
|
@ -17,7 +17,7 @@
|
|||
packages = rec {
|
||||
default = snooper-server;
|
||||
snooper-server = helpers.packages."${system}".mkClojureBin {
|
||||
name = "org.fudo/snooper";
|
||||
name = "org.fudo/snooper-server";
|
||||
primaryNamespace = "snooper.cli";
|
||||
src = ./.;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
packages:
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
snooper-server = packages."${pkgs.system}.snooper-server";
|
||||
cfg = config.services.snooper;
|
||||
|
||||
in {
|
||||
options.services.snooper = with types; {
|
||||
enable = mkEnableOption "Enable Snooper notifiaction server.";
|
||||
|
||||
verbose = mkEnableOption "Generate verbose logs and output.";
|
||||
|
||||
event-topics = mkOption {
|
||||
type = listOf str;
|
||||
description = "MQTT topics on which to listen for detection events.";
|
||||
};
|
||||
|
||||
notification-topic = mkOption {
|
||||
type = str;
|
||||
description = "MQTT topic on which to send notifications.";
|
||||
};
|
||||
|
||||
mqtt-client = {
|
||||
host = mkOption {
|
||||
type = str;
|
||||
description = "Hostname of the MQTT server.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = port;
|
||||
description = "Port on which the MQTT server is listening.";
|
||||
default = 1883;
|
||||
};
|
||||
|
||||
username = mkOption {
|
||||
type = str;
|
||||
description = "User as which to connect to the MQTT server.";
|
||||
};
|
||||
|
||||
password-file = mkOption {
|
||||
type = str;
|
||||
description =
|
||||
"File (on the local host) containing the password for the MQTT server.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.snooper = {
|
||||
path = [ snooper-server ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
LoadCredential = [ "mqtt.passwd:${cfg.mqtt-client.password-file}" ];
|
||||
ExecStart = pkgs.writeShellScript "snooper-server.sh"
|
||||
(concatStringsSep " " ([
|
||||
"snooper-server"
|
||||
"--mqtt-host=${cfg.mqtt.host}"
|
||||
"--mqtt-port=${toString cfg.mqtt.port}"
|
||||
"--mqtt-user=${cfg.mqtt.username}"
|
||||
"--mqtt-password-file=$CREDENTIALS_DIRECTORY/mqtt.passwd"
|
||||
"--notification-topic=${cfg.notification-topic}"
|
||||
] ++ (map (topic: "--event-topic=${topic}") cfg.event-topics)
|
||||
++ (optional cfg.verbose "--verbose")));
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -5,10 +5,12 @@
|
|||
[clojure.string :as str]
|
||||
[snooper.core :as snooper]
|
||||
[milquetoast.client :as mqtt]
|
||||
[fudo-clojure.logging :as log]))
|
||||
[fudo-clojure.logging :as log])
|
||||
(:gen-class))
|
||||
|
||||
(def cli-opts
|
||||
[["-v" "--verbose" "Provide verbose output."]
|
||||
["-h" "--help" "Print this message."]
|
||||
|
||||
[nil "--mqtt-host HOSTNAME" "Hostname of MQTT server."]
|
||||
[nil "--mqtt-port PORT" "Port on which to connect to the MQTT server."
|
||||
|
@ -44,13 +46,15 @@
|
|||
(defn -main [& args]
|
||||
(let [required-args #{:mqtt-host :mqtt-port :mqtt-user :mqtt-password-file :event-topic :notification-topic}
|
||||
{:keys [options _ errors summary]} (parse-opts args required-args cli-opts)]
|
||||
(when (:help options) (msg-quit 0 (usage summary)))
|
||||
(when (seq errors) (msg-quit 1 (usage summary errors)))
|
||||
(let [{:keys [mqtt-host
|
||||
mqtt-port
|
||||
mqtt-user
|
||||
mqtt-password-file
|
||||
notification-topic
|
||||
event-topic]} options
|
||||
event-topic
|
||||
verbose]} options
|
||||
catch-shutdown (async/chan)
|
||||
mqtt-client (mqtt/connect-json! :host mqtt-host
|
||||
:port mqtt-port
|
||||
|
@ -59,13 +63,18 @@
|
|||
(slurp)
|
||||
(str/trim)))
|
||||
logger (log/print-logger)]
|
||||
(snooper/listen! :mqtt-client mqtt-client
|
||||
(when verbose
|
||||
(println (format "launching snooper server to listen on %s and report events on %s"
|
||||
event-topic notification-topic)))
|
||||
(snooper/listen! :mqtt-client mqtt-client
|
||||
:notification-topic notification-topic
|
||||
:event-topics event-topic
|
||||
:logger logger)
|
||||
:logger logger
|
||||
:verbose verbose)
|
||||
(.addShutdownHook (Runtime/getRuntime)
|
||||
(Thread. (fn [] (>!! catch-shutdown true))))
|
||||
(<!! catch-shutdown)
|
||||
(println "stopping snooper server")
|
||||
;; Stopping the MQTT will stop tattler
|
||||
(mqtt/stop! mqtt-client)
|
||||
(System/exit 0))))
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
(ns snooper.core
|
||||
(:require [clojure.core.async :refer [go-loop alts! chan]]
|
||||
(:require [clojure.core.async :refer [go-loop alts!]]
|
||||
[clojure.pprint :refer [pprint]]
|
||||
[fudo-clojure.logging :as log]
|
||||
[milquetoast.client :as mqtt]
|
||||
[malli.core :as t]))
|
||||
|
||||
(defn pthru [o] (clojure.pprint/pprint o) o)
|
||||
|
||||
(def critical-objects [:person :bear])
|
||||
(def normal-objects [:cat :dog])
|
||||
|
||||
(defn- verbose-pthru [verbose obj]
|
||||
(when verbose (pprint obj))
|
||||
obj)
|
||||
|
||||
(defn- objects-criticality [objs]
|
||||
(cond (some (partial contains? objs) critical-objects) :high
|
||||
(some (partial contains? objs) normal-objects) :medium
|
||||
:else nil))
|
||||
:else :low))
|
||||
|
||||
(defn- objects-probability [objs]
|
||||
(let [prob (apply max (vals objs))]
|
||||
|
@ -58,7 +61,7 @@
|
|||
(defmethod event-summary :possibly [{:keys [description location]}]
|
||||
(format "There could possibly be %s at the %s" description location))
|
||||
(defmethod event-summary :likely [{:keys [description location]}]
|
||||
(format "There's might %s at the %s" description location))
|
||||
(format "There might be %s at the %s" description location))
|
||||
(defmethod event-summary :probably [{:keys [description location]}]
|
||||
(format "There's probably %s at the %s" description location))
|
||||
(defmethod event-summary :definitely [{:keys [description location]}]
|
||||
|
@ -84,17 +87,19 @@
|
|||
[& {mqtt-client :mqtt-client
|
||||
notification-topic :notification-topic
|
||||
event-topics :event-topics
|
||||
logger :logger}]
|
||||
logger :logger
|
||||
verbose :verbose}]
|
||||
(let [incoming (map (partial mqtt/subscribe! mqtt-client) event-topics)
|
||||
valid-evt? (t/validator MotionEvent)]
|
||||
(go-loop [evts (alts! incoming)]
|
||||
(let [evt (first evts)]
|
||||
(clojure.pprint/pprint evt)
|
||||
(when verbose (pprint evt))
|
||||
(cond (nil? evt) (log/info! logger "stopping")
|
||||
(valid-evt? evt) (do (log/info! logger (format "received motion event id %s from %s"
|
||||
(:id evt)
|
||||
(:topic evt)))
|
||||
(mqtt/send! mqtt-client notification-topic (pthru (translate-event (:payload evt))))
|
||||
(mqtt/send! mqtt-client notification-topic
|
||||
(verbose-pthru verbose (translate-event (:payload evt))))
|
||||
(recur (alts! incoming)))
|
||||
:else (do (log/error! logger (format "invalid motion event: %s" evt))
|
||||
(recur (alts! incoming))))))))
|
||||
|
|
Loading…
Reference in New Issue