openpdu/src/board.go

193 lines
3.7 KiB
Go

package main
import (
"fmt"
"log"
"strings"
"github.com/spf13/viper"
)
type Channel struct {
id string
num uint
name string
value bool
inverted bool // low level only
startValue bool
parent *Board
}
type Board struct {
id string
name string
channelCount uint
inverted bool // low level only
channels []Channel
}
type Outlet struct {
num uint
board *Board
channel *Channel
}
func (c Channel) Toggle() (bool, error) {
c.value = !c.value
return c.value, nil
}
func (c Channel) On() error {
c.value = true
return nil
}
func (c Channel) Off() error {
c.value = true
return nil
}
func (c Channel) Status() bool {
return c.value
}
var boards []Board
var allChannels map[string]*Channel
var outlets []Outlet
func newDummyChannel(v *viper.Viper, channelID string) Channel {
v.SetDefault("name", "unknown")
v.SetDefault("startValue", false)
v.SetDefault("inverted", false)
// newUUID := UUID.New().String()
// v.SetDefault("id", newUUID)
return Channel{
id: channelID,
num: v.GetUint("num"),
name: v.GetString("name"),
value: v.GetBool("startValue"),
inverted: v.GetBool("inverted"),
startValue: v.GetBool("startValue"),
}
}
func newDummyBoard(v *viper.Viper, id string) Board {
var b Board
v.SetDefault("name", "board "+id)
v.SetDefault("inverted", false)
v.SetDefault("type", "dummy")
v.SetDefault("channelCount", 0)
v.SetDefault("channels", "")
if v.GetInt("channelCount") > 0 {
for i := 0; i < v.GetInt("channelCount"); i++ {
v.SetDefault("channels."+fmt.Sprint(i)+".num", i)
}
}
b = Board{
id: id,
name: v.GetString("name"),
channelCount: v.GetUint("channelCount"),
inverted: v.GetBool("inverted"),
}
channels := make([]Channel, v.GetInt("channelCount"))
if v.GetInt("channelCount") > 0 {
channelsConfig := v.Sub("channels")
if channelsConfig != nil {
for channelid1 := range channelsConfig.AllSettings() {
channelid := strings.ToLower(channelid1)
channelConfig := channelsConfig.Sub(channelid)
c := newDummyChannel(channelConfig, channelid)
c.parent = &b
if c.num >= v.GetUint("channelCount") {
continue
}
channels[c.num] = c
allChannels[c.id] = &c
}
}
}
b.channels = channels
return b
}
func parseBoardsConfig() {
// TODO: init boards array?
allChannels = make(map[string]*Channel)
boardsConfig := viper.Sub("boards")
if boardsConfig == nil {
logWarning("No board configured")
return
}
for key := range boardsConfig.AllSettings() {
boardConfig := boardsConfig.Sub(key)
boardType := boardConfig.GetString("type")
switch boardType {
case "gpio":
default:
boards = append(boards, newDummyBoard(boardConfig, key))
}
}
outletsConfig := viper.Sub("outlets")
if outletsConfig == nil {
logWarning("No outlet configured")
return
}
for key := range outletsConfig.AllSettings() {
outletConfig := outletsConfig.Sub(key)
num := outletConfig.GetUint("num")
channelID := strings.ToLower(outletConfig.GetString("channelID"))
channel := allChannels[channelID]
// TODO: channel non esistente
o := Outlet{
num: num,
board: channel.parent,
channel: channel,
}
outlets = append(outlets, o)
}
// dumpa tutto
for b := range boards {
boards[b].Dump()
}
// dumpa tutto
for o := range outlets {
outlets[o].Dump()
}
}
func (c Channel) Dump() {
v := "off"
if c.startValue {
v = "on"
}
log.Printf(" Channel %d (start: %s): %s \n", c.num, v, c.name)
}
func (b Board) Dump() {
log.Printf("Board '%s' (id: %s): %d channels\n", b.name, b.id, b.channelCount)
for c := range b.channels {
b.channels[c].Dump()
}
}
func (o Outlet) Dump() {
log.Printf("Outlet %v: channel name: %v\n", o.num, o.channel.name)
}