Hi!
What is the best way to simulate a message from the gateway to the gateway bridge? Picture for clarification.
Thanks in advanced!
Hi!
What is the best way to simulate a message from the gateway to the gateway bridge? Picture for clarification.
Thanks in advanced!
Youâd need to write a script that writes some dummy messages following the packet_forwarder protocol (as defined here), and send them through UDP to the lora-gateway-bridge.
May I ask what are you trying to test with this?
We have no gateway and we are trying to simulate how the flow works after the Gateway Bridge receives the message. Is this something dumb to do?
Given that your gateway communicates with the LoRa Gateway Bridge component, which communicates with an MQTT broker, you could basically publish simulated gateway messages direct to the MQTT broker. The format is documented here: https://docs.loraserver.io/lora-gateway-bridge/use/data/.
But it seems wrong to skip components (?). Wouldnât it be best to test the Gateway Bridge instead of skipping it?
No, not at all, but itâll definitely be some work to do. I was asking because if you needed to test loraserver and lora-app-server only, Iâve got a script that âsimulatesâ the gateway-bridge allowing to send messages through MQTT to the loraserver, exactly what Orne is suggesting.
Itâs kind of messy as it was a quick hack to test my own setup, but you can tweak it a bit with your personal keys, macs, etc., to get it going. The sendMessage function acts as an RX message from the gateway-bridge only, but it should be fairly easy to add a stats message, just check the data formats at Orneâs link. Check it here.
The gateway to lora-gateway-bridge communication is usually kind of straight forward, and once you get a gateway youâll have to configure the packet forwarder anyway. But again, you may simulate the packet_forwarder if you like.
Hi! Thank you so much for that script.
One question. Where do I specify:
In the script?
Those are setup at the loraserver end, not per message. See https://docs.loraserver.io/loraserver/install/config/.
Thank you! One last question.
I seem to have some trouble with the payload. The error message comes from here: chirpstack-application-server/internal/codec/cayenne_lpp.go at 887bb2f6bb5015c18e519a3de3e422ad056fe9f4 ¡ brocaar/chirpstack-application-server ¡ GitHub
Seems some of the payload does not comply with cayenne (?). The error itself:
Error: time="2018-02-14T18:02:01Z" level=error msg="decode payload error" application_id=1 codec=CAYENNE_LPP dev_eui=1616161616161616 error="invalid data type: 20" f_cnt=0 f_port=1
.
Seems to have something to do with mPayload
and when the temperature generateTemp1byte
is appended (?)
Generated mPayload: [0 20 0 208 115 108 192 205 199 187 192 5]
Thank you so much for all your help.
Sorry, It doesnât, I donât even know what the Cayenne format is . As I mentioned, this works for my setup, where I use 2âs complement to encode different types of values depending on the amount of bytes, data type and min/max values, generating the bytes array following something like this:
func GenerateSomeFloat(originalFloat float32) []byte {
encodedFloat := uint32( (originalFloat / maxValue) * float32(math.Pow(2, 31)) )
byteArray := make([]byte, 4)
binary.BigEndian.PutUint32(byteArray, encodedFloat)
return byteArray
}
The uints and arrays sizes depend of course in how many bytes you are using to represent your value. If you are interested, our general format is based on this GPS encoding format from Multitech.
Then, at lora-app-server, I decode like this (note that I have implemented what we call âdata typesâ that define for example that a Latitude is a 4 bytes float that allows negatives, ranging from -90.0 to 90.0):
func ReadFloatData(dataType DataType, dataArray []byte) (float64, error) {
if dataType.NumBytes != int32(len(dataArray)) {
return 0.0, ErrNumBytes
}
intData := new(big.Int)
intData.SetBytes(dataArray)
//Precision is given by the max repesentable number minus 1.
precision := float64((dataType.NumBytes * 8) - 1)
var fData float64
floatInt, _ := new(big.Float).SetInt(intData).Float64()
if dataType.AllowsNegative {
fData = (floatInt / (math.Pow(2, precision) - 1.0)) * dataType.MaxVal
if fData > dataType.MaxVal {
fData = (2*dataType.MaxVal - fData) * -1.0
}
} else {
//If no negatives are allowd, we don't need a sign bit, so we divide by the whole precision.
fData = (floatInt / math.Pow(2, precision+1)) * dataType.MaxVal
if fData > dataType.MaxVal {
return 0.0, ErrDataTypeRange
}
}
//Check for min val, return n error if the value is outside the range.
if fData < dataType.MinVal {
return 0.0, ErrDataTypeRange
}
return fData, nil
}
In summary, if you want to use the Cayenne encoding, then youâll need to generate your bytes array payload following that format, not with the generateSomtehing functions at the script which follow our own encoding.
Sorry, I missed the link. You could use it to create the byte arrays you are looking for, or maybe some other library like this or this to pre-encode some sample data and then hardcode it to the script.
Again, thank you so much!! You are a lifesaver.
(Note)
I knew I have seen Cayenne somewhere. I picked Cayenne as predefined payload codec for my test-application in the GUI.
Hello guys, Iâm trying to fix a problem because I want to simulate a GW/node and I have the Lora server configurated and I have another virtual machine to be my ââgatewayââ.
Someone can explain how can I install that to Send a package for my gateway bridge?
Did you installed in LoRaServer the script? And also did you install the gateway bridge in the same machine you have the loraserver run?
Iâm trying to get a GW+Node simulator and I canât I see this topic so maybe can help me
Hi, @dicarva. If you are referring to my script, as I mentioned, itâs a bit messy and outdated. Iâve been meaning to rewrite it properly, maybe if I get some time this or next week Iâll get to it. Iâll post it here if any modifications are made.
Anyway, the important thing is that itâs not to be installed over anything else -itâs just a simple script that may be compiled and executed by itself-, and its location doesnât matter. So youâd need to clone the repo (or copy the file, whatever you like), modify the source to adjust it for your needs (change gw mac, device keys, etc.) and point it to wherever your mosquitto broker is, the just go build
and run it.
Good luck!
How you did you point to Mosquitto broker?
Check the file lora-node.go
, itâs there. You need to change these lines with you mosquitto location and credentials (if any):
opts := MQTT.NewClientOptions()
opts.AddBroker("tcp://localhost:1883")
opts.SetUsername("loraserver_gw")
opts.SetPassword("ChpP2eeW1Tck")
lora-node.go:12:2: cannot find package âGitHub - brocaar/lorawan: Package lorawan provides structures and tools to read and write LoraWAN messages from and to a slice of bytes.â in any of:
/usr/src/github.com/brocaar/lorawan (from $GOROOT)
/home/diogo/go/src/github.com/brocaar/lorawan (from $GOPATH)
lora-node.go:13:2: cannot find package âGitHub - eclipse/paho.mqtt.golangâ in any of:
/usr/src/github.com/eclipse/paho.mqtt.golang (from $GOROOT)
/home/diogo/go/src/github.com/eclipse/paho.mqtt.golang (from $GOPATH)
he show me this error bit I wonât to install because I already have the loraserver
You need to fetch those packages first because the script depends on them. From the terminal:
go get github.com/brocaar/lorawan
go get github.com/eclipse/paho.mqtt.golang
That said, please take a careful look at the script and modify anything you need to before using it. As I mentioned, itâs outdated (anything could be broken) and pretty cusomized to our test scenario.
./lora-node.go:320:4: error: unknown field âAppEUIâ in âlorawan.JoinRequestPayloadâ
AppEUI: appEUI,
^
./lora-node.go:326:19: error: reference to undefined field or method âSetMICâ
if err := joinPhy.SetMIC(appKey); err != nil {
^
./lora-node.go:355:4: error: unknown field âAppEUIâ in âlorawan.JoinRequestPayloadâ
AppEUI: appEUI,
^
./lora-node.go:361:19: error: reference to undefined field or method âSetMICâ
if err := joinPhy.SetMIC(appKey); err != nil {
^
./lora-node.go:407:15: error: reference to undefined field or method âSetMICâ
if err := phy.SetMIC(nwkSKey); err != nil {
^
./lora-node.go:319:15: error: incompatible type for field 2 in struct construction (type has no methods)
MACPayload: &lorawan.JoinRequestPayload{
^
./lora-node.go:354:15: error: incompatible type for field 2 in struct construction (type has no methods)
MACPayload: &lorawan.JoinRequestPayload{
^
./lora-node.go:396:12: error: incompatible type for field 4 in struct construction
FOpts: lorawan.MACCommand{}, // you can leave this out when there is no MAC command to send
This is normal?
Ah, well, there you go, it is indeed outdated and tries to use some old definitions from Orneâs lorawan package that no longer exist. But still, you could check github.com/brocaar/lorawan
and try to reimplement what has changed at the script (Iâm not able to do it right now, maybe in a couple of days or next week).