forked from OpenPDU/openpdu
new source promoted
This commit is contained in:
88
source/board.go
Normal file
88
source/board.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package main
|
||||
|
||||
import "log"
|
||||
|
||||
// BoardType Status
|
||||
const (
|
||||
BoardTypeDummy uint = 0
|
||||
BoardTypeGPIO uint = 1
|
||||
BoardTypeI2CGPIO uint = 2
|
||||
BoardTypeI2CADC uint = 3
|
||||
)
|
||||
|
||||
// Board def
|
||||
type Board struct {
|
||||
ChannelCount uint `json:"channelcount"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type uint `json:"type"`
|
||||
Bus uint `json:"bus"`
|
||||
Address uint `json:"address"`
|
||||
dummyValue map[uint]bool
|
||||
}
|
||||
|
||||
// ChannelName - return the name of a channel, useful for onboard GPIO
|
||||
func (b *Board) ChannelName(num uint) string {
|
||||
return string(num)
|
||||
}
|
||||
|
||||
// PowerON def
|
||||
func (b *Board) PowerON(num uint) error {
|
||||
switch b.Type {
|
||||
case BoardTypeDummy:
|
||||
if b.dummyValue == nil {
|
||||
b.dummyValue = make(map[uint]bool)
|
||||
}
|
||||
b.dummyValue[num] = true
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PowerOFF def
|
||||
func (b *Board) PowerOFF(num uint) error {
|
||||
switch b.Type {
|
||||
case BoardTypeDummy:
|
||||
if b.dummyValue == nil {
|
||||
b.dummyValue = make(map[uint]bool)
|
||||
}
|
||||
b.dummyValue[num] = false
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PowerToggle def
|
||||
func (b *Board) PowerToggle(num uint) error {
|
||||
switch b.Type {
|
||||
case BoardTypeDummy:
|
||||
if b.dummyValue == nil {
|
||||
b.dummyValue = make(map[uint]bool)
|
||||
}
|
||||
v, _ := b.PowerStatus(num)
|
||||
log.Printf("toggle prestatus %v:%v", num, b.dummyValue[num])
|
||||
b.dummyValue[num] = !v
|
||||
log.Printf("toggle poststatus %v:%v", num, b.dummyValue[num])
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PowerStatus def
|
||||
func (b *Board) PowerStatus(num uint) (bool, error) {
|
||||
switch b.Type {
|
||||
case BoardTypeDummy:
|
||||
if b.dummyValue == nil {
|
||||
b.dummyValue = make(map[uint]bool)
|
||||
}
|
||||
val, ok := b.dummyValue[num]
|
||||
if !ok {
|
||||
b.dummyValue[num] = false
|
||||
val = false
|
||||
}
|
||||
log.Printf("status %v:%v", num, val)
|
||||
return val, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
45
source/boardlink.go
Normal file
45
source/boardlink.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package main
|
||||
|
||||
// Boardlink def
|
||||
type Boardlink struct {
|
||||
BoardID string `json:"boardid"`
|
||||
Channel uint `json:"channel"`
|
||||
board *Board
|
||||
}
|
||||
|
||||
// Board def
|
||||
func (bl Boardlink) Board() *Board {
|
||||
if bl.board == nil {
|
||||
for i := range TheConfig.Boards {
|
||||
if TheConfig.Boards[i].ID == bl.BoardID {
|
||||
bl.board = TheConfig.Boards[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return bl.board
|
||||
}
|
||||
|
||||
// PowerON def
|
||||
func (bl Boardlink) PowerON() error {
|
||||
b := bl.Board()
|
||||
return b.PowerON(bl.Channel)
|
||||
}
|
||||
|
||||
// PowerOFF def
|
||||
func (bl Boardlink) PowerOFF() error {
|
||||
b := bl.Board()
|
||||
return b.PowerOFF(bl.Channel)
|
||||
}
|
||||
|
||||
// PowerToggle def
|
||||
func (bl Boardlink) PowerToggle() error {
|
||||
b := bl.Board()
|
||||
return b.PowerToggle(bl.Channel)
|
||||
}
|
||||
|
||||
// PowerStatus def
|
||||
func (bl Boardlink) PowerStatus() (bool, error) {
|
||||
b := bl.Board()
|
||||
return b.PowerStatus(bl.Channel)
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package main
|
||||
|
||||
// Board definition
|
||||
type Board struct {
|
||||
ID string `mapstructure:"id"`
|
||||
Name string `mapstructure:"name"`
|
||||
Type string `mapstructure:"type"`
|
||||
}
|
||||
@@ -1,78 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// Config definition
|
||||
type Config struct {
|
||||
hostname string `mapstructure:"hostname"`
|
||||
boards []*Board `flow,mapstructure:"boards"`
|
||||
// Configuration def
|
||||
type Configuration struct {
|
||||
Hostname string `json:"hostname"`
|
||||
Outlets map[(uint)]Outlet `json:"outlets"`
|
||||
Boards []*Board `json:"boards"`
|
||||
MQTT MQTTConfig `json:"mqtt"`
|
||||
}
|
||||
|
||||
// Configuration container
|
||||
var Configuration Config
|
||||
|
||||
func init() {
|
||||
viper.SetConfigName("openpdu") // name of config file (without extension)
|
||||
viper.SetConfigType("yaml") // type of config file
|
||||
viper.AddConfigPath("/etc/openpdu/") // path to look for the config file in
|
||||
viper.AddConfigPath(".") // optionally look for config in the working directory
|
||||
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)
|
||||
}
|
||||
|
||||
viper.SetDefault("hostname", "openpdu1")
|
||||
br := viper.Get("boards").([]interface{})
|
||||
for k, v := range br {
|
||||
log.Printf("Key: %v", k)
|
||||
log.Printf(" Value: %v", v)
|
||||
var ba Board
|
||||
viper.UnmarshalKey("boards."+string(k), ba)
|
||||
log.Printf(" Valueid: %v", ba.ID)
|
||||
}
|
||||
|
||||
log.Printf("basdo: %v", viper.Get("boards[0]"))
|
||||
log.Printf("todo: %v", viper.AllSettings())
|
||||
|
||||
Configuration := Config{}
|
||||
err = viper.Unmarshal(&Configuration)
|
||||
func loadConfig(filename string) (Configuration, error) {
|
||||
bytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
fmt.Printf("unable to decode into config struct, %v", err)
|
||||
return Configuration{}, err
|
||||
}
|
||||
|
||||
viper.WriteConfigAs("openpdu_out.yaml")
|
||||
|
||||
log.Printf("All settings - hostname: %v \n", Configuration.hostname)
|
||||
for idx, b := range Configuration.boards {
|
||||
log.Printf("b %v: %v (%v)", idx, b.Name, b.Type)
|
||||
|
||||
var c Configuration
|
||||
err = json.Unmarshal(bytes, &c)
|
||||
if err != nil {
|
||||
return Configuration{}, err
|
||||
}
|
||||
// var b []Board
|
||||
// var brd Board
|
||||
// b = viper.Get("boards").([]Board)
|
||||
// for brd := range viper.Get("boards") {
|
||||
// log.Printf("brd: %v", brd)
|
||||
// }
|
||||
// log.Printf("bo: %v", viper.Get("boards"))
|
||||
// log.Printf("bo: %v", b)
|
||||
log.Printf("cfg: %v", Configuration)
|
||||
log.Printf("cfgb: %v", Configuration.boards)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func writeConfig() {
|
||||
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.SetDefault("hostname", "openpdu")
|
||||
err := viper.WriteConfig()
|
||||
if err != nil { // Handle errors reading the config file
|
||||
log.Printf("Fatato error config file: %s \n", err)
|
||||
func saveConfig(c Configuration, filename string) error {
|
||||
bytes, err := json.MarshalIndent(c, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("ok credo \n")
|
||||
|
||||
return ioutil.WriteFile(filename, bytes, 0644)
|
||||
}
|
||||
|
||||
// TheConfig def
|
||||
var TheConfig Configuration
|
||||
|
||||
104
source/i2c.go
104
source/i2c.go
@@ -1,104 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"periph.io/x/periph/conn/i2c"
|
||||
"periph.io/x/periph/conn/i2c/i2creg"
|
||||
"periph.io/x/periph/host"
|
||||
)
|
||||
|
||||
// I2CBoard bla
|
||||
type I2CBoard struct {
|
||||
i2cdev i2c.Dev
|
||||
channels uint
|
||||
data []byte
|
||||
inverted bool
|
||||
}
|
||||
|
||||
// MyBoard bla
|
||||
var MyBoard = I2CBoard{
|
||||
channels: 8,
|
||||
inverted: true,
|
||||
}
|
||||
|
||||
func (b I2CBoard) channelStatus(ch uint) (bool, error) {
|
||||
if b.channels <= 0 {
|
||||
return false, errors.New("Board without channels")
|
||||
}
|
||||
if ch >= b.channels {
|
||||
return false, errors.New("Invalid channel")
|
||||
}
|
||||
write := []byte{0x0A}
|
||||
err := b.i2cdev.Tx(write, b.data)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
byteToConsider := ch / b.channels
|
||||
value := (b.data[byteToConsider] >> (ch % 8) & 1) == 1
|
||||
if b.inverted {
|
||||
value = !value
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (b I2CBoard) channelToggle(ch uint) error {
|
||||
var mask byte
|
||||
|
||||
if b.channels <= 0 {
|
||||
return errors.New("Board without channels")
|
||||
}
|
||||
if ch >= b.channels {
|
||||
return errors.New("Invalid channel")
|
||||
}
|
||||
|
||||
// if b.data == nil {
|
||||
_, _ = b.channelStatus(ch)
|
||||
// }
|
||||
|
||||
byteToConsider := ch / b.channels
|
||||
mask = 1 << (ch % 8)
|
||||
v := b.data[byteToConsider]
|
||||
v ^= mask
|
||||
b.data[byteToConsider] = v
|
||||
|
||||
write := append([]byte{0x09}, b.data...)
|
||||
_, err := b.i2cdev.Write(write)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Make sure periph is initialized.
|
||||
if _, err := host.Init(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Use i2creg I²C bus registry to find the first available I²C bus.
|
||||
mybus, err := i2creg.Open("/dev/i2c-0")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// defer mybus.Close()
|
||||
|
||||
// bus 0
|
||||
// Dev is a valid conn.Conn.
|
||||
mydevice := &i2c.Dev{Addr: 0x27, Bus: mybus}
|
||||
|
||||
// Send a command 0x10 and expect a 5 bytes reply.
|
||||
// write := []byte{0x10}
|
||||
write := []byte{0x0}
|
||||
// read := make([]byte, 5)
|
||||
// if err := d.Tx(write, read); err != nil {
|
||||
if _, err := mydevice.Write(write); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
MyBoard.i2cdev = *mydevice
|
||||
MyBoard.data = make([]byte, (MyBoard.channels-1)/8+1)
|
||||
|
||||
}
|
||||
@@ -1,19 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// Dictionary definition
|
||||
type Dictionary map[string]interface{}
|
||||
|
||||
func initOutlets() {
|
||||
for _, o := range TheConfig.Outlets {
|
||||
o.PowerInitial()
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
nam := viper.Get("hostname")
|
||||
log.Printf("hostname: %v\n", nam)
|
||||
var err error
|
||||
|
||||
var c1 Configuration
|
||||
|
||||
c1 = createMockConfig()
|
||||
|
||||
err = saveConfig(c1, "t.json")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
TheConfig, err = loadConfig("t.json")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = saveConfig(TheConfig, "t1.json")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
startServer()
|
||||
|
||||
}
|
||||
|
||||
// https://github.com/ColorlibHQ/AdminLTE/archive/v2.4.17.tar.gz
|
||||
|
||||
101
source/mock.go
Normal file
101
source/mock.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package main
|
||||
|
||||
func createMockConfig() Configuration {
|
||||
b1 := new(Board)
|
||||
b1.ID = "47e41dc9-4a14-4b79-8644-d7442a15cb50"
|
||||
b1.Name = "Virtual IO"
|
||||
b1.Type = BoardTypeDummy
|
||||
b1.ChannelCount = 40
|
||||
|
||||
b2 := new(Board)
|
||||
b2.ID = "6561df75-bf93-43f5-82ac-9b3dda081961"
|
||||
b2.Name = "Internal GPIO"
|
||||
b2.Type = BoardTypeGPIO
|
||||
b2.ChannelCount = 40
|
||||
|
||||
b3 := new(Board)
|
||||
b3.Bus = 1
|
||||
b3.Address = 0x29
|
||||
b3.ID = "79690164-214f-41b0-93f9-e910dd54f323"
|
||||
b3.Name = "bordo1"
|
||||
b3.Type = BoardTypeI2CGPIO
|
||||
b3.ChannelCount = 8
|
||||
|
||||
b4 := new(Board)
|
||||
b4.Bus = 1
|
||||
b4.Address = 0x27
|
||||
b4.ID = "93f446d8-59e4-4abd-8bf7-e31cd80bc713"
|
||||
b4.Name = "bordo2"
|
||||
b4.Type = BoardTypeI2CADC
|
||||
b4.ChannelCount = 4
|
||||
|
||||
return Configuration{
|
||||
Hostname: "maramao",
|
||||
MQTT: MQTTConfig{
|
||||
BrokerIP: "192.168.2.190",
|
||||
BrokerPort: "1883",
|
||||
ClientID: "openpdu-123",
|
||||
Username: "DVES_USER",
|
||||
Password: "DVES_PASS",
|
||||
CleanSession: false,
|
||||
Topic: "openpdu/ok",
|
||||
HomeAssistant: true,
|
||||
},
|
||||
Boards: []*Board{b1, b2, b3, b4},
|
||||
Outlets: map[(uint)]Outlet{
|
||||
0: Outlet{
|
||||
Name: "uscita 0",
|
||||
Location: "port 1 dx",
|
||||
HasPowerMeter: true,
|
||||
Command: Boardlink{
|
||||
BoardID: b1.ID,
|
||||
Channel: 0,
|
||||
},
|
||||
PowerMeter: Boardlink{
|
||||
BoardID: b4.ID,
|
||||
Channel: 0,
|
||||
},
|
||||
},
|
||||
1: Outlet{
|
||||
Name: "uscita 1",
|
||||
Location: "port 1 sx",
|
||||
HasPowerMeter: true,
|
||||
Command: Boardlink{
|
||||
BoardID: b1.ID,
|
||||
Channel: 1,
|
||||
},
|
||||
PowerMeter: Boardlink{
|
||||
BoardID: b4.ID,
|
||||
Channel: 1,
|
||||
},
|
||||
},
|
||||
2: Outlet{
|
||||
Name: "uscita 2",
|
||||
Location: "port 2 dx",
|
||||
HasPowerMeter: false,
|
||||
Command: Boardlink{
|
||||
BoardID: "79690164-214f-41b0-93f9-e910dd54f323",
|
||||
Channel: 2,
|
||||
},
|
||||
},
|
||||
3: Outlet{
|
||||
Name: "uscita 5v 1",
|
||||
Location: "usb avanti 1",
|
||||
HasPowerMeter: false,
|
||||
Command: Boardlink{
|
||||
BoardID: "47e41dc9-4a14-4b79-8644-d7442a15cb50",
|
||||
Channel: 21,
|
||||
},
|
||||
},
|
||||
4: Outlet{
|
||||
Name: "uscita 5v 2",
|
||||
Location: "usb avanti 2",
|
||||
HasPowerMeter: false,
|
||||
Command: Boardlink{
|
||||
BoardID: "47e41dc9-4a14-4b79-8644-d7442a15cb50",
|
||||
Channel: 22,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
13
source/mqtt.go
Normal file
13
source/mqtt.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
// MQTTConfig def
|
||||
type MQTTConfig struct {
|
||||
BrokerIP string `json:"ip"`
|
||||
BrokerPort string `json:"port"`
|
||||
ClientID string `json:"clientid"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
CleanSession bool `json:"cleansession"`
|
||||
Topic string `json:"topic"`
|
||||
HomeAssistant bool `json:"homeassistant"`
|
||||
}
|
||||
49
source/outlet.go
Normal file
49
source/outlet.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
// Outlet Initial Status
|
||||
const (
|
||||
OutletInitialStatusOFF uint = 0
|
||||
OutletInitialStatusON uint = 1
|
||||
OutletInitialStatusLAST uint = 2 // if hardware supported
|
||||
)
|
||||
|
||||
// Outlet def
|
||||
type Outlet struct {
|
||||
Name string `json:"name"`
|
||||
Location string `json:"location"`
|
||||
HasPowerMeter bool `json:"haspowermeter"`
|
||||
InitialStatus uint `json:"initialstatus"`
|
||||
Command Boardlink `json:"command"`
|
||||
PowerMeter Boardlink `json:"powermeter"`
|
||||
}
|
||||
|
||||
// PowerON def
|
||||
func (o Outlet) PowerON() error {
|
||||
return o.Command.PowerON()
|
||||
}
|
||||
|
||||
// PowerOFF def
|
||||
func (o Outlet) PowerOFF() error {
|
||||
return o.Command.PowerOFF()
|
||||
}
|
||||
|
||||
// PowerToggle def
|
||||
func (o Outlet) PowerToggle() error {
|
||||
return o.Command.PowerToggle()
|
||||
}
|
||||
|
||||
// PowerInitial def
|
||||
func (o Outlet) PowerInitial() error {
|
||||
switch o.InitialStatus {
|
||||
case OutletInitialStatusOFF:
|
||||
return o.Command.PowerOFF()
|
||||
case OutletInitialStatusON:
|
||||
return o.Command.PowerON()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PowerStatus def
|
||||
func (o Outlet) PowerStatus() (bool, error) {
|
||||
return o.Command.PowerStatus()
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// Outlet definition
|
||||
type Outlet interface {
|
||||
On() error
|
||||
Off() error
|
||||
Toggle() (bool, error)
|
||||
Name() (string, error)
|
||||
Status() (bool, error)
|
||||
Location() string
|
||||
Board() Board
|
||||
Channel() uint
|
||||
}
|
||||
|
||||
type config struct {
|
||||
outlets []g
|
||||
}
|
||||
type g struct {
|
||||
n string
|
||||
k string
|
||||
}
|
||||
|
||||
func inita() {
|
||||
viper.SetConfigName("openpdu")
|
||||
viper.SetConfigType("json")
|
||||
viper.AddConfigPath(".")
|
||||
viper.ReadInConfig()
|
||||
|
||||
viper.Set("sboards[0].name", "ciao")
|
||||
viper.Set("sboards[0].type", "virtual")
|
||||
viper.Set("sboards[1].name", "ciao1")
|
||||
viper.Set("sboards[1].type", "virtual1")
|
||||
viper.WriteConfigAs("openpdu_out.json")
|
||||
|
||||
allSettings := viper.AllSettings()
|
||||
log.Printf("All settings: %v \n", allSettings)
|
||||
}
|
||||
|
||||
func inzxcit() {
|
||||
var err error
|
||||
var C = config{
|
||||
outlets: []g{
|
||||
{n: "pio1", k: "pao1"},
|
||||
{n: "pio2", k: "pao2"},
|
||||
{n: "pio3", k: "pao3"},
|
||||
},
|
||||
}
|
||||
|
||||
// err = viper.Marshal(&C)
|
||||
// if err != nil {
|
||||
// log.Printf("unable to decode into struct, %v", err)
|
||||
// }
|
||||
|
||||
err = viper.Unmarshal(&C)
|
||||
if err != nil {
|
||||
log.Printf("unable to decode into struct, %v", err)
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package main
|
||||
|
||||
// VirtualOutlet definition
|
||||
type VirtualOutlet struct {
|
||||
name string
|
||||
status bool
|
||||
location string
|
||||
}
|
||||
|
||||
// On - Switch on the virtual outlet
|
||||
func (o VirtualOutlet) On() error {
|
||||
o.status = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Off - Switch off the virtual outlet
|
||||
func (o VirtualOutlet) Off() error {
|
||||
o.status = false
|
||||
return nil
|
||||
}
|
||||
|
||||
// Toggle - Toggle the virtual outlet and return actual status
|
||||
func (o VirtualOutlet) Toggle() (bool, error) {
|
||||
o.status = !o.status
|
||||
return o.status, nil
|
||||
}
|
||||
|
||||
// Name - Returns the virtual outlet name
|
||||
func (o VirtualOutlet) Name() (string, error) {
|
||||
return o.name, nil
|
||||
}
|
||||
|
||||
// Status - Returns the virtual outlet status
|
||||
func (o VirtualOutlet) Status() (bool, error) {
|
||||
return o.status, nil
|
||||
}
|
||||
|
||||
// Location - Returns the virtual outlet location (set in configuration)
|
||||
func (o VirtualOutlet) Location() string {
|
||||
return o.location
|
||||
}
|
||||
|
||||
// Board - There's no physical board, so it's always an empty Board
|
||||
func (o VirtualOutlet) Board() Board {
|
||||
return Board{}
|
||||
}
|
||||
|
||||
// Channel - There's no physical channel, so it's always zero
|
||||
func (o VirtualOutlet) Channel() uint {
|
||||
return 0
|
||||
}
|
||||
29
source/web.go
Normal file
29
source/web.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-macaron/pongo2"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
func startServer() {
|
||||
m := macaron.Classic()
|
||||
m.Use(pongo2.Pongoer())
|
||||
m.Use(macaron.Static("static"))
|
||||
// m.Get("/", myHandler)
|
||||
|
||||
m.Get("/", statusPage)
|
||||
m.Get("/json/status", jsonStatus)
|
||||
m.Post("/json/outlet/:outlet/on", jsonOutletPowerON)
|
||||
m.Post("/json/outlet/:outlet/off", jsonOutletPowerOFF)
|
||||
m.Post("/json/outlet/:outlet/toggle", jsonOutletPowerToggle)
|
||||
|
||||
m.Get("/boards", func(ctx *macaron.Context) {
|
||||
ctx.HTML(200, "boards") // 200 is the response code.
|
||||
})
|
||||
|
||||
log.Println("Server is running...")
|
||||
log.Println(http.ListenAndServe("0.0.0.0:4000", m))
|
||||
}
|
||||
129
source/webjson.go
Normal file
129
source/webjson.go
Normal file
@@ -0,0 +1,129 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
func jsonStatus(ctx *macaron.Context) {
|
||||
|
||||
out := [][]string{}
|
||||
|
||||
for num, o := range TheConfig.Outlets {
|
||||
pwr, _ := o.PowerStatus()
|
||||
pwrstr := "0"
|
||||
if pwr {
|
||||
pwrstr = "1"
|
||||
}
|
||||
out = append(out, []string{fmt.Sprintf("%d", num), o.Name, pwrstr})
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": out,
|
||||
})
|
||||
}
|
||||
|
||||
func jsonOutletPowerToggle(ctx *macaron.Context) {
|
||||
var outletnum64 uint64
|
||||
var err error
|
||||
|
||||
outletnum64, err = strconv.ParseUint(ctx.Params(":outlet"), 10, 32)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "error",
|
||||
"error": "No outlet specified",
|
||||
})
|
||||
}
|
||||
|
||||
outletnum := uint(outletnum64)
|
||||
outlet, exists := TheConfig.Outlets[outletnum]
|
||||
if !exists {
|
||||
// error: outlet doesn't exists
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "error",
|
||||
"error": "Outlet doesn't exists",
|
||||
})
|
||||
}
|
||||
|
||||
err = outlet.PowerToggle()
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "error",
|
||||
"error": "Can't toggle power",
|
||||
})
|
||||
}
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "ok",
|
||||
})
|
||||
}
|
||||
|
||||
func jsonOutletPowerON(ctx *macaron.Context) {
|
||||
var outletnum64 uint64
|
||||
var err error
|
||||
|
||||
outletnum64, err = strconv.ParseUint(ctx.Params(":outlet"), 10, 32)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "error",
|
||||
"error": "No outlet specified",
|
||||
})
|
||||
}
|
||||
outletnum := uint(outletnum64)
|
||||
|
||||
outlet, exists := TheConfig.Outlets[outletnum]
|
||||
if !exists {
|
||||
// error: outlet doesn't exists
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "error",
|
||||
"error": "Outlet doesn't exists",
|
||||
})
|
||||
}
|
||||
|
||||
err = outlet.PowerON()
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "error",
|
||||
"error": "Can't toggle power",
|
||||
})
|
||||
}
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "ok",
|
||||
})
|
||||
}
|
||||
|
||||
func jsonOutletPowerOFF(ctx *macaron.Context) {
|
||||
var outletnum64 uint64
|
||||
var err error
|
||||
|
||||
outletnum64, err = strconv.ParseUint(ctx.Params(":outlet"), 10, 32)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "error",
|
||||
"error": "No outlet specified",
|
||||
})
|
||||
}
|
||||
outletnum := uint(outletnum64)
|
||||
|
||||
outlet, exists := TheConfig.Outlets[outletnum]
|
||||
if !exists {
|
||||
// error: outlet doesn't exists
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "error",
|
||||
"error": "Outlet doesn't exists",
|
||||
})
|
||||
}
|
||||
|
||||
err = outlet.PowerOFF()
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "error",
|
||||
"error": "Can't toggle power",
|
||||
})
|
||||
}
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "ok",
|
||||
})
|
||||
}
|
||||
14
source/webpages.go
Normal file
14
source/webpages.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import "gopkg.in/macaron.v1"
|
||||
|
||||
func statusPage(ctx *macaron.Context) {
|
||||
var pluglist []Dictionary
|
||||
|
||||
for num, o := range TheConfig.Outlets {
|
||||
pluglist = append(pluglist, Dictionary{"id": num, "description": o.Name})
|
||||
}
|
||||
|
||||
ctx.Data["pluglist"] = pluglist
|
||||
ctx.HTML(200, "status") // 200 is the response code.
|
||||
}
|
||||
113
source/webui.go
113
source/webui.go
@@ -1,113 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-macaron/pongo2"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
func statusPage(ctx *macaron.Context) {
|
||||
ctx.Data["pluglist"] = []Dictionary{
|
||||
{"id": 1, "description": "p1"},
|
||||
{"id": 2, "description": "p2"},
|
||||
{"id": 3, "description": "p3"},
|
||||
{"id": 4, "description": "p4"},
|
||||
{"id": 5, "description": "p5"},
|
||||
{"id": 6, "description": "p6"},
|
||||
{"id": 7, "description": "p7"},
|
||||
{"id": 8, "description": "p8"},
|
||||
}
|
||||
ctx.HTML(200, "status") // 200 is the response code.
|
||||
}
|
||||
|
||||
func jsonStatus(ctx *macaron.Context) {
|
||||
|
||||
p0, err := MyBoard.channelStatus(0)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
p1, err := MyBoard.channelStatus(1)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
p2, err := MyBoard.channelStatus(2)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
p3, err := MyBoard.channelStatus(3)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
p4, err := MyBoard.channelStatus(4)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
p5, err := MyBoard.channelStatus(5)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
p6, err := MyBoard.channelStatus(6)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
p7, err := MyBoard.channelStatus(7)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": [][]string{
|
||||
{"0", "p0", fmt.Sprint(p0)},
|
||||
{"1", "p1", fmt.Sprint(p1)},
|
||||
{"2", "p2", fmt.Sprint(p2)},
|
||||
{"3", "p3", fmt.Sprint(p3)},
|
||||
{"4", "p4", fmt.Sprint(p4)},
|
||||
{"5", "p5", fmt.Sprint(p5)},
|
||||
{"6", "p6", fmt.Sprint(p6)},
|
||||
{"7", "p7", fmt.Sprint(p7)},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func jsonOutletToggle(ctx *macaron.Context) {
|
||||
id, err := strconv.ParseUint(ctx.Params(":id"), 10, 64)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = MyBoard.channelToggle(uint(id))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ctx.JSON(http.StatusOK, Dictionary{
|
||||
"data": "ok",
|
||||
})
|
||||
}
|
||||
|
||||
func startServer() {
|
||||
m := macaron.Classic()
|
||||
m.Use(pongo2.Pongoer())
|
||||
m.Use(macaron.Static("static"))
|
||||
// m.Get("/", myHandler)
|
||||
|
||||
m.Get("/", statusPage)
|
||||
m.Get("/json/status", jsonStatus)
|
||||
m.Post("/json/outlet/:id/toggle", jsonOutletToggle)
|
||||
|
||||
m.Get("/boards", func(ctx *macaron.Context) {
|
||||
ctx.HTML(200, "boards") // 200 is the response code.
|
||||
})
|
||||
|
||||
log.Println("Server is running...")
|
||||
log.Println(http.ListenAndServe("0.0.0.0:4000", m))
|
||||
}
|
||||
Reference in New Issue
Block a user