diff --git a/visualiser/main.css b/visualiser/main.css new file mode 100644 index 0000000..7fbf4d5 --- /dev/null +++ b/visualiser/main.css @@ -0,0 +1,8 @@ +.center { + display: block; + margin-left: auto; + margin-top: auto; + margin-bottom: auto; + margin-right: auto; + height: 100vh; +} diff --git a/visualiser/main.dot b/visualiser/main.dot new file mode 100644 index 0000000..68f26fa --- /dev/null +++ b/visualiser/main.dot @@ -0,0 +1,63 @@ +graph { + fan_one [shape=circle, style=filled, fillcolor=FAN_ONE,label="",color=FAN_ONE] + fan_two [shape=circle, style=filled, fillcolor=FAN_TWO,label="",color=FAN_TWO] + radio_one [shape=invtrapezium,style=filled,fillcolor=RADIO_ONE,label="",color=RADIO_ONE] + lamp_one [shape=cylinder,style=filled,fillcolor=LAMP_ONE,label="",color=LAMP_ONE] + lamp_two [shape=cylinder,style=filled,fillcolor=LAMP_TWO,label="",color=LAMP_TWO] + printer_one [shape=box,style=filled,fillcolor=PRINTER_ONE,label="",color=PRINTER_ONE] + printer_two [shape=box,style=filled,fillcolor=PRINTER_TWO,label="",color=PRINTER_TWO] + + fan_one -- fan_two [color=FAN_ONE_FAN_TWO] + fan_one -- radio_one [color=FAN_ONE_RADIO_ONE] + fan_one -- lamp_one [color=FAN_ONE_LAMP_ONE] + fan_one -- lamp_two [color=FAN_ONE_LAMP_TWO] + fan_one -- printer_one [color=FAN_ONE_PRINTER_ONE] + fan_one -- printer_two [color=FAN_ONE_PRINTER_TWO] + + fan_two -- radio_one [color=FAN_TWO_RADIO_ONE] + fan_two -- lamp_one [color=FAN_TWO_LAMP_ONE] + fan_two -- lamp_two [color=FAN_TWO_LAMP_TWO] + fan_two -- printer_one [color=FAN_TWO_PRINTER_ONE] + fan_two -- printer_two [color=FAN_TWO_PRINTER_TWO] + + radio_one -- lamp_one [color=RADIO_ONE_LAMP_ONE] + radio_one -- lamp_two [color=RADIO_ONE_LAMP_TWO] + radio_one -- printer_one [color=RADIO_ONE_PRINTER_ONE] + radio_one -- printer_two [color=RADIO_ONE_PRINTER_TWO] + + lamp_one -- lamp_two [color=LAMP_ONE_LAMP_TWO] + lamp_one -- printer_one [color=LAMP_ONE_PRINTER_ONE] + lamp_one -- printer_two [color=LAMP_ONE_PRINTER_TWO] + + lamp_two -- printer_one [color=LAMP_TWO_PRINTER_ONE] + lamp_two -- printer_two [color=LAMP_TWO_PRINTER_TWO] + + printer_one -- printer_two [color=PRINTER_ONE_PRINTER_TWO] + + // printer_two -- printer_one [color=PRINTER_ONE_PRINTER_TWO] + // printer_two -- lamp_two [color=LAMP_TWO_PRINTER_TWO] + // printer_two -- lamp_one [color=LAMP_ONE_PRINTER_TWO] + // printer_two -- radio_one [color=RADIO_ONE_PRINTER_TWO] + // printer_two -- fan_two [color=FAN_TWO_PRINTER_TWO] + // printer_two -- fan_one [color=FAN_ONE_PRINTER_TWO] + + // printer_one -- lamp_two [color=LAMP_TWO_PRINTER_ONE] + // printer_one -- lamp_one [color=LAMP_ONE_PRINTER_ONE] + // printer_one -- radio_one [color=RADIO_ONE_PRINTER_ONE] + // printer_one -- fan_two [color=FAN_TWO_PRINTER_ONE] + // printer_one -- fan_one [color=FAN_ONE_PRINTER_ONE] + + // lamp_two -- lamp_one [color=LAMP_ONE_LAMP_TWO] + // lamp_two -- radio_one [color=RADIO_ONE_LAMP_TWO] + // lamp_two -- fan_two [color=FAN_TWO_LAMP_TWO] + // lamp_two -- fan_one [color=FAN_ONE_LAMP_TWO] + + // lamp_one -- radio_one [color=RADIO_ONE_LAMP_ONE] + // lamp_one -- fan_two [color=FAN_TWO_LAMP_ONE] + // lamp_one -- fan_one [color=FAN_ONE_LAMP_ONE] + + // radio_one -- fan_two [color=FAN_TWO_RADIO_ONE] + // radio_one -- fan_one [color=FAN_ONE_RADIO_ONE] + + // fan_two -- fan_one [color=FAN_ONE_FAN_TWO] +} diff --git a/visualiser/main.el b/visualiser/main.el new file mode 100644 index 0000000..8c753a2 --- /dev/null +++ b/visualiser/main.el @@ -0,0 +1,281 @@ +(require 'dash) +(require 'mqtt-mode) +;; (toggle-debug-on-error) +(setq mqtt-host "mqtt.klank.school") +(setq mqtt-port 7000) + +;; directory variables +(defconst graphviz-command "circo") +(defconst graph-output-format "svg") +(defconst graph-dir "graphs/") +(defconst image-dir (concat graph-output-format "s/")) +(defconst working-directory "/home/riviera/XPUB2/public-moment/performance/") + +;; 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 graph-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" graph-output-format " " + working-directory graph-dir (concat "graph" (number-to-string snapshot) ".dot") + " -o " + working-directory image-dir + (concat "graph" (number-to-string snapshot) "." 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" graph-output-format " " + working-directory graph-dir (concat "graph" (number-to-string snapshot) ".dot") + " -o " + working-directory "main." 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) diff --git a/visualiser/main.html b/visualiser/main.html new file mode 100644 index 0000000..bf17de8 --- /dev/null +++ b/visualiser/main.html @@ -0,0 +1,18 @@ + + +
+ + + + +