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 }