vapourismo / knx-go Goto Github PK
View Code? Open in Web Editor NEWKNX clients and protocol implementation in Go
License: MIT License
KNX clients and protocol implementation in Go
License: MIT License
The received message on the inbound seems to be different on different architecture. So on my Mac (AMD64) the casting to LDataInd works for all incoming messages. On my BeagleBoneBlack I use the ARM 5 architecture, which receives some messages of type LDataCon.
Build options:
GOOS=linux GOARCH=arm GOARM=5
Function:
func serveGroupInbound(inbound <-chan cemi.Message, outbound chan<- GroupEvent)
Code:
if ind, ok := msg.(*cemi.LDataInd); ok
Workaround: Adding additional check like...
if con, ok := msg.(*cemi.LDataCon); ok
Is this an appropriate solution?
i try connect to knx virtual in another machine, code below
` client, err := knx.NewGroupTunnel("224.0.23.12:3671", knx.DefaultTunnelConfig)
if err != nil {
log.Errorf(err)
}
defer client.Close()
for msg := range client.Inbound() {
fmt.Println(msg.Data)
}`
when my long press button,knx virtual display light is on,but code not print anything,what's matter?
Hi thanks you so much for this repository! I'm new to working with KNX on such a close-to-wire level.
I'm wondering how to work with DPT 7.007 values: they arn't specifically mentioned in the code. I also saw issue #7 mentioning https://godoc.org/github.com/vapourismo/knx-go/knx#GroupEvent
yet i'm unsure how to proceed.
Hi,
I am doing POC with this library for one of the upcoming project.
I have a KNX virtual running ( https://www.knx.org/knx-en/for-professionals/get-started/knx-virtual/index.php ) in windows box.
When i try to use this package and control a switch group, KNX virtual is crashing. I dont see any issue when i try with Python library . ( https://xknx.io/ )
Can it be a problem with Virutal device which unable to intercept go request ? Will there be similar impact when we deal with real devices ?. For business reasons, we have to use go language. Any comment or help on this ?
Go Code:
data := dpt.DPT_1001(true).Pack()
err = client.Send(knx.GroupEvent{
Command: knx.GroupWrite,
Destination: cemi.NewGroupAddr3(1, 1, 1),
Data: data,
})
Python Code:
switch = Switch(xknx,name='ch1',group_address='1/1/1')
await switch.set_on()
await xknx.stop()
Thanks,
Hello,
with eibd / knxd, to send a datagram i have groupwrite and groupswrite
knxtool groupwrite ip:localhost 1/1/1 01 will send a normal telegram
knxtool groupswrite ip:localhost 1/1/1 01 will send a short telegram
and knxd will give the information on reception too.
Layer 1(7F88EB404110,596802CF) Recv L_Data low from 0.0.1 to 1/1/1 hops: 05 T_DATA_XXX_REQ A_GroupValue_Write (small) 01
Is it possible to send short telegrams in knx-go ?
And is it possible to know if an incoming telegram is short or not ?
Thank you
Hey Ole, do you know what we need to do that telefgraf update their go.mod
to our newest version?
The authReq 0x3D1 is not supported.
Can you help me to implement it?
This seems the case for all extended AL Codes
Wireshark description is available here: https://github.com/wireshark/wireshark/blob/499a33c7092cb20d18e6194e09bb6f704e716076/epan/dissectors/packet-cemi.c#L430
Hi!
Is it possible to implement a status query of all group addresses connected to the gateway? Or, for example, without waiting for the status change, just request the current value of the group address?
At the moment, we get the status value only by changing it.
Hey folks,
honestly I'm not sure if it's a bug or a feature and if the culprit is telegraf or knx-go itself, but maybe you can help me on that.
I use telegraf (w/ kno-go) to monitor measurements points like temperature, CO2, VOC, into influxdb2 & grafana. I realize now with more and more data I log (more GAs) I loose more and more measurements points, meaning that are not show up in the DB.
I debug the issue and I sure the KNX bus itself nor config of the devices and the IP router is the problem. I monitor the bus in the ETS and also w/ xknx on the IP layer on my Mac. Both monitor the same amount of telegrams, but telegraf logs much less. See attachment. Between the the GA 7/3/91 and 7/2/151 that telegraf see back-to-back, xknx logs much much more.
I scan the relevant parts of telegraf, but I don't see any issue here. It loops in line 128 among the received telegrams in the input queue, which comes from knx-go. So my best guess was that already knx-go miss the telegrams, but I'm not a GO ninja.
Alex
Some uses of cemi.NewGroupAddrString() do not return errors, but it should. For example:
Thank you,
Juan
Hello,
I have an issue in Telegraf which use this/your Code.
The problem is the following, when the KNX-Router lost connection (for example during update of switch or router) then Telegraf don't recognize it.
After the connection with the KNX-Router is reablished, telegraf doesn't know it.
It works only after I restart Telegraf manually.
I already opend a Report at the Telegraf Repo.
influxdata/telegraf#13632
There powersj asked me to file here an upstream issue, if there is a way to check when the server goes down via an error?
Hi, thanks for the great work, I was succesfull in sending a telegram to an actuator, but I'm not finding a way to read a group addess at request an not only when sent from the actuator. Is there an easy way to read a group address without having it sent ciclically?
Best regards
Nicola
I want to send a DESCRIPTION_REQUEST over IP Gateway.
I can't find an implementation, did you implemented it ? If no, I can help
Hello,
I believe in
Line 141 in 6d1e5b4
should be a 8-bit unsigned value, as the DPT value is 0...100 percentage.
type DPT_5001 uint8
When Im using DPT 1.005
[[inputs.knx_listener.measurement]]
name = "Alarm"
dpt = "1.005"
addresses = ["0/2/2", # Windalarm (Markise)
"0/2/3", # Windalarm (Raffstores)
"0/2/4"] # Regenalarm
knx-go is writing wrong source tag in some situations.
Situation: my sensor is having PA 1.1.50.
At the same time im using ETS6 connected to my KNX-IP Interface (Gira X1) via tunneling connection, having PA 1.1.6
Now i do a "GroupValue_Read" for example on 0/2/2. my Sensor (1.1.50) is responding via GroupValue_Response with its address. But in telegraf im getting 1.1.6 as source tag, but it has to be 1.1.50 instead.
For now other DPTs dont have this problem. First time I notice this but only with DPT 1.005.
I looks like knx-go is taking the PA from the GroupValue_Read message but the correct address is in the GroupValue_Response message
Hello,
I have another question, I hope this is the right place to ask.
As I previously mentioned on another ticket, I have a N148/21 with only one tunnel connection.
If the gateway connection is not available (it can happen if the previous connection is not properly disconnected) the gateway will be unavailable for 1 min.
So I'm using ResendInterval: 60 * time.Second,
But because the gateway and the go app are not on the same network, the connection might be lost for several minutes.
So I'm using ResponseTimeout: 1 * time.Hour
to any (temporary) network issue
But does the lib try to reconnect automatically if the connection is lost?
Thanks,
Hello,
in example
// Send 20.5°C to group 1/2/3.
err = client.Send(0, 2563, dpt.ValueTemp(20.5).Pack())
How to convert address "1/2/3" to uint (2563)?
Can we use another DPTs (not only for temperature)?
During development while having the go race detector turned on, I noticed the following data race warning:
==================
WARNING: DATA RACE
Write at 0x00c0000c4550 by goroutine 26:
runtime.recvDirect()
/opt/homebrew/opt/go/libexec/src/runtime/chan.go:348 +0x7c
github.com/vapourismo/knx-go/knx.(*Tunnel).process.deferwrap1()
/Users/tschinke/go/pkg/mod/github.com/vapourismo/[email protected]/knx/tunnel.go:471 +0x34
runtime.deferreturn()
/opt/homebrew/opt/go/libexec/src/runtime/panic.go:602 +0x5c
github.com/vapourismo/knx-go/knx.(*Tunnel).serve()
/Users/tschinke/go/pkg/mod/github.com/vapourismo/[email protected]/knx/tunnel.go:554 +0x21c
github.com/vapourismo/knx-go/knx.NewTunnel.gowrap1()
/Users/tschinke/go/pkg/mod/github.com/vapourismo/[email protected]/knx/tunnel.go:616 +0x34
Previous read at 0x00c0000c4550 by goroutine 3401:
runtime.chansend1()
/opt/homebrew/opt/go/libexec/src/runtime/chan.go:146 +0x2c
github.com/vapourismo/knx-go/knx.(*Tunnel).handleConnStateRes.func1()
/Users/tschinke/go/pkg/mod/github.com/vapourismo/[email protected]/knx/tunnel.go:455 +0x100
Goroutine 26 (running) created at:
github.com/vapourismo/knx-go/knx.NewTunnel()
/Users/tschinke/go/pkg/mod/github.com/vapourismo/[email protected]/knx/tunnel.go:616 +0x330
github.com/vapourismo/knx-go/knx.NewGroupTunnel()
/Users/tschinke/go/pkg/mod/github.com/vapourismo/[email protected]/knx/tunnel.go:653 +0x70
gitlab/group/wzo-bms/subnet-gateway/domain/connector/knxip/adapter/vapourismo.(*Broker).connect()
/Users/tschinke/git/gitlab/group/wzo-bms/subnet-gateway.git/domain/connector/knxip/adapter/vapourismo/adapter.go:94 +0x208
gitlab/group/wzo-bms/subnet-gateway/domain/connector/knxip/adapter/vapourismo.NewBroker.func1()
/Users/tschinke/git/gitlab/group/wzo-bms/subnet-gateway.git/domain/connector/knxip/adapter/vapourismo/adapter.go:33 +0x34
Goroutine 3401 (running) created at:
github.com/vapourismo/knx-go/knx.(*Tunnel).handleConnStateRes()
/Users/tschinke/go/pkg/mod/github.com/vapourismo/[email protected]/knx/tunnel.go:447 +0x1a0
github.com/vapourismo/knx-go/knx.(*Tunnel).process()
/Users/tschinke/go/pkg/mod/github.com/vapourismo/[email protected]/knx/tunnel.go:531 +0x5bc
github.com/vapourismo/knx-go/knx.(*Tunnel).serve()
/Users/tschinke/go/pkg/mod/github.com/vapourismo/[email protected]/knx/tunnel.go:554 +0x21c
github.com/vapourismo/knx-go/knx.NewTunnel.gowrap1()
/Users/tschinke/go/pkg/mod/github.com/vapourismo/[email protected]/knx/tunnel.go:616 +0x34
==================
I'm not sure, if I'm doing something unexpected, but I don't believe so.
Hello,
Thank you very much for sharing your great work on knx in go !
i wanted to get the cemi.GroupValueRead events, so i modified groups.go this way :
// GroupComm represents a group communication.
type GroupComm struct {
Source cemi.IndividualAddr
Destination cemi.GroupAddr
Data []byte
Command cemi.APCI
}
if app, ok := ind.Data.(*cemi.AppData); ok && (app.Command == cemi.GroupValueResponse || app.Command == cemi.GroupValueWrite || app.Command == cemi.GroupValueRead) {
outbound <- GroupComm{
Source: ind.Source,
Destination: cemi.GroupAddr(ind.Destination),
Data: app.Data,
Command: app.Command,
}
} else {
util.Log(inbound, "Received L_Data.ind frame does not contain application data")
}
I'm really new to your code and don't know if it has negative side effects.
Is it possible to get more events, on may be to have a subscription mechanism ?
Regards
Alexandre
Hi,
I started to add some missing DPTs and to do some clean-up by following the specifications (units, allowed ranges, ...).
I also realized that the MulticastLoopback is disabled by default when using net.ListenMulticastUDP
.
What would be the best procedure for you to integrate all these changes? Changes made so far are in this branch. Would you be available to discuss this?
Thank you very much for your help.
Hello,
I would like an example to read the initial values from the gateway with sensors in C # (Visual Studio).
I found an example that only gives the new values (after the values are changed), but I also need the first values.
Many Thanks
Fariz
Probably : if !ind.Control2.IsGroupAddr() - ! missing ?
// Filter indications that do not target group addresses.
if ind.Control2.IsGroupAddr() {
util.Log(inbound, "Received L_Data.ind does target a group address")
continue
}
Thank you for integrating the read event.
Several data types are still missing (like flow related 12.1200 f.e.) . Would be nice to see them all implemented.
Hello!
Please add DPT232 support for RGB
Hi,
I am using a weinzierl device with security enabled. I can query it using the xknx python library and an example similar to this one. This is my working test:
import asyncio
import logging
from xknx import XKNX
from xknx.io import ConnectionConfig, ConnectionType, SecureConfig
from xknx.tools import group_value_write
from xknx.devices import Light
logging.basicConfig(level=logging.INFO)
logging.getLogger("xknx.log").level = logging.DEBUG
logging.getLogger("xknx.knx").level = logging.DEBUG
async def main() -> None:
"""Test connection with IP secure tunnelling."""
connection_config = ConnectionConfig(
connection_type=ConnectionType.TUNNELING_TCP_SECURE,
gateway_ip="192.168.1.44",
individual_address="1.0.11",
secure_config=SecureConfig(
user_id=1,
device_authentication_password="*******",
user_password="***********",
),
)
xknx = XKNX(connection_config=connection_config)
await xknx.start()
print("Tunnel connected")
# Connect to KNX/IP bus, switch on light, wait 2 seconds and switch of off again
light = Light(xknx, name="TestLight", group_address_switch="1/1/5")
await light.set_on()
await asyncio.sleep(2)
await light.set_off()
await xknx.stop()
asyncio.run(main())
I would like to query the same device using telegraf to push some metrics to influxdb but I couldn't find any config example to connect to a secure tunnel. Does knx-go supports connecting to a secure tunnel? In case it's supported, can you share an example config?
tpdu.go contains the following lines in func (app *AppData) Pack(buffer []byte)
:
buffer[2] &= 63
buffer[2] |= byte(app.Command&3) << 6
What do they do?
I wanted to implement DPT 16.000/16.001.
Because of copy(buffer[2:], app.Data)
, buffer[2:16]
contain a 14 Byte String.
The mentioned lines overwrite the first byte in buffer[2]
.
I guess, I lack knowledge on the basics of assembling KNX datagrams.
Thanks for your reply.
Hi,
will there be a support for DPT 251.600, 6 bytes. It's a RGBW LED connected through a DALI KNX adapter from Hager (TXA664D).
Thanks,
Mitch
Could you please add DPT 17.001 needed for scenes?
I needed this function, may be it can be useful to others
// NewGroupAddrFromString returns a cemi.GroupAddr from a group address string a/b or a/b/c
func NewGroupAddrFromString(groupAddress string) (cemi.GroupAddr, error) {
parts := strings.Split(groupAddress, "/")
if len(parts) < 2 || len(parts) > 3 {
return 0, fmt.Errorf("%s is not a valid group address", groupAddress)
}
n := make([]int, 0, len(parts))
for _, part := range parts {
p, err := strconv.Atoi(part)
if err != nil {
return 0, fmt.Errorf("%s is not a valid group address", groupAddress)
}
n = append(n, p)
}
if len(n) == 2 {
return cemi.NewGroupAddr2(uint8(n[0]), uint8(n[1])), nil
}
return cemi.NewGroupAddr3(uint8(n[0]), uint8(n[1]), uint8(n[2])), nil
}
This library currently supports only KNXnet/IP. I am interested in extending the support for my application, which should also be able to directly communicate to serial KNX gateway/devices (which are mounted on a system as a /dev/tty*
device).
My question is: How would I go about doing that?
I've noticed in the code that the Socket
interface might be the solution. To just replace the current TunnelSocket
implementation with one that writes directly to a local serial device. But I'm not sure if it's just as simple as replacing the interface implementaiton. Does the rest of the library exclusively depend on the fact that it is KNXnet/IP?
From you experience with KNX, would this work? Is there anything that needs to be added to correctly send the []byte
payloads? Because I see there are some Pack
and Unpack
methods that handle enriching and extracting the data). Would something similar need to be done if I want to send directly to a serial device?
The conversation only works for DPT with format yy.xxx but will fail if they have four digits like yy.xxxx
Why are there Strings defined like "On" "Off" or "Up" "Down"
`// DPT_1001 represents DPT 1.001 (G) / DPT_Switch.
type DPT_1001 bool
func (d DPT_1001) Pack() []byte {
return []byte{packB1(bool(d))}
}
func (d *DPT_1001) Unpack(data []byte) error {
return unpackB1(data, (*bool)(d))
}
func (d DPT_1001) Unit() string {
return ""
}
func (d DPT_1001) String() string {
if d {
return "On"
} else {
return "Off"
}
}`
but in influxdb all DPT1.xxx are boolean with values "true" oder "false"
I would expect seeing these Strings filled into the field "_value"
Line 103 in 922a0d5
Hello,
I have a N148/21 interface, that only supports 1 tunnelling connection.
When the connection is already taken, the interface returns a "NO_MORE_CONNECTIONS" error (code 0x24)
With the default configuration it times out after a 10 secs
Is it possible to detect it and retry after 1 min?
Thanks
Hi @vapourismo,
I added two comments to 2cc5ef2. What is your opinion on these?
Hello, is there a list with supported DPT types?
I found only DPT1 and DPT9 at dpt package.
Thank you
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.