Update openpdu_example.yaml, board.go, and 11 more files...
This commit is contained in:
parent
0687cb2258
commit
ef2b809707
@ -4,7 +4,8 @@ display:
|
|||||||
swaptopbottom: false
|
swaptopbottom: false
|
||||||
type: ssd1306
|
type: ssd1306
|
||||||
w: 128
|
w: 128
|
||||||
hostname: openpdu-rack1
|
system:
|
||||||
|
hostname: openpdu-rack1
|
||||||
|
|
||||||
mqtt:
|
mqtt:
|
||||||
cliendid: openpdu-main
|
cliendid: openpdu-main
|
||||||
@ -25,23 +26,24 @@ boards:
|
|||||||
type: dummy
|
type: dummy
|
||||||
inverted: false
|
inverted: false
|
||||||
channelCount: 4
|
channelCount: 4
|
||||||
|
name: The Dummy Board
|
||||||
channels:
|
channels:
|
||||||
4976c508-1f63-4894-a859-cc5bd555b3c1:
|
4976c508-1f63-4894-a859-cc5bd555b3c1:
|
||||||
num: 0
|
num: 0
|
||||||
name: autonomo
|
name: autonomo
|
||||||
startValue: false
|
onboot: off
|
||||||
c0a4d271-2b75-41c0-8b05-86c5ca0b3e94:
|
c0a4d271-2b75-41c0-8b05-86c5ca0b3e94:
|
||||||
num: 1
|
num: 1
|
||||||
name: fenomeno
|
name: fenomeno
|
||||||
startValue: false
|
onboot: off
|
||||||
4d0b384f-6bcb-4eca-a803-ebea90c2a434:
|
4d0b384f-6bcb-4eca-a803-ebea90c2a434:
|
||||||
num: 2
|
num: 2
|
||||||
name: ecomeno
|
name: ecomeno
|
||||||
startValue: false
|
onboot: off
|
||||||
acb5e9d5-959c-4427-a850-17c262b96c16:
|
acb5e9d5-959c-4427-a850-17c262b96c16:
|
||||||
num: 3
|
num: 3
|
||||||
name: ripopolo
|
name: ripopolo
|
||||||
startValue: false
|
onboot: off
|
||||||
outlets:
|
outlets:
|
||||||
0fca047e-0e7f-4cee-83a8-2086ee306faf:
|
0fca047e-0e7f-4cee-83a8-2086ee306faf:
|
||||||
num: 0
|
num: 0
|
||||||
|
111
src/board.go
111
src/board.go
@ -9,46 +9,48 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Channel struct {
|
type Channel struct {
|
||||||
id string
|
ID string
|
||||||
num uint
|
Num uint
|
||||||
name string
|
Name string
|
||||||
value bool
|
Value bool
|
||||||
inverted bool // low level only
|
Inverted bool // low level only
|
||||||
startValue bool
|
OnBoot string
|
||||||
parent *Board
|
Parent *Board
|
||||||
}
|
}
|
||||||
|
|
||||||
type Board struct {
|
type Board struct {
|
||||||
id string
|
ID string
|
||||||
name string
|
Name string
|
||||||
channelCount uint
|
ChannelCount uint
|
||||||
inverted bool // low level only
|
Inverted bool // low level only
|
||||||
channels []Channel
|
Channels []Channel
|
||||||
}
|
}
|
||||||
|
|
||||||
type Outlet struct {
|
type Outlet struct {
|
||||||
num uint
|
ID string
|
||||||
board *Board
|
Num uint
|
||||||
channel *Channel
|
Description string
|
||||||
|
Board *Board
|
||||||
|
Channel *Channel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Channel) Toggle() (bool, error) {
|
func (c Channel) Toggle() (bool, error) {
|
||||||
c.value = !c.value
|
c.Value = !c.Value
|
||||||
return c.value, nil
|
return c.Value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Channel) On() error {
|
func (c Channel) On() error {
|
||||||
c.value = true
|
c.Value = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Channel) Off() error {
|
func (c Channel) Off() error {
|
||||||
c.value = true
|
c.Value = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Channel) Status() bool {
|
func (c Channel) Status() bool {
|
||||||
return c.value
|
return c.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
var boards []Board
|
var boards []Board
|
||||||
@ -57,17 +59,26 @@ var outlets []Outlet
|
|||||||
|
|
||||||
func newDummyChannel(v *viper.Viper, channelID string) Channel {
|
func newDummyChannel(v *viper.Viper, channelID string) Channel {
|
||||||
v.SetDefault("name", "unknown")
|
v.SetDefault("name", "unknown")
|
||||||
v.SetDefault("startValue", false)
|
v.SetDefault("lastValue", false)
|
||||||
v.SetDefault("inverted", 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()
|
// newUUID := UUID.New().String()
|
||||||
// v.SetDefault("id", newUUID)
|
// v.SetDefault("id", newUUID)
|
||||||
return Channel{
|
return Channel{
|
||||||
id: channelID,
|
ID: channelID,
|
||||||
num: v.GetUint("num"),
|
Num: v.GetUint("num"),
|
||||||
name: v.GetString("name"),
|
Name: v.GetString("name"),
|
||||||
value: v.GetBool("startValue"),
|
Value: value,
|
||||||
inverted: v.GetBool("inverted"),
|
Inverted: v.GetBool("inverted"),
|
||||||
startValue: v.GetBool("startValue"),
|
OnBoot: v.GetString("onboot"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,10 +98,10 @@ func newDummyBoard(v *viper.Viper, id string) Board {
|
|||||||
}
|
}
|
||||||
|
|
||||||
b = Board{
|
b = Board{
|
||||||
id: id,
|
ID: id,
|
||||||
name: v.GetString("name"),
|
Name: v.GetString("name"),
|
||||||
channelCount: v.GetUint("channelCount"),
|
ChannelCount: v.GetUint("channelCount"),
|
||||||
inverted: v.GetBool("inverted"),
|
Inverted: v.GetBool("inverted"),
|
||||||
}
|
}
|
||||||
|
|
||||||
channels := make([]Channel, v.GetInt("channelCount"))
|
channels := make([]Channel, v.GetInt("channelCount"))
|
||||||
@ -101,16 +112,16 @@ func newDummyBoard(v *viper.Viper, id string) Board {
|
|||||||
channelid := strings.ToLower(channelid1)
|
channelid := strings.ToLower(channelid1)
|
||||||
channelConfig := channelsConfig.Sub(channelid)
|
channelConfig := channelsConfig.Sub(channelid)
|
||||||
c := newDummyChannel(channelConfig, channelid)
|
c := newDummyChannel(channelConfig, channelid)
|
||||||
c.parent = &b
|
c.Parent = &b
|
||||||
if c.num >= v.GetUint("channelCount") {
|
if c.Num >= v.GetUint("channelCount") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
channels[c.num] = c
|
channels[c.Num] = c
|
||||||
allChannels[c.id] = &c
|
allChannels[c.ID] = &c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.channels = channels
|
b.Channels = channels
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
@ -139,6 +150,8 @@ func parseBoardsConfig() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outlets = make([]Outlet, len(allChannels))
|
||||||
|
|
||||||
outletsConfig := viper.Sub("outlets")
|
outletsConfig := viper.Sub("outlets")
|
||||||
if outletsConfig == nil {
|
if outletsConfig == nil {
|
||||||
logWarning("No outlet configured")
|
logWarning("No outlet configured")
|
||||||
@ -148,16 +161,20 @@ func parseBoardsConfig() {
|
|||||||
for key := range outletsConfig.AllSettings() {
|
for key := range outletsConfig.AllSettings() {
|
||||||
outletConfig := outletsConfig.Sub(key)
|
outletConfig := outletsConfig.Sub(key)
|
||||||
num := outletConfig.GetUint("num")
|
num := outletConfig.GetUint("num")
|
||||||
|
outletConfig.SetDefault("description", "no description")
|
||||||
|
description := outletConfig.GetString("description")
|
||||||
channelID := strings.ToLower(outletConfig.GetString("channelID"))
|
channelID := strings.ToLower(outletConfig.GetString("channelID"))
|
||||||
channel := allChannels[channelID]
|
channel := allChannels[channelID]
|
||||||
// TODO: channel non esistente
|
// TODO: channel non esistente
|
||||||
o := Outlet{
|
o := Outlet{
|
||||||
num: num,
|
ID: key,
|
||||||
board: channel.parent,
|
Num: num,
|
||||||
channel: channel,
|
Description: description,
|
||||||
|
Board: channel.Parent,
|
||||||
|
Channel: channel,
|
||||||
}
|
}
|
||||||
|
|
||||||
outlets = append(outlets, o)
|
outlets[num] = o
|
||||||
}
|
}
|
||||||
|
|
||||||
// dumpa tutto
|
// dumpa tutto
|
||||||
@ -173,20 +190,16 @@ func parseBoardsConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c Channel) Dump() {
|
func (c Channel) Dump() {
|
||||||
v := "off"
|
log.Printf(" Channel %d (on boot: %s): %s \n", c.Num, c.OnBoot, c.Name)
|
||||||
if c.startValue {
|
|
||||||
v = "on"
|
|
||||||
}
|
|
||||||
log.Printf(" Channel %d (start: %s): %s \n", c.num, v, c.name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Board) Dump() {
|
func (b Board) Dump() {
|
||||||
log.Printf("Board '%s' (id: %s): %d channels\n", b.name, b.id, b.channelCount)
|
log.Printf("Board '%s' (id: %s): %d channels\n", b.Name, b.ID, b.ChannelCount)
|
||||||
for c := range b.channels {
|
for c := range b.Channels {
|
||||||
b.channels[c].Dump()
|
b.Channels[c].Dump()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Outlet) 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{}
|
type Dictionary map[string]interface{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
viper.SetDefault("hostname", "openpdu")
|
viper.SetDefault("system.hostname", "openpdu")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
parseBoardsConfig()
|
parseBoardsConfig()
|
||||||
go mqttLoop()
|
go mqttLoop()
|
||||||
go UpsConnect()
|
go UpsConnect()
|
||||||
logInfo("hostname: " + viper.GetString("hostname"))
|
logInfo("hostname: " + viper.GetString("system.hostname"))
|
||||||
startServer()
|
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
|
var o Outlet
|
||||||
for i := range outlets {
|
for i := range outlets {
|
||||||
o = outlets[i]
|
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)
|
data = append(data, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ func jsonOutletToggle(ctx *macaron.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
viper.SetDefault("listeningport", 4000)
|
viper.SetDefault("system.listeningport", 4000)
|
||||||
}
|
}
|
||||||
|
|
||||||
func startServer() {
|
func startServer() {
|
||||||
@ -69,6 +69,9 @@ func startServer() {
|
|||||||
// m.Get("/", myHandler)
|
// m.Get("/", myHandler)
|
||||||
|
|
||||||
m.Get("/", statusPage)
|
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("/lan", lanPage)
|
||||||
m.Get("/mqtt", mqttPage)
|
m.Get("/mqtt", mqttPage)
|
||||||
m.Post("/mqtt", binding.Bind(MQTTPostForm{}), mqttPost)
|
m.Post("/mqtt", binding.Bind(MQTTPostForm{}), mqttPost)
|
||||||
@ -83,8 +86,8 @@ func startServer() {
|
|||||||
ctx.HTML(200, "boards") // 200 is the response code.
|
ctx.HTML(200, "boards") // 200 is the response code.
|
||||||
})
|
})
|
||||||
|
|
||||||
logInfo("hostname: " + viper.GetString("hostname"))
|
logInfo("hostname: " + viper.GetString("system.hostname"))
|
||||||
|
|
||||||
logInfo("Web interface ready")
|
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)
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,16 @@
|
|||||||
<!-- Tell the browser to be responsive to screen width -->
|
<!-- Tell the browser to be responsive to screen width -->
|
||||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
||||||
<!-- Bootstrap 3.3.7 -->
|
<!-- Bootstrap 3.3.7 -->
|
||||||
<link rel="stylesheet" href="../../bower_components/bootstrap/dist/css/bootstrap.min.css">
|
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
|
||||||
<!-- Font Awesome -->
|
<!-- Font Awesome -->
|
||||||
<link rel="stylesheet" href="../../bower_components/font-awesome/css/font-awesome.min.css">
|
<link rel="stylesheet" href="/bower_components/font-awesome/css/font-awesome.min.css">
|
||||||
<!-- Ionicons -->
|
<!-- Ionicons -->
|
||||||
<link rel="stylesheet" href="../../bower_components/Ionicons/css/ionicons.min.css">
|
<link rel="stylesheet" href="/bower_components/Ionicons/css/ionicons.min.css">
|
||||||
<!-- Theme style -->
|
<!-- Theme style -->
|
||||||
<link rel="stylesheet" href="adminlte/css/AdminLTE.min.css">
|
<link rel="stylesheet" href="/adminlte/css/AdminLTE.min.css">
|
||||||
<!-- AdminLTE Skins. Choose a skin from the css/skins
|
<!-- AdminLTE Skins. Choose a skin from the css/skins
|
||||||
folder instead of downloading all of them to reduce the load. -->
|
folder instead of downloading all of them to reduce the load. -->
|
||||||
<link rel="stylesheet" href="adminlte/css/skins/_all-skins.min.css">
|
<link rel="stylesheet" href="/adminlte/css/skins/_all-skins.min.css">
|
||||||
|
|
||||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||||
@ -23,4 +23,4 @@
|
|||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
|
||||||
<!-- Google Font -->
|
<!-- Google Font -->
|
||||||
<link rel="stylesheet" href="../../googlefonts/fonts.css">
|
<link rel="stylesheet" href="/googlefonts/fonts.css">
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<!-- jQuery 3 -->
|
<!-- jQuery 3 -->
|
||||||
<script src="../../bower_components/jquery/dist/jquery.min.js"></script>
|
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
|
||||||
<!-- Bootstrap 3.3.7 -->
|
<!-- Bootstrap 3.3.7 -->
|
||||||
<script src="../../bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
|
<script src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||||
<!-- Slimscroll -->
|
<!-- Slimscroll -->
|
||||||
<script src="../../bower_components/jquery-slimscroll/jquery.slimscroll.min.js"></script>
|
<script src="/bower_components/jquery-slimscroll/jquery.slimscroll.min.js"></script>
|
||||||
<!-- FastClick -->
|
<!-- FastClick -->
|
||||||
<script src="../../bower_components/fastclick/lib/fastclick.js"></script>
|
<script src="/bower_components/fastclick/lib/fastclick.js"></script>
|
||||||
<!-- AdminLTE App -->
|
<!-- AdminLTE App -->
|
||||||
<script src="adminlte/js/adminlte.min.js"></script>
|
<script src="/adminlte/js/adminlte.min.js"></script>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li class="treeview {% if pageselected in " lan mqtt ups syslog backup " %}active menu-open{% endif %}">
|
<li class="treeview {% if pageselected in " outlets lan mqtt ups syslog backup " %}active menu-open{% endif %}">
|
||||||
|
|
||||||
<a href="#">
|
<a href="#">
|
||||||
<i class="fa fa-gears"></i>
|
<i class="fa fa-gears"></i>
|
||||||
@ -30,6 +30,10 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
<ul class="treeview-menu">
|
<ul class="treeview-menu">
|
||||||
|
<li {% if pageselected=="outlets" %}class="active" {% endif %}>
|
||||||
|
<a href="/outlets"><i class="fa fa-circle-o"></i> Outlets</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li {% if pageselected=="lan" %}class="active" {% endif %}>
|
<li {% if pageselected=="lan" %}class="active" {% endif %}>
|
||||||
<a href="/lan"><i class="fa fa-circle-o"></i> LAN</a>
|
<a href="/lan"><i class="fa fa-circle-o"></i> LAN</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -8,21 +8,18 @@
|
|||||||
<body class="hold-transition skin-blue sidebar-mini">
|
<body class="hold-transition skin-blue sidebar-mini">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
||||||
{% include "common/page-header.html" %} {% with pageselected="mqtt" %} {% include "common/sidebar-menu.html" %} {% endwith %}
|
{% include "common/page-header.html" %} {% with pageselected="mqtt" %} {% include "common/sidebar-menu.html" %}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
<!-- Content Wrapper. Contains page content -->
|
<!-- Content Wrapper. Contains page content -->
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Main content -->
|
<!-- Main content -->
|
||||||
<section class="content">
|
<section class="content">
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
|
|
||||||
|
|
||||||
<div class="box box-info">
|
<div class="box box-info">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">MQTT configuration</h3>
|
<h3 class="box-title">MQTT configuration</h3>
|
||||||
@ -50,42 +47,48 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="host" class="col-sm-2 control-label">Host</label>
|
<label for="host" class="col-sm-2 control-label">Host</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="host" name="host" placeholder="Hostname or IP address" value="{{ host }}">
|
<input type="text" class="form-control" id="host" name="host" placeholder="Hostname or IP address"
|
||||||
|
value="{{ host }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="port" class="col-sm-2 control-label">Port</label>
|
<label for="port" class="col-sm-2 control-label">Port</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="port" name="port" placeholder="1883" value="{{ port }}">
|
<input type="text" class="form-control" id="port" name="port" placeholder="1883"
|
||||||
|
value="{{ port }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="clientid" class="col-sm-2 control-label">Client ID</label>
|
<label for="clientid" class="col-sm-2 control-label">Client ID</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="clientid" name="clientid" placeholder="client id" value="{{ clientid }}">
|
<input type="text" class="form-control" id="clientid" name="clientid" placeholder="client id"
|
||||||
|
value="{{ clientid }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="prefix" class="col-sm-2 control-label">Prefix</label>
|
<label for="prefix" class="col-sm-2 control-label">Prefix</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="prefix" name="prefix" placeholder="topic prefix" value="{{ prefix }}">
|
<input type="text" class="form-control" id="prefix" name="prefix" placeholder="topic prefix"
|
||||||
|
value="{{ prefix }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="username" class="col-sm-2 control-label">Username</label>
|
<label for="username" class="col-sm-2 control-label">Username</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="username" name="username" placeholder="username (if required)" value="{{ username }}">
|
<input type="text" class="form-control" id="username" name="username"
|
||||||
|
placeholder="username (if required)" value="{{ username }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="password" class="col-sm-2 control-label">Password</label>
|
<label for="password" class="col-sm-2 control-label">Password</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="password" class="form-control" id="password" name="password" placeholder="password (if required)" value="{{ password }}">
|
<input type="password" class="form-control" id="password" name="password"
|
||||||
|
placeholder="password (if required)" value="{{ password }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
114
templates/outlet_edit.html
Normal file
114
templates/outlet_edit.html
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
{% include "common/common-head.html" %}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="hold-transition skin-blue sidebar-mini">
|
||||||
|
<div class="wrapper">
|
||||||
|
|
||||||
|
{% include "common/page-header.html" %}
|
||||||
|
{% with pageselected="outlets" %}
|
||||||
|
{% include "common/sidebar-menu.html" %}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
|
<!-- Content Wrapper. Contains page content -->
|
||||||
|
<div class="content-wrapper">
|
||||||
|
|
||||||
|
<!-- Main content -->
|
||||||
|
<section class="content">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
|
||||||
|
<div class="box box-info">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">Outlet configuration</h3>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-header -->
|
||||||
|
<!-- form start -->
|
||||||
|
<form class="form-horizontal" method="post">
|
||||||
|
<div class="box-body">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="num" class="col-sm-2 control-label">Outlet #</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="num" disabled="" value="{{ outlet.Num }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="description" class="col-sm-2 control-label">Description</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="description" name="description" placeholder="Enter a meaningful description"
|
||||||
|
value="{{ outlet.Description }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="onboot" class="col-sm-2 control-label">On Boot</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<select class="form-control" id="onboot" name="onboot">
|
||||||
|
{% for i in onboot_values %}
|
||||||
|
{% if i == outlet.Channel.OnBoot %}
|
||||||
|
<option value="{{ i }}" selected>{{ i }}</option>
|
||||||
|
{% else %}
|
||||||
|
<option value="{{ i }}">{{ i }}</option>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="board" class="col-sm-2 control-label">Board</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="board" disabled="" value="{{ outlet.Board.Name }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="channel" class="col-sm-2 control-label">Board port</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="channel" disabled="" value="{{ outlet.Channel.Name }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="channel" class="col-sm-2 control-label">Board port #</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="channel" disabled="" value="{{ outlet.Channel.Num }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- /.box-body -->
|
||||||
|
<div class="box-footer">
|
||||||
|
<button type="submit" class="btn btn-info pull-right">Save</button>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-footer -->
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.col -->
|
||||||
|
</div>
|
||||||
|
<!-- /.row -->
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<!-- /.content -->
|
||||||
|
</div>
|
||||||
|
<!-- /.content-wrapper -->
|
||||||
|
|
||||||
|
{% include "common/footer.html" %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- ./wrapper -->
|
||||||
|
|
||||||
|
{% include "common/common-js.html" %}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
92
templates/outlets.html
Normal file
92
templates/outlets.html
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
{% include "common/common-head.html" %}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="hold-transition skin-blue sidebar-mini">
|
||||||
|
<div class="wrapper">
|
||||||
|
|
||||||
|
{% include "common/page-header.html" %}
|
||||||
|
{% with pageselected="outlets" %}
|
||||||
|
{% include "common/sidebar-menu.html" %}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
|
<!-- Content Wrapper. Contains page content -->
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<!-- Content Header (Page header) -->
|
||||||
|
<section class="content-header">
|
||||||
|
<h1>
|
||||||
|
Outlet configuration
|
||||||
|
</h1>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Main content -->
|
||||||
|
<section class="content">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<div class="box">
|
||||||
|
|
||||||
|
<div class="box-body">
|
||||||
|
<table id="outlettable" class="table table-bordered table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 15px">#</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Internal channel</th>
|
||||||
|
<th style="width: 150px">On boot</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
{%- for outlet in outlets -%}
|
||||||
|
<tr>
|
||||||
|
<td>{{ outlet.Num }}</td>
|
||||||
|
<td><a href="/outlet/{{ outlet.Num }}">{{ outlet.Description }}</a></td>
|
||||||
|
<td>{{ outlet.Channel.Name }}</td>
|
||||||
|
<td>{{ outlet.Channel.OnBoot }}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-body -->
|
||||||
|
</div>
|
||||||
|
<!-- /.box -->
|
||||||
|
</div>
|
||||||
|
<!-- /.col -->
|
||||||
|
</div>
|
||||||
|
<!-- /.row -->
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<!-- /.content -->
|
||||||
|
</div>
|
||||||
|
<!-- /.content-wrapper -->
|
||||||
|
|
||||||
|
{% include "common/footer.html" %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- ./wrapper -->
|
||||||
|
|
||||||
|
{% include "common/common-js.html" %}
|
||||||
|
|
||||||
|
<!-- DataTables -->
|
||||||
|
<script src="../../bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||||
|
<script src="../../bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
var table = $('#outlettable').DataTable({
|
||||||
|
paging: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -8,7 +8,10 @@
|
|||||||
<body class="hold-transition skin-blue sidebar-mini">
|
<body class="hold-transition skin-blue sidebar-mini">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
||||||
{% include "common/page-header.html" %} {% with pageselected="ups" %} {% include "common/sidebar-menu.html" %} {% endwith %}
|
{% include "common/page-header.html" %}
|
||||||
|
{% with pageselected="ups" %}
|
||||||
|
{% include "common/sidebar-menu.html" %}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
<!-- Content Wrapper. Contains page content -->
|
<!-- Content Wrapper. Contains page content -->
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
@ -80,28 +83,32 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="host" class="col-sm-2 control-label">Host</label>
|
<label for="host" class="col-sm-2 control-label">Host</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="host" name="host" placeholder="Hostname or IP address" value="{{ host }}">
|
<input type="text" class="form-control" id="host" name="host" placeholder="Hostname or IP address"
|
||||||
|
value="{{ host }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="upsname" class="col-sm-2 control-label">UPS Name</label>
|
<label for="upsname" class="col-sm-2 control-label">UPS Name</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="upsname" name="upsname" placeholder="UPS name" value="{{ upsname }}">
|
<input type="text" class="form-control" id="upsname" name="upsname" placeholder="UPS name"
|
||||||
|
value="{{ upsname }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="username" class="col-sm-2 control-label">Username</label>
|
<label for="username" class="col-sm-2 control-label">Username</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="username" name="username" placeholder="username (if required)" value="{{ username }}">
|
<input type="text" class="form-control" id="username" name="username"
|
||||||
|
placeholder="username (if required)" value="{{ username }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="password" class="col-sm-2 control-label">Password</label>
|
<label for="password" class="col-sm-2 control-label">Password</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="password" class="form-control" id="password" name="password" placeholder="password (if required)" value="{{ password }}">
|
<input type="password" class="form-control" id="password" name="password"
|
||||||
|
placeholder="password (if required)" value="{{ password }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user