hook nmea messages up to widgets

This commit is contained in:
Daniel 2025-05-18 18:23:27 +00:00
parent 36b1284996
commit e49173cfdd

View File

@ -2,6 +2,8 @@
(local { : fdopen } (require :posix.stdio)) (local { : fdopen } (require :posix.stdio))
(local nmea (require :nmea)) (local nmea (require :nmea))
(import-macros { : define-tests : expect : expect= } :assert)
(local { (local {
: Gtk : Gtk
: OsmGpsMap : 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 [] (fn styles []
(let [style_provider (Gtk.CssProvider)] (let [style_provider (Gtk.CssProvider)]
(Gtk.StyleContext.add_provider_for_screen (Gtk.StyleContext.add_provider_for_screen
@ -38,20 +50,73 @@ label.readout {
:on_destroy Gtk.main_quit :on_destroy Gtk.main_quit
})) }))
(fn osm-widget [] (local state-widgets { })
(doto (OsmGpsMap.Map {})
(tset :map-source OsmGpsMap.MapSource_t.OPENSTREETMAP) (fn osm-widget []
(: :set_center_and_zoom 52.595 -0.1 14) (let [w
(: :layer_add (OsmGpsMap.MapOsd { (doto (OsmGpsMap.Map {})
:show_copyright true (tset :map-source OsmGpsMap.MapSource_t.OPENSTREETMAP)
; :show_coordinates true (: :set_center_and_zoom 52.595 -0.1 17)
:show_scale true (: :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 [] (fn readouts []
(doto (Gtk.Box (doto (Gtk.Box
@ -60,9 +125,10 @@ label.readout {
:halign Gtk.Align.END :halign Gtk.Align.END
}) })
(-> (: :get_style_context) (: :add_class :readouts)) (-> (: :get_style_context) (: :add_class :readouts))
(: :add (readout "21:05:00")) (: :add (readout :time ""))
(: :add (readout "00:00")) (: :add (readout :elapsed-time ""))
(: :add (readout "25 km/h")))) (: :add (readout :speed "0"))))
(local socket-path (or (. arg 1) "/var/run/gnss-share.sock")) (local socket-path (or (. arg 1) "/var/run/gnss-share.sock"))
(local gnss-socket (local gnss-socket
@ -75,8 +141,19 @@ label.readout {
(each [l #(socket:read "l")] (each [l #(socket:read "l")]
; (print "gnss" l) ; (print "gnss" l)
(if (not (= 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) true)
(let [sock (gnss-socket:get_socket) (let [sock (gnss-socket:get_socket)