Group geofence events

Feature request by @huangpeizhi #87
This commit is contained in:
Josh Baker 2016-12-06 10:30:48 -07:00
parent 32014e7560
commit 3a483e55ff
4 changed files with 74 additions and 7 deletions

45
controller/bson.go Normal file
View File

@ -0,0 +1,45 @@
package controller
import (
"crypto/md5"
"crypto/rand"
"encoding/binary"
"encoding/hex"
"io"
"os"
"sync/atomic"
"time"
)
func bsonID() string {
b := make([]byte, 12)
binary.BigEndian.PutUint32(b, uint32(time.Now().Unix()))
copy(b[4:], bsonMachine)
binary.BigEndian.PutUint32(b[8:], atomic.AddUint32(&bsonCounter, 1))
binary.BigEndian.PutUint16(b[7:], bsonProcess)
return hex.EncodeToString(b)
}
var (
bsonProcess = uint16(os.Getpid())
bsonMachine = func() []byte {
host, err := os.Hostname()
if err != nil {
b := make([]byte, 3)
if _, err := io.ReadFull(rand.Reader, b); err != nil {
panic("random error: " + err.Error())
}
return b
}
hw := md5.New()
hw.Write([]byte(host))
return hw.Sum(nil)[:3]
}()
bsonCounter = func() uint32 {
b := make([]byte, 4)
if _, err := io.ReadFull(rand.Reader, b); err != nil {
panic("random error: " + err.Error())
}
return binary.BigEndian.Uint32(b)
}()
)

View File

@ -104,6 +104,10 @@ func (c *Controller) cmdMassInsert(msg *server.Message) (res string, err error)
id := strconv.FormatInt(int64(j), 10) id := strconv.FormatInt(int64(j), 10)
var values []resp.Value var values []resp.Value
if j%8 == 0 { if j%8 == 0 {
values = append(values, resp.StringValue("set"),
resp.StringValue(key), resp.StringValue(id),
resp.StringValue("STRING"), resp.StringValue(fmt.Sprintf("str%v", j)))
} else {
lat, lon := randMassInsertPosition(minLat, minLon, maxLat, maxLon) lat, lon := randMassInsertPosition(minLat, minLon, maxLat, maxLon)
values = make([]resp.Value, 0, 16) values = make([]resp.Value, 0, 16)
values = append(values, resp.StringValue("set"), resp.StringValue(key), resp.StringValue(id)) values = append(values, resp.StringValue("set"), resp.StringValue(key), resp.StringValue(id))
@ -111,10 +115,6 @@ func (c *Controller) cmdMassInsert(msg *server.Message) (res string, err error)
values = append(values, resp.StringValue("FIELD"), resp.StringValue("fname"), resp.FloatValue(rand.Float64()*10)) values = append(values, resp.StringValue("FIELD"), resp.StringValue("fname"), resp.FloatValue(rand.Float64()*10))
} }
values = append(values, resp.StringValue("POINT"), resp.FloatValue(lat), resp.FloatValue(lon)) values = append(values, resp.StringValue("POINT"), resp.FloatValue(lat), resp.FloatValue(lon))
} else {
values = append(values, resp.StringValue("set"),
resp.StringValue(key), resp.StringValue(id),
resp.StringValue("STRING"), resp.StringValue(fmt.Sprintf("str%v", j)))
} }
if err := docmd(values); err != nil { if err := docmd(values); err != nil {
log.Fatal(err) log.Fatal(err)

View File

@ -127,25 +127,46 @@ func FenceMatch(hookName string, sw *scanWriter, fence *liveFenceSwitches, detai
} }
sw.mu.Unlock() sw.mu.Unlock()
if fence.groups == nil {
fence.groups = make(map[string]string)
}
groupkey := details.key + ":" + details.id
var group string
var ok bool
if detect == "enter" {
group = bsonID()
fence.groups[groupkey] = group
} else if detect == "cross" {
group = bsonID()
delete(fence.groups, groupkey)
} else {
group, ok = fence.groups[groupkey]
if !ok {
group = bsonID()
fence.groups[groupkey] = group
}
}
jskey := jsonString(details.key) jskey := jsonString(details.key)
ores := res ores := res
msgs := make([]string, 0, 2) msgs := make([]string, 0, 2)
if fence.detect == nil || fence.detect[detect] { if fence.detect == nil || fence.detect[detect] {
if strings.HasPrefix(ores, "{") { if strings.HasPrefix(ores, "{") {
res = `{"command":"` + details.command + `","detect":"` + detect + `","hook":` + jshookName + `,"key":` + jskey + `,"time":` + jstime + `,` + ores[1:] res = `{"command":"` + details.command + `","group":"` + group + `","detect":"` + detect + `","hook":` + jshookName + `,"key":` + jskey + `,"time":` + jstime + `,` + ores[1:]
} }
msgs = append(msgs, res) msgs = append(msgs, res)
} }
switch detect { switch detect {
case "enter": case "enter":
if fence.detect == nil || fence.detect["inside"] { if fence.detect == nil || fence.detect["inside"] {
msgs = append(msgs, `{"command":"`+details.command+`","detect":"inside","hook":`+jshookName+`,"key":`+jskey+`,"time":`+jstime+`,`+ores[1:]) msgs = append(msgs, `{"command":"`+details.command+`","group":"`+group+`","detect":"inside","hook":`+jshookName+`,"key":`+jskey+`,"time":`+jstime+`,`+ores[1:])
} }
case "exit", "cross": case "exit", "cross":
if fence.detect == nil || fence.detect["outside"] { if fence.detect == nil || fence.detect["outside"] {
msgs = append(msgs, `{"command":"`+details.command+`","detect":"outside","hook":`+jshookName+`,"key":`+jskey+`,"time":`+jstime+`,`+ores[1:]) msgs = append(msgs, `{"command":"`+details.command+`","group":"`+group+`","detect":"outside","hook":`+jshookName+`,"key":`+jskey+`,"time":`+jstime+`,`+ores[1:])
} }
case "roam": case "roam":
if len(msgs) > 0 { if len(msgs) > 0 {
var nmsgs []string var nmsgs []string

View File

@ -22,6 +22,7 @@ type liveFenceSwitches struct {
maxLat, maxLon float64 maxLat, maxLon float64
cmd string cmd string
roam roamSwitches roam roamSwitches
groups map[string]string
} }
type roamSwitches struct { type roamSwitches struct {