Improve popupdescription of devices
The Popup window of locations now shows the last update, speed and accuracy.
This commit is contained in:
parent
e2c3d199ae
commit
ee2720539d
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue