229 lines
5.0 KiB
Go
229 lines
5.0 KiB
Go
package board
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
|
|
PahoMQTT "github.com/eclipse/paho.mqtt.golang"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
type DummyChannel struct {
|
|
ID string
|
|
Num uint
|
|
name string
|
|
mqttStateTopic string
|
|
mqttCommandTopic string
|
|
value bool
|
|
onboot string
|
|
parent *DummyBoard
|
|
onChannelUpdateFunctions map[string]onChannelUpdateFunction
|
|
}
|
|
|
|
type DummyBoard struct {
|
|
ID string
|
|
Name string
|
|
ChannelCount uint
|
|
channels []*DummyChannel
|
|
}
|
|
|
|
func newDummyChannel(v *viper.Viper, channelID string) DummyChannel {
|
|
v.SetDefault("name", "unknown")
|
|
v.SetDefault("lastValue", false)
|
|
v.SetDefault("onboot", "off")
|
|
v.SetDefault("mqtt.statetopic", v.GetString("name"))
|
|
|
|
value := false
|
|
switch v.GetString("onboot") {
|
|
case "on":
|
|
value = true
|
|
case "last":
|
|
value = v.GetBool("lastValue")
|
|
}
|
|
// newUUID := UUID.New().String()
|
|
// v.SetDefault("id", newUUID)
|
|
return DummyChannel{
|
|
ID: channelID,
|
|
Num: v.GetUint("num"),
|
|
name: v.GetString("name"),
|
|
mqttStateTopic: v.GetString("mqtt.statetopic"),
|
|
mqttCommandTopic: v.GetString("mqtt.commandtopic"),
|
|
value: value,
|
|
onboot: v.GetString("onboot"),
|
|
}
|
|
}
|
|
|
|
func newDummyBoard(v *viper.Viper, id string) *Board {
|
|
var b *DummyBoard
|
|
|
|
v.SetDefault("name", "board "+id)
|
|
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 = &DummyBoard{
|
|
ID: id,
|
|
Name: v.GetString("name"),
|
|
ChannelCount: v.GetUint("channelCount"),
|
|
}
|
|
|
|
channels := make([]*DummyChannel, 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
|
|
var b1 Board = b
|
|
return &b1
|
|
}
|
|
|
|
func (c *DummyChannel) Toggle() (bool, error) {
|
|
c.value = !c.value
|
|
c.SaveLastState()
|
|
for f := range c.onChannelUpdateFunctions {
|
|
c.onChannelUpdateFunctions[f](!c.value, c)
|
|
}
|
|
return c.value, nil
|
|
}
|
|
|
|
func (c *DummyChannel) On() error {
|
|
oldval := c.value
|
|
c.value = true
|
|
c.SaveLastState()
|
|
for f := range c.onChannelUpdateFunctions {
|
|
c.onChannelUpdateFunctions[f](oldval, c)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *DummyChannel) Off() error {
|
|
oldval := c.value
|
|
c.value = true
|
|
c.SaveLastState()
|
|
for f := range c.onChannelUpdateFunctions {
|
|
c.onChannelUpdateFunctions[f](oldval, c)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *DummyChannel) ToString() string {
|
|
if !c.value {
|
|
return "off"
|
|
}
|
|
return "on"
|
|
}
|
|
|
|
func (c *DummyChannel) SaveLastState() {
|
|
if c.onboot == "last" {
|
|
s := fmt.Sprintf("boards.%s.channels.%s.lastvalue", c.parent.ID, c.ID)
|
|
viper.Set(s, c.value)
|
|
viper.WriteConfig()
|
|
}
|
|
}
|
|
|
|
func (c *DummyChannel) Status() bool {
|
|
return c.value
|
|
}
|
|
|
|
func (c *DummyChannel) Parent() Board {
|
|
return c.parent
|
|
}
|
|
|
|
func (c *DummyChannel) Dump() {
|
|
log.Printf(" Channel %d (on boot: %s): %s \n", c.Num, c.onboot, c.name)
|
|
}
|
|
|
|
func (b DummyBoard) 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 (b *DummyBoard) Initialize() {
|
|
return
|
|
}
|
|
|
|
func (b *DummyBoard) Channel(num uint64) Channel {
|
|
return b.channels[num]
|
|
}
|
|
|
|
func (c *DummyChannel) Name() string {
|
|
return c.name
|
|
}
|
|
|
|
func (c *DummyChannel) OnBoot() string {
|
|
return c.onboot
|
|
}
|
|
|
|
func (c *DummyChannel) SetOnBoot(str string) {
|
|
c.onboot = str
|
|
s := fmt.Sprintf("boards.%s.channels.%s.onboot", c.parent.ID, c.ID)
|
|
viper.Set(s, str)
|
|
}
|
|
|
|
func (c *DummyChannel) SetMQTTStateTopic(str string) {
|
|
c.mqttStateTopic = str
|
|
s := fmt.Sprintf("boards.%s.channels.%s.mqtt.statetopic", c.parent.ID, c.ID)
|
|
viper.Set(s, str)
|
|
}
|
|
|
|
func (c *DummyChannel) SetMQTTCommandTopic(str string) {
|
|
c.mqttCommandTopic = str
|
|
s := fmt.Sprintf("boards.%s.channels.%s.mqtt.commandtopic", c.parent.ID, c.ID)
|
|
viper.Set(s, str)
|
|
}
|
|
|
|
func (c *DummyChannel) MQTTHandler(client PahoMQTT.Client, msg PahoMQTT.Message) {
|
|
switch string(msg.Payload()) {
|
|
case "on":
|
|
if !c.value {
|
|
c.value = true
|
|
c.SaveLastState()
|
|
}
|
|
case "off":
|
|
if c.value {
|
|
c.value = false
|
|
c.SaveLastState()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (c *DummyChannel) MQTTStateTopic() string {
|
|
return c.mqttStateTopic
|
|
}
|
|
|
|
func (c *DummyChannel) MQTTCommandTopic() string {
|
|
return c.mqttCommandTopic
|
|
}
|
|
|
|
func init() {
|
|
RegisterBoardType("dummy", newDummyBoard)
|
|
}
|
|
|
|
func (c *DummyChannel) AddOnChannelUpdateFunction(name string, f onChannelUpdateFunction) {
|
|
if c.onChannelUpdateFunctions == nil {
|
|
c.onChannelUpdateFunctions = make(map[string]onChannelUpdateFunction)
|
|
}
|
|
c.onChannelUpdateFunctions[name] = f
|
|
}
|