前回は、ブラウザ上のボタンを押した際に1秒間電球を光らせてみました。
今回は、POSTリクエストの際に値を送って、その値に応じた明るさに電球を光らせてみます。
リポジトリ
ソースコード
go.mod
module github.com/kimizuka/shining-go go 1.24.3 require github.com/akualab/dmx v0.0.0-20130922234952-1ec6837faba7 require github.com/tarm/goserial v0.0.0-20151007205400-b3440c3c6355 // indirect
go.sum
github.com/akualab/dmx v0.0.0-20130922234952-1ec6837faba7 h1:NiSujjEOEg6lSdiIftZoHa0oAsDTZlabXrU7Lfa5jyw= github.com/akualab/dmx v0.0.0-20130922234952-1ec6837faba7/go.mod h1:fGkOc9nHK/v2N4kXLbb+uet+BC9TiqI7srodczLFMnQ= github.com/tarm/goserial v0.0.0-20151007205400-b3440c3c6355 h1:Kp3kg8YL2dc75mckomrHZQTfzNyFGnaqFhJeQw4ozGc= github.com/tarm/goserial v0.0.0-20151007205400-b3440c3c6355/go.mod h1:jcMo2Odv5FpDA6rp8bnczbUolcICW6t54K3s9gOlgII=
main.go
package main import ( "encoding/json" "log" "net/http" "github.com/akualab/dmx" ) func onLight(level int) { dmx, err := dmx.NewDMXConnection("/dev/tty.usbserial-EN437503") // ポートを合わせる if err != nil { log.Fatal(err) } dmx.SetChannel(2, byte(level)) // チャンネルを合わせる dmx.Render() dmx.Close() } func shiningGetHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") switch r.Method { case http.MethodPost: var request struct { Level int `json:"level"` } if err := json.NewDecoder(r.Body).Decode(&request); err != nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return } if request.Level < 0 || 100 < request.Level { http.Error(w, "Level must be between 0 and 100", http.StatusBadRequest) return } onLight(request.Level) response := struct { Level int `json:"level"` }{ Level: request.Level, } json.NewEncoder(w).Encode(response) } } func main() { fs := http.FileServer(http.Dir("./public")) http.Handle("/", fs) http.HandleFunc("/api/shining", shiningGetHandler) port := ":8080" err := http.ListenAndServe(port, nil) if err != nil { log.Fatal(err) } }
public/index.html
<html> <head> <meta charset="UTF-8"> <title>Shining Go</title> <style> body { display: flex; align-items: center; justify-content: center; gap: 16px; position: fixed; inset: 0; transition: background .2s ease-in-out; &[data-level="0"] { background: #212121; } &[data-level="50"] { background: #BDBDBD; } &[data-level="100"] { background: #FAFAFA; } } button { width: 96px; height: 96px; font-size: 48px; cursor: pointer; } </style> </head> <body data-level="0"> <button data-level="0">0</button> <button data-level="50">50</button> <button data-level="100">100</button> <script> [].slice.call(document.querySelectorAll('[data-level]')).forEach((elm) => { elm.addEventListener('click', (evt) => { const level = Number(evt.target.dataset.level || 0); fetch('/api/shining', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ level }) }).then(async (res) => { const json = await res.json(); document.body.dataset.level = String(json.level); }); }); }); </script> </body> </html>
これで、OKです。
「0」で消灯。「100」で点灯。「50」でうっすら点灯という挙動になりました。
再びボタンを押すまでその状態を維持します。
DEMO
gifアニメで見ると、50の明るさと100の明るさの差がわかりにくいですが、人眼で見るとほんのりと差がわかります。