Skip to content

Commit

Permalink
Add in-tree Bacnet driver (#344)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexGodbehere authored Sep 19, 2024
1 parent 45407a9 commit 98a2b1f
Show file tree
Hide file tree
Showing 8 changed files with 665 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ jobs:
- acs-edge
- edge-modbus
- edge-test
- edge-bacnet
permissions:
contents: read
packages: write
Expand Down
2 changes: 2 additions & 0 deletions edge-bacnet/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
tmp
33 changes: 33 additions & 0 deletions edge-bacnet/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# syntax=docker/dockerfile:1

FROM node:22-alpine AS build
ARG acs_npm=NO
ARG revision=unknown

USER root
RUN <<'SHELL'
install -d -o node -g node /home/node/app
SHELL
WORKDIR /home/node/app
USER node
COPY package*.json ./
RUN <<'SHELL'
touch /home/node/.npmrc
if [ "${acs_npm}" != NO ]
then
npm config set @amrc-factoryplus:registry "${acs_npm}"
fi

npm install --save=false
SHELL
COPY --chown=node . .
RUN <<'SHELL'
echo "export const GIT_VERSION=\"$revision\";" > ./lib/git-version.js
SHELL

FROM node:22-alpine AS run
# Copy across from the build container.
WORKDIR /home/node/app
COPY --from=build --chown=root:root /home/node/app ./
USER node
CMD node bin/driver.js
6 changes: 6 additions & 0 deletions edge-bacnet/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
top=..
include ${top}/mk/acs.init.mk

repo?=edge-bacnet

include ${mk}/acs.js.mk
14 changes: 14 additions & 0 deletions edge-bacnet/bin/driver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* AMRC Connectivity Stack
* Modbus Edge Agent driver
* Copyright 2024 AMRC
*/

import { PolledDriver } from "@amrc-factoryplus/edge-driver";
import { BacnetHandler } from "../lib/bacnet.js";

const drv = new PolledDriver({
env: process.env,
handler: BacnetHandler,
serial: true,
});
drv.run();
83 changes: 83 additions & 0 deletions edge-bacnet/lib/bacnet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* AMRC Connectivity Stack
* Modbus Edge Agent driver
* Copyright 2024 AMRC
*/

import bacnet from 'node-bacnet';
import { BufferX } from '@amrc-factoryplus/edge-driver'

export class BacnetHandler {
constructor (driver, conf) {
this.driver = driver
this.conf = conf
this.log = driver.debug.bound('bacnet')

const {
listenInterface,
port,
broadcastAddress,
apduTimeout,
} = conf

this.client = new bacnet({
port: port,
interface: listenInterface,
broadcastAddress: broadcastAddress,
apduTimeout: apduTimeout,
})
}

static create (driver, conf) {
return new BacnetHandler(driver, conf)
}

connect () {
// This is a stateless protocol, so we don't need to wait for
// the connection to be established
return 'UP'
}

parseAddr (spec) {

const parts = spec.split(',')

// If there are three parts, then the last one is the propertyID. If
// it is missing then the propertyId is 85

const type = Number.parseInt(parts[0])
if (Number.isNaN(type) || type < 0) return

const instance = Number.parseInt(parts[1])
if (Number.isNaN(instance) || instance < 0) return

const propertyId = Number.parseInt(parts[2] || '85')

return {
type,
instance,
propertyId,
}
}

async poll (addr) {
const { client } = this

return new Promise((resolve, reject) => {

// XXX - It would be nice to support readPropertyMultiple in the
// future when the driver library supports it
client.readProperty(this.conf.host, {
type: addr.type,
instance: addr.instance,
}, addr.propertyId, (err, value) => {
if (err) {
resolve(undefined)
}
else {
const buffer = BufferX.fromJSON(value.values[0])
resolve(buffer)
}
})
})
}
}
Loading

0 comments on commit 98a2b1f

Please sign in to comment.