### Install knx-go library Source: https://context7.com/vapourismo/knx-go/llms.txt Use the go get command to fetch the library and its dependencies into your Go project. ```bash go get -u github.com/vapourismo/knx-go/... ``` -------------------------------- ### Use knxbridge CLI Tool for KNX Network Bridging Source: https://context7.com/vapourismo/knx-go/llms.txt Provides examples of using the knxbridge command-line tool to bridge KNX networks. It demonstrates how to expose a KNX network behind a gateway to a multicast group, allowing routers to access devices, and how to connect two KNX networks by relaying messages bidirectionally between their gateways. The tool facilitates connectivity between different network segments. ```bash # Expose a KNX network behind a gateway on a multicast group # This allows routers to access devices behind the gateway knxbridge 10.0.0.2:3671 224.0.23.12:3671 # Connect two KNX networks through their gateways # Messages are relayed bidirectionally between networks knxbridge 10.0.0.2:3671 10.0.0.3:3671 # Bridge gateway at 192.168.1.100 to multicast knxbridge 192.168.1.100:3671 224.0.23.12:3671 ``` -------------------------------- ### Retrieve KNX Server Description via Unicast UDP Source: https://context7.com/vapourismo/knx-go/llms.txt Demonstrates how to get detailed information about a specific KNXnet/IP server using unicast UDP. This function retrieves device hardware details and supported services from a given server address and port within a specified timeout. ```go package main import ( "fmt" "log" "os" "time" "github.com/vapourismo/knx-go/knx" "github.com/vapourismo/knx-go/knx/util" ) func main() { util.Logger = log.New(os.Stdout, "", log.LstdFlags) // Get description from a specific server description, err := knx.DescribeTunnel("192.168.1.254:3671", 750*time.Millisecond) if err != nil { log.Fatal(err) } if description == nil { log.Fatal("No response from server") } fmt.Printf("Device Information:\n") fmt.Printf(" Name: %s\n", description.DeviceHardware.DeviceName) fmt.Printf(" KNX Address: %s\n", description.DeviceHardware.Address) fmt.Printf(" Serial: %x\n", description.DeviceHardware.SerialNumber) fmt.Printf("Supported Services:\n") for _, family := range description.SupportedServices { fmt.Printf(" Family %d, Version %d\n", family.Type, family.Version) } } ``` -------------------------------- ### Low-Level CEMI Communication in Go Source: https://context7.com/vapourismo/knx-go/llms.txt Provides an example of using the Tunnel type for raw CEMI frame manipulation, allowing for fine-grained control over KNXnet/IP communication. ```go package main import ( "log" "os" "time" "github.com/vapourismo/knx-go/knx" "github.com/vapourismo/knx-go/knx/cemi" "github.com/vapourismo/knx-go/knx/knxnet" "github.com/vapourismo/knx-go/knx/util" ) func main() { util.Logger = log.New(os.Stdout, "", log.LstdFlags) config := knx.TunnelConfig{ ResendInterval: 500 * time.Millisecond, HeartbeatInterval: 10 * time.Second, ResponseTimeout: 10 * time.Second, SendLocalAddress: false, UseTCP: false, } tunnel, err := knx.NewTunnel("10.0.0.7:3671", knxnet.TunnelLayerData, config) if err != nil { log.Fatal(err) } defer tunnel.Close() ldata := cemi.LData{ Control1: cemi.Control1NoRepeat | cemi.Control1StdFrame | cemi.Control1WantAck, Control2: cemi.Control2GroupAddr | cemi.Control2Hops(6), Source: cemi.NewIndividualAddr3(1, 1, 1), Destination: uint16(cemi.NewGroupAddr3(1, 2, 3)), Data: &cemi.AppData{ Command: cemi.GroupWrite, Data: []byte{0x01}, }, } err = tunnel.Send(&cemi.LDataReq{LData: ldata}) if err != nil { log.Fatal(err) } for msg := range tunnel.Inbound() { switch m := msg.(type) { case *cemi.LDataInd: log.Printf("L_Data.ind: %+v", m) case *cemi.LDataCon: log.Printf("L_Data.con: %+v", m) } } } ``` -------------------------------- ### Go Temperature Monitor: Connect, Read, and Handle Events Source: https://context7.com/vapourismo/knx-go/llms.txt Demonstrates connecting to a KNX gateway, setting up a temperature monitor, requesting current temperatures from specified group addresses, and processing incoming temperature data. It includes error handling, graceful shutdown, and decoding of DPT_9001 temperature values. Requires a running KNX gateway and configured temperature sensors. ```go package main import ( "fmt" "log" "os" "os/signal" syscall "syscall" "github.com/vapourismo/knx-go/knx" "github.com/vapourismo/knx-go/knx/cemi" "github.com/vapourismo/knx-go/knx/dpt" "github.com/vapourismo/knx-go/knx/util" ) func main() { util.Logger = log.New(os.Stdout, "[KNX] ", log.LstdFlags) // Connect to gateway client, err := knx.NewGroupTunnel("192.168.1.100:3671", knx.DefaultTunnelConfig) if err != nil { log.Fatalf("Failed to connect: %v", err) } defer client.Close() // Handle graceful shutdown sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) // Temperature sensors group addresses sensors := map[string]cemi.GroupAddr{ "Living Room": cemi.NewGroupAddr3(1, 0, 1), "Bedroom": cemi.NewGroupAddr3(1, 0, 2), "Kitchen": cemi.NewGroupAddr3(1, 0, 3), } // Request current temperatures for name, addr := range sensors { err := client.Send(knx.GroupEvent{ Command: knx.GroupRead, Destination: addr, }) if err != nil { log.Printf("Failed to request %s temperature: %v", name, err) } } fmt.Println("Monitoring temperatures... (Ctrl+C to exit)") // Process incoming events for { select { case <-sigChan: fmt.Println("\nShutting down...") return case event, ok := <-client.Inbound(): if !ok { log.Println("Connection closed") return } // Find sensor name sensorName := "Unknown" for name, addr := range sensors { if addr == event.Destination { sensorName = name break } } // Decode temperature if event.Command == knx.GroupResponse || event.Command == knx.GroupWrite { var temp dpt.DPT_9001 if err := temp.Unpack(event.Data); err != nil { log.Printf("Failed to decode temperature: %v", err) continue } fmt.Printf("[%s] %s: %s\n", event.Command, sensorName, temp) } } } } ``` -------------------------------- ### Create and Parse Individual Addresses in Go Source: https://context7.com/vapourismo/knx-go/llms.txt Demonstrates how to instantiate 3-level and 2-level KNX individual addresses and parse them from string representations. This is essential for uniquely identifying devices on a KNX network. ```go package main import ( "fmt" "log" "github.com/vapourismo/knx-go/knx/cemi" ) func main() { // 3-level individual address: Area/Line/Device (e.g., 1.2.3) addr3 := cemi.NewIndividualAddr3(1, 2, 3) fmt.Printf("3-level address: %s (raw: %d)\n", addr3, addr3) // 2-level individual address: Subnetwork/Device (e.g., 18.3) addr2 := cemi.NewIndividualAddr2(18, 3) fmt.Printf("2-level address: %s (raw: %d)\n", addr2, addr2) // Parse from string addrStr, err := cemi.NewIndividualAddrString("1.2.3") if err != nil { log.Fatal(err) } fmt.Printf("Parsed address: %s\n", addrStr) // Parse 2-level from string addr2Str, err := cemi.NewIndividualAddrString("18.3") if err != nil { log.Fatal(err) } fmt.Printf("Parsed 2-level: %s\n", addr2Str) } ``` -------------------------------- ### Define and Use KNX Group Commands in Go Source: https://context7.com/vapourismo/knx-go/llms.txt Illustrates how to define and utilize different KNX group commands such as GroupWrite, GroupRead, and GroupResponse. This involves creating `knx.GroupEvent` structs with appropriate commands, destinations, and data payloads. Dependencies include 'github.com/vapourismo/knx-go/knx' and 'github.com/vapourismo/knx-go/knx/cemi', and 'github.com/vapourismo/knx-go/knx/dpt'. ```go package main import ( "fmt" "github.com/vapourismo/knx-go/knx" "github.com/vapourismo/knx-go/knx/cemi" "github.com/vapourismo/knx-go/knx/dpt" ) func main() { // GroupWrite - Write a value to a group address writeEvent := knx.GroupEvent{ Command: knx.GroupWrite, Destination: cemi.NewGroupAddr3(1, 2, 3), Data: dpt.DPT_1001(true).Pack(), } fmt.Printf("Write command: %s\n", writeEvent.Command) // GroupRead - Request current value from a group address readEvent := knx.GroupEvent{ Command: knx.GroupRead, Destination: cemi.NewGroupAddr3(1, 2, 3), Data: nil, // No data for read requests } fmt.Printf("Read command: %s\n", readEvent.Command) // GroupResponse - Response to a read request responseEvent := knx.GroupEvent{ Command: knx.GroupResponse, Destination: cemi.NewGroupAddr3(1, 2, 3), Data: dpt.DPT_9001(21.5).Pack(), } fmt.Printf("Response command: %s\n", responseEvent.Command) } ``` -------------------------------- ### Discover KNXnet/IP Servers on Network Source: https://context7.com/vapourismo/knx-go/llms.txt Shows how to find KNXnet/IP servers (routers and gateways) on the network using multicast discovery. It supports discovering on the default interface or a specified network interface, with a configurable timeout. ```go package main import ( "fmt" "log" "net" "os" "time" "github.com/vapourismo/knx-go/knx" "github.com/vapourismo/knx-go/knx/util" ) func main() { util.Logger = log.New(os.Stdout, "", log.LstdFlags) // Discover all KNXnet/IP servers on the default interface servers, err := knx.Discover("224.0.23.12:3671", 750*time.Millisecond) if err != nil { log.Fatal(err) } for _, server := range servers { fmt.Printf("Found server:\n") fmt.Printf(" Name: %s\n", server.DeviceHardware.DeviceName) fmt.Printf(" Address: %s\n", server.DeviceHardware.Address) fmt.Printf(" Serial: %x\n", server.DeviceHardware.SerialNumber) fmt.Printf(" MAC: %s\n", net.HardwareAddr(server.DeviceHardware.MACAddress[:])) } // Discover on a specific network interface ifi, _ := net.InterfaceByName("eth0") servers, err = knx.DiscoverOnInterface(ifi, "224.0.23.12:3671", 750*time.Millisecond) if err != nil { log.Fatal(err) } fmt.Printf("Found %d servers on eth0\n", len(servers)) } ``` -------------------------------- ### Dynamically Produce and Use KNX Datapoint Types in Go Source: https://context7.com/vapourismo/knx-go/llms.txt Demonstrates how to dynamically create and use KNX datapoint instances by their string name using the dpt package. It covers listing supported types, producing specific types like temperature (9.001) and switch (1.001), unpacking received data, and packing values for transmission. Dependencies include the 'github.com/vapourismo/knx-go/knx/dpt' package. ```go package main import ( "fmt" "log" "sort" "github.com/vapourismo/knx-go/knx/dpt" ) func main() { // List all supported datapoint types types := dpt.ListSupportedTypes() sort.Strings(types) fmt.Println("Supported DPT types:") for _, t := range types[:10] { // Print first 10 fmt.Printf(" %s\n", t) } fmt.Printf(" ... and %d more\n", len(types)-10) // Dynamically create a datapoint by name tempDpt, ok := dpt.Produce("9.001") if !ok { log.Fatal("Unknown DPT type") } // Unpack data into the dynamic type data := []byte{0x0C, 0xE2} // ~21.5°C encoded if err := tempDpt.Unpack(data); err != nil { log.Fatal(err) } fmt.Printf("Dynamic DPT 9.001: %s (unit: %s)\n", tempDpt, tempDpt.Unit()) // Create and use a switch datapoint switchDpt, ok := dpt.Produce("1.001") if !ok { log.Fatal("Unknown DPT type") } switchDpt.Unpack([]byte{0x01}) fmt.Printf("Dynamic DPT 1.001: %s\n", switchDpt) // Pack a value tempDpt2, _ := dpt.Produce("9.001") // Set value via type assertion if t, ok := tempDpt2.(*dpt.DPT_9001); ok { *t = 25.0 fmt.Printf("Packed 25°C: %x\n", tempDpt2.Pack()) } } ``` -------------------------------- ### Describe a Single KNXnet/IP Server Source: https://github.com/vapourismo/knx-go/blob/master/README.md Retrieves detailed configuration and status information from a specific KNXnet/IP server at a given IP address and port. ```go package main import ( "log" "os" "time" "github.com/kr/pretty" "github.com/vapourismo/knx-go/knx" "github.com/vapourismo/knx-go/knx/util" ) func main() { util.Logger = log.New(os.Stdout, "", log.LstdFlags) servers, err := knx.DescribeTunnel("192.168.1.254:3671", time.Millisecond*750) if err != nil { log.Fatal(err) } util.Logger.Printf("%# v", pretty.Formatter(servers)) } ``` -------------------------------- ### Create and Parse KNX Group Addresses Source: https://context7.com/vapourismo/knx-go/llms.txt Illustrates how to create and parse KNX group addresses using the library. It covers both 3-level (Main/Middle/Sub) and 2-level (Main/Sub) addressing schemes, as well as parsing from string representations and raw integer values. ```go package main import ( "fmt" "log" "github.com/vapourismo/knx-go/knx/cemi" ) func main() { // 3-level group address: Main/Middle/Sub (e.g., 1/2/3) addr3 := cemi.NewGroupAddr3(1, 2, 3) fmt.Printf("3-level address: %s (raw: %d)\n", addr3, addr3) // 2-level group address: Main/Sub (e.g., 1/515) addr2 := cemi.NewGroupAddr2(1, 515) fmt.Printf("2-level address: %s (raw: %d)\n", addr2, addr2) // Parse from string addrStr, err := cemi.NewGroupAddrString("1/2/3") if err != nil { log.Fatal(err) } fmt.Printf("Parsed address: %s\n", addrStr) // Parse 2-level from string addr2Str, err := cemi.NewGroupAddrString("1/515") if err != nil { log.Fatal(err) } fmt.Printf("Parsed 2-level: %s\n", addr2Str) // Parse raw address addrRaw, err := cemi.NewGroupAddrString("2819") if err != nil { log.Fatal(err) } fmt.Printf("Parsed raw: %s\n", addrRaw) } ``` -------------------------------- ### Handle Floating Point Datapoint Types (DPT 9.xxx) in Go Source: https://context7.com/vapourismo/knx-go/llms.txt Demonstrates the usage of 2-byte floating point DPTs for physical measurements like temperature, humidity, and power. Includes methods for packing, unpacking, and unit retrieval. ```go package main import ( "fmt" "log" "github.com/vapourismo/knx-go/knx/dpt" ) func main() { // DPT 9.001 - Temperature in °C temp := dpt.DPT_9001(21.5) fmt.Printf("Temperature: %s, Unit: %s, Packed: %x\n", temp, temp.Unit(), temp.Pack()) var tempVal dpt.DPT_9001 if err := tempVal.Unpack(temp.Pack()); err != nil { log.Fatal(err) } fmt.Printf("Unpacked temperature: %.2f\n", float32(tempVal)) // DPT 9.002 - Temperature difference in K tempDiff := dpt.DPT_9002(5.0) fmt.Printf("Temperature diff: %s\n", tempDiff) // DPT 9.004 - Illumination in lux lux := dpt.DPT_9004(500.0) fmt.Printf("Illumination: %s\n", lux) // DPT 9.005 - Wind speed in m/s windSpeed := dpt.DPT_9005(12.5) fmt.Printf("Wind speed: %s\n", windSpeed) // DPT 9.006 - Pressure in Pa pressure := dpt.DPT_9006(101325.0) fmt.Printf("Pressure: %s\n", pressure) // DPT 9.007 - Humidity in % humidity := dpt.DPT_9007(65.0) fmt.Printf("Humidity: %s\n", humidity) // DPT 9.008 - Air quality in ppm airQuality := dpt.DPT_9008(400.0) fmt.Printf("Air quality: %s\n", airQuality) // DPT 9.020 - Voltage in mV voltage := dpt.DPT_9020(3300.0) fmt.Printf("Voltage: %s\n", voltage) // DPT 9.021 - Current in mA current := dpt.DPT_9021(500.0) fmt.Printf("Current: %s\n", current) // DPT 9.024 - Power in kW power := dpt.DPT_9024(2.5) fmt.Printf("Power: %s\n", power) } ``` -------------------------------- ### Group Communication via Multicast Routing in Go Source: https://context7.com/vapourismo/knx-go/llms.txt Shows how to join a KNXnet/IP multicast group to communicate with routers on the network without a dedicated tunnel connection. ```go package main import ( "log" "os" "github.com/vapourismo/knx-go/knx" "github.com/vapourismo/knx-go/knx/cemi" "github.com/vapourismo/knx-go/knx/dpt" "github.com/vapourismo/knx-go/knx/util" ) func main() { util.Logger = log.New(os.Stdout, "", log.LstdFlags) client, err := knx.NewGroupRouter("224.0.23.12:3671", knx.DefaultRouterConfig) if err != nil { log.Fatal(err) } defer client.Close() err = client.Send(knx.GroupEvent{ Command: knx.GroupWrite, Destination: cemi.NewGroupAddr3(0, 0, 1), Data: dpt.DPT_1001(true).Pack(), }) if err != nil { log.Fatal(err) } for msg := range client.Inbound() { log.Printf("Command: %s, From: %s, To: %s, Data: %x", msg.Command, msg.Source, msg.Destination, msg.Data) } } ``` -------------------------------- ### Low-Level Multicast Communication with KNX Router Source: https://context7.com/vapourismo/knx-go/llms.txt Demonstrates using the Router type for low-level CEMI access via multicast. It includes configuration for message retention and interface selection, sending a CEMI indication, and processing incoming messages. ```go package main import ( "log" "net" "os" "time" "github.com/vapourismo/knx-go/knx" "github.com/vapourismo/knx-go/knx/cemi" "github.com/vapourismo/knx-go/knx/util" ) func main() { util.Logger = log.New(os.Stdout, "", log.LstdFlags) // Custom router configuration config := knx.RouterConfig{ RetainCount: 32, // Messages to retain for resend Interface: nil, // Use system default interface MulticastLoopbackEnabled: false, PostSendPauseDuration: 20 * time.Millisecond, } // Or specify a network interface ifi, _ := net.InterfaceByName("eth0") config.Interface = ifi router, err := knx.NewRouter("224.0.23.12:3671", config) if err != nil { log.Fatal(err) } defer router.Close() // Send CEMI indication ldata := cemi.LData{ Control1: cemi.Control1StdFrame, Control2: cemi.Control2GroupAddr | cemi.Control2Hops(6), Destination: uint16(cemi.NewGroupAddr3(1, 2, 3)), Data: &cemi.AppData{ Command: cemi.GroupWrite, Data: []byte{0x00}, // Off }, } err = router.Send(&cemi.LDataInd{LData: ldata}) if err != nil { log.Fatal(err) } // Process incoming CEMI messages for msg := range router.Inbound() { if ind, ok := msg.(*cemi.LDataInd); ok { log.Printf("Received from %s to %d: %x", ind.Source, ind.Destination, ind.Data) } } } ``` -------------------------------- ### Establish KNXnet/IP Group Communication Source: https://github.com/vapourismo/knx-go/blob/master/README.md Demonstrates how to connect to a KNX gateway or router to send and receive group communication messages. It uses the GroupTunnel or GroupRouter abstractions to handle data transmission and inbound message processing. ```go package main import ( "log" "os" "github.com/vapourismo/knx-go/knx" "github.com/vapourismo/knx-go/knx/cemi" "github.com/vapourismo/knx-go/knx/dpt" "github.com/vapourismo/knx-go/knx/util" ) func main() { util.Logger = log.New(os.Stdout, "", log.LstdFlags) client, err := knx.NewGroupTunnel("10.0.0.7:3671", knx.DefaultTunnelConfig) if err != nil { log.Fatal(err) } defer client.Close() err = client.Send(knx.GroupEvent{ Command: knx.GroupWrite, Destination: cemi.NewGroupAddr3(1, 2, 3), Data: dpt.DPT_9001(20.5).Pack(), }) if err != nil { log.Fatal(err) } for msg := range client.Inbound() { var temp dpt.DPT_9001 err := temp.Unpack(msg.Data) if err != nil { continue } util.Logger.Printf("%+v: %v", msg, temp) } } ``` -------------------------------- ### Handle Boolean Datapoint Types (DPT 1.xxx) in Go Source: https://context7.com/vapourismo/knx-go/llms.txt Shows how to initialize and pack/unpack various boolean-based KNX datapoint types such as switches, alarms, and state sensors. These types are used for binary control signals. ```go package main import ( "fmt" "log" "github.com/vapourismo/knx-go/knx/dpt" ) func main() { // DPT 1.001 - Switch (On/Off) switchOn := dpt.DPT_1001(true) fmt.Printf("Switch: %s, packed: %x\n", switchOn, switchOn.Pack()) var switchVal dpt.DPT_1001 if err := switchVal.Unpack([]byte{0x01}); err != nil { log.Fatal(err) } fmt.Printf("Unpacked switch: %s\n", switchVal) // DPT 1.002 - Bool (True/False) boolVal := dpt.DPT_1002(true) fmt.Printf("Bool: %s\n", boolVal) // DPT 1.003 - Enable (Enable/Disable) enableVal := dpt.DPT_1003(true) fmt.Printf("Enable: %s\n", enableVal) // DPT 1.005 - Alarm (Alarm/No alarm) alarmVal := dpt.DPT_1005(true) fmt.Printf("Alarm: %s\n", alarmVal) // DPT 1.008 - Up/Down upDown := dpt.DPT_1008(true) // true = Down fmt.Printf("UpDown: %s\n", upDown) // DPT 1.009 - Open/Close openClose := dpt.DPT_1009(true) // true = Close fmt.Printf("OpenClose: %s\n", openClose) // DPT 1.019 - Window/Door sensor windowDoor := dpt.DPT_1019(true) // true = Open fmt.Printf("Window/Door: %s\n", windowDoor) // DPT 1.100 - Heat/Cool heatCool := dpt.DPT_1100(true) // true = Heating fmt.Printf("Heat/Cool: %s\n", heatCool) } ``` -------------------------------- ### Group Communication via Tunneling in Go Source: https://context7.com/vapourismo/knx-go/llms.txt Demonstrates how to connect to a KNXnet/IP gateway using a unicast tunnel connection to send and receive group communication messages. ```go package main import ( "log" "os" "github.com/vapourismo/knx-go/knx" "github.com/vapourismo/knx-go/knx/cemi" "github.com/vapourismo/knx-go/knx/dpt" "github.com/vapourismo/knx-go/knx/util" ) func main() { util.Logger = log.New(os.Stdout, "", log.LstdFlags) client, err := knx.NewGroupTunnel("10.0.0.7:3671", knx.DefaultTunnelConfig) if err != nil { log.Fatal(err) } defer client.Close() err = client.Send(knx.GroupEvent{ Command: knx.GroupWrite, Destination: cemi.NewGroupAddr3(1, 2, 3), Data: dpt.DPT_9001(20.5).Pack(), }) if err != nil { log.Fatal(err) } for msg := range client.Inbound() { var temp dpt.DPT_9001 if err := temp.Unpack(msg.Data); err != nil { continue } util.Logger.Printf("Source: %s, Destination: %s, Temperature: %s", msg.Source, msg.Destination, temp) } } ``` -------------------------------- ### Discover KNXnet/IP Servers Source: https://github.com/vapourismo/knx-go/blob/master/README.md Uses the discovery mechanism to identify all available KNXnet/IP routers and gateways on the network within a specified timeout period. ```go package main import ( "log" "os" "time" "github.com/kr/pretty" "github.com/vapourismo/knx-go/knx" "github.com/vapourismo/knx-go/knx/util" ) func main() { util.Logger = log.New(os.Stdout, "", log.LstdFlags) servers, err := knx.Discover("224.0.23.12:3671", time.Millisecond*750) if err != nil { log.Fatal(err) } util.Logger.Printf("%# v", pretty.Formatter(servers)) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.