Skip to content

Commit f2d9113

Browse files
Merge pull request #17 from OS2iot/stage
Release Stage to master
2 parents 892cd42 + 6345987 commit f2d9113

File tree

22 files changed

+789
-48
lines changed

22 files changed

+789
-48
lines changed

README.md

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -78,34 +78,38 @@ Solution:
7878
5. restart the application.
7979

8080
## Adding an ADR Algorithm
81-
When the ADR Algorithm has been tested, and is ready for deployment, it has to be built as a Go Module.
82-
83-
The module is created running:
84-
```bash
85-
mkdir example-mod-name
86-
cd example-mod-name
87-
go mod init example-mod-name
88-
curl https://raw.githubusercontent.com/brocaar/chirpstack-network-server/master/examples/adr-plugin/main.go -o main.go
89-
```
90-
Replace the necessary parts in `main.go` with your own adr algorithm.
91-
Run:
92-
```bash
93-
$env:GOOS="linux"
94-
$env:GOARCH="amd64"
95-
go build
96-
```
97-
and install the packages as described in the output of `go build`.
98-
finally `go build` can be run again to create the plugin, which is a binary with the name of your module `example-mod-name`.
81+
When the ADR Algorithm has been tested, and is ready for deployment, the ADR Algorithm has to be added to chirpstack. It is mandatory that the custom adr module is writtin in js.
82+
83+
## Adding the Plugin to Chirpstack
84+
85+
### Docker
9986

100-
### Adding the Plugin to the Network Server
101-
If the default `docker-compose.yml` file is used, the folder `./configuration/chirpstack-network-server` is already copied to `/etc/chirpstack-network-server` in the docker container.
102-
Therefore a new folder can be added such as `./configuration/chirpstack-network-server/adr-plugins` in which the go module can be added.
103-
This makes the module available at `/etc/chirpstack-network-server/adr-plugins/example-mod-name` within the network server container.
87+
If the default `docker-compose.yml` file is used, the folder `./configuration/chirpstack` is already copied to `/etc/chirpstack` in the docker container.
88+
Therefore a new folder can be added such as `./configuration/chirpstack/adr-modules` in which the js file can be added.
89+
This makes the file available at `/etc/chirpstack/adr-modules/example-file.js` within the chirpstack container.
10490

105-
The last step is to specify the file as being an adr-plugin within the `chirpstack-network-server.toml` config file by adding `adr_plugins=["/etc/chirpstack-network-server/adr-plugins/example-mod-name"]` under `[network_server.network_settings]`, like this:
91+
The last step is to specify the file as being an adr-plugin within the `chirpstack.toml` config file by adding `adr_plugins=["/etc/chirpstack/adr-modules/example-file.js"]` under `[network]`, like this:
10692
```toml
107-
[network_server.network_settings]
108-
adr_plugins=["/etc/chirpstack-network-server/adr-plugins/example-mod-name"]
93+
[network]
94+
adr_plugins=["/etc/chirpstack/adr-modules/example-file.js"]
10995
```
11096

111-
Your should now be able to restart the network server and the new adr algorithm should be available in the ChirpStack Application Server.
97+
You should now be able to restart the chirpstack server and the new adr algorithm should be available in Chirpstack.
98+
99+
### Helm
100+
101+
When hosting via helm the steps are slightly different.
102+
103+
1. Make sure that the persistent volume claim belonging to the chirpstack exists in your hosted setup.
104+
2. Find the actual name of the network-server pod. This can be done in a few ways. If you're have a connection via a GUI like `Lens` it can be found under the `Pods` list. If you're hosting on an Azure Kubernetes service, it can be found under the side menu `Workloads -> Pods`
105+
3. Use `kubectl` to copy the module into the pod
106+
```bash
107+
kubectl cp ./path/to/module/adr-module chirpstack-xxxxxxxxx-xxxxx:/etc/chirpstack/adr-modules
108+
```
109+
4. Update `configmap.yaml` located under `/helm/charts/chirpstack/templates` with the path to the plugin under `[network]`, like this:
110+
```toml
111+
[network]
112+
adr_plugins=["/etc/chirpstack/adr-modules/example-file.js"]
113+
```
114+
The first line already exists
115+
5. Once the helm chart has redeployed restart the network server to enable the new module.
16.1 MB
Binary file not shown.
Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,30 @@
11
# See https://www.chirpstack.io/gateway-bridge/install/config/ for a full
22
# configuration example and documentation.
33

4-
[integration.mqtt.auth.generic]
5-
servers=["tcp://mosquitto:1883"]
6-
username=""
7-
password=""
4+
# Integration configuration.
5+
[integration]
6+
# Payload marshaler.
7+
#
8+
# This defines how the MQTT payloads are encoded. Valid options are:
9+
# * protobuf: Protobuf encoding
10+
# * json: JSON encoding (for debugging)
11+
marshaler="protobuf"
12+
13+
[integration.mqtt]
14+
# Event topic template.
15+
event_topic_template="gateway/{{ .GatewayID }}/event/{{ .EventType }}"
16+
17+
# State topic template.
18+
state_topic_template="gateway/{{ .GatewayID }}/state/{{ .StateType }}"
19+
20+
# Command topic template.
21+
command_topic_template="gateway/{{ .GatewayID }}/command/#"
22+
[integration.mqtt.auth]
23+
# Type defines the MQTT authentication type to use.
24+
#
25+
# Set this to the name of one of the sections below.
26+
type="generic"
27+
[integration.mqtt.auth.generic]
28+
servers=["tcp://mosquitto:1883"]
29+
username=""
30+
password=""
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// This must return the name of the ADR algorithm.
2+
export function name() {
3+
return "Slowly Correcting ADR Algorithm";
4+
}
5+
6+
// This must return the id of the ADR algorithm.
7+
export function id() {
8+
return "scadra";
9+
}
10+
11+
// This handles the ADR request.
12+
//
13+
// Input object example:
14+
// {
15+
// regionName: "eu868",
16+
// regionCommonName: "EU868",
17+
// devEui: "0102030405060708",
18+
// macVersion: "1.0.3",
19+
// regParamsRevision: "A",
20+
// adr: true,
21+
// dr: 1,
22+
// txPowerIndex: 0,
23+
// nbTrans: 1,
24+
// maxTxPowerIndex: 15,
25+
// requiredSnrForDr: -17.5,
26+
// installationMargin: 10,
27+
// minDr: 0,
28+
// maxDr: 5,
29+
// uplinkHistory: [
30+
// {
31+
// "fCnt": 10,
32+
// "maxSnr": 7.5,
33+
// "maxRssi": -110,
34+
// "txPowerIndex": 0,
35+
// "gatewayCount": 3
36+
// }
37+
// ]
38+
// }
39+
//
40+
// This function must return an object, example:
41+
// {
42+
// dr: 2,
43+
// txPowerIndex: 1,
44+
// nbTrans: 1
45+
// }
46+
// Handle function for ADR request.
47+
export function handle(req) {
48+
// This defines the default response, which is equal to the current device state.
49+
let resp = {
50+
dr: req.DR,
51+
txPowerIndex: req.TxPowerIndex,
52+
nbTrans: req.NbTrans,
53+
};
54+
55+
resp.txPowerIndex = 0;
56+
57+
// If ADR is disabled, return with current values.
58+
if (!req.ADR) {
59+
return [resp, null];
60+
}
61+
62+
let lostPackageCnt = getLostPackageCount(req);
63+
// If 5 or more packages are lost during the last received packages, decrease the data-rate
64+
if (lostPackageCnt >= 5) {
65+
resp.dr -= 1;
66+
} else if (
67+
req.UplinkHistory.length === 20 &&
68+
getLostPackageCount(req, 20) <= 2
69+
) {
70+
// If 2 or fewer packages are lost during the last 20 received packages, the dr might be able to be increased
71+
72+
// We only want to increase the dr if none of the previously received packages
73+
// are within the installationMargin of the minimum required snr for the current dr
74+
// The installationMargin should prevent us from increasing the dr too much, such that packages are lost
75+
// when cars park in a spot.
76+
let minSNR = getMinSNR(req);
77+
let installationMargin = 10;
78+
// A margin of around 10 seems okay
79+
// This value has been chosen based on the loRaSNR values from sensors installed in a parking lot,
80+
// where a fluctuation of +- 10 can be seen (should be caused by cars parking and leaving).
81+
let diffSNR = minSNR - req.requiredHistoryCount - installationMargin;
82+
83+
// Examples:
84+
// minSNR = -5
85+
// requiredSNRforDR = -10
86+
// installationMargin = 10
87+
// diffSNR = -5 - -10 - 10 = -5
88+
// => Not safe to increase the dr
89+
90+
// minSNR = 5
91+
// requiredSNRforDR = -10
92+
// installationMargin = 10
93+
// diffSNR = 5 - -10 - 10 = 5
94+
// => The dr should be safe to increase
95+
96+
if (diffSNR > 0) {
97+
resp.dr += 1;
98+
}
99+
}
100+
101+
// If the data rate is increased or reduced to something outside the Min - Max range,
102+
// set it to the respective limit
103+
if (req.maxDr < resp.dr) {
104+
resp.dr = req.maxDr;
105+
}
106+
107+
if (req.MinDR > resp.dr) {
108+
resp.dr = req.MinDR;
109+
}
110+
111+
return [resp, null];
112+
}
113+
114+
function getMinSNR(req) {
115+
let snrM = 999;
116+
117+
for (const uh of req.uplinkHistory) {
118+
if (uh.maxSnr < snrM) {
119+
snrM = uh.maxSnr;
120+
}
121+
}
122+
return snrM;
123+
}
124+
125+
// Function to get the count of lost packages from the request.
126+
function getLostPackageCount(req, ...lastXElement) {
127+
if (req.uplinkHistory.length < 2) {
128+
return 0;
129+
}
130+
131+
let elements = req.uplinkHistory;
132+
133+
if (lastXElement.length > 0) {
134+
let x = lastXElement[0];
135+
if (x < elements.length) {
136+
elements = elements.slice(elements.length - x);
137+
}
138+
}
139+
140+
let lostPackets = 0;
141+
let previousFCnt = 0;
142+
143+
for (let i = 0; i < elements.length; i++) {
144+
const m = elements[i];
145+
146+
if (i === 0) {
147+
previousFCnt = m.FCnt;
148+
continue;
149+
}
150+
151+
lostPackets += m.FCnt - previousFCnt - 1; // there is always an expected difference of 1
152+
previousFCnt = m.FCnt;
153+
}
154+
155+
return lostPackets;
156+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[postgresql]
2+
dsn="postgres://chirpstack:chirpstack@postgresChirpstackV4/chirpstack?sslmode=disable"
3+
4+
[redis]
5+
servers=["redis://redis:6379"]
6+
7+
[network]
8+
net_id="000000"
9+
adr_plugins=["/etc/chirpstack/adr-modules/sensade-adr-mod/sensade-adr.js"]
10+
11+
enabled_regions=["eu868"]
12+
13+
[api]
14+
bind="0.0.0.0:8080"
15+
jwt_secret="verysecret"
16+
17+
[integration]
18+
enabled=["mqtt"]
19+
20+
[integration.mqtt]
21+
server="tcp://mosquitto:1883"
22+
json=true

0 commit comments

Comments
 (0)