Update config.go, display.go, and 7 more files...
This commit is contained in:
parent
1219291a6d
commit
9e2ef61772
@ -7,14 +7,12 @@ import (
|
||||
)
|
||||
|
||||
func readConfig() {
|
||||
viper.SetConfigName("openpdu.yaml") // name of config file (without extension)
|
||||
viper.SetConfigName("openpdu") // name of config file (without extension)
|
||||
viper.SetConfigType("yaml")
|
||||
viper.AddConfigPath("/etc/openpdu/") // path to look for the config file in
|
||||
viper.AddConfigPath(".") // optionally look for config in the working directory
|
||||
viper.AddConfigPath("/etc/openpdu/") // path to look for the config file in
|
||||
err := viper.ReadInConfig() // Find and read the config file
|
||||
if err != nil { // Handle errors reading the config file
|
||||
log.Printf("Fatal error config file: %s \n", err)
|
||||
log.Printf("Can't read config file: %s \n", err)
|
||||
}
|
||||
|
||||
viper.SetDefault("hostname", "openpdu")
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/font/basicfont"
|
||||
"golang.org/x/image/math/fixed"
|
||||
@ -14,6 +15,18 @@ import (
|
||||
"periph.io/x/periph/devices/ssd1306"
|
||||
)
|
||||
|
||||
func init() {
|
||||
viper.SetDefault("DisplayType", "none")
|
||||
displayLoop()
|
||||
}
|
||||
|
||||
func displayLoop() {
|
||||
if viper.GetString("DisplayType") == "ssd1306" {
|
||||
initI2C()
|
||||
go disp()
|
||||
}
|
||||
}
|
||||
|
||||
func addLabel(img *image.RGBA, x, y int, label string) {
|
||||
col := color.RGBA{200, 100, 0, 255}
|
||||
point := fixed.Point26_6{fixed.Int26_6(x * 64), fixed.Int26_6(y * 64)}
|
||||
|
15
src/main.go
15
src/main.go
@ -12,17 +12,14 @@ import (
|
||||
// Dictionary aaa
|
||||
type Dictionary map[string]interface{}
|
||||
|
||||
func init() {
|
||||
viper.SetDefault("hostname", "openpdu")
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
readConfig()
|
||||
|
||||
nam := viper.Get("hostname")
|
||||
log.Printf("hostname: %v\n", nam)
|
||||
|
||||
initI2C()
|
||||
|
||||
go disp()
|
||||
|
||||
go mqttLoop()
|
||||
log.Printf("hostname: %v\n", viper.Get("hostname"))
|
||||
startServer()
|
||||
}
|
||||
|
||||
|
91
src/mqtt.go
91
src/mqtt.go
@ -2,32 +2,85 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
MQTT "github.com/eclipse/paho.mqtt.golang"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var MQTTclient MQTT.Client
|
||||
|
||||
func init() {
|
||||
// set the protocol, ip and port of the broker.
|
||||
opts := MQTT.NewClientOptions().AddBroker("tcp://localhost:1883")
|
||||
viper.SetDefault("MqttCliendID", "OpenPDU") // max 23 chars
|
||||
viper.SetDefault("MqttPrefix", "openpdu") // max 23 chars
|
||||
viper.SetDefault("MqttSchema", "tcp")
|
||||
viper.SetDefault("MqttHost", "localhost")
|
||||
viper.SetDefault("MqttPort", "1883")
|
||||
viper.SetDefault("MqttUsername", "")
|
||||
viper.SetDefault("MqttPassword", "")
|
||||
|
||||
// set the id to the client.
|
||||
opts.SetClientID("Device-pub")
|
||||
// MQTT.ERROR = log.New(os.Stdout, "[ERROR] ", 0)
|
||||
// MQTT.CRITICAL = log.New(os.Stdout, "[CRIT] ", 0)
|
||||
// MQTT.WARN = log.New(os.Stdout, "[WARN] ", 0)
|
||||
// MQTT.DEBUG = log.New(os.Stdout, "[DEBUG] ", 0)
|
||||
|
||||
// create a new client.
|
||||
c := MQTT.NewClient(opts)
|
||||
token := c.Connect()
|
||||
token.Wait()
|
||||
if token.Error() != nil {
|
||||
fmt.Println(token.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
message := "hello this is the trial message"
|
||||
c.Publish("some_topic", 0, false, message)
|
||||
|
||||
//c.Subscribe("some_topic", 0, nil);
|
||||
c.Disconnect(250)
|
||||
//MQTTclient.Subscribe("some_topic", 0, nil);
|
||||
//MQTTclient.Disconnect(250)
|
||||
}
|
||||
|
||||
// https://girishjoshi.io/post/golang-paho-mqtt/
|
||||
|
||||
func mqttLoop() {
|
||||
uri := viper.GetString("MqttSchema") + "://" + viper.GetString("MqttHost") + ":" + viper.GetString("MqttPort")
|
||||
opts := MQTT.NewClientOptions().AddBroker(uri)
|
||||
|
||||
opts.SetClientID(viper.GetString("MqttCliendID"))
|
||||
|
||||
if username := viper.GetString("MqttUsername"); username != "" {
|
||||
opts.SetUsername(username)
|
||||
}
|
||||
|
||||
if password := viper.GetString("MqttPassword"); password != "" {
|
||||
opts.SetPassword(password)
|
||||
}
|
||||
|
||||
opts.SetAutoReconnect(true)
|
||||
opts.SetConnectRetryInterval(5 * time.Second)
|
||||
opts.SetConnectTimeout(5 * time.Second)
|
||||
|
||||
opts.SetConnectionLostHandler(func(c MQTT.Client, err error) {
|
||||
fmt.Printf("!!!!!! mqtt connection lost error: %s\n" + err.Error())
|
||||
})
|
||||
opts.SetReconnectingHandler(func(c MQTT.Client, options *MQTT.ClientOptions) {
|
||||
fmt.Println("...... mqtt reconnecting ......")
|
||||
})
|
||||
opts.SetOnConnectHandler(func(c MQTT.Client) {
|
||||
fmt.Println("...... mqtt connected ......")
|
||||
// MQTTclient.Publish("openpdu/status", 0, false, "connected")
|
||||
})
|
||||
|
||||
MQTTclient = MQTT.NewClient(opts)
|
||||
|
||||
for {
|
||||
token := MQTTclient.Connect()
|
||||
token.Wait()
|
||||
if MQTTclient.IsConnected() {
|
||||
break
|
||||
}
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func MQTTreconfigure() {
|
||||
if MQTTclient.IsConnected() {
|
||||
MQTTclient.Disconnect(250)
|
||||
}
|
||||
go mqttLoop()
|
||||
}
|
||||
|
||||
func MQTTpublish(topic string, value string) {
|
||||
if MQTTclient.IsConnected() {
|
||||
MQTTclient.Publish(viper.GetString("MqttPrefix")+"/"+topic, 0, false, value)
|
||||
}
|
||||
}
|
||||
|
56
src/mqtt_ui.go
Normal file
56
src/mqtt_ui.go
Normal file
@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
func mqttPage(ctx *macaron.Context) {
|
||||
ctx.Data["schema"] = viper.GetString("MqttSchema")
|
||||
ctx.Data["host"] = viper.GetString("MqttHost")
|
||||
ctx.Data["port"] = viper.GetString("MqttPort")
|
||||
ctx.Data["clientid"] = viper.GetString("MqttCliendID")
|
||||
ctx.Data["prefix"] = viper.GetString("MqttPrefix")
|
||||
ctx.Data["username"] = viper.GetString("MqttUsername")
|
||||
ctx.Data["password"] = viper.GetString("MqttPassword")
|
||||
|
||||
ctx.Data["schemas"] = []string{"tcp", "ssl", "ws"}
|
||||
ctx.HTML(200, "mqtt")
|
||||
}
|
||||
|
||||
type MQTTPostForm struct {
|
||||
Schema string `form:"schema" binding:"Required"`
|
||||
Host string `form:"host" binding:"Required"`
|
||||
Port string `form:"port" binding:"Required"`
|
||||
Prefix string `form:"prefix" binding:"Required"`
|
||||
ClientID string `form:"clientid" binding:"Required"`
|
||||
Username string `form:"username"`
|
||||
Password string `form:"password"`
|
||||
}
|
||||
|
||||
func mqttPost(ctx *macaron.Context, f MQTTPostForm) {
|
||||
schema := strings.ToLower(strings.TrimSpace(f.Schema))
|
||||
switch schema {
|
||||
case
|
||||
"tcp",
|
||||
"ssl",
|
||||
"ws":
|
||||
viper.Set("MqttSchema", schema)
|
||||
default:
|
||||
mqttPage(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
viper.Set("MqttHost", strings.ToLower(strings.TrimSpace(f.Host)))
|
||||
viper.Set("MqttPort", strings.ToLower(strings.TrimSpace(f.Port)))
|
||||
viper.Set("MqttCliendID", strings.TrimSpace(f.ClientID))
|
||||
viper.Set("MqttPrefix", strings.TrimSpace(f.Prefix))
|
||||
viper.Set("MqttUsername", strings.TrimSpace(f.Username))
|
||||
viper.Set("MqttPassword", f.Password)
|
||||
|
||||
viper.WriteConfig()
|
||||
|
||||
mqttPage(ctx)
|
||||
}
|
@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-macaron/binding"
|
||||
"github.com/go-macaron/pongo2"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
@ -25,6 +26,7 @@ func statusPage(ctx *macaron.Context) {
|
||||
}
|
||||
|
||||
func jsonStatus(ctx *macaron.Context) {
|
||||
MQTTpublish("openpdu/status", "asdss")
|
||||
|
||||
p0, err := MyBoard.channelStatus(0)
|
||||
if err != nil {
|
||||
@ -85,10 +87,12 @@ func jsonOutletToggle(ctx *macaron.Context) {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
MQTTpublish("openpdu/toggolo1", string(id))
|
||||
err = MyBoard.channelToggle(uint(id))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
MQTTpublish("openpdu/toggolo2", string(id))
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "ok",
|
||||
})
|
||||
@ -101,6 +105,8 @@ func startServer() {
|
||||
// m.Get("/", myHandler)
|
||||
|
||||
m.Get("/", statusPage)
|
||||
m.Get("/mqtt", mqttPage)
|
||||
m.Post("/mqtt", binding.Bind(MQTTPostForm{}), mqttPost)
|
||||
m.Get("/json/status", jsonStatus)
|
||||
m.Post("/json/outlet/:id/toggle", jsonOutletToggle)
|
||||
|
||||
|
@ -26,20 +26,33 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% if pageselected in "lan mqtt ups syslog backup restore" %}
|
||||
<li class="treeview active menu-open">
|
||||
{% else %}
|
||||
<li class="treeview">
|
||||
{% endif %}
|
||||
|
||||
<a href="#">
|
||||
<i class="fa fa-gears"></i> <span>Settings</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<ul class="treeview-menu">
|
||||
<li><a href="/settings/lan"><i class="fa fa-circle-o"></i> LAN</a></li>
|
||||
<li><a href="/settings/mqtt"><i class="fa fa-circle-o"></i> MQTT</a></li>
|
||||
<li><a href="/settings/ups"><i class="fa fa-circle-o"></i> UPS</a></li>
|
||||
<li><a href="/settings/syslog"><i class="fa fa-circle-o"></i> syslog</a></li>
|
||||
<li><a href="/settings/backup"><i class="fa fa-circle-o"></i> backup</a></li>
|
||||
<li><a href="/settings/restore"><i class="fa fa-circle-o"></i> restore</a></li>
|
||||
<li><a href="/lan"><i class="fa fa-circle-o"></i> LAN</a></li>
|
||||
|
||||
{% if pageselected == "mqtt" %}
|
||||
<li class="active">
|
||||
{% else %}
|
||||
<li>
|
||||
{% endif %}
|
||||
<a href="/mqtt"><i class="fa fa-circle-o"></i> MQTT</a></li>
|
||||
|
||||
<li><a href="/ups"><i class="fa fa-circle-o"></i> UPS</a></li>
|
||||
<li><a href="/syslog"><i class="fa fa-circle-o"></i> syslog</a></li>
|
||||
<li><a href="/backup"><i class="fa fa-circle-o"></i> backup</a></li>
|
||||
<li><a href="/restore"><i class="fa fa-circle-o"></i> restore</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
123
templates/mqtt.html
Normal file
123
templates/mqtt.html
Normal file
@ -0,0 +1,123 @@
|
||||
<!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="mqtt" %}
|
||||
{% 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">MQTT configuration</h3>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<!-- form start -->
|
||||
<form class="form-horizontal" method="post">
|
||||
<div class="box-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="schema" class="col-sm-2 control-label">Schema</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control" id="schema" name="schema">
|
||||
{% for i in schemas %}
|
||||
{% if i == schema %}
|
||||
<option value="{{ i }}" selected>{{ i }}</option>
|
||||
{% else %}
|
||||
<option value="{{ i }}">{{ i }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="host" class="col-sm-2 control-label">Host</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="host" name="host" placeholder="Hostname or IP address" value="{{ host }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="port" class="col-sm-2 control-label">Port</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="port" name="port" placeholder="1883" value="{{ port }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="clientid" class="col-sm-2 control-label">Client ID</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="clientid" name="clientid" placeholder="client id" value="{{ clientid }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="prefix" class="col-sm-2 control-label">Prefix</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="prefix" name="prefix" placeholder="topic prefix" value="{{ prefix }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="username" class="col-sm-2 control-label">Username</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="username" name="username" placeholder="username (if required)" value="{{ username }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password" class="col-sm-2 control-label">Password</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="password" name="password" placeholder="password (if required)" value="{{ password }}">
|
||||
</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>
|
||||
|
Loading…
Reference in New Issue
Block a user