working base to play with. Ended up combining sensors/devs with a key value store. Need to compile GRPC again...
parent
e64efad3fc
commit
d8ae5d89b4
@ -1,72 +0,0 @@
|
||||
package I2C
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type I2CDevice struct {
|
||||
*I2CBus // embeds bus
|
||||
bool // stores whether dev is currently connected
|
||||
int // addr
|
||||
Data *data
|
||||
}
|
||||
|
||||
type data struct {
|
||||
string
|
||||
bool
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func (d I2CDevice) String() string {
|
||||
t := map[int]string{97: "DO Sensor", 99: "pH Sensor", 102: "Temperature Sensor", 64: "DHT11 Sensor"}
|
||||
return t[d.int]
|
||||
}
|
||||
|
||||
func NewDevice(addr int, bus *I2CBus) *I2CDevice {
|
||||
d := &I2CDevice{}
|
||||
d.I2CBus = bus
|
||||
d.int = addr
|
||||
d.Data = &data{}
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *I2CDevice) GetAddr() int {
|
||||
return d.int
|
||||
}
|
||||
|
||||
func (d *I2CDevice) GetStatus() bool {
|
||||
// TODO
|
||||
return d.I2CBus.GetStatus(d.int)
|
||||
}
|
||||
|
||||
func (d *I2CDevice) GetType() string {
|
||||
// TODO
|
||||
return fmt.Sprint(d)
|
||||
}
|
||||
|
||||
func (d *I2CDevice) GetData() string {
|
||||
d.Data.Lock()
|
||||
defer d.Data.Unlock()
|
||||
d.Data.string = d.I2CBus.GetData(d.int)
|
||||
return d.Data.string
|
||||
}
|
||||
|
||||
func (d *data) Active() {
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
if !d.bool {
|
||||
d.string = ""
|
||||
d.bool = true
|
||||
}
|
||||
}
|
||||
|
||||
func (d *data) Killed() {
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
if d.bool {
|
||||
d.string = time.Now().Format("Mon at 03:04:05pm MST")
|
||||
d.bool = false
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
package I2C
|
||||
|
||||
import (
|
||||
_ "fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
i2c monitor implements a long running monitor responsible for sending active devices to the rlc
|
||||
*/
|
||||
|
||||
type I2CMonitor struct {
|
||||
*I2CBus
|
||||
Devices *devs
|
||||
DevChan chan int
|
||||
}
|
||||
|
||||
type devs struct {
|
||||
sync.Mutex
|
||||
m map[int]*I2CDevice
|
||||
}
|
||||
|
||||
func NewMonitor(bus int, ch chan int) *I2CMonitor {
|
||||
m := &I2CMonitor{}
|
||||
b := NewBus(bus)
|
||||
m.I2CBus = b
|
||||
d := make(map[int]*I2CDevice)
|
||||
m.Devices = &devs{m: d}
|
||||
m.DevChan = ch
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *I2CMonitor) Update() {
|
||||
/*
|
||||
scans bus and adds new active devices
|
||||
*/
|
||||
devs := m.Scan()
|
||||
chng := m.Devices.Parse(m.I2CBus, devs)
|
||||
for _, d := range chng {
|
||||
go m.ConnectDevice(d)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *I2CMonitor) Monitor() {
|
||||
// functon that updates the device list and notifies rlc of any changes to sensor composition
|
||||
s := make(chan struct{})
|
||||
t := 5 * time.Second
|
||||
go func(signal chan struct{}, to time.Duration) { // simple signal func to init scan
|
||||
for {
|
||||
signal <- struct{}{}
|
||||
time.Sleep(to)
|
||||
}
|
||||
}(s, t)
|
||||
|
||||
for {
|
||||
<-s
|
||||
m.Update()
|
||||
}
|
||||
}
|
||||
|
||||
func (m *I2CMonitor) ConnectDevice(addr int) {
|
||||
m.DevChan <- addr
|
||||
}
|
||||
|
||||
func (m *I2CMonitor) GetDevice(addr int) interface {
|
||||
GetAddr() int
|
||||
GetData() string
|
||||
GetStatus() bool
|
||||
GetType() string
|
||||
} {
|
||||
m.Devices.Lock()
|
||||
defer m.Devices.Unlock()
|
||||
return m.Devices.m[addr]
|
||||
}
|
||||
|
||||
func (d *devs) Parse(bus *I2CBus, devices map[int]bool) []int {
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
newdevs := []int{}
|
||||
for addr, status := range devices {
|
||||
if dev, exists := d.m[addr]; exists {
|
||||
// device seen
|
||||
if status != dev.bool { // if device state changed
|
||||
dev.bool = status
|
||||
if status {
|
||||
newdevs = append(newdevs, dev.GetAddr())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// device not seen yet
|
||||
if status {
|
||||
// active
|
||||
newd := NewDevice(addr, bus)
|
||||
newd.bool = status
|
||||
d.m[addr] = newd
|
||||
newdevs = append(newdevs, newd.GetAddr())
|
||||
}
|
||||
}
|
||||
}
|
||||
return newdevs
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package reactor
|
||||
|
||||
import (
|
||||
pb "FRMS/internal/pkg/grpc"
|
||||
"FRMS/internal/pkg/sensor"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type DeviceManager interface {
|
||||
GetInfo() (*pb.Device, error)
|
||||
SetStatus(int) error
|
||||
}
|
||||
|
||||
func NewDeviceManager(addr int, status int) (DeviceManager, error) {
|
||||
dev := &pb.Device{Addr: int32(addr), Status: pb.Status(int32(status))}
|
||||
return sensor.NewDeviceManager(dev)
|
||||
}
|
||||
|
||||
type DeviceCoordinator struct {
|
||||
Managers map[int]DeviceManager
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func NewDeviceCoordinator() *DeviceCoordinator {
|
||||
dm := &DeviceCoordinator{}
|
||||
dm.Managers = make(map[int]DeviceManager)
|
||||
return dm
|
||||
}
|
||||
|
||||
func (c *DeviceCoordinator) UpdateDevices(active map[int]bool) error {
|
||||
// update dev status, add new ones
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
var err error
|
||||
|
||||
for addr, _ := range active {
|
||||
// loop over devs
|
||||
if _, ok := c.Managers[addr]; !ok {
|
||||
// no device
|
||||
if c.Managers[addr], err = NewDeviceManager(addr, 1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
// all devs accounted for
|
||||
for addr, dm := range c.Managers {
|
||||
if active[addr] {
|
||||
err = dm.SetStatus(1)
|
||||
} else {
|
||||
err = dm.SetStatus(0)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *DeviceCoordinator) GetDevices() ([]*pb.Device, error) {
|
||||
// TODO
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
|
||||
var err error
|
||||
var devices []*pb.Device
|
||||
var dev *pb.Device
|
||||
|
||||
for _, dm := range c.Managers {
|
||||
dev, err = dm.GetInfo()
|
||||
devices = append(devices, dev)
|
||||
}
|
||||
|
||||
return devices, err
|
||||
}
|
Loading…
Reference in New Issue