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