37
src/app/process/octoprint/octoprint.go
Normal file
37
src/app/process/octoprint/octoprint.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package octoprint
|
||||
|
||||
import (
|
||||
"log"
|
||||
"powerswitch/app/process"
|
||||
)
|
||||
|
||||
const (
|
||||
start_cmd = "docker-compose -f /etc/printctrl/octoprint/docker-compose.yml up -d"
|
||||
stop_cmd = "docker-compose -f /etc/printctrl/octoprint/docker-compose.yml down"
|
||||
)
|
||||
|
||||
var (
|
||||
logger log.Logger = *log.Default()
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger.SetFlags(log.Llongfile | log.Ltime)
|
||||
}
|
||||
|
||||
func Start() error {
|
||||
p := process.NewProcess(start_cmd)
|
||||
return p.Start()
|
||||
}
|
||||
|
||||
func Stop() error {
|
||||
p := process.NewProcess(stop_cmd)
|
||||
return p.Start()
|
||||
}
|
||||
|
||||
func ReStart() error {
|
||||
err := Stop()
|
||||
if err != nil {
|
||||
logger.Print(err)
|
||||
}
|
||||
return Start()
|
||||
}
|
77
src/app/process/process.go
Normal file
77
src/app/process/process.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package process
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"log"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
var (
|
||||
logger log.Logger = *log.Default()
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger.SetFlags(log.Llongfile | log.Ltime)
|
||||
}
|
||||
|
||||
type Process struct {
|
||||
StdoutChannel chan string
|
||||
StderrChannel chan string
|
||||
|
||||
process *exec.Cmd
|
||||
stdout io.ReadCloser
|
||||
stderr io.ReadCloser
|
||||
}
|
||||
|
||||
func NewProcess(command string) *Process {
|
||||
p := new(Process)
|
||||
p.process = exec.Command("bash", "-c", command)
|
||||
var err error
|
||||
p.stdout, err = p.process.StdoutPipe()
|
||||
if err != nil {
|
||||
logger.Panic(err)
|
||||
}
|
||||
p.stderr, err = p.process.StderrPipe()
|
||||
if err != nil {
|
||||
logger.Panic(err)
|
||||
}
|
||||
p.StdoutChannel = make(chan string)
|
||||
p.StderrChannel = make(chan string)
|
||||
return p
|
||||
}
|
||||
|
||||
func (p Process) Start() error {
|
||||
err := p.process.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p Process) Observe() {
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(p.stdout)
|
||||
for scanner.Scan() {
|
||||
p.StdoutChannel <- scanner.Text()
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(p.stderr)
|
||||
for scanner.Scan() {
|
||||
p.StderrChannel <- scanner.Text()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (p Process) Kill() {
|
||||
p.process.Process.Kill()
|
||||
}
|
||||
|
||||
func (p Process) Wait() error {
|
||||
err := p.process.Wait()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
9
src/go.mod
Normal file
9
src/go.mod
Normal file
@@ -0,0 +1,9 @@
|
||||
module powerswitch
|
||||
|
||||
go 1.22.6
|
||||
|
||||
require (
|
||||
github.com/taigrr/systemctl v1.0.10
|
||||
periph.io/x/conn/v3 v3.7.2
|
||||
periph.io/x/host/v3 v3.8.5
|
||||
)
|
8
src/go.sum
Normal file
8
src/go.sum
Normal file
@@ -0,0 +1,8 @@
|
||||
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
|
||||
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
|
||||
github.com/taigrr/systemctl v1.0.10 h1:J1ifqf9wXYpbGYjCOgDIz9niFLCdlpNpIHRn9cA1J7g=
|
||||
github.com/taigrr/systemctl v1.0.10/go.mod h1:TpeHkNuHgYT63FI5jVLBf5VNAGbxEFH3FHqg5ReXnd0=
|
||||
periph.io/x/conn/v3 v3.7.2 h1:qt9dE6XGP5ljbFnCKRJ9OOCoiOyBGlw7JZgoi72zZ1s=
|
||||
periph.io/x/conn/v3 v3.7.2/go.mod h1:Ao0b4sFRo4QOx6c1tROJU1fLJN1hUIYggjOrkIVnpGg=
|
||||
periph.io/x/host/v3 v3.8.5 h1:g4g5xE1XZtDiGl1UAJaUur1aT7uNiFLMkyMEiZ7IHII=
|
||||
periph.io/x/host/v3 v3.8.5/go.mod h1:hPq8dISZIc+UNfWoRj+bPH3XEBQqJPdFdx218W92mdc=
|
98
src/internal/apiservice/data/data.go
Normal file
98
src/internal/apiservice/data/data.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package apiservice_data
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
apiservice_relay "powerswitch/internal/apiservice/relay"
|
||||
)
|
||||
|
||||
type state string
|
||||
|
||||
type State struct {
|
||||
State state `json:"state"`
|
||||
}
|
||||
|
||||
const (
|
||||
StateOn state = "on"
|
||||
StateOff state = "off"
|
||||
id int = 1
|
||||
)
|
||||
|
||||
var (
|
||||
logger log.Logger = *log.Default()
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger.SetFlags(log.Llongfile | log.Ltime)
|
||||
}
|
||||
|
||||
func AddHandler() {
|
||||
http.HandleFunc("GET /data/state", handle_get_powerstate)
|
||||
http.HandleFunc("PATCH /data/state", handle_patch_powerstate)
|
||||
}
|
||||
|
||||
func GetState() (bool, error) {
|
||||
res, err := apiservice_relay.GetRelay(id)
|
||||
return !res, err
|
||||
}
|
||||
|
||||
func SetState(state bool) error {
|
||||
return apiservice_relay.SetRelay(id, !state)
|
||||
}
|
||||
|
||||
func handle_get_powerstate(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-type", "application/json; charset=utf-8;")
|
||||
state, err := apiservice_relay.GetRelay(id)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
var res State
|
||||
if state {
|
||||
res.State = StateOff
|
||||
} else {
|
||||
res.State = StateOn
|
||||
}
|
||||
tmp, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(tmp)
|
||||
}
|
||||
|
||||
func handle_patch_powerstate(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-type", "application/json; charset=utf-8;")
|
||||
|
||||
tmp, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
var state State
|
||||
err = json.Unmarshal(tmp, &state)
|
||||
if err != nil {
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
set_state := true
|
||||
if state.State == StateOn {
|
||||
set_state = false
|
||||
}
|
||||
err = apiservice_relay.SetRelay(id, set_state)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
98
src/internal/apiservice/power/power.go
Normal file
98
src/internal/apiservice/power/power.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package apiservice_power
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
apiservice_relay "powerswitch/internal/apiservice/relay"
|
||||
)
|
||||
|
||||
type state string
|
||||
|
||||
type State struct {
|
||||
State state `json:"state"`
|
||||
}
|
||||
|
||||
const (
|
||||
StateOn state = "on"
|
||||
StateOff state = "off"
|
||||
id int = 0
|
||||
)
|
||||
|
||||
var (
|
||||
logger log.Logger = *log.Default()
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger.SetFlags(log.Llongfile | log.Ltime)
|
||||
}
|
||||
|
||||
func AddHandler() {
|
||||
http.HandleFunc("GET /power/state", handle_get_powerstate)
|
||||
http.HandleFunc("PATCH /power/state", handle_patch_powerstate)
|
||||
}
|
||||
|
||||
func GetState() (bool, error) {
|
||||
res, err := apiservice_relay.GetRelay(id)
|
||||
return !res, err
|
||||
}
|
||||
|
||||
func SetState(state bool) error {
|
||||
return apiservice_relay.SetRelay(id, !state)
|
||||
}
|
||||
|
||||
func handle_get_powerstate(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-type", "application/json; charset=utf-8;")
|
||||
state, err := apiservice_relay.GetRelay(id)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
var res State
|
||||
if state {
|
||||
res.State = StateOff
|
||||
} else {
|
||||
res.State = StateOn
|
||||
}
|
||||
tmp, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(tmp)
|
||||
}
|
||||
|
||||
func handle_patch_powerstate(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-type", "application/json; charset=utf-8;")
|
||||
|
||||
tmp, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
var state State
|
||||
err = json.Unmarshal(tmp, &state)
|
||||
if err != nil {
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
set_state := true
|
||||
if state.State == StateOn {
|
||||
set_state = false
|
||||
}
|
||||
err = apiservice_relay.SetRelay(id, set_state)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
132
src/internal/apiservice/printer/printer.go
Normal file
132
src/internal/apiservice/printer/printer.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package apiservice_printer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"powerswitch/app/process/octoprint"
|
||||
apiservice_data "powerswitch/internal/apiservice/data"
|
||||
apiservice_power "powerswitch/internal/apiservice/power"
|
||||
)
|
||||
|
||||
type state string
|
||||
|
||||
type State struct {
|
||||
State state `json:"state"`
|
||||
}
|
||||
|
||||
const (
|
||||
StateOn state = "on"
|
||||
StateOff state = "off"
|
||||
)
|
||||
|
||||
var (
|
||||
logger log.Logger = *log.Default()
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger.SetFlags(log.Llongfile | log.Ltime)
|
||||
}
|
||||
|
||||
func AddHandler() {
|
||||
http.HandleFunc("GET /printer/state", handle_get_printerstate)
|
||||
http.HandleFunc("PATCH /printer/state", handle_patch_printerstate)
|
||||
}
|
||||
|
||||
func handle_get_printerstate(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-type", "application/json; charset=utf-8;")
|
||||
data_state, err := apiservice_data.GetState()
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
power_state, err := apiservice_power.GetState()
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
var res State
|
||||
if data_state && power_state {
|
||||
res.State = StateOn
|
||||
} else {
|
||||
res.State = StateOff
|
||||
}
|
||||
tmp, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(tmp)
|
||||
}
|
||||
|
||||
func handle_patch_printerstate(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-type", "application/json; charset=utf-8;")
|
||||
|
||||
tmp, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
var state State
|
||||
err = json.Unmarshal(tmp, &state)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
if state.State == StateOn {
|
||||
err := apiservice_data.SetState(true)
|
||||
if err != nil {
|
||||
logger.Print(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
err = apiservice_power.SetState(true)
|
||||
if err != nil {
|
||||
logger.Print(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
err = octoprint.ReStart()
|
||||
if err != nil {
|
||||
logger.Print(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
err := octoprint.Stop()
|
||||
if err != nil {
|
||||
logger.Print(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
err = apiservice_power.SetState(false)
|
||||
if err != nil {
|
||||
logger.Print(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
err = apiservice_data.SetState(false)
|
||||
if err != nil {
|
||||
logger.Print(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, err.Error())))
|
||||
return
|
||||
}
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
130
src/internal/apiservice/relay/relay.go
Normal file
130
src/internal/apiservice/relay/relay.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package apiservice_relay
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"periph.io/x/conn/v3/gpio"
|
||||
"periph.io/x/conn/v3/gpio/gpioreg"
|
||||
)
|
||||
|
||||
type relay struct {
|
||||
Id int `json:"id"`
|
||||
Value bool `json:"value"`
|
||||
}
|
||||
|
||||
var (
|
||||
logger log.Logger = *log.Default()
|
||||
gpios = []string{"GPIO26", "GPIO20", "GPIO21"}
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger.SetFlags(log.Llongfile | log.Ltime)
|
||||
}
|
||||
|
||||
func GetRelay(id int) (bool, error) {
|
||||
if id >= len(gpios) {
|
||||
return false, errors.New("index out of range")
|
||||
}
|
||||
p := gpioreg.ByName(gpios[id])
|
||||
if p == nil {
|
||||
return false, errors.New("gpio not found")
|
||||
}
|
||||
state := p.Read()
|
||||
return bool(state), nil
|
||||
}
|
||||
|
||||
func SetRelay(id int, state bool) error {
|
||||
if id >= len(gpios) {
|
||||
return errors.New("index out of range")
|
||||
}
|
||||
p := gpioreg.ByName(gpios[id])
|
||||
if p == nil {
|
||||
return errors.New("gpio not found")
|
||||
}
|
||||
return p.Out(gpio.Level(state))
|
||||
}
|
||||
|
||||
func AddHandler() {
|
||||
http.HandleFunc("GET /relay/{id}", handle_get_relays)
|
||||
http.HandleFunc("PATCH /relay/{id}", handle_patch_relays)
|
||||
}
|
||||
|
||||
func handle_get_relays(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-type", "application/json; charset=utf-8;")
|
||||
id, err := strconv.Atoi(r.PathValue("id"))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if id >= len(gpios) {
|
||||
logger.Print("Index out of range: ", id)
|
||||
w.WriteHeader(http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
p := gpioreg.ByName(gpios[id])
|
||||
if p == nil {
|
||||
logger.Print("unable to find gpio")
|
||||
w.WriteHeader(http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
state := p.Read()
|
||||
logger.Print("state: ", state)
|
||||
var rel relay
|
||||
rel.Id = id
|
||||
rel.Value = bool(state)
|
||||
res, err := json.Marshal(rel)
|
||||
if err != nil {
|
||||
logger.Print("unable marshal obj to json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Write(res)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func handle_patch_relays(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-type", "application/json; charset=utf-8;")
|
||||
|
||||
id, err := strconv.Atoi(r.PathValue("id"))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if id >= len(gpios) {
|
||||
logger.Print("Index out of range: ", id)
|
||||
w.WriteHeader(http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
|
||||
tmp, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(`{"error": "cannot read reqest body"}`))
|
||||
return
|
||||
}
|
||||
var rel relay
|
||||
err = json.Unmarshal(tmp, &rel)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(`{"error": "cannot unmarshal json to object"}`))
|
||||
return
|
||||
}
|
||||
p := gpioreg.ByName(gpios[id])
|
||||
if p == nil {
|
||||
logger.Print("unable to find gpio")
|
||||
w.WriteHeader(http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
err = p.Out(gpio.Level(rel.Value))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(json.RawMessage(`{"error": "cannot set gpio"}`))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
40
src/main.go
Normal file
40
src/main.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
apiservice_data "powerswitch/internal/apiservice/data"
|
||||
apiservice_power "powerswitch/internal/apiservice/power"
|
||||
apiservice_printer "powerswitch/internal/apiservice/printer"
|
||||
apiservice_relay "powerswitch/internal/apiservice/relay"
|
||||
|
||||
host "periph.io/x/host/v3"
|
||||
)
|
||||
|
||||
var (
|
||||
logger log.Logger = *log.Default()
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger.SetFlags(log.Llongfile | log.Ltime)
|
||||
logger.Println("Starting")
|
||||
}
|
||||
|
||||
func main() {
|
||||
var webui_path string
|
||||
flag.StringVar(&webui_path, "w", "../webui", "Specify path to serve the web ui. Default is ../webui")
|
||||
flag.Parse()
|
||||
|
||||
host.Init()
|
||||
|
||||
apiservice_data.AddHandler()
|
||||
apiservice_power.AddHandler()
|
||||
apiservice_printer.AddHandler()
|
||||
apiservice_relay.AddHandler()
|
||||
|
||||
port := ":5005"
|
||||
http.Handle("/", http.FileServer(http.Dir(webui_path)))
|
||||
logger.Fatal(http.ListenAndServe(port, nil))
|
||||
}
|
Reference in New Issue
Block a user