package main import ( "bytes" "crypto/tls" "encoding/json" "flag" "io" "log" "net/http" ) type switcher struct { Name string `json:"name"` State bool `json:"state"` } var ( logger log.Logger = *log.Default() ) func init() { logger.SetFlags(log.Llongfile | log.Ltime) } func patch_request(url string, cmd string) error { req, err := http.NewRequest(http.MethodPatch, url, bytes.NewReader([]byte(cmd))) if err != nil { return err } res, err := http.DefaultClient.Do(req) if err != nil { return err } logger.Printf("got response!\n") logger.Printf("status code: %d\n", res.StatusCode) return nil } func do_the_switch(sw switcher) { var url string var cmd string switch sw.Name { case "chicken": url = "http://barsch:8080/katara/chicken" if sw.State { cmd = "{\"value\":\"on\"}" } else { cmd = "{\"value\":\"off\"}" } case "bed": url = "http://barsch:8080/katara/bed" if sw.State { cmd = "{\"value\":\"on\"}" } else { cmd = "{\"value\":\"off\"}" } case "sauna": url = "http://barsch:8080/katara/sauna" if sw.State { cmd = "{\"value\":\"on\"}" } else { cmd = "{\"value\":\"off\"}" } case "nut": url = "https://perinode-ms26f.local/sample/gpio2" if sw.State { cmd = "{\"data\": true}" } else { cmd = "{\"data\": false}" } case "wood": url = "https://perinode-gzzx6.local/sample/gpio1" if sw.State { cmd = "{\"data\": true}" } else { cmd = "{\"data\": false}" } case "tomato": url = "https://perinode-jim7u.local/sample/gpio1" if sw.State { cmd = "{\"data\": true}" } else { cmd = "{\"data\": false}" } case "barn": url = "https://perinode-jim7u.local/sample/gpio1" if sw.State { cmd = "{\"data\": true}" } else { cmd = "{\"data\": false}" } default: logger.Printf("Unknown switch: %s", sw.Name) return } err := patch_request(url, cmd) if err != nil { logger.Print(err) } } func http_endpoint_water_switch(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-type", "application/json; charset=utf-8;") if r.Method == http.MethodPatch { tmp, err := io.ReadAll(r.Body) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write(json.RawMessage(`{"error": "cannot unmarshal json to object"}`)) } else { var sw switcher err = json.Unmarshal(tmp, &sw) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write(json.RawMessage(`{"error": "cannot unmarshal json to object"}`)) } else { do_the_switch(sw) w.WriteHeader(http.StatusAccepted) } } } else { w.WriteHeader(http.StatusMethodNotAllowed) } } func main() { logger.Println("starting") var webui_path string flag.StringVar(&webui_path, "w", "./webui", "Specify path to serve the web ui. Default is ./webui") flag.Parse() http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} // Serve files from static folder http.Handle("/", http.FileServer(http.Dir(webui_path))) http.HandleFunc("/water/switch", http_endpoint_water_switch) port := ":5005" logger.Println("Server is running on port" + port) // Start server on port specified above logger.Fatal(http.ListenAndServe(port, nil)) }