Add navigation support via PureMaps

This commit is contained in:
Arsen Musayelyan 2022-11-07 12:22:14 -08:00
parent f33b3d2b56
commit 992eb2e085
4 changed files with 219 additions and 3 deletions

2
go.mod
View File

@ -15,7 +15,7 @@ require (
github.com/mozillazg/go-pinyin v0.19.0
github.com/rs/zerolog v1.26.1
github.com/urfave/cli/v2 v2.3.0
go.arsenm.dev/infinitime v0.0.0-20221025193634-0ad671d3f550
go.arsenm.dev/infinitime v0.0.0-20221107042015-72b558707ee3
go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0
golang.org/x/text v0.3.7
modernc.org/sqlite v1.17.2

4
go.sum
View File

@ -397,8 +397,8 @@ github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.4 h1:zNWRjYUW32G9KirMXYHQHVNFkXvMI7LpgNW2AgYAoIs=
github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
go.arsenm.dev/infinitime v0.0.0-20221025193634-0ad671d3f550 h1:GScKSLy9KI83+au3mV9w6koiYRap/uYNarRoUleou4k=
go.arsenm.dev/infinitime v0.0.0-20221025193634-0ad671d3f550/go.mod h1:K3NJ6fyPv5qqHUedB3MccKOE0whJMJZ80l/yTzzTrgc=
go.arsenm.dev/infinitime v0.0.0-20221107042015-72b558707ee3 h1:BfZkb41Gq6h9gy5Cg5jDd5hEk9kI27/h+EX0KN3qZv8=
go.arsenm.dev/infinitime v0.0.0-20221107042015-72b558707ee3/go.mod h1:K3NJ6fyPv5qqHUedB3MccKOE0whJMJZ80l/yTzzTrgc=
go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0 h1:1K96g1eww+77GeGchwMhd0NTrs7Mk/Hc3M3ItW5NbG4=
go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0/go.mod h1:goK9z735lfXmqlDxu9qN7FS8t0HJHN3PjyDtCToUY4w=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=

View File

@ -178,6 +178,12 @@ func main() {
log.Error().Err(err).Msg("Error intializing metrics collection")
}
// Initialize metrics collection
err = initPureMaps(ctx, dev)
if err != nil {
log.Error().Err(err).Msg("Error intializing puremaps integration")
}
// Start control socket
err = startSocket(ctx, dev)
if err != nil {

210
maps.go Normal file
View File

@ -0,0 +1,210 @@
package main
import (
"context"
"strings"
"github.com/godbus/dbus/v5"
"github.com/rs/zerolog/log"
"go.arsenm.dev/infinitime"
)
const (
interfaceName = "io.github.rinigus.PureMaps.navigator"
iconProperty = interfaceName + ".icon"
narrativeProperty = interfaceName + ".narrative"
manDistProperty = interfaceName + ".manDist"
progressProperty = interfaceName + ".progress"
)
func initPureMaps(ctx context.Context, dev *infinitime.Device) error {
// Connect to session bus. This connection is for method calls.
conn, err := newSessionBusConn(ctx)
if err != nil {
return err
}
exists, err := pureMapsExists(ctx, conn)
if err != nil {
return err
}
// Connect to session bus. This connection is for method calls.
monitorConn, err := newSessionBusConn(ctx)
if err != nil {
return err
}
// Define rules to listen for
var rules = []string{
"type='signal',interface='io.github.rinigus.PureMaps.navigator'",
}
var flag uint = 0
// Becode monitor for notifications
call := monitorConn.BusObject().CallWithContext(
ctx, "org.freedesktop.DBus.Monitoring.BecomeMonitor", 0, rules, flag,
)
if call.Err != nil {
return call.Err
}
var navigator dbus.BusObject
if exists {
navigator = conn.Object("io.github.rinigus.PureMaps", "/io/github/rinigus/PureMaps/navigator")
err = setAll(navigator, dev)
if err != nil {
log.Error().Err(err).Msg("Error setting all navigation fields")
}
}
go func() {
signalCh := make(chan *dbus.Message, 10)
monitorConn.Eavesdrop(signalCh)
for {
select {
case sig := <-signalCh:
if sig.Type != dbus.TypeSignal {
continue
}
var member string
err = sig.Headers[dbus.FieldMember].Store(&member)
if err != nil {
log.Error().Err(err).Msg("Error getting dbus member field")
continue
}
if !strings.HasSuffix(member, "Changed") {
continue
}
log.Debug().Str("member", member).Msg("Signal received from PureMaps navigator")
// The object must be retrieved in this loop in case PureMaps was not
// open at the time ITD was started.
navigator = conn.Object("io.github.rinigus.PureMaps", "/io/github/rinigus/PureMaps/navigator")
member = strings.TrimSuffix(member, "Changed")
switch member {
case "icon":
var icon string
err = navigator.StoreProperty(iconProperty, &icon)
if err != nil {
log.Error().Err(err).Str("property", member).Msg("Error getting property")
continue
}
err = dev.Navigation.SetFlag(infinitime.NavFlag(icon))
if err != nil {
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
continue
}
case "narrative":
var narrative string
err = navigator.StoreProperty(narrativeProperty, &narrative)
if err != nil {
log.Error().Err(err).Str("property", member).Msg("Error getting property")
continue
}
err = dev.Navigation.SetNarrative(narrative)
if err != nil {
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
continue
}
case "manDist":
var manDist string
err = navigator.StoreProperty(manDistProperty, &manDist)
if err != nil {
log.Error().Err(err).Str("property", member).Msg("Error getting property")
continue
}
err = dev.Navigation.SetManDist(manDist)
if err != nil {
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
continue
}
case "progress":
var progress int32
err = navigator.StoreProperty(progressProperty, &progress)
if err != nil {
log.Error().Err(err).Str("property", member).Msg("Error getting property")
continue
}
err = dev.Navigation.SetProgress(uint8(progress))
if err != nil {
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
continue
}
}
case <-ctx.Done():
return
}
}
}()
if exists {
log.Info().Msg("Sending PureMaps data to InfiniTime")
}
return nil
}
func setAll(navigator dbus.BusObject, dev *infinitime.Device) error {
var icon string
err := navigator.StoreProperty(iconProperty, &icon)
if err != nil {
return err
}
err = dev.Navigation.SetFlag(infinitime.NavFlag(icon))
if err != nil {
return err
}
var narrative string
err = navigator.StoreProperty(narrativeProperty, &narrative)
if err != nil {
return err
}
err = dev.Navigation.SetNarrative(narrative)
if err != nil {
return err
}
var manDist string
err = navigator.StoreProperty(manDistProperty, &manDist)
if err != nil {
return err
}
err = dev.Navigation.SetManDist(manDist)
if err != nil {
return err
}
var progress int32
err = navigator.StoreProperty(progressProperty, &progress)
if err != nil {
return err
}
return dev.Navigation.SetProgress(uint8(progress))
}
// pureMapsExists checks to make sure the PureMaps service exists on the bus
func pureMapsExists(ctx context.Context, conn *dbus.Conn) (bool, error) {
var names []string
err := conn.BusObject().CallWithContext(
ctx, "org.freedesktop.DBus.ListNames", 0,
).Store(&names)
if err != nil {
return false, err
}
return strSlcContains(names, "io.github.rinigus.PureMaps"), nil
}