Skip to content

Commit

Permalink
Merge pull request #9 from SmartParksOrg/dev
Browse files Browse the repository at this point in the history
~Stable V1.1.1
  • Loading branch information
adminfriso authored Dec 3, 2020
2 parents 0baa22f + b61b39d commit b09bbcf
Show file tree
Hide file tree
Showing 22 changed files with 16,700 additions and 2,331 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ jobs:
node-version: [12.x]

steps:
- uses: actions/checkout@v2.2.0
- uses: actions/checkout@v2.3.4
- name: Setup Node.js ${{ matrix.node-version }} environment
uses: actions/setup-node@v1.4.2
uses: actions/setup-node@v2.1.2
with:
node-version: ${{ matrix.node-version }}

Expand Down
18,729 changes: 16,438 additions & 2,291 deletions package-lock.json

Large diffs are not rendered by default.

40 changes: 21 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@smartparks/node-red-contrib-chirpstack",
"version": "1.0.0",
"version": "1.1.1",
"description": "An adapter for node-red to easily connect to the ChirpStack gRPC API.",
"keywords": [
"node-red",
Expand Down Expand Up @@ -35,41 +35,43 @@
"chirpstack-application-management": "./dist/nodes/chirpstack-application-management/chirpstack-application-management.js",
"chirpstack-gateway-management": "./dist/nodes/chirpstack-gateway-management/chirpstack-gateway-management.js",
"chirpstack-organization-management": "./dist/nodes/chirpstack-organization-management/chirpstack-organization-management.js",
"chirpstack-device-profile-management": "./dist/nodes/chirpstack-device-profile-management/chirpstack-device-profile-management.js"
"chirpstack-device-profile-management": "./dist/nodes/chirpstack-device-profile-management/chirpstack-device-profile-management.js",
"chirpstack-network-server": "./dist/nodes/chirpstack-network-server/chirpstack-network-server.js"
}
},
"dependencies": {
"@chirpstack/chirpstack-api": "^3.8.1",
"grpc": "^1.24.3"
"grpc": "^1.24.4",
"tslib": "^2.0.3"
},
"devDependencies": {
"@rollup/plugin-typescript": "^6.0.0",
"@types/express": "^4.17.7",
"@rollup/plugin-typescript": "^8.0.0",
"@types/express": "^4.17.9",
"@types/jest": "^26.0.15",
"@types/node": "^14.14.3",
"@types/node": "^14.14.10",
"@types/node-red": "^1.1.1",
"@types/node-red-node-test-helper": "^0.2.1",
"@types/sinon": "^9.0.8",
"@types/sinon": "^9.0.9",
"@types/supertest": "^2.0.10",
"@typescript-eslint/eslint-plugin": "^4.5.0",
"@typescript-eslint/parser": "^4.5.0",
"@typescript-eslint/eslint-plugin": "^4.9.0",
"@typescript-eslint/parser": "^4.9.0",
"colorette": "^1.2.1",
"concurrently": "^5.3.0",
"copyfiles": "^2.4.0",
"eslint": "^7.12.0",
"eslint-config-prettier": "^6.14.0",
"eslint-plugin-jest": "^24.1.0",
"copyfiles": "^2.4.1",
"eslint": "^7.14.0",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-jest": "^24.1.3",
"eslint-plugin-prettier": "^3.1.4",
"glob": "^7.1.6",
"jest": "^26.6.1",
"jest": "^26.6.3",
"mustache": "^4.0.1",
"node-red": "^1.2.2",
"node-red": "^1.2.6",
"node-red-node-test-helper": "^0.2.5",
"onchange": "^7.1.0",
"prettier": "^2.0.5",
"rollup": "^2.32.1",
"ts-jest": "^26.4.2",
"typescript": "^4.0.3"
"prettier": "^2.2.1",
"rollup": "^2.34.0",
"ts-jest": "^26.4.4",
"typescript": "^4.1.2"
},
"jest": {
"testEnvironment": "node",
Expand Down
34 changes: 34 additions & 0 deletions src/__tests__/chirpstack-network-server.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import testHelper, { TestFlowsItem } from "node-red-node-test-helper";
import chirpstackNetworkServerNode from "../nodes/chirpstack-network-server/chirpstack-network-server";
import { ChirpstackNetworkServerNodeDef } from "../nodes/chirpstack-network-server/modules/types";

type FlowsItem = TestFlowsItem<ChirpstackNetworkServerNodeDef>;
type Flows = Array<FlowsItem>;

describe("chirpstack-network-server node", () => {
beforeEach((done) => {
testHelper.startServer(done);
});

afterEach((done) => {
testHelper.unload().then(() => {
testHelper.stopServer(done);
});
});

it("should be loaded", (done) => {
const flows: Flows = [
{
id: "n1",
type: "chirpstack-network-server",
name: "chirpstack-network-server",
},
];
testHelper.load(chirpstackNetworkServerNode, flows, () => {
const n1 = testHelper.getNode("n1");
expect(n1).toBeTruthy();
expect(n1.name).toEqual("chirpstack-network-server");
done();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const nodeInit: NodeInitializer = (RED): void => {
): void {
RED.nodes.createNode(this, config);
this.chirpstackConnection = setConnection(this, config, RED);
this.on("input", () => {
this.chirpstackConnection = setConnection(this, config, RED);
});

switch (config.action) {
case "list":
Expand Down
50 changes: 32 additions & 18 deletions src/nodes/chirpstack-connection/chirpstack-connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,38 @@ const nodeInit: NodeInitializer = (RED): void => {
loginRequest.setEmail(this.username);
loginRequest.setPassword(this.password);
// Send the login request
internalServiceClient.login(loginRequest, (error, response) => {
// Build a gRPC metadata object, setting the authorization key to the JWT we
// got back from logging in.
if (error) {
this.error(
"Error on connection for Chirpstack application " +
this.host +
": " +
error
);
throw error;
}
if (!response) {
this.error("Received empty response from Chirpstack");
throw new Error("emptyResponse");
}
this.grpcMetadata = new grpc.Metadata();
this.grpcMetadata.set("authorization", "Bearer " + response.getJwt());
new Promise((resolve) => {
internalServiceClient.login(loginRequest, (error, response) => {
// Build a gRPC metadata object, setting the authorization key to the JWT we
// got back from logging in.
if (error) {
this.error(
"Error on connection for Chirpstack application " +
this.host +
": " +
error
);
this.throwError = error.code + " : " + error.message;
return resolve;
// throw error;
} else {
if (!response) {
this.error("Received empty response from Chirpstack");
this.throwError = "Received empty response from Chirpstack";
// throw new Error("emptyResponse");
return resolve;
} else {
this.grpcMetadata = new grpc.Metadata();
this.grpcMetadata.set(
"authorization",
"Bearer " + response.getJwt()
);
return resolve;
}
}
});
}).then(() => {
return;
});
}

Expand Down
1 change: 1 addition & 0 deletions src/nodes/chirpstack-connection/modules/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface ChirpstackConnectionNode
ChirpstackConnectionOptions {
fullAddress: string;
grpcMetadata: grpc.Metadata;
throwError: string;
}

// export type ChirpstackConnectionNode = Node;
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const nodeInit: NodeInitializer = (RED): void => {
): void {
RED.nodes.createNode(this, config);
this.chirpstackConnection = setConnection(this, config, RED);
this.on("input", () => {
this.chirpstackConnection = setConnection(this, config, RED);
});

switch (config.action) {
case "list":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const nodeInit: NodeInitializer = (RED): void => {
): void {
RED.nodes.createNode(this, config);
this.chirpstackConnection = setConnection(this, config, RED);
this.on("input", () => {
this.chirpstackConnection = setConnection(this, config, RED);
});

switch (config.action) {
case "list":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const nodeInit: NodeInitializer = (RED): void => {
): void {
RED.nodes.createNode(this, config);
this.chirpstackConnection = setConnection(this, config, RED);
this.on("input", () => {
this.chirpstackConnection = setConnection(this, config, RED);
});

switch (config.action) {
case "list":
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script type="text/html" data-template-name="chirpstack-network-server">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-connection"><i class="fa fa-desktop"></i> Connection</label>
<input type="text" id="node-input-connection">
</div>
<div class="form-row">
<label for="node-input-action"><i class="fa fa-download"></i> Action</label>
<select id="node-input-action">
<option value="createMacReq">Create Mac Request</option>
</select>
</div>
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<script type="text/html" data-help-name="chirpstack-network-server">
<p>Node description goes here.</p>
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { EditorRED } from "node-red";
import { ChirpstackNetworkServerEditorNodeProperties } from "./modules/types";

declare const RED: EditorRED;

RED.nodes.registerType<ChirpstackNetworkServerEditorNodeProperties>(
"chirpstack-network-server",
{
category: "chirpstack",
color: "#2094f3",
defaults: {
connection: { value: "", type: "chirpstack-connection" },
name: { value: "" },
action: { value: "createMacReq" },
},
inputs: 1,
outputs: 1,
icon: "chirpstack.png",
paletteLabel: "ChirpStack network server requests",
label() {
return this.name || "ChirpStack network server requests";
},
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { EditorNodeProperties } from "node-red";
import { ChirpstackNetworkServerOptions } from "../../shared/types";

export interface ChirpstackNetworkServerEditorNodeProperties
extends EditorNodeProperties,
ChirpstackNetworkServerOptions {}
79 changes: 79 additions & 0 deletions src/nodes/chirpstack-network-server/chirpstack-network-server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { NodeInitializer } from "node-red";
import {
ChirpstackNetworkServerNode,
ChirpstackNetworkServerNodeDef,
} from "./modules/types";
import { setConnection } from "../shared/setConnection";
import grpc from "grpc";
import { CreateMACCommandQueueItemRequest } from "@chirpstack/chirpstack-api/ns/ns_pb";
import { NetworkServerServiceClient } from "@chirpstack/chirpstack-api/ns/ns_grpc_pb";

const nodeInit: NodeInitializer = (RED): void => {
function ChirpstackNetworkServerNodeConstructor(
this: ChirpstackNetworkServerNode,
config: ChirpstackNetworkServerNodeDef
): void {
RED.nodes.createNode(this, config);
this.chirpstackConnection = setConnection(this, config, RED);
this.on("input", () => {
this.chirpstackConnection = setConnection(this, config, RED);
});

switch (config.action) {
case "createMacReq":
createMacRequest(this);
break;
default:
this.on("input", (msg, send, done) => {
this.error("no action selected");
msg.payload = undefined;
send(msg);
done();
});
break;
}
}

function createMacRequest(node: ChirpstackNetworkServerNode): void {
node.on("input", (msg, send, done) => {
const createMACCommandQueueItemRequest = new CreateMACCommandQueueItemRequest();
//eslint-disable-next-line @typescript-eslint/no-explicit-any
const inputParams: any = msg.payload;

createMACCommandQueueItemRequest.setCid(inputParams.cid); // number
createMACCommandQueueItemRequest.setCommandsList(
inputParams.commandsList
); // [string]
createMACCommandQueueItemRequest.setDevEui(inputParams.devEui); // string
//createMACCommandQueueItemRequest.setExtension()

new NetworkServerServiceClient(
node.chirpstackConnection.fullAddress,
grpc.credentials.createInsecure()
).createMACCommandQueueItem(
createMACCommandQueueItemRequest,
node.chirpstackConnection.grpcMetadata,
null,
(error, emptyResponse) => {
if (error) {
node.error(error);
msg.payload = error;
send(msg);
done();
return;
}
msg.payload = emptyResponse?.toObject();
send(msg);
done();
}
);
});
}

RED.nodes.registerType(
"chirpstack-network-server",
ChirpstackNetworkServerNodeConstructor
);
};

export = nodeInit;
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/nodes/chirpstack-network-server/modules/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ChirpstackBaseNode, ChirpstackBaseNodeDef } from "../../shared/types";
import { ChirpstackNetworkServerOptions } from "../shared/types";

export interface ChirpstackNetworkServerNodeDef
extends ChirpstackBaseNodeDef,
ChirpstackNetworkServerOptions {}

// export interface ChirpstackNetworkServerNode extends ChirpstackBaseNode {}
export type ChirpstackNetworkServerNode = ChirpstackBaseNode;
4 changes: 4 additions & 0 deletions src/nodes/chirpstack-network-server/shared/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface ChirpstackNetworkServerOptions {
connection: string;
action: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const nodeInit: NodeInitializer = (RED): void => {
): void {
RED.nodes.createNode(this, config);
this.chirpstackConnection = setConnection(this, config, RED);
this.on("input", () => {
this.chirpstackConnection = setConnection(this, config, RED);
});

switch (config.action) {
case "list":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ const nodeInit: NodeInitializer = (RED): void => {
): void {
RED.nodes.createNode(this, config);
this.chirpstackConnection = setConnection(this, config, RED);
this.on("input", () => {
this.chirpstackConnection = setConnection(this, config, RED);
});

switch (config.action) {
case "list":
listAllUsers(this);
Expand Down
Loading

0 comments on commit b09bbcf

Please sign in to comment.