package main import ( "bytes" "encoding/binary" "fmt" "html/template" "log" "net" "sync" "github.com/codegangsta/martini" "github.com/codegangsta/martini-contrib/render" ) type Header int32 type ControlPacket [50]uint16 type StatePacket [73]uint16 var mutex sync.Mutex var templateMap = make(map[string]interface{}) var controlDesc [50]string var stateDesc [73]string func init() { controlDesc[5] = "Oven Mode" controlDesc[6] = "Cook On/Off" controlDesc[7] = "Wash On/Off" controlDesc[8] = "System On/Off" controlDesc[9] = "Temp" controlDesc[10] = "Humidity" controlDesc[11] = "Time" controlDesc[12] = "Preheat On/Off" controlDesc[15] = "Convection RPM" controlDesc[16] = "Cooldown On/Off" controlDesc[17] = "Core Temp" controlDesc[20] = "Wash Type" controlDesc[21] = "Wash Total" controlDesc[22] = "Wash Steps" controlDesc[23] = "Wash Step Type" stateDesc[0] = "Firmware Y" stateDesc[1] = "Firmware Y" stateDesc[2] = "Firmware M" stateDesc[3] = "Firmware D" stateDesc[4] = "Cook State" stateDesc[5] = "Temp Setting" stateDesc[6] = "Humidity Setting" stateDesc[7] = "Time Setting" stateDesc[8] = "Temp Value" stateDesc[9] = "Humidity Value" stateDesc[10] = "Time Value" stateDesc[11] = "Wash State" stateDesc[12] = "Wash Type" stateDesc[13] = "Wash Steps" stateDesc[16] = "Door Open/Close" stateDesc[32] = "Core Temp 1" stateDesc[33] = "Core Temp 2" stateDesc[34] = "Core Temp 3" stateDesc[35] = "Core Temp 4" } func main() { go ListenUDP() m := martini.Classic() m.Use(render.Renderer()) m.Get("/", func(r render.Render) { mutex.Lock() defer mutex.Unlock() r.HTML(200, "main", templateMap) }) m.Run() } func ListenUDP() { addr, err := net.ResolveUDPAddr("udp", ":40001") if err != nil { log.Fatal(err) } conn, err := net.ListenUDP("udp", addr) if err != nil { log.Fatal(err) } defer conn.Close() for { b := make([]byte, 1024) _, _, err := conn.ReadFromUDP(b) if err != nil { log.Fatal(err) } buf := bytes.NewReader(b) var header Header err = binary.Read(buf, binary.LittleEndian, &header) if err != nil { log.Fatal(err) } switch header { case 0: var packet ControlPacket err = binary.Read(buf, binary.LittleEndian, &packet) if err != nil { log.Fatal(err) } mapControl(packet) case 1: var packet StatePacket err = binary.Read(buf, binary.LittleEndian, &packet) if err != nil { log.Fatal(err) } mapState(packet) } } } func mapControl(packet ControlPacket) { mutex.Lock() defer mutex.Unlock() var controlTable string for i, v := range packet { class := "odd" if i%2 == 0 { class = "even" } controlTable += fmt.Sprintf("%v0x%04X0x%04X%d%v\n", class, 40001+i, i, v, v, controlDesc[i]) } templateMap["Table_Control"] = template.HTML(controlTable) } func mapState(packet StatePacket) { mutex.Lock() defer mutex.Unlock() var stateTable string for i, v := range packet { class := "odd" if i%2 == 0 { class = "even" } stateTable += fmt.Sprintf("%v0x%04X0x%04X%d%v\n", class, 30001+i, i, v, v, stateDesc[i]) } templateMap["Table_State"] = template.HTML(stateTable) }