112 lines
2.6 KiB
Go
112 lines
2.6 KiB
Go
package redis
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"src.dualinventive.com/go/dinet/ditime"
|
|
"src.dualinventive.com/go/dinet/rpc"
|
|
"src.dualinventive.com/go/dinet/rts"
|
|
"src.dualinventive.com/go/lib/dilog"
|
|
)
|
|
|
|
// Store a single DI-Net RPC message in the RTS cache
|
|
func (r *Redis) write(logger dilog.Logger, key, field string, value []byte) error {
|
|
logger.WithFields(dilog.Fields{
|
|
"field": field,
|
|
"value": string(value),
|
|
}).Debug("write")
|
|
|
|
c, err := r.getConn()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
closeerr := c.Close()
|
|
// we are closing the connection so it is too late for errors.
|
|
_ = closeerr
|
|
}()
|
|
|
|
_, err = c.Do("HSET", key, field, value)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Set last update in the root
|
|
_, err = c.Do("HSET", key, "last_update", strconv.FormatUint(uint64(ditime.Now()), 10))
|
|
return err
|
|
}
|
|
|
|
// writeSensorGPS writes a GPS entry of the device sensor in redis
|
|
func (r *Redis) writeSensorGPS(m *rpc.Msg, value rpc.GPSSensorData) error {
|
|
c, err := r.getConn()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer func() {
|
|
closeerr := c.Close()
|
|
// we are closing the connection so it is too late for errors.
|
|
_ = closeerr
|
|
}()
|
|
|
|
// Set GPS
|
|
_, err = c.Do("GEOADD", rts.SensorGeohashKey, value.Longitude, value.Latitude, m.DeviceUID)
|
|
return err
|
|
}
|
|
|
|
// publish sends a Redis publish command to Redis
|
|
func (r *Redis) publish(m *rpc.Msg) error {
|
|
c, err := r.getConn()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
closeerr := c.Close()
|
|
// we are closing the connection so it is too late for errors.
|
|
_ = closeerr
|
|
}()
|
|
|
|
var channel string
|
|
var message interface{}
|
|
|
|
// NOTE: the ordering should not be changed!
|
|
switch {
|
|
case rpc.ValidDeviceUID(m.DeviceUID):
|
|
// Message has device:uid || device:uid && project:id properties
|
|
channel = rts.ChanDevice
|
|
message = m.DeviceUID
|
|
case rpc.ValidProjectID(m.ProjectID):
|
|
// Message has project:id but not device:uid
|
|
channel = rts.ChanProject
|
|
message = m.ProjectID
|
|
default:
|
|
return nil
|
|
}
|
|
|
|
_, err = c.Do("PUBLISH", channel, message)
|
|
return err
|
|
}
|
|
|
|
// fieldName calculates the Redis HSET field name based on m.Class(), m.Method() and supplied id
|
|
func fieldName(m *rpc.Msg, id uint16) string {
|
|
if id > 0 && len(m.Method()) > 0 {
|
|
return fmt.Sprintf("%s:%d:%s", m.Class(), id, m.Method())
|
|
}
|
|
return string(m.ClassMethod)
|
|
}
|
|
|
|
// keyName calculates the Redis key field based on the device UID or project ID
|
|
func keyName(m *rpc.Msg) string {
|
|
var name string
|
|
|
|
// NOTE: the ordering should not be changed!
|
|
if rpc.ValidDeviceUID(m.DeviceUID) {
|
|
name = rts.KeyPrefixDevice + m.DeviceUID
|
|
} else if rpc.ValidProjectID(m.ProjectID) {
|
|
name = fmt.Sprintf("%s%d", rts.KeyPrefixProject, m.ProjectID)
|
|
}
|
|
|
|
return name
|
|
}
|