listeningdaemon/visualiser/visualiser.el
2024-10-31 16:04:08 +00:00

288 lines
11 KiB
EmacsLisp

;; visualiser.el
(load-file "~/.emacs.d/elpa/dash-20240510.1327/dash.elc")
(load-file "~/.emacs.d/elpa/mqtt-mode-20180611.1735/mqtt-mode.elc")
(require 'dash)
(require 'mqtt-mode)
(toggle-debug-on-error)
;; directory variables
(defconst graphviz-command "circo")
(defconst graphviz-graph-output-format "svg")
(defconst graphviz-graph-output-dir "graphs/")
(defconst graphviz-image-output-dir (concat graphviz-graph-output-format "s/"))
(defconst working-directory "~/Applications/listeningdaemon/visualiser/")
(load-file (concat working-directory "secrets.el"))
;; colors
;; (defconst on-color "black" "The default color for objects which are active")
(defconst off-color "invis" "The default color for objects which are not active")
(defvar colors '("black" "red" "green" "blue" "magenta" "yellow" "orange" "purple" "cyan")
"colors for the nodes and edges to choose from")
;;; nodes
;; default colors
(defvar fan-one-color off-color)
(defvar fan-two-color off-color)
(defvar radio-one-color off-color)
(defvar lamp-one-color off-color)
(defvar lamp-two-color off-color)
(defvar printer-one-color off-color)
(defvar printer-two-color off-color)
;;; edges
;; default colors
(defvar fan-one-fan-two-color off-color)
(defvar fan-one-radio-one-color off-color)
(defvar fan-one-lamp-one-color off-color)
(defvar fan-one-lamp-two-color off-color)
(defvar fan-one-printer-one-color off-color)
(defvar fan-one-printer-two-color off-color)
(defvar fan-two-radio-one-color off-color)
(defvar fan-two-lamp-one-color off-color)
(defvar fan-two-lamp-two-color off-color)
(defvar fan-two-printer-one-color off-color)
(defvar fan-two-printer-two-color off-color)
(defvar radio-one-lamp-one-color off-color)
(defvar radio-one-lamp-two-color off-color)
(defvar radio-one-printer-one-color off-color)
(defvar radio-one-printer-two-color off-color)
(defvar lamp-one-lamp-two-color off-color)
(defvar lamp-one-printer-one-color off-color)
(defvar lamp-one-printer-two-color off-color)
(defvar lamp-two-printer-one-color off-color)
(defvar lamp-two-printer-two-color off-color)
(defvar printer-one-printer-two-color off-color)
(setq snapshot 10000)
(defun turn-object-on (object)
"Turn an object on"
nil
nil
(setq on-color (elt colors (random (length colors))))
(cond ((equal object 'fan-one)
(setq fan-one-color on-color)
(format-graph))
((equal object 'fan-two)
(setq fan-two-color on-color)
(format-graph))
((equal object 'lamp-one)
(setq lamp-one-color on-color)
(format-graph))
((equal object 'lamp-two)
(setq lamp-two-color on-color)
(format-graph))
((equal object 'radio-one)
(setq radio-one-color on-color)
(format-graph))
((equal object 'printer-one)
(setq printer-one-color on-color)
(format-graph))
((equal object 'printer-two)
(setq printer-two-color on-color)
(format-graph))))
(defun turn-object-off (object)
"Turn an object off"
nil
nil
(cond ((equal object 'fan-one)
(setq fan-one-color off-color)
(format-graph))
((equal object 'fan-two)
(setq fan-two-color off-color)
(format-graph))
((equal object 'lamp-one)
(setq lamp-one-color off-color)
(format-graph))
((equal object 'lamp-two)
(setq lamp-two-color off-color)
(format-graph))
((equal object 'radio-one)
(setq radio-one-color off-color)
(format-graph))
((equal object 'printer-one)
(setq printer-one-color off-color)
(format-graph))
((equal object 'printer-two)
(setq printer-one-color off-color)
(format-graph))))
(defun graph-write-file-quietly ()
"Write the graph buffer to a graphviz file quietly"
(let ((inhibit-message t))
(write-file (concat working-directory graphviz-graph-output-dir "graph" (number-to-string snapshot) ".dot") t)))
(defun format-graph-image-numbered ()
"format the numbered image of the graph quietly, for the .gif"
(let ((inhibit-message t))
(shell-command
(concat graphviz-command " -T" graphviz-graph-output-format " "
working-directory graphviz-graph-output-dir (concat "graph" (number-to-string snapshot) ".dot")
" -o "
working-directory graphviz-image-output-dir
(concat "graph" (number-to-string snapshot) "." graphviz-graph-output-format)))))
(defun format-graph-image-main ()
"format the image of the main graph quietly"
nil
nil
(let ((inhibit-message t))
(shell-command
(concat graphviz-command " -T" graphviz-graph-output-format " "
working-directory graphviz-graph-output-dir (concat "graph" (number-to-string snapshot) ".dot")
" -o "
;; working-directory "main." graphviz-graph-output-format
;; output the generated image to /var/www/ so that the webpage stays updated
"/var/www/img/main." graphviz-graph-output-format
))))
(defun format-graph ()
"Series of functions to format the graph to display in the browser
and ultimately turn into a .gif"
nil
nil
;; preprocess graph
(shell-command (concat "cpp -DFAN_ONE=" fan-one-color " "
"-DFAN_TWO=" fan-two-color " "
"-DRADIO_ONE=" radio-one-color " "
"-DLAMP_ONE=" lamp-one-color " "
"-DLAMP_TWO=" lamp-two-color " "
"-DPRINTER_ONE=" printer-one-color " "
"-DPRINTER_TWO=" printer-two-color " "
"-DFAN_ONE_FAN_TWO=" fan-one-fan-two-color " "
"-DFAN_ONE_RADIO_ONE=" fan-one-radio-one-color " "
"-DFAN_ONE_LAMP_ONE=" fan-one-lamp-one-color " "
"-DFAN_ONE_LAMP_TWO=" fan-one-lamp-two-color " "
"-DFAN_ONE_PRINTER_ONE=" fan-one-printer-one-color " "
"-DFAN_ONE_PRINTER_TWO=" fan-one-printer-two-color " "
"-DFAN_TWO_RADIO_ONE=" fan-two-radio-one-color " "
"-DFAN_TWO_LAMP_ONE=" fan-two-lamp-one-color " "
"-DFAN_TWO_LAMP_TWO=" fan-two-lamp-two-color " "
"-DFAN_TWO_PRINTER_ONE=" fan-two-printer-one-color " "
"-DFAN_TWO_PRINTER_TWO=" fan-two-printer-two-color " "
"-DRADIO_ONE_LAMP_ONE=" radio-one-lamp-one-color " "
"-DRADIO_ONE_LAMP_TWO=" radio-one-lamp-two-color " "
"-DRADIO_ONE_PRINTER_ONE=" radio-one-printer-one-color " "
"-DRADIO_ONE_PRINTER_TWO=" radio-one-printer-two-color " "
"-DLAMP_ONE_LAMP_TWO=" lamp-one-lamp-two-color " "
"-DLAMP_ONE_PRINTER_ONE=" lamp-one-printer-one-color " "
"-DLAMP_ONE_PRINTER_TWO=" lamp-one-printer-two-color " "
"-DLAMP_TWO_PRINTER_ONE=" lamp-two-printer-one-color " "
"-DLAMP_TWO_PRINTER_TWO=" lamp-two-printer-two-color " "
"-DPRINTER_ONE_PRINTER_TWO=" printer-one-printer-two-color " "
working-directory "main.dot")
(concat "graph" (number-to-string snapshot) ".dot") "*Error*")
(switch-to-buffer-other-window
(concat "graph" (number-to-string snapshot) ".dot"))
(set-mark (point))
(forward-line 6)
(kill-region 0 (point) t)
(graph-write-file-quietly)
;; create a backup of the graph, for the .gif
(format-graph-image-numbered)
;; change main.png for displaying in the browser
(format-graph-image-main)
(setq snapshot (+ snapshot 1)))
;; (illuminate-edges '("transform" "printer" "one" "fan" "two") "1")
(defun illuminate-edges (topic payload)
"Function to illuminate the edges of the graph"
nil
nil
(setq on-color (elt colors (random (length colors))))
(let ((payload (string-limit payload 1)))
(let ((from-object (string-join (list (cadr topic) (caddr topic)) "-"))
(to-object (string-join (list (cadddr topic) (car (last topic))) "-")))
(message "From: %s" from-object)
(message "To: %s" to-object)
(when (string-equal payload "1")
(set (intern (concat from-object "-" to-object "-color")) on-color)
(set (intern (concat to-object "-" from-object "-color")) on-color))
(when (string-equal payload "0")
(set (intern (concat from-object "-" to-object "-color")) off-color)
(set (intern (concat to-object "-" from-object "-color")) off-color))
(format-graph))))
(defun illuminate-nodes (topic payload)
"Function to illuminate the nodes on the graph, a decision tree"
nil
nil
(setq on-color (elt colors (random (length colors))))
(let ((payload (string-limit payload 1)))
;;(message "Topic: %s. Payload %s." topic payload)
(cond ((and (member "fan" topic) (member "one" topic) (string-equal "1" payload))
(turn-object-on 'fan-one)
(message "Fan one turns on"))
((and (member "fan" topic) (member "one" topic) (string-equal "0" payload))
(message "Fan one turns off")
(turn-object-off 'fan-one))
((and (member "fan" topic) (member "two" topic) (string-equal "1" payload))
(message "Fan two turns on")
(turn-object-on 'fan-two))
((and (member "fan" topic) (member "two" topic) (string-equal "0" payload))
(message "Fan two turns off")
(turn-object-off 'fan-two))
((and (member "lamp" topic) (member "one" topic) (string-equal "1" payload))
(message "Lamp one turns on")
(turn-object-on 'lamp-one))
((and (member "lamp" topic) (member "one" topic) (string-equal "0" payload))
(message "Lamp one turns off")
(turn-object-off 'lamp-one))
((and (member "lamp" topic) (member "two" topic) (string-equal "1" payload))
(message "lamp two turns on")
(turn-object-on 'lamp-two))
((and (member "lamp" topic) (member "two" topic) (string-equal "0" payload))
(message "lamp two turns off")
(turn-object-off 'lamp-two))
((and (member "radio" topic) (member "one" topic) (string-equal "1" payload))
(turn-object-on 'radio-one))
((and (member "radio" topic) (member "one" topic) (string-equal "0" payload))
(turn-object-off 'radio-one))
((and (member "printer" topic) (member "one" topic) (string-equal "2" payload))
(turn-object-on 'printer-one))
((and (member "printer" topic) (member "one" topic) (string-equal "1" payload))
(turn-object-on 'printer-one))
((and (member "printer" topic) (member "one" topic) (string-equal "0" payload))
(turn-object-off 'printer-one))
((and (member "printer" topic) (member "two" topic) (string-equal "2" payload))
(turn-object-on 'printer-two))
((and (member "printer" topic) (member "two" topic) (string-equal "1" payload))
(turn-object-on 'printer-two))
((and (member "printer" topic) (member "two" topic) (string-equal "0" payload))
(turn-object-off 'printer-two)))))
;; printers
(add-to-list 'mqtt-message-receive-functions
(lambda (msg)
"Functions to execute on recieving a message"
nil
(let ((m (string-split msg " ")))
(let ((msg-car (car m))
(payload (cdr m)))
(let ((topic (string-split msg-car "/")))
;; (message "Topic: %s. Payload %s" topic payload)
(cond ((member "transform" topic)
(illuminate-edges topic (car payload)))
((member "main" topic)
(illuminate-nodes topic (car payload)))
;; ((member "gesture" topic)
;; (display-gesture))
))))))
(format-graph)
;; (start-process-shell-command "browser" nil (concat "firefox " working-directory "main.html --kiosk"))
(mqtt-start-consumer)