Update board.go, mqtt.go, and 4 more files...

This commit is contained in:
Paolo Asperti 2021-01-05 11:27:49 +01:00
parent 76576053e2
commit 1edac26c50
6 changed files with 130 additions and 67 deletions

View File

@ -12,6 +12,7 @@ type Channel struct {
ID string ID string
Num uint Num uint
Name string Name string
MQTTTopic string
Value bool Value bool
Inverted bool // low level only Inverted bool // low level only
OnBoot string OnBoot string
@ -36,19 +37,42 @@ type Outlet struct {
func (c *Channel) Toggle() (bool, error) { func (c *Channel) Toggle() (bool, error) {
c.Value = !c.Value c.Value = !c.Value
c.OnChange()
return c.Value, nil return c.Value, nil
} }
func (c *Channel) On() error { func (c *Channel) On() error {
c.Value = true c.Value = true
c.OnChange()
return nil return nil
} }
func (c *Channel) Off() error { func (c *Channel) Off() error {
c.Value = true c.Value = true
c.OnChange()
return nil return nil
} }
func (c *Channel) ToString() string {
if !c.Value {
return "off"
}
return "on"
}
func (c *Channel) UpdateMQTT() {
MQTTpublish(c.MQTTTopic, c.ToString())
}
func (c *Channel) OnChange() {
if c.OnBoot == "last" {
s := fmt.Sprintf("boards.%s.channels.%s.lastvalue", c.Parent.ID, c.ID)
viper.Set(s, c.Value)
viper.WriteConfig()
}
c.UpdateMQTT()
}
func (c *Channel) Status() bool { func (c *Channel) Status() bool {
return c.Value return c.Value
} }
@ -62,6 +86,7 @@ func newDummyChannel(v *viper.Viper, channelID string) Channel {
v.SetDefault("lastValue", false) v.SetDefault("lastValue", false)
v.SetDefault("inverted", false) v.SetDefault("inverted", false)
v.SetDefault("onboot", "off") v.SetDefault("onboot", "off")
v.SetDefault("mqtttopic", v.GetString("name"))
value := false value := false
switch v.GetString("onboot") { switch v.GetString("onboot") {
@ -76,6 +101,7 @@ func newDummyChannel(v *viper.Viper, channelID string) Channel {
ID: channelID, ID: channelID,
Num: v.GetUint("num"), Num: v.GetUint("num"),
Name: v.GetString("name"), Name: v.GetString("name"),
MQTTTopic: v.GetString("mqtttopic"),
Value: value, Value: value,
Inverted: v.GetBool("inverted"), Inverted: v.GetBool("inverted"),
OnBoot: v.GetString("onboot"), OnBoot: v.GetString("onboot"),

View File

@ -69,6 +69,7 @@ func mqttLoop() {
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
} }
go MQTTRefreshLoop()
} }
func MQTTreconfigure() { func MQTTreconfigure() {
@ -83,3 +84,16 @@ func MQTTpublish(topic string, value string) {
MQTTclient.Publish(viper.GetString("Mqtt.Prefix")+"/"+topic, 0, false, value) MQTTclient.Publish(viper.GetString("Mqtt.Prefix")+"/"+topic, 0, false, value)
} }
} }
func MQTTRefreshLoop() {
for {
MQTTRefresh()
time.Sleep(30 * time.Second)
}
}
func MQTTRefresh() {
for o := range outlets {
outlets[o].Channel.UpdateMQTT()
}
}

View File

@ -19,6 +19,7 @@ func outletsPage(ctx *macaron.Context) {
type OutletPostForm struct { type OutletPostForm struct {
Description string `form:"description" binding:"Required"` Description string `form:"description" binding:"Required"`
MQTTTopic string `form:"mqtttopic"`
OnBoot string `form:"onboot" binding:"Required"` OnBoot string `form:"onboot" binding:"Required"`
} }
@ -76,6 +77,14 @@ func outletEditPost(ctx *macaron.Context, f OutletPostForm) {
s2 := fmt.Sprintf("outlets.%s.description", outlets[num].ID) s2 := fmt.Sprintf("outlets.%s.description", outlets[num].ID)
viper.Set(s2, outlets[num].Description) viper.Set(s2, outlets[num].Description)
mqtt := strings.TrimSpace(f.MQTTTopic)
if mqtt == "" {
mqtt = outlets[num].Channel.Name
}
outlets[num].Channel.MQTTTopic = mqtt
s3 := fmt.Sprintf("boards.%s.channels.%s.mqtttopic", outlets[num].Board.ID, outlets[num].Channel.ID)
viper.Set(s3, mqtt)
viper.WriteConfig() viper.WriteConfig()
ctx.Redirect("/outlets") ctx.Redirect("/outlets")

60
src/status_ui.go Normal file
View File

@ -0,0 +1,60 @@
package main
import (
"fmt"
"net/http"
"strconv"
"gopkg.in/macaron.v1"
)
func statusPage(ctx *macaron.Context) {
ctx.HTML(200, "status") // 200 is the response code.
}
func jsonStatus(ctx *macaron.Context) {
// MQTTpublish("openpdu/status", "asdss")
var data = [][]string{}
var o *Outlet
for i := range outlets {
o = outlets[i]
d := []string{fmt.Sprintf("%d", o.Num), o.Channel.Name, fmt.Sprintf("%v", o.Channel.Value)}
data = append(data, d)
}
ctx.JSON(http.StatusOK, Dictionary{
"data": data,
})
}
func jsonOutletToggle(ctx *macaron.Context) {
var err error
var num uint64
var outlet *Outlet
num, err = strconv.ParseUint(ctx.Params(":id"), 10, 64)
if err != nil {
ctx.JSON(http.StatusOK, Dictionary{
"data": "error1",
})
}
if num >= uint64(len(outlets)) || num < 0 {
ctx.JSON(http.StatusOK, Dictionary{
"data": "error2",
})
}
outlet = outlets[num]
_, err = outlet.Channel.Toggle()
if err != nil {
ctx.JSON(http.StatusOK, Dictionary{
"data": "error3",
})
}
ctx.JSON(http.StatusOK, Dictionary{
"data": "ok",
})
}

View File

@ -1,9 +1,7 @@
package main package main
import ( import (
"fmt"
"net/http" "net/http"
"strconv"
"github.com/go-macaron/binding" "github.com/go-macaron/binding"
"github.com/go-macaron/pongo2" "github.com/go-macaron/pongo2"
@ -11,58 +9,6 @@ import (
"gopkg.in/macaron.v1" "gopkg.in/macaron.v1"
) )
func statusPage(ctx *macaron.Context) {
ctx.HTML(200, "status") // 200 is the response code.
}
func jsonStatus(ctx *macaron.Context) {
// MQTTpublish("openpdu/status", "asdss")
var data = [][]string{}
var o *Outlet
for i := range outlets {
o = outlets[i]
d := []string{fmt.Sprintf("%d", o.Num), o.Channel.Name, fmt.Sprintf("%v", o.Channel.Value)}
data = append(data, d)
}
ctx.JSON(http.StatusOK, Dictionary{
"data": data,
})
}
func jsonOutletToggle(ctx *macaron.Context) {
var err error
var num uint64
var outlet *Outlet
num, err = strconv.ParseUint(ctx.Params(":id"), 10, 64)
if err != nil {
ctx.JSON(http.StatusOK, Dictionary{
"data": "error1",
})
}
if num >= uint64(len(outlets)) || num < 0 {
ctx.JSON(http.StatusOK, Dictionary{
"data": "error2",
})
}
outlet = outlets[num]
_, err = outlet.Channel.Toggle()
if err != nil {
ctx.JSON(http.StatusOK, Dictionary{
"data": "error3",
})
}
// MQTTpublish("openpdu/toggolo1", fmt.Sprint(id))
ctx.JSON(http.StatusOK, Dictionary{
"data": "ok",
})
}
func init() { func init() {
viper.SetDefault("system.listeningport", 4000) viper.SetDefault("system.listeningport", 4000)
} }

View File

@ -61,6 +61,14 @@
</div> </div>
</div> </div>
<div class="form-group">
<label for="mqtttopic" class="col-sm-2 control-label">MQTT Topic</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="mqtttopic" name="mqtttopic" placeholder="MQTT Topic without prefix (defaults to board port name)"
value="{{ outlet.Channel.MQTTTopic }}">
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="board" class="col-sm-2 control-label">Board</label> <label for="board" class="col-sm-2 control-label">Board</label>
<div class="col-sm-10"> <div class="col-sm-10">