Hook Programming Guide¶
This is a programming guide for writing hooks. See full JavaScript Hooks SDK API reference here.
Hook Signature¶
A hook has the following function signature (see: InvokeFn). An InvokeParams object with the below properties is passed into each invocation of a hook. A conventional way to access the params that the hooks needs is through destructuring the params object.
module.exports = async ({
points,
sdk,
groupVariables,
globalVariables,
config,
args,
}) => {
// access destructured params in function body
};
points¶
Selected points for this hook in the form of a queryable interface, ResultSet. If grouping has been specified in the hook configuration, this will the points for the group.
Each item in the ResultSet is a Point object.
module.exports = async ({ points, sdk, config, args }) => {
// points has all the native JavaScript array methods
console.log(points.length); // 10
// there are also additional methods for selecting points
const AirFlowSetpoint = points.byLabel("discharge-air-flow-sp").first();
const Floor2Points = points.where((p) => p.attrs.spaceRef === "Floor 2");
};
Points also have a latestValue
property that exposed the current value of the point
module.exports = async ({ points, sdk, config, args }) => {
const DamperPosition = points.byLabel("damper-sensor").first();
DamperPosition.latestValue.value; // last value as integer
DamperPosition.latestValue.value; // last value as integer
DamperPosition.latestValue.ts; // timestamp of latest value
};
To query if the latest value was changed since the last invocation, use the isChanged()
method
module.exports = async ({ points, sdk, config, args }) => {
const DamperPosition = points.byLabel("damper-sensor").first();
const isChanged = DamperPosition.isChanged();
};
Points have a method called trueFor
to check how long a point value has been in a certain condition. This is helpful for writing control logic.
module.exports = async ({ points }) => {
const DamperPosition = points.byLabel("damper-sensor").first();
const damperHigh = await DamperPosition.trueFor(
"1m",
(v) => Number(v.value) > 95
);
};
Command reads and writes can be made by using methods on the point object. If the hook is configured to use a command contest, writes made with this API will automatically be associated with that groups' context.
module.exports = async ({ points }) => {
const DischargeAirTempSP = points
.byLabel("discharge-air-temp-setpoint")
.first();
// read
const [initialValue, readError] = await DischargeAirTempSP.read();
// write
const [success, writeError] = await DischargeAirTempSP.write({ real: 70 });
};
Variables¶
Variables provide the ability to acess state across hook runs. Variables are defined in the hook configuration. Additionally, variables are backed by a Point object, and can be updated internally, or set over Bacnet.
groupVariables¶
Group variables are scoped to a hook group. An instance of a variable with the same properties is created for each group invocation of the hook. This enables the user to write reusable logic across groups.
The easiest way to query a variable is by it's label.
module.exports = async ({ groupVariables }) => {
// this is a different variable for each group
const DamperLoop = groupVariables.byLabel("inDamperLoop");
};
globalVariables¶
Global variables are scoped to the hook itself. The same instance of a global variable is passed into each hook group.
module.exports = async ({ globalVariables }) => {
// this is the same variable for all groups
const DamperLoop = globalVariables.byLabel("minSetpoint");
};
config¶
Configuration options for the application.
module.exports = async ({ config }) => {
const apiUrl = config["apiUrl"];
};
args¶
Args (if any) for this function invocation (mostly used in “On Request” run mode when invoked from the Normal API)
module.exports = async ({ config }) => {
const startingTemp = args["startingTemp"];
};
sdk¶
An instance of the Normal Applications SDK (i.e. RunParams) configured for this hook.
sdk.groupKey¶
The key of the current group (if grouping is not specified, this is an empty string)
module.exports = async ({ sdk }) => {
const group = sdk.groupKey;
};
sdk.logEvent¶
Write to the event log. This message will show up the in integrated console and also in the run logs.
module.exports = async ({ sdk }) => {
sdk.logEvent("Something happened");
};
sdk.http¶
An Axios client for accessing the Normal HTTP API. This Axios instance is configured to point to the internal Normal API, and will also automatically authenticate itself based on the Application authentication settings.
module.exports = async ({ sdk }) => {
const commands = await sdk.http(
"/api/v2/command"
);
};
sdk.sleep¶
Pause execution for a given number of milliseconds
module.exports = async ({ sdk }) => {
await sdk.sleep(2000);
};