Improve popupdescription of devices

The Popup window of locations now shows the last update, speed and
accuracy.
This commit is contained in:
Felix Niederwanger 2022-01-05 16:27:15 +01:00
parent e2c3d199ae
commit ee2720539d
Signed by: phoenix
GPG key ID: 31860289A704FB3C
4 changed files with 69 additions and 9 deletions

View file

@ -7,10 +7,11 @@ import (
type Location struct {
Timestamp int64
Lon float32
Lat float32
Alt float32
Acc float32
Lon float32 `json:"lon"`
Lat float32 `json:"lat"`
Alt float32 `json:"alt"`
Acc float32 `json:"acc"`
Velocity float32 `json:"vel"`
}
// Distance computes the distance (in meters) between two points

View file

@ -7,15 +7,18 @@ import (
"net/http"
"os"
"strings"
"time"
"gopkg.in/ini.v1"
)
// Config contains the main program configuration
type Config struct {
wwwDir string
bindAddr string
mqttRemote string
wwwDir string
bindAddr string
mqttRemote string
mqttClientId string
mqttTopic string
}
var config Config
@ -27,6 +30,8 @@ func (c *Config) SetDefaults() {
c.wwwDir = "./www"
c.bindAddr = "127.0.0.1:8090"
c.mqttRemote = "127.0.0.1"
c.mqttTopic = "owntracks/#"
c.mqttClientId = "ot-browser"
}
func mqttRecv(id string, loc Location) {
@ -59,6 +64,8 @@ func parseProgramArguments() error {
fmt.Println(" -w,--www DIR Set WWW content directory")
fmt.Println(" -c,--config FILE Read configuration from the ini FILE")
fmt.Println(" -b,--bind ADDR Bind webserver to ADDR")
fmt.Println(" --mqtt ADDR Set MQTT remote address")
fmt.Println(" --clientid CLIENTID Set MQTT client id")
os.Exit(0)
} else if arg == "-w" || arg == "--www" {
i++
@ -71,6 +78,12 @@ func parseProgramArguments() error {
} else if arg == "-b" || arg == "--bind" {
i++
config.bindAddr = args[i]
} else if arg == "--mqtt" {
i++
config.mqttRemote = args[i]
} else if arg == "--clientid" {
i++
config.mqttClientId = args[i]
} else {
return fmt.Errorf("invalid argument: %s", arg)
}
@ -90,7 +103,7 @@ func main() {
os.Exit(1)
}
mqtt.Received = mqttRecv
if err := mqtt.Connect(config.mqttRemote, "owntracks/#", "", "", "ot-browser"); err != nil {
if err := mqtt.Connect(config.mqttRemote, config.mqttTopic, "", "", config.mqttClientId); err != nil {
fmt.Fprintf(os.Stderr, "mqtt error: %s\n", err)
os.Exit(1)
}
@ -143,8 +156,43 @@ func handlerDevices(w http.ResponseWriter, r *http.Request) {
w.Write(buf)
}
func timeDeltastr(now int64, tsmp int64) string {
delta := now - tsmp
if delta > 0 {
if delta < 10 {
// Practically fresh
return "now"
} else if delta < 60 {
return fmt.Sprintf("%d seconds ago", delta)
} else {
minutes := delta / 60
if minutes == 1 {
return "1 minute ago"
} else if minutes < 60 {
return fmt.Sprintf("%d minutes ago", minutes)
} else {
hours := minutes / 60
if hours == 1 {
return "1 hour ago"
} else if hours < 24 {
return fmt.Sprintf("%d hours ago", hours)
}
days := hours / 24
if days == 1 {
return "yesterday"
} else if days < 7 {
return fmt.Sprintf("%d days ago", days)
}
}
}
}
t_unix := time.Unix(tsmp, 0)
return t_unix.Format("2006-01-02-15:04:05")
}
func handlerLocations(w http.ResponseWriter, r *http.Request) {
locations := make([]GeoJSON, 0)
now := time.Now().Unix()
for dev, loc := range devices {
point := CreatePoint(loc.Lon, loc.Lat)
point.Properties["name"] = dev
@ -152,6 +200,14 @@ func handlerLocations(w http.ResponseWriter, r *http.Request) {
point.Properties["time"] = fmt.Sprintf("%d", loc.Timestamp)
point.Properties["altitude"] = fmt.Sprintf("%f", loc.Alt)
point.Properties["accuracy"] = fmt.Sprintf("%f", loc.Acc)
description := timeDeltastr(now, loc.Timestamp)
if loc.Velocity > 1 {
description += fmt.Sprintf(" %.2fkm/h", loc.Velocity)
}
if loc.Acc > 5 {
description += fmt.Sprintf(" +/- %.0fm", loc.Acc)
}
point.Properties["description"] = description
locations = append(locations, point)
}

View file

@ -155,5 +155,8 @@ func parseLocationJson(buf string) (Location, error) {
if dat["tst"] != nil {
loc.Timestamp = int64(dat["tst"].(float64))
}
if dat["vel"] != nil {
loc.Velocity = float32(dat["vel"].(float64))
}
return loc, nil
}

View file

@ -15,7 +15,7 @@ var doFitBounds = true;
function refresh(e) {
var popupContent = function(fId) {
var feature = e.features[fId];
return feature.properties['name' ];
return "<h3>" + feature.properties['name'] + "</h3>\n<p>" + feature.properties['description'] + "</p>";
},
bindFeaturePopup = function(fId) {
realtime.getLayer(fId).bindPopup(popupContent(fId));