package sensor import ( _"fmt" "time" "sync" _ "FRMS/internal/pkg/I2C" "log" ) type Manager struct { *Dev I2CDevice *Active Hb time.Duration } type Active struct { sync.Mutex bool int } type Dev struct { // last known values Addr int Type string Status string // could be more efficient but to hell with it } type I2CDevice interface { // basic device info GetAddr() int GetStatus() string GetType() string } func NewDeviceManager(i2c I2CDevice) *Manager { m := &Manager{Hb:time.Duration(1*time.Second)} m.I2CDevice = i2c m.Active = &Active{} m.Dev = &Dev{Addr:i2c.GetAddr(),Type:i2c.GetType(),Status:i2c.GetStatus()} return m } func (m *Manager) Start() { // goal is to start a long running monitoring routine if !m.Activate() { log.Fatal("Manager already running!") } // atomically activated if this runs go m.Monitor() } func (m *Manager) Exit() { if !m.Deactivate() { log.Fatal("Manager already exited!") } } func (m *Manager) Monitor() { for m.IsActive() { if m.Status == "KILLED" { m.Exit() } time.Sleep(m.Hb) } } func (m *Manager) GetType() string { return m.Type } func (m *Manager) GetStatus() string { m.Status = m.I2CDevice.GetStatus() return m.Status } func (m *Manager) GetData() string { return "" } func (m *Manager) GetAddr() int { return m.Addr } // atomic activation and deactivation func (a *Active) Activate() bool { // returns true if success, false otherwise a.Lock() defer a.Unlock() if a.bool { // already active return false } else { a.bool = true a.int = 0 return a.bool } } func (a *Active) Deactivate() bool { // returns true if success false otherise a.Lock() defer a.Unlock() if a.bool { a.bool = false return true } else { // already deactivated return a.bool // false } } func (a *Active) IsActive() bool { a.Lock() defer a.Unlock() return a.bool }