Update board_dummy.go, board_i2c.go, and board_mqtt.go
This commit is contained in:
parent
8e21944d8e
commit
264ecbf657
@ -15,7 +15,7 @@ type DummyChannel struct {
|
|||||||
name string
|
name string
|
||||||
mqttStateTopic string
|
mqttStateTopic string
|
||||||
mqttCommandTopic string
|
mqttCommandTopic string
|
||||||
Value bool
|
value bool
|
||||||
onboot string
|
onboot string
|
||||||
parent *DummyBoard
|
parent *DummyBoard
|
||||||
onChannelUpdateFunctions map[string]onChannelUpdateFunction
|
onChannelUpdateFunctions map[string]onChannelUpdateFunction
|
||||||
@ -49,7 +49,7 @@ func newDummyChannel(v *viper.Viper, channelID string) DummyChannel {
|
|||||||
name: v.GetString("name"),
|
name: v.GetString("name"),
|
||||||
mqttStateTopic: v.GetString("mqtt.statetopic"),
|
mqttStateTopic: v.GetString("mqtt.statetopic"),
|
||||||
mqttCommandTopic: v.GetString("mqtt.commandtopic"),
|
mqttCommandTopic: v.GetString("mqtt.commandtopic"),
|
||||||
Value: value,
|
value: value,
|
||||||
onboot: v.GetString("onboot"),
|
onboot: v.GetString("onboot"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,17 +97,17 @@ func newDummyBoard(v *viper.Viper, id string) *Board {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *DummyChannel) Toggle() (bool, error) {
|
func (c *DummyChannel) Toggle() (bool, error) {
|
||||||
c.Value = !c.Value
|
c.value = !c.value
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
for f := range c.onChannelUpdateFunctions {
|
for f := range c.onChannelUpdateFunctions {
|
||||||
c.onChannelUpdateFunctions[f](!c.Value, c)
|
c.onChannelUpdateFunctions[f](!c.value, c)
|
||||||
}
|
}
|
||||||
return c.Value, nil
|
return c.value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *DummyChannel) On() error {
|
func (c *DummyChannel) On() error {
|
||||||
oldval := c.Value
|
oldval := c.value
|
||||||
c.Value = true
|
c.value = true
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
for f := range c.onChannelUpdateFunctions {
|
for f := range c.onChannelUpdateFunctions {
|
||||||
c.onChannelUpdateFunctions[f](oldval, c)
|
c.onChannelUpdateFunctions[f](oldval, c)
|
||||||
@ -116,8 +116,8 @@ func (c *DummyChannel) On() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *DummyChannel) Off() error {
|
func (c *DummyChannel) Off() error {
|
||||||
oldval := c.Value
|
oldval := c.value
|
||||||
c.Value = true
|
c.value = true
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
for f := range c.onChannelUpdateFunctions {
|
for f := range c.onChannelUpdateFunctions {
|
||||||
c.onChannelUpdateFunctions[f](oldval, c)
|
c.onChannelUpdateFunctions[f](oldval, c)
|
||||||
@ -126,26 +126,22 @@ func (c *DummyChannel) Off() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *DummyChannel) ToString() string {
|
func (c *DummyChannel) ToString() string {
|
||||||
if !c.Value {
|
if !c.value {
|
||||||
return "off"
|
return "off"
|
||||||
}
|
}
|
||||||
return "on"
|
return "on"
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (c *DummyChannel) UpdateMQTT() {
|
|
||||||
// mqtt.Publish(c.MQTTStateTopic, c.ToString()) // bisogna rimuovere questa
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (c *DummyChannel) SaveLastState() {
|
func (c *DummyChannel) SaveLastState() {
|
||||||
if c.onboot == "last" {
|
if c.onboot == "last" {
|
||||||
s := fmt.Sprintf("boards.%s.channels.%s.lastvalue", c.parent.ID, c.ID)
|
s := fmt.Sprintf("boards.%s.channels.%s.lastvalue", c.parent.ID, c.ID)
|
||||||
viper.Set(s, c.Value)
|
viper.Set(s, c.value)
|
||||||
viper.WriteConfig()
|
viper.WriteConfig()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *DummyChannel) Status() bool {
|
func (c *DummyChannel) Status() bool {
|
||||||
return c.Value
|
return c.value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *DummyChannel) Parent() Board {
|
func (c *DummyChannel) Parent() Board {
|
||||||
@ -163,7 +159,7 @@ func (b DummyBoard) Dump() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b DummyBoard) Initialize() {
|
func (b *DummyBoard) Initialize() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,13 +196,13 @@ func (c *DummyChannel) SetMQTTCommandTopic(str string) {
|
|||||||
func (c *DummyChannel) MQTTHandler(client PahoMQTT.Client, msg PahoMQTT.Message) {
|
func (c *DummyChannel) MQTTHandler(client PahoMQTT.Client, msg PahoMQTT.Message) {
|
||||||
switch string(msg.Payload()) {
|
switch string(msg.Payload()) {
|
||||||
case "on":
|
case "on":
|
||||||
if !c.Value {
|
if !c.value {
|
||||||
c.Value = true
|
c.value = true
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
}
|
}
|
||||||
case "off":
|
case "off":
|
||||||
if c.Value {
|
if c.value {
|
||||||
c.Value = false
|
c.value = false
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
406
src/board/board_i2c.go
Normal file
406
src/board/board_i2c.go
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
package board
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.openpdu.org/OpenPDU/openpdu/i2c"
|
||||||
|
"git.openpdu.org/OpenPDU/openpdu/syslog"
|
||||||
|
PahoMQTT "github.com/eclipse/paho.mqtt.golang"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
I2C "periph.io/x/periph/conn/i2c"
|
||||||
|
)
|
||||||
|
|
||||||
|
type I2CChannel struct {
|
||||||
|
ID string
|
||||||
|
Num uint
|
||||||
|
name string
|
||||||
|
mqttStateTopic string
|
||||||
|
mqttCommandTopic string
|
||||||
|
onboot string
|
||||||
|
parent *I2CBoard
|
||||||
|
onChannelUpdateFunctions map[string]onChannelUpdateFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
type I2CBoard struct {
|
||||||
|
ID string
|
||||||
|
Name string
|
||||||
|
ChannelCount uint
|
||||||
|
channels []*I2CChannel
|
||||||
|
i2cDevice *I2C.Dev
|
||||||
|
inverted bool
|
||||||
|
i2cDataA []byte
|
||||||
|
i2cDataB []byte
|
||||||
|
lastUpdate time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func newI2CChannel(v *viper.Viper, channelID string) I2CChannel {
|
||||||
|
v.SetDefault("name", "unknown")
|
||||||
|
v.SetDefault("lastValue", false)
|
||||||
|
v.SetDefault("onboot", "off")
|
||||||
|
v.SetDefault("mqtt.statetopic", v.GetString("name"))
|
||||||
|
|
||||||
|
return I2CChannel{
|
||||||
|
ID: channelID,
|
||||||
|
Num: v.GetUint("num"),
|
||||||
|
name: v.GetString("name"),
|
||||||
|
mqttStateTopic: v.GetString("mqtt.statetopic"),
|
||||||
|
mqttCommandTopic: v.GetString("mqtt.commandtopic"),
|
||||||
|
onboot: v.GetString("onboot"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newI2CBoard(v *viper.Viper, id string) *Board {
|
||||||
|
var b *I2CBoard
|
||||||
|
|
||||||
|
v.SetDefault("name", "board "+id)
|
||||||
|
v.SetDefault("type", "i2c")
|
||||||
|
v.SetDefault("channelCount", 0)
|
||||||
|
v.SetDefault("channels", "")
|
||||||
|
v.SetDefault("inverted", true)
|
||||||
|
|
||||||
|
if v.GetInt("channelCount") > 0 {
|
||||||
|
for i := 0; i < v.GetInt("channelCount"); i++ {
|
||||||
|
v.SetDefault("channels."+fmt.Sprint(i)+".num", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b = &I2CBoard{
|
||||||
|
ID: id,
|
||||||
|
Name: v.GetString("name"),
|
||||||
|
ChannelCount: v.GetUint("channelCount"),
|
||||||
|
inverted: v.GetBool("inverted"),
|
||||||
|
}
|
||||||
|
|
||||||
|
channels := make([]*I2CChannel, 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 := newI2CChannel(channelConfig, channelid)
|
||||||
|
c.parent = b
|
||||||
|
if c.Num >= v.GetUint("channelCount") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
channels[c.Num] = &c
|
||||||
|
AllChannels[c.ID] = &c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.channels = channels
|
||||||
|
syslog.Info("Created new I2C board")
|
||||||
|
var b1 Board = b
|
||||||
|
return &b1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) Toggle() (bool, error) {
|
||||||
|
oldval := c.Status()
|
||||||
|
c.setToggle()
|
||||||
|
c.parent.WriteStatus()
|
||||||
|
c.SaveLastState()
|
||||||
|
for f := range c.onChannelUpdateFunctions {
|
||||||
|
c.onChannelUpdateFunctions[f](oldval, c)
|
||||||
|
}
|
||||||
|
return c.Status(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) setToggle() {
|
||||||
|
var data *[]byte
|
||||||
|
var mask byte
|
||||||
|
|
||||||
|
if c.Num < 8 {
|
||||||
|
data = &c.parent.i2cDataA
|
||||||
|
} else {
|
||||||
|
data = &c.parent.i2cDataB
|
||||||
|
}
|
||||||
|
mask = 1 << (c.Num % 8)
|
||||||
|
log.Printf("toggle1: %v \n", c.parent.i2cDataA[0])
|
||||||
|
(*data)[0] ^= mask
|
||||||
|
log.Printf("toggle2: %v \n", c.parent.i2cDataA[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) On() error {
|
||||||
|
oldval := c.Status()
|
||||||
|
c.SetOn()
|
||||||
|
c.parent.WriteStatus()
|
||||||
|
c.SaveLastState()
|
||||||
|
for f := range c.onChannelUpdateFunctions {
|
||||||
|
c.onChannelUpdateFunctions[f](oldval, c)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) SetOn() {
|
||||||
|
var data *[]byte
|
||||||
|
var mask byte
|
||||||
|
|
||||||
|
if c.Num < 8 {
|
||||||
|
data = &c.parent.i2cDataA
|
||||||
|
} else {
|
||||||
|
data = &c.parent.i2cDataB
|
||||||
|
}
|
||||||
|
mask = 1 << (c.Num % 8)
|
||||||
|
(*data)[0] |= mask
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) Off() error {
|
||||||
|
oldval := c.Status()
|
||||||
|
c.SetOff()
|
||||||
|
c.parent.WriteStatus()
|
||||||
|
c.SaveLastState()
|
||||||
|
for f := range c.onChannelUpdateFunctions {
|
||||||
|
c.onChannelUpdateFunctions[f](oldval, c)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) SetOff() {
|
||||||
|
var data *[]byte
|
||||||
|
var mask byte
|
||||||
|
|
||||||
|
if c.Num < 8 {
|
||||||
|
data = &c.parent.i2cDataA
|
||||||
|
} else {
|
||||||
|
data = &c.parent.i2cDataB
|
||||||
|
}
|
||||||
|
mask = (1 << (c.Num % 8)) ^ 0xFF
|
||||||
|
(*data)[0] &= mask
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) ToString() string {
|
||||||
|
if !c.Status() {
|
||||||
|
return "off"
|
||||||
|
}
|
||||||
|
return "on"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) SaveLastState() {
|
||||||
|
if c.onboot == "last" {
|
||||||
|
s := fmt.Sprintf("boards.%s.channels.%s.lastvalue", c.parent.ID, c.ID)
|
||||||
|
viper.Set(s, c.Status())
|
||||||
|
viper.WriteConfig()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) Status() bool {
|
||||||
|
var data *[]byte
|
||||||
|
c.parent.ReadStatus()
|
||||||
|
if c.Num < 8 {
|
||||||
|
data = &c.parent.i2cDataA
|
||||||
|
} else {
|
||||||
|
data = &c.parent.i2cDataB
|
||||||
|
}
|
||||||
|
value := ((*data)[0] >> (c.Num % 8) & 1) == 1
|
||||||
|
log.Printf("status ch %v: %v", c.Num, value)
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) Parent() Board {
|
||||||
|
return c.parent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) Dump() {
|
||||||
|
log.Printf(" Channel %d (on boot: %s): %s \n", c.Num, c.onboot, c.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b I2CBoard) 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 *I2CBoard) ReadStatus() {
|
||||||
|
now := time.Now()
|
||||||
|
diff := now.Sub(b.lastUpdate)
|
||||||
|
ns := diff.Nanoseconds()
|
||||||
|
if ns < 10*1000000 { // 10ms
|
||||||
|
// syslog.Debug(fmt.Sprintf("I2C update skipped because less than 10ms passed (%v)", ns))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
replyA := [1]byte{}
|
||||||
|
replyB := [1]byte{}
|
||||||
|
b.i2cDevice.Tx([]byte{0x12}, replyA[:])
|
||||||
|
b.i2cDevice.Tx([]byte{0x13}, replyB[:])
|
||||||
|
|
||||||
|
log.Printf("read1: %v \n", replyA)
|
||||||
|
if b.inverted {
|
||||||
|
replyA[0] ^= 0xFF
|
||||||
|
replyB[0] ^= 0xFF
|
||||||
|
}
|
||||||
|
log.Printf("read2: %v \n", replyA)
|
||||||
|
|
||||||
|
b.i2cDataA[0] = replyA[0]
|
||||||
|
b.i2cDataB[0] = replyB[0]
|
||||||
|
b.lastUpdate = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *I2CBoard) WriteStatus() {
|
||||||
|
// var dA, dB, oA, oB []byte
|
||||||
|
var dA, dB []byte
|
||||||
|
|
||||||
|
dA = []byte{0x12, 0x00}
|
||||||
|
dB = []byte{0x13, 0x00}
|
||||||
|
|
||||||
|
dA[1] = b.i2cDataA[0]
|
||||||
|
|
||||||
|
log.Printf("write1: %v \n", dA)
|
||||||
|
|
||||||
|
dB[1] = b.i2cDataB[0]
|
||||||
|
if b.inverted {
|
||||||
|
dA[1] ^= 0xff
|
||||||
|
dB[1] ^= 0xff
|
||||||
|
}
|
||||||
|
// dA = append([]byte{0x12}, dA...)
|
||||||
|
log.Printf("write2: %v \n", dA)
|
||||||
|
// dB = append([]byte{0x13}, dB...)
|
||||||
|
|
||||||
|
// b.i2cDevice.Tx(dA, oA)
|
||||||
|
// b.i2cDevice.Tx(dB, oB)
|
||||||
|
|
||||||
|
if _, err := b.i2cDevice.Write(dA); err != nil {
|
||||||
|
syslog.Err(err.Error())
|
||||||
|
}
|
||||||
|
if _, err := b.i2cDevice.Write(dB); err != nil {
|
||||||
|
syslog.Err(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("write3: %v \n", dA)
|
||||||
|
// log.Printf("write3: %v - %v\n", dA, oA)
|
||||||
|
|
||||||
|
b.lastUpdate = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *I2CBoard) Initialize() {
|
||||||
|
syslog.Info("Initializing I2C board")
|
||||||
|
|
||||||
|
for {
|
||||||
|
if i2c.I2Cbus == nil {
|
||||||
|
syslog.Warning("i2cboard: i2cbus not found")
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MCP23017 - can work in 8bit mode or 16bit mode, you have to set IOCON.BANK=1 (8bit) or =0 (16bit default)
|
||||||
|
* 16 bit mode:
|
||||||
|
* 0x00 IO direction bank A (1=input 0=output)
|
||||||
|
* 0x01 IO direction bank B (1=input 0=output)
|
||||||
|
* 0x12 GPIO A
|
||||||
|
* 0x13 GPIO B
|
||||||
|
*
|
||||||
|
* 8 bit mode
|
||||||
|
* 0x00 IO direction (1=input 0=output)
|
||||||
|
* 0x09 GPIO
|
||||||
|
*/
|
||||||
|
|
||||||
|
mydevice := &I2C.Dev{Addr: 0x27, Bus: i2c.I2Cbus}
|
||||||
|
|
||||||
|
// set all output
|
||||||
|
write := []byte{0x0, 0x0}
|
||||||
|
if _, err := mydevice.Write(write); err != nil {
|
||||||
|
syslog.Err(err.Error())
|
||||||
|
}
|
||||||
|
write = []byte{0x01, 0x0}
|
||||||
|
if _, err := mydevice.Write(write); err != nil {
|
||||||
|
syslog.Err(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
b.i2cDevice = mydevice
|
||||||
|
b.i2cDataA = make([]byte, 1)
|
||||||
|
b.i2cDataB = make([]byte, 1)
|
||||||
|
syslog.Info("I2C board: reading initial status")
|
||||||
|
b.ReadStatus()
|
||||||
|
|
||||||
|
for i := range b.channels {
|
||||||
|
c := b.channels[i]
|
||||||
|
switch c.onboot {
|
||||||
|
case "on":
|
||||||
|
c.SetOn()
|
||||||
|
case "off":
|
||||||
|
c.SetOff()
|
||||||
|
case "last":
|
||||||
|
s := fmt.Sprintf("boards.%s.channels.%s.lastvalue", c.parent.ID, c.ID)
|
||||||
|
|
||||||
|
switch viper.GetBool(s) {
|
||||||
|
case true:
|
||||||
|
c.SetOn()
|
||||||
|
case false:
|
||||||
|
c.SetOff()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
syslog.Info(fmt.Sprintf("Channel %d status: %v", i, c.Status()))
|
||||||
|
}
|
||||||
|
|
||||||
|
b.WriteStatus()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *I2CBoard) Channel(num uint64) Channel {
|
||||||
|
return b.channels[num]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) Name() string {
|
||||||
|
return c.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) OnBoot() string {
|
||||||
|
return c.onboot
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) 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 *I2CChannel) 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 *I2CChannel) 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 *I2CChannel) MQTTHandler(client PahoMQTT.Client, msg PahoMQTT.Message) {
|
||||||
|
switch string(msg.Payload()) {
|
||||||
|
case "on":
|
||||||
|
if !c.Status() {
|
||||||
|
c.On()
|
||||||
|
}
|
||||||
|
case "off":
|
||||||
|
if c.Status() {
|
||||||
|
c.Off()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) MQTTStateTopic() string {
|
||||||
|
return c.mqttStateTopic
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) MQTTCommandTopic() string {
|
||||||
|
return c.mqttCommandTopic
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterBoardType("i2c", newI2CBoard)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *I2CChannel) AddOnChannelUpdateFunction(name string, f onChannelUpdateFunction) {
|
||||||
|
if c.onChannelUpdateFunctions == nil {
|
||||||
|
c.onChannelUpdateFunctions = make(map[string]onChannelUpdateFunction)
|
||||||
|
}
|
||||||
|
c.onChannelUpdateFunctions[name] = f
|
||||||
|
}
|
@ -17,7 +17,7 @@ type MQTTChannel struct {
|
|||||||
name string
|
name string
|
||||||
mqttStateTopic string
|
mqttStateTopic string
|
||||||
mqttCommandTopic string
|
mqttCommandTopic string
|
||||||
Value bool
|
value bool
|
||||||
onboot string
|
onboot string
|
||||||
parent *MQTTBoard
|
parent *MQTTBoard
|
||||||
MQTTRemoteStateTopic string
|
MQTTRemoteStateTopic string
|
||||||
@ -66,7 +66,7 @@ func newMQTTChannel(v *viper.Viper, channelID string) MQTTChannel {
|
|||||||
name: v.GetString("name"),
|
name: v.GetString("name"),
|
||||||
mqttStateTopic: v.GetString("mqtt.statetopic"),
|
mqttStateTopic: v.GetString("mqtt.statetopic"),
|
||||||
mqttCommandTopic: v.GetString("mqtt.commandtopic"),
|
mqttCommandTopic: v.GetString("mqtt.commandtopic"),
|
||||||
Value: value,
|
value: value,
|
||||||
onboot: v.GetString("onboot"),
|
onboot: v.GetString("onboot"),
|
||||||
MQTTRemoteStateTopic: v.GetString("mqttremote.statetopic"),
|
MQTTRemoteStateTopic: v.GetString("mqttremote.statetopic"),
|
||||||
MQTTRemoteCommandTopic: v.GetString("mqttremote.commandtopic"),
|
MQTTRemoteCommandTopic: v.GetString("mqttremote.commandtopic"),
|
||||||
@ -133,18 +133,18 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *MQTTChannel) Toggle() (bool, error) {
|
func (c *MQTTChannel) Toggle() (bool, error) {
|
||||||
c.Value = !c.Value
|
c.value = !c.value
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
for f := range c.onChannelUpdateFunctions {
|
for f := range c.onChannelUpdateFunctions {
|
||||||
c.onChannelUpdateFunctions[f](!c.Value, c)
|
c.onChannelUpdateFunctions[f](!c.value, c)
|
||||||
}
|
}
|
||||||
c.UpdateRemoteMQTT()
|
c.UpdateRemoteMQTT()
|
||||||
return c.Value, nil
|
return c.value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MQTTChannel) On() error {
|
func (c *MQTTChannel) On() error {
|
||||||
oldval := c.Value
|
oldval := c.value
|
||||||
c.Value = true
|
c.value = true
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
for f := range c.onChannelUpdateFunctions {
|
for f := range c.onChannelUpdateFunctions {
|
||||||
c.onChannelUpdateFunctions[f](oldval, c)
|
c.onChannelUpdateFunctions[f](oldval, c)
|
||||||
@ -154,8 +154,8 @@ func (c *MQTTChannel) On() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *MQTTChannel) Off() error {
|
func (c *MQTTChannel) Off() error {
|
||||||
oldval := c.Value
|
oldval := c.value
|
||||||
c.Value = false
|
c.value = false
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
for f := range c.onChannelUpdateFunctions {
|
for f := range c.onChannelUpdateFunctions {
|
||||||
c.onChannelUpdateFunctions[f](oldval, c)
|
c.onChannelUpdateFunctions[f](oldval, c)
|
||||||
@ -165,7 +165,7 @@ func (c *MQTTChannel) Off() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *MQTTChannel) ToString() string {
|
func (c *MQTTChannel) ToString() string {
|
||||||
if !c.Value {
|
if !c.value {
|
||||||
return "off"
|
return "off"
|
||||||
}
|
}
|
||||||
return "on"
|
return "on"
|
||||||
@ -174,7 +174,7 @@ func (c *MQTTChannel) ToString() string {
|
|||||||
func (c *MQTTChannel) SaveLastState() {
|
func (c *MQTTChannel) SaveLastState() {
|
||||||
if c.onboot == "last" {
|
if c.onboot == "last" {
|
||||||
s := fmt.Sprintf("boards.%s.channels.%s.lastvalue", c.parent.ID, c.ID)
|
s := fmt.Sprintf("boards.%s.channels.%s.lastvalue", c.parent.ID, c.ID)
|
||||||
viper.Set(s, c.Value)
|
viper.Set(s, c.value)
|
||||||
viper.WriteConfig()
|
viper.WriteConfig()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ func (c *MQTTChannel) UpdateRemoteMQTT() {
|
|||||||
connected := c.parent.MQTTClient.IsConnected()
|
connected := c.parent.MQTTClient.IsConnected()
|
||||||
if connected {
|
if connected {
|
||||||
v := c.MQTTRemotePayloadOff
|
v := c.MQTTRemotePayloadOff
|
||||||
if c.Value {
|
if c.value {
|
||||||
v = c.MQTTRemotePayloadOn
|
v = c.MQTTRemotePayloadOn
|
||||||
}
|
}
|
||||||
c.parent.MQTTClient.Publish(c.MQTTRemoteCommandTopic, 0, false, v)
|
c.parent.MQTTClient.Publish(c.MQTTRemoteCommandTopic, 0, false, v)
|
||||||
@ -191,7 +191,7 @@ func (c *MQTTChannel) UpdateRemoteMQTT() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *MQTTChannel) Status() bool {
|
func (c *MQTTChannel) Status() bool {
|
||||||
return c.Value
|
return c.value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MQTTChannel) Parent() Board {
|
func (c *MQTTChannel) Parent() Board {
|
||||||
@ -261,16 +261,16 @@ func (b *MQTTBoard) Initialize() {
|
|||||||
func (c *MQTTChannel) MQTTRemoteHandler(client PahoMQTT.Client, msg PahoMQTT.Message) {
|
func (c *MQTTChannel) MQTTRemoteHandler(client PahoMQTT.Client, msg PahoMQTT.Message) {
|
||||||
switch string(msg.Payload()) {
|
switch string(msg.Payload()) {
|
||||||
case c.MQTTRemotePayloadOn:
|
case c.MQTTRemotePayloadOn:
|
||||||
if !c.Value {
|
if !c.value {
|
||||||
c.Value = true
|
c.value = true
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
for f := range c.onChannelUpdateFunctions {
|
for f := range c.onChannelUpdateFunctions {
|
||||||
c.onChannelUpdateFunctions[f](false, c)
|
c.onChannelUpdateFunctions[f](false, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case c.MQTTRemotePayloadOff:
|
case c.MQTTRemotePayloadOff:
|
||||||
if c.Value {
|
if c.value {
|
||||||
c.Value = false
|
c.value = false
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
for f := range c.onChannelUpdateFunctions {
|
for f := range c.onChannelUpdateFunctions {
|
||||||
c.onChannelUpdateFunctions[f](true, c)
|
c.onChannelUpdateFunctions[f](true, c)
|
||||||
@ -287,14 +287,14 @@ func (c *MQTTChannel) MQTTHandler(client PahoMQTT.Client, msg PahoMQTT.Message)
|
|||||||
))
|
))
|
||||||
switch string(msg.Payload()) {
|
switch string(msg.Payload()) {
|
||||||
case "on":
|
case "on":
|
||||||
if !c.Value {
|
if !c.value {
|
||||||
c.Value = true
|
c.value = true
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
c.UpdateRemoteMQTT()
|
c.UpdateRemoteMQTT()
|
||||||
}
|
}
|
||||||
case "off":
|
case "off":
|
||||||
if c.Value {
|
if c.value {
|
||||||
c.Value = false
|
c.value = false
|
||||||
c.SaveLastState()
|
c.SaveLastState()
|
||||||
c.UpdateRemoteMQTT()
|
c.UpdateRemoteMQTT()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user