diff --git a/config/data.go b/config/data.go index a541f4d..9e5f30c 100644 --- a/config/data.go +++ b/config/data.go @@ -19,6 +19,7 @@ type GroupDef struct { // Bulp repräsentiert ein einzelnes Gerät. type Bulp struct { + Name string `yaml:"name"` IP string `yaml:"ip"` Port string `yaml:"port"` } diff --git a/data.go b/data.go new file mode 100644 index 0000000..dc08d3d --- /dev/null +++ b/data.go @@ -0,0 +1,16 @@ +package main + +// BulbStatus fasst den Status zusammen, der im Template dargestellt wird. +type BulbStatus struct { + IP string + Port string + Name string + IsOn bool + Message string // Optional: Zusätzliche Infos, z. B. Fehleranzeige +} + +// GroupStatus repräsentiert eine Gruppe von Bulbs für die Anzeige. +type GroupStatus struct { + Name string + Bulbs []BulbStatus +} diff --git a/go.mod b/go.mod index fae20b1..20aacd5 100644 --- a/go.mod +++ b/go.mod @@ -3,3 +3,33 @@ module kattudden/wiz-controller go 1.23.3 require gopkg.in/yaml.v2 v2.4.0 + +require ( + github.com/bytedance/sonic v1.12.8 // indirect + github.com/bytedance/sonic/loader v0.2.3 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gin-contrib/sse v1.0.0 // indirect + github.com/gin-gonic/gin v1.10.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.25.0 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.14.0 // indirect + golang.org/x/crypto v0.33.0 // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum index 7534661..3088fda 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,80 @@ +github.com/bytedance/sonic v1.12.8 h1:4xYRVRlXIgvSZ4e8iVTlMF5szgpXd4AfvuWgA8I8lgs= +github.com/bytedance/sonic v1.12.8/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.3 h1:yctD0Q3v2NOGfSWPLPvG2ggA2kV6TS6s4wioyEqssH0= +github.com/bytedance/sonic/loader v0.2.3/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= +github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8= +github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +golang.org/x/arch v0.14.0 h1:z9JUEZWr8x4rR0OU6c4/4t6E6jOZ8/QBS2bBYBm4tx4= +golang.org/x/arch v0.14.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/images/light-off.png b/images/light-off.png new file mode 100644 index 0000000..4ffa269 Binary files /dev/null and b/images/light-off.png differ diff --git a/images/light-on.png b/images/light-on.png new file mode 100644 index 0000000..d951b2f Binary files /dev/null and b/images/light-on.png differ diff --git a/images/room.png b/images/room.png new file mode 100644 index 0000000..78363c7 Binary files /dev/null and b/images/room.png differ diff --git a/main.go b/main.go index d702250..a5b35ed 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,9 @@ import ( "fmt" "kattudden/wiz-controller/config" "kattudden/wiz-controller/controller" + "net/http" + + "github.com/gin-gonic/gin" ) func main() { @@ -13,16 +16,55 @@ func main() { return } - for groupName, group := range config.Groups { - fmt.Println("Gruppe:", groupName) + //gin.SetMode(gin.ReleaseMode) + r := gin.Default() + r.LoadHTMLGlob("templates/*") - for _, bulp := range group.Bulps { - fmt.Printf(" Bulp: ip: %s, port: %s\n", bulp.IP, bulp.Port) - status, err := controller.GetStatus(bulp.IP, bulp.Port) - if err != nil { - fmt.Println(err) + r.GET("/", func(c *gin.Context) { + // Erstelle einen Slice, der alle Gruppen mitsamt den Bulb-Status enthält. + var groups []GroupStatus + + // Für jede Gruppe in den Konfigurationsdaten: Status der Bulbs abfragen. + for groupName, group := range config.Groups { + var bulbs []BulbStatus + + for _, bulp := range group.Bulps { + // Abfrage des Status, hier wird angenommen, dass controller.GetStatus(ip, port) einen Status zurückgibt + status, err := controller.GetStatus(bulp.IP, bulp.Port) + bulb := BulbStatus{ + IP: bulp.IP, + Port: bulp.Port, + Name: bulp.Name, + } + + if err != nil { + bulb.Message = fmt.Sprintf("Fehler: %v", err) + } else { + // Beispiel: Wir nutzen status.Result.State um zu bestimmen, ob das Licht an ist. + bulb.IsOn = status.Result.State + } + + bulbs = append(bulbs, bulb) } - fmt.Println("status:", status.Result.State) + + groupStatus := GroupStatus{ + Name: groupName, + Bulbs: bulbs, + } + groups = append(groups, groupStatus) } - } + + c.HTML(http.StatusOK, "index.html", gin.H{ + "groups": groups, + }) + }) + + // static files + r.StaticFile("/styles.css", "static/styles.css") + r.StaticFile("/favicon.ico", "static/favicon.ico") + r.StaticFile("/light-off.png", "images/light-off.png") + r.StaticFile("/light-on.png", "images/light-on.png") + r.StaticFile("/room.png", "images/room.png") + + r.Run() } diff --git a/misc/sample-config.yml b/misc/sample-config.yml index d2469d9..3b2271e 100644 --- a/misc/sample-config.yml +++ b/misc/sample-config.yml @@ -5,8 +5,11 @@ groups: wohnzimmer: bulps: - ip: "192.168.0.151" + name: "Wohnzimmer gross" port: "38899" - ip: "192.168.0.152" + name: "Wohnzimmer klein 1" port: "38899" - ip: "192.168.0.153" + name: "Wohnzimmer klein 2" port: "38899" \ No newline at end of file diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..a26b2a5 Binary files /dev/null and b/static/favicon.ico differ diff --git a/static/styles.css b/static/styles.css new file mode 100644 index 0000000..fd2365d --- /dev/null +++ b/static/styles.css @@ -0,0 +1,162 @@ +/* Grundlegender Reset */ +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +/* Body-Styles */ +body { + font-family: 'Helvetica Neue', Arial, sans-serif; + line-height: 1.6; + color: #333; + background-color: #f8f8f8; + padding: 20px; +} + +/* Container für zentrierten Inhalt */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 15px; +} + +/* Header */ +header { + background-color: #fff; + border-bottom: 1px solid #e0e0e0; + padding: 20px 0; + margin-bottom: 30px; + text-align: center; +} + +header h1 { + margin-bottom: 10px; +} + +header nav ul { + list-style: none; + display: flex; + justify-content: center; + gap: 20px; +} + +header nav ul li a { + text-decoration: none; + color: #555; + font-weight: 500; + padding: 8px 12px; + transition: background-color 0.3s, color 0.3s; +} + +header nav ul li a:hover { + background-color: #007BFF; + color: #fff; + border-radius: 4px; +} + +/* Main Bereich */ +main { + background-color: #fff; + padding: 40px; + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05); + margin-bottom: 30px; +} + +/* Überschriften */ +h2, +h3 { + margin-bottom: 15px; + color: #222; +} + +/* Gruppen-Karten */ +.group-card { + border: 1px solid #e0e0e0; + border-radius: 8px; + padding: 20px; + margin-bottom: 30px; + transition: box-shadow 0.3s; +} + +.group-card:hover { + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); +} + +/* Gruppen-Header */ +.group-header { + display: flex; + align-items: center; + gap: 15px; + margin-bottom: 20px; +} + +.group-image { + width: 50px; + height: 50px; +} + +/* Liste der Glühbirnen */ +.bulb-list { + display: flex; + flex-wrap: wrap; + gap: 20px; +} + +.bulb { + flex: 1 1 200px; + background-color: #f0f0f0; + border-radius: 8px; + padding: 15px; + text-align: center; + transition: transform 0.3s; +} + +.bulb:hover { + transform: translateY(-5px); +} + +.bulb-info p { + margin-bottom: 10px; + font-weight: bold; +} + +/* Statusbild der Glühbirne */ +.bulb-status-image img { + width: 60px; + height: 60px; +} + +/* Fehlermeldung */ +.bulb-error p { + margin-top: 10px; + color: red; + font-size: 0.9em; +} + +/* Footer */ +footer { + text-align: center; + padding: 20px 0; + border-top: 1px solid #e0e0e0; + color: #777; +} + +/* Responsive Anpassen */ +@media (max-width: 768px) { + header nav ul { + flex-direction: column; + gap: 10px; + } + + main { + padding: 20px; + } + + .bulb-list { + flex-direction: column; + } +} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..9ce6179 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,68 @@ + + + + + + + + + + + + WIZ-Controller + + + + + + + + +
+

WIZ-Controller

+
+
+ +
+ {{/* Iteration über die Gruppen */}} + {{range .groups}} +
+ +

+ Raum Symbol + {{.Name}} +

+
    + {{/* Iteriere über die Bulbs innerhalb der aktuellen Gruppe */}} + {{range .Bulbs}} +
  • + + Name: {{.Name}} + {{if .Message}} + Fehler: {{.Message}} + {{else}} + + {{if .IsOn}}Licht an{{else}}Licht aus{{end}} + Status: {{if .IsOn}}An{{else}}Aus{{end}} + {{end}} +
  • + {{end}} +
+
+ {{else}} +

Keine Gruppen vorhanden!

+ {{end}} +
+ +
+ + + + + + \ No newline at end of file