You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.1 KiB
Go

3 years ago
package sensor
import (
_"fmt"
"time"
3 years ago
"sync"
_ "FRMS/internal/pkg/I2C"
"log"
3 years ago
)
type Manager struct {
*Dev
I2CDevice
SystemUpdates
*Active
Hb time.Duration
3 years ago
}
type SystemUpdates interface {
DeviceUpdateHandler(int, string, string)
}
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
}
3 years ago
func NewDeviceManager(i2c I2CDevice,sys SystemUpdates) *Manager {
m := &Manager{Hb:time.Duration(1*time.Second)}
m.I2CDevice = i2c
m.SystemUpdates = sys
m.Active = &Active{}
m.Dev = &Dev{Addr:i2c.GetAddr(),Type:i2c.GetType(),Status:i2c.GetStatus()}
return m
3 years ago
}
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()
3 years ago
}
func (m *Manager) Exit() {
if !m.Deactivate() {
log.Fatal("Manager already exited!")
}
3 years ago
}
func (m *Manager) Monitor() {
for m.IsActive() {
go m.DeviceStatus()
time.Sleep(m.Hb)
}
3 years ago
}
func (m *Manager) DeviceStatus() {
status := m.GetStatus()
if status != m.Status { // changed
go m.DeviceUpdateHandler(m.Addr,status,m.Type)
m.Status = status
}
}
// 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
}
}
3 years ago
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
}