Update openpdu_example.yaml, board.go, and 11 more files...
This commit is contained in:
111
src/board.go
111
src/board.go
@@ -9,46 +9,48 @@ import (
|
||||
)
|
||||
|
||||
type Channel struct {
|
||||
id string
|
||||
num uint
|
||||
name string
|
||||
value bool
|
||||
inverted bool // low level only
|
||||
startValue bool
|
||||
parent *Board
|
||||
ID string
|
||||
Num uint
|
||||
Name string
|
||||
Value bool
|
||||
Inverted bool // low level only
|
||||
OnBoot string
|
||||
Parent *Board
|
||||
}
|
||||
|
||||
type Board struct {
|
||||
id string
|
||||
name string
|
||||
channelCount uint
|
||||
inverted bool // low level only
|
||||
channels []Channel
|
||||
ID string
|
||||
Name string
|
||||
ChannelCount uint
|
||||
Inverted bool // low level only
|
||||
Channels []Channel
|
||||
}
|
||||
|
||||
type Outlet struct {
|
||||
num uint
|
||||
board *Board
|
||||
channel *Channel
|
||||
ID string
|
||||
Num uint
|
||||
Description string
|
||||
Board *Board
|
||||
Channel *Channel
|
||||
}
|
||||
|
||||
func (c Channel) Toggle() (bool, error) {
|
||||
c.value = !c.value
|
||||
return c.value, nil
|
||||
c.Value = !c.Value
|
||||
return c.Value, nil
|
||||
}
|
||||
|
||||
func (c Channel) On() error {
|
||||
c.value = true
|
||||
c.Value = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Channel) Off() error {
|
||||
c.value = true
|
||||
c.Value = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Channel) Status() bool {
|
||||
return c.value
|
||||
return c.Value
|
||||
}
|
||||
|
||||
var boards []Board
|
||||
@@ -57,17 +59,26 @@ var outlets []Outlet
|
||||
|
||||
func newDummyChannel(v *viper.Viper, channelID string) Channel {
|
||||
v.SetDefault("name", "unknown")
|
||||
v.SetDefault("startValue", false)
|
||||
v.SetDefault("lastValue", false)
|
||||
v.SetDefault("inverted", false)
|
||||
v.SetDefault("onboot", "off")
|
||||
|
||||
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 Channel{
|
||||
id: channelID,
|
||||
num: v.GetUint("num"),
|
||||
name: v.GetString("name"),
|
||||
value: v.GetBool("startValue"),
|
||||
inverted: v.GetBool("inverted"),
|
||||
startValue: v.GetBool("startValue"),
|
||||
ID: channelID,
|
||||
Num: v.GetUint("num"),
|
||||
Name: v.GetString("name"),
|
||||
Value: value,
|
||||
Inverted: v.GetBool("inverted"),
|
||||
OnBoot: v.GetString("onboot"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,10 +98,10 @@ func newDummyBoard(v *viper.Viper, id string) Board {
|
||||
}
|
||||
|
||||
b = Board{
|
||||
id: id,
|
||||
name: v.GetString("name"),
|
||||
channelCount: v.GetUint("channelCount"),
|
||||
inverted: v.GetBool("inverted"),
|
||||
ID: id,
|
||||
Name: v.GetString("name"),
|
||||
ChannelCount: v.GetUint("channelCount"),
|
||||
Inverted: v.GetBool("inverted"),
|
||||
}
|
||||
|
||||
channels := make([]Channel, v.GetInt("channelCount"))
|
||||
@@ -101,16 +112,16 @@ func newDummyBoard(v *viper.Viper, id string) Board {
|
||||
channelid := strings.ToLower(channelid1)
|
||||
channelConfig := channelsConfig.Sub(channelid)
|
||||
c := newDummyChannel(channelConfig, channelid)
|
||||
c.parent = &b
|
||||
if c.num >= v.GetUint("channelCount") {
|
||||
c.Parent = &b
|
||||
if c.Num >= v.GetUint("channelCount") {
|
||||
continue
|
||||
}
|
||||
channels[c.num] = c
|
||||
allChannels[c.id] = &c
|
||||
channels[c.Num] = c
|
||||
allChannels[c.ID] = &c
|
||||
}
|
||||
}
|
||||
}
|
||||
b.channels = channels
|
||||
b.Channels = channels
|
||||
|
||||
return b
|
||||
}
|
||||
@@ -139,6 +150,8 @@ func parseBoardsConfig() {
|
||||
|
||||
}
|
||||
|
||||
outlets = make([]Outlet, len(allChannels))
|
||||
|
||||
outletsConfig := viper.Sub("outlets")
|
||||
if outletsConfig == nil {
|
||||
logWarning("No outlet configured")
|
||||
@@ -148,16 +161,20 @@ func parseBoardsConfig() {
|
||||
for key := range outletsConfig.AllSettings() {
|
||||
outletConfig := outletsConfig.Sub(key)
|
||||
num := outletConfig.GetUint("num")
|
||||
outletConfig.SetDefault("description", "no description")
|
||||
description := outletConfig.GetString("description")
|
||||
channelID := strings.ToLower(outletConfig.GetString("channelID"))
|
||||
channel := allChannels[channelID]
|
||||
// TODO: channel non esistente
|
||||
o := Outlet{
|
||||
num: num,
|
||||
board: channel.parent,
|
||||
channel: channel,
|
||||
ID: key,
|
||||
Num: num,
|
||||
Description: description,
|
||||
Board: channel.Parent,
|
||||
Channel: channel,
|
||||
}
|
||||
|
||||
outlets = append(outlets, o)
|
||||
outlets[num] = o
|
||||
}
|
||||
|
||||
// dumpa tutto
|
||||
@@ -173,20 +190,16 @@ func parseBoardsConfig() {
|
||||
}
|
||||
|
||||
func (c Channel) Dump() {
|
||||
v := "off"
|
||||
if c.startValue {
|
||||
v = "on"
|
||||
}
|
||||
log.Printf(" Channel %d (start: %s): %s \n", c.num, v, c.name)
|
||||
log.Printf(" Channel %d (on boot: %s): %s \n", c.Num, c.OnBoot, 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()
|
||||
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)
|
||||
log.Printf("Outlet %v: channel name: %v\n", o.Num, o.Channel.Name)
|
||||
}
|
||||
|
||||
1
src/board_ui.go
Normal file
1
src/board_ui.go
Normal file
@@ -0,0 +1 @@
|
||||
package main
|
||||
@@ -8,14 +8,14 @@ import (
|
||||
type Dictionary map[string]interface{}
|
||||
|
||||
func init() {
|
||||
viper.SetDefault("hostname", "openpdu")
|
||||
viper.SetDefault("system.hostname", "openpdu")
|
||||
}
|
||||
|
||||
func main() {
|
||||
parseBoardsConfig()
|
||||
go mqttLoop()
|
||||
go UpsConnect()
|
||||
logInfo("hostname: " + viper.GetString("hostname"))
|
||||
logInfo("hostname: " + viper.GetString("system.hostname"))
|
||||
startServer()
|
||||
}
|
||||
|
||||
|
||||
82
src/outlets_ui.go
Normal file
82
src/outlets_ui.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
func outletsPage(ctx *macaron.Context) {
|
||||
|
||||
ctx.Data["outlets"] = outlets
|
||||
|
||||
ctx.HTML(200, "outlets")
|
||||
}
|
||||
|
||||
type OutletPostForm struct {
|
||||
Description string `form:"description" binding:"Required"`
|
||||
OnBoot string `form:"onboot" binding:"Required"`
|
||||
}
|
||||
|
||||
func outletEditPage(ctx *macaron.Context) {
|
||||
var err error
|
||||
var num uint64
|
||||
var o Outlet
|
||||
num, err = strconv.ParseUint(ctx.Params(":num"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"result": "error",
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
o = outlets[num]
|
||||
ctx.Data["outlet"] = o
|
||||
|
||||
ctx.Data["onboot_values"] = []string{"on", "off", "last"}
|
||||
ctx.HTML(200, "outlet_edit")
|
||||
}
|
||||
|
||||
func outletEditPost(ctx *macaron.Context, f OutletPostForm) {
|
||||
var err error
|
||||
var num uint64
|
||||
|
||||
num, err = strconv.ParseUint(ctx.Params(":num"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"result": "error",
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
onboot := "on"
|
||||
onbootForm := strings.ToLower(strings.TrimSpace(f.OnBoot))
|
||||
switch onbootForm {
|
||||
case
|
||||
"on",
|
||||
"off",
|
||||
"last":
|
||||
onboot = onbootForm
|
||||
default:
|
||||
outletsPage(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
outlets[num].Channel.OnBoot = onboot
|
||||
s1 := fmt.Sprintf("boards.%s.channels.%s.onboot", outlets[num].Board.ID, outlets[num].Channel.ID)
|
||||
viper.Set(s1, onboot)
|
||||
|
||||
outlets[num].Description = strings.TrimSpace(f.Description)
|
||||
s2 := fmt.Sprintf("outlets.%s.description", outlets[num].ID)
|
||||
viper.Set(s2, outlets[num].Description)
|
||||
|
||||
viper.WriteConfig()
|
||||
|
||||
ctx.Redirect("/outlets")
|
||||
}
|
||||
11
src/webui.go
11
src/webui.go
@@ -33,7 +33,7 @@ func jsonStatus(ctx *macaron.Context) {
|
||||
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)}
|
||||
d := []string{fmt.Sprintf("%d", o.Num), o.Channel.Name, fmt.Sprintf("%v", o.Channel.Value)}
|
||||
data = append(data, d)
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func jsonOutletToggle(ctx *macaron.Context) {
|
||||
}
|
||||
|
||||
func init() {
|
||||
viper.SetDefault("listeningport", 4000)
|
||||
viper.SetDefault("system.listeningport", 4000)
|
||||
}
|
||||
|
||||
func startServer() {
|
||||
@@ -69,6 +69,9 @@ func startServer() {
|
||||
// m.Get("/", myHandler)
|
||||
|
||||
m.Get("/", statusPage)
|
||||
m.Get("/outlets", outletsPage)
|
||||
m.Get("/outlet/:num", outletEditPage)
|
||||
m.Post("/outlet/:num", binding.Bind(OutletPostForm{}), outletEditPost)
|
||||
m.Get("/lan", lanPage)
|
||||
m.Get("/mqtt", mqttPage)
|
||||
m.Post("/mqtt", binding.Bind(MQTTPostForm{}), mqttPost)
|
||||
@@ -83,8 +86,8 @@ func startServer() {
|
||||
ctx.HTML(200, "boards") // 200 is the response code.
|
||||
})
|
||||
|
||||
logInfo("hostname: " + viper.GetString("hostname"))
|
||||
logInfo("hostname: " + viper.GetString("system.hostname"))
|
||||
|
||||
logInfo("Web interface ready")
|
||||
http.ListenAndServe("0.0.0.0:"+viper.GetString("listeningport"), m)
|
||||
http.ListenAndServe("0.0.0.0:"+viper.GetString("system.listeningport"), m)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user