From e49173cfdda723db283da0ad3cdab6c508d43821 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 18 May 2025 18:23:27 +0000 Subject: [PATCH] hook nmea messages up to widgets --- pkgs/maps/main.fnl | 113 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 95 insertions(+), 18 deletions(-) diff --git a/pkgs/maps/main.fnl b/pkgs/maps/main.fnl index 34a5970..4486f49 100644 --- a/pkgs/maps/main.fnl +++ b/pkgs/maps/main.fnl @@ -2,6 +2,8 @@ (local { : fdopen } (require :posix.stdio)) (local nmea (require :nmea)) +(import-macros { : define-tests : expect : expect= } :assert) + (local { : Gtk : OsmGpsMap @@ -20,6 +22,16 @@ label.readout { } ") +(local utc-offset + (let [now (os.time) + localt (os.date "*t" now) + utct (os.date "!*t" now)] + (tset localt :isdst false) + (os.difftime (os.time localt) (os.time utct)))) + + + + (fn styles [] (let [style_provider (Gtk.CssProvider)] (Gtk.StyleContext.add_provider_for_screen @@ -38,20 +50,73 @@ label.readout { :on_destroy Gtk.main_quit })) -(fn osm-widget [] - (doto (OsmGpsMap.Map {}) - (tset :map-source OsmGpsMap.MapSource_t.OPENSTREETMAP) - (: :set_center_and_zoom 52.595 -0.1 14) - (: :layer_add (OsmGpsMap.MapOsd { - :show_copyright true - ; :show_coordinates true - :show_scale true - })) - )) +(local state-widgets { }) + +(fn osm-widget [] + (let [w + (doto (OsmGpsMap.Map {}) + (tset :map-source OsmGpsMap.MapSource_t.OPENSTREETMAP) + (: :set_center_and_zoom 52.595 -0.1 17) + (: :layer_add (OsmGpsMap.MapOsd { + :show_copyright true + ; :show_coordinates true + :show_scale true + })) + )] + (tset state-widgets :osm w) + w)) + + +(fn readout [name text] + (let [w + (doto (Gtk.Label {:label text : name}) + (-> (: :get_style_context) + (: :add_class :readout)))] + (tset state-widgets name w) + w)) + +(local knot-in-m-s + (/ 1852 ; metres in nautical mile + 3600 ; seconds in an hour + )) + +(fn hhmmss [seconds-since-midnight] + (let [s (% seconds-since-midnight 60) + m (% (// (- seconds-since-midnight s) 60) 60) + h (// (- seconds-since-midnight (* m 60) s) 3600)] + (string.format "%d:%02d:%02d" h m s))) + +(expect= (hhmmss (+ 45 (* 60 12) (* 60 60 3))) "3:12:45") + + +(local + app-state { + :time-of-day 0 + :elapsed-time 0 + :speed 14 + :lat 49 + :lon 0 + :course 22 + } + ) + + +(fn merge [table1 table2] + (collect [k v (pairs table2) &into table1] + k v)) + + +(fn update-app-state [new-vals] + (merge app-state new-vals) + (each [name widget (pairs state-widgets)] + (case name + :speed (widget:set_label + (string.format "%.1f km/h" (* app-state.speed 3.6))) + :osm (widget:set_center app-state.lat app-state.lon) + :time (widget:set_label + (hhmmss (+ utc-offset app-state.time-of-day))) + ))) -(fn readout [text] - (doto (Gtk.Label {:label text}) - (-> (: :get_style_context) (: :add_class :readout)))) (fn readouts [] (doto (Gtk.Box @@ -60,9 +125,10 @@ label.readout { :halign Gtk.Align.END }) (-> (: :get_style_context) (: :add_class :readouts)) - (: :add (readout "21:05:00")) - (: :add (readout "00:00")) - (: :add (readout "25 km/h")))) + (: :add (readout :time "")) + (: :add (readout :elapsed-time "")) + (: :add (readout :speed "0")))) + (local socket-path (or (. arg 1) "/var/run/gnss-share.sock")) (local gnss-socket @@ -75,8 +141,19 @@ label.readout { (each [l #(socket:read "l")] ; (print "gnss" l) (if (not (= l "")) - (print (view (nmea.parse l))))) - + (let [message (nmea.parse l)] + (case message + { : lat : lon : utc} + (update-app-state + { + : lat : lon + :time-of-day + (let [(h m s) (string.match utc "(..)(..)(..)")] + (+ s (* m 60) (* h 60 60))) + } + ) + { : speed-knots } + (update-app-state { :speed (* speed-knots knot-in-m-s) }))))) true) (let [sock (gnss-socket:get_socket)