The gateways module is the central API of the Weble IoT Universal Gateway. It exposes everything needed to read and write values, manage gateway instances, addresses, and routes, listen to live events, and call driver-specific methods.
It is loaded with:
peer('supervision').require('gateways', function(err, gateways){
// ... gateways.<method>(...)
})
Every method follows the standard Node.js convention: the last argument is a callback(err, ...results).
Most methods accept an address key as their first argument. An address key can be any of:
| Form | Example | Notes |
|---|---|---|
| Numeric id | 23055 |
The internal SQL id of the address. Fastest. |
| Alias | 'tempLivingRoom' |
The alias defined on the address. |
| Name | '4/7/25' |
The protocol-specific address name (KNX group address, Modbus register, BACnet object id, ...). Must be unique across all gateways. |
| Object | {id: 23055} |
An object with at least an id property — typically an address object you got from another call. |
The same flexibility applies to gateway keys: numeric id, name, or {id} object.
writeValue(addressKey, value, callback)Write a decoded value to the address. The driver translates the value into the protocol-specific representation and emits it.
gateways.writeValue('4/7/25', 1, function(err){
if(err) console.error('write failed', err)
})
gateways.writeValue('tempSetpoint', 21.5, function(err){ ... })
gateways.writeValue(23055, true, function(err){ ... })
| Param | Type | Description |
|---|---|---|
addressKey |
key | Address to write to |
value |
number / string / boolean / object | Decoded value, must match what the driver accepts (see acceptsWrite) |
callback |
function(err) |
Called once the write has been acknowledged by the driver |
The callback is invoked after the driver confirms the write — for protocols with no acknowledgement (e.g. KNX broadcast), it is invoked as soon as the frame has been queued.
REST equivalent:
POST /peers/gateways/writeValue— see REST peers dispatcher.
readValue(addressKey, callback)Trigger an active read request to the driver. Use this when you want fresh data and not just the last cached value.
gateways.readValue('%M1', function(err, value, value_string, value_date){
if(err) return console.error(err)
console.log('M1 =', value, '(', value_string, ') updated at', value_date)
})
The callback receives (err, value, value_string, value_date).
REST equivalent:
GET /peers/gateways/readValue?address=...
getLastValue(addressKey, callback)Return the last cached value without sending a read request to the driver. Much faster than readValue and the recommended way to query state for dashboards, logic conditions, etc.
gateways.getLastValue('4/7/25', function(err, value, value_string, value_date){
console.log(value)
})
// Batch lookup with an array
gateways.getLastValue(['4/7/25', '4/7/26', 'tempLiving'], function(err, values, value_strings, value_dates){
console.log(values) // [1, 0, 21.5]
})
When the address does not exist or no value has been received yet, err is set and value is undefined.
REST equivalent:
GET /peers/gateways/getLastValue?address=...
getLastStatus(addressKey, callback)Same as getLastValue but returns the address status instead of the value (e.g. "ok", "error", "timeout", …). Useful for health monitoring.
gateways.getLastStatus('4/7/25', function(err, status){ ... })
acceptsRead(gatewayId, addressName, callback)Check whether a given address is readable on a given gateway. Returns a boolean in the callback.
acceptsWrite(gatewayId, addressKey, value, callback)Check whether a given value can be written to an address before actually doing it. Returns a boolean in the callback. Use this for input validation in user interfaces.
decodeValue(addressKey, value_string, callback) / encodeValue(addressKey, value, callback)Convert between string and decoded representations of a value, using the driver's encoder/decoder. Useful when accepting user input from a form.
gateways.decodeValue('4/7/25', '21.5°C', function(err, decoded){ ... })
gateways.encodeValue('4/7/25', 21.5, function(err, asString){ ... })
The gateways module emits events whenever an address value changes. The standard pattern:
function onValue(addressId, value, value_string, value_date){
console.log('changed:', addressId, value)
}
// Listen to one specific address
gateways.on('newValue 4/7/25', onValue)
// Listen to ALL addresses (use sparingly — high traffic)
gateways.on('newValue', onValue)
// Stop listening
gateways.removeListener('newValue 4/7/25', onValue)
Other lifecycle events emitted by the module:
| Event | Arguments | Description |
|---|---|---|
newValue / newValue <addressKey> |
(id, value, value_string, value_date) |
Address value changed |
newValueLog |
(id, value, value_string, value_date) |
Same, after the logger has persisted it |
gatewayState <gatewayId> |
(state) |
Gateway connection state changed ('connected', 'disconnected', 'error', …) |
addressInserted |
(address) |
New address created |
addressUpdated |
(newAddress, oldAddress) |
Address modified |
addressDeleted |
(address) |
Address removed |
gatewayInserted / gatewayUpdated / gatewayDeleted |
(gateway) |
Gateway lifecycle |
routeInserted / routeUpdated / routeDeleted |
(route, index) |
Route lifecycle |
routeError |
(routeId, type, message, fname) |
Route execution failed |
isRoutingPaused / isRoutingStarted |
(state) |
Routing engine state |
Always pair
on()withremoveListener()when your code path is no longer interested in the event. See the memory leak rule.
getGateways(filter, callback)Return all gateway instances as an object keyed by gateway id. The optional filter is a function (gateway) => boolean applied locally on each candidate.
gateways.getGateways(function(err, gws){
Object.keys(gws).forEach(function(id){
console.log(id, gws[id].name, gws[id].driver)
})
})
// Only Modbus gateways
gateways.getGateways(function(gw){ return gw.driver === 'modbus' }, function(err, gws){ ... })
REST equivalent:
GET /peers/gateways/getGateways
getGateway(gatewayKey, callback)Return a single gateway by id, name, or object.
gateways.getGateway(12, function(err, gw){
console.log(gw.name, gw.driver, gw.json)
})
REST equivalent:
GET /peers/gateways/getGateway?gateway=12
insertGateway(gateway, callback) / updateGateway(gateway, callback) / deleteGateway(gatewayKey, callback)Create, modify, or delete a gateway instance.
gateways.insertGateway({
name : 'Boiler Modbus',
driver : 'modbus',
description : 'TCP gateway to the basement boiler',
json : {
host : '192.168.1.50',
port : 502,
unit : 1
}
}, function(err, newId){
console.log('created gateway id =', newId)
})
The structure of the json field depends on the driver — see the corresponding driver page for the expected schema, or call getSchema(driverName, callback) to retrieve it programmatically.
startGateway(key, cb) / stopGateway(key, cb) / restartGateway(key, cb)Control the lifecycle of a single gateway process. The driver process is launched, killed, or restarted via PM2.
gateways.restartGateway(12, function(err){
if(err) console.error('restart failed', err)
})
testGateway(gatewayKey, callback)Run the driver's built-in connectivity test against the gateway and return the result. Used by the UI when the user clicks "Test connection".
getCrashLog(gatewayKey, callback) / getStats(callback)Retrieve the last crash dump for a gateway, or aggregated statistics across all gateways (uptime, write/read counts, errors).
getAddresses(filter, callback)Return all addresses as an object keyed by address id. The optional filter is a function (address) => boolean.
gateways.getAddresses(function(err, addrs){
console.log(Object.keys(addrs).length, 'addresses total')
})
// Only KNX addresses on a specific gateway
gateways.getAddresses(function(a){ return a.gateway_id === 12 }, function(err, addrs){ ... })
REST equivalent:
GET /peers/gateways/getAddresses
getAddressesByGateway(gatewayKey, callback)Return only the addresses of one gateway, as an array. More efficient than getAddresses with a filter for large databases — the result is streamed in chunks.
gateways.getAddressesByGateway(12, function(err, addrs){
addrs.forEach(function(a){ console.log(a.name, a.alias) })
})
You can also pass an object to add a secondary filter: {gateway: 12, filter: function(a){...}}.
getAddress(addressKey, callback)Return a single address (or array of addresses) by key.
gateways.getAddress('4/7/25', function(err, addr){
console.log(addr.id, addr.name, addr.alias, addr.value)
})
gateways.getAddress(['4/7/25', '4/7/26'], function(err, addrs){ ... })
insertAddress(address, callback)Create one or more addresses. Pass a single object or an array.
gateways.insertAddress({
name : '4/7/25',
alias : 'tempLivingRoom',
description : 'Living room temperature',
gateway_id : 12,
json : {
dpt : '9.001' // KNX 2-byte float
}
}, function(err, newId){
console.log('inserted address id =', newId)
})
The json field structure is driver-specific. To insert many addresses at once, prefer importAddresses.
You can also pass onduplicatekey: true to update the address if one with the same name already exists on the gateway.
updateAddress(address, callback) / replaceAddress(address, callback)Modify an existing address. updateAddress requires the id field; replaceAddress performs an upsert (update if found, insert otherwise) based on name + gateway_id.
importAddresses(addresses, callback)Bulk-import addresses with throttling. Designed for thousands of addresses without blocking the gateway. The callback is invoked multiple times: once with the progress ratio (0..1) for each chunk, and finally with err = 'end'.
gateways.importAddresses(bigArray, function(err, progress){
if(err === 'end') return console.log('done')
if(err) return console.error(err)
console.log('progress', Math.round(progress * 100), '%')
})
deleteAddress(addressKey, callback)Definitively remove an address (or array of addresses). The callback returns an error if any of them is not found — in batch mode, none is deleted if at least one key is invalid.
A route binds a source address to one or more destination addresses, optionally through a transformation function. Routes are the heart of the gateway's protocol-translation engine.
getRoutes(callback)Return all routes as an array.
gateways.getRoutes(function(err, routes){
routes.forEach(function(r){ console.log(r.id, r.from, '→', r.to) })
})
getRoute(routeIds, callback)Return a single route by id, or an array of routes.
insertRoute(route, index, callback)Insert a new route at the given position (or at the end if index is omitted).
gateways.insertRoute({
from : '4/7/25',
to : '%M1',
type : 'write'
}, function(err, newId){
console.log('inserted route', newId)
})
You can also pass an array of route objects to insert multiple at once.
updateRoute(route, callback) / replaceRoute(routes, callback) / deleteRoute(routeKey, callback)Standard CRUD operations. replaceRoute is an upsert.
moveRoute(routeKey, index, callback)Reorder a route by moving it to a different position in the global routing table.
refreshRoute(routeIds, callback)Re-evaluate a route immediately — useful after changing address metadata that affects routing.
pauseRoutes(callback) / resumeRoutes(callback) / isRoutingPaused(callback)Temporarily suspend the routing engine without unloading routes. Use this for maintenance windows or when running bulk operations that you don't want to trigger downstream effects.
gateways.pauseRoutes(function(){
// do something heavy without triggering routes
gateways.resumeRoutes(function(){ console.log('routing resumed') })
})
startRoutes(callback) / stopRoutes(callback) / isRoutingStarted(callback)Fully start or stop the routing engine. Unlike pause/resume, this unloads route definitions from memory and writes the new state to disk (routingActive flag). Used at boot and during firmware upgrades.
Routing functions are JavaScript snippets you can attach to a route to transform values in transit (e.g. multiply by 10, convert units, dispatch based on the value).
| Method | Description |
|---|---|
getRoutingFunctions(callback) |
List all defined routing functions |
insertRoutingFunction(fundef, callback) |
Add a new routing function |
updateRoutingFunction(fundef, callback) |
Modify a routing function |
replaceRoutingFunction(fundef, callback) |
Upsert |
renameRoutingFunction(oldname, newname, callback) |
Rename and update all routes that reference it |
deleteRoutingFunction(fundefname, callback) |
Remove a routing function |
matchingRoutingFunctions(type, functionsFlat) |
Return functions whose signature matches a given route type |
A fundef object looks like:
{
functionPath : 'utils/multiplyBy10',
type : 'transform',
code : 'function(value){ return value * 10 }'
}
getRoutesGraph(callback) / getRoutesStatus(callback) / getRouteStatus(routeId, callback)Inspect the runtime routing graph (which sources are wired to which destinations) and per-route execution status (last call time, error count, etc.).
getSchema(driverName, callback)Return the JSON schema describing the configuration of a driver — used by the UI to render the gateway configuration form.
gateways.getSchema('modbus', function(err, schema){
console.log(schema.gateway, schema.address)
})
getSchemas(callback) / getSchemasName(callback) / getSchemasStructure(callback)Return all driver schemas, just the names, or a structural overview.
requireDriver(driverName, callback)Load the driver-specific API of a driver. This returns a proxy object whose methods correspond to whatever the driver chose to expose. Use this when you need driver-specific operations that are not part of the generic gateways API.
gateways.requireDriver('knx', function(err, knxApi){
knxApi.scan(function(err, devices){ ... })
})
callGatewayMethod(gatewayKey, methodName, args, callback)Call a custom method exposed by a specific gateway instance (as opposed to a driver class). This is the lower-level dispatcher used internally by the UI's "Driver actions" buttons.
gateways.callGatewayMethod(12, 'rescan', [], function(err, result){ ... })
A view is a saved layout / dashboard configuration tied to one or more gateways.
| Method | Description |
|---|---|
getViews(callback) |
List all views |
getView(viewKey, callback) |
Get one view |
insertView(viewObject, callback) |
Create a new view |
updateView(viewObject, callback) |
Modify a view |
deleteView(viewKey, callback) |
Delete a view |
startView(gatewayKey, viewKey, callback) |
Activate a view on a gateway |
stopView(gatewayKey, viewKey, callback) |
Deactivate it |
getActiveViews(callback) |
List currently active views |
An address object returned by getAddress, getAddresses, getAddressesByGateway, etc. has the following common fields:
| Field | Type | Description |
|---|---|---|
id |
integer | SQL primary key |
name |
string | Protocol-specific address name (unique across all gateways) |
alias |
string | Human-friendly alias (optional, unique if set) |
description |
string | Free-form description |
gateway_id |
integer | Foreign key to the parent gateway |
json |
object | Driver-specific configuration (data point type, register address, polling rate, …) |
value |
any | Last known decoded value (kept in cache, may be undefined) |
value_string |
string | Last known string representation of the value |
value_date |
Date | Timestamp of the last received value |
status |
string | Last known status — 'ok', 'error', 'timeout', … |
The json field's structure depends entirely on the driver. See each driver page for the per-protocol field reference.
| Field | Type | Description |
|---|---|---|
id |
integer | SQL primary key |
name |
string | Display name |
description |
string | Free-form description |
driver |
string | Driver name (e.g. 'modbus', 'bacnet', 'knx') |
cluster |
integer | Cluster identifier (0 for single-gateway setups) |
active |
0 / 1 | Whether the gateway is enabled |
json |
object | Driver-specific configuration (host, port, credentials, …) |
private_json |
object | Internal flags, including authorizedUsers for per-user access control |
gateways.readValue('tempLiving', function(err, value, vs, vd){
if(err) return console.error(err)
console.log('temp =', value)
})
function onChange(id, value){ console.log('temp =', value) }
gateways.on('newValue tempLiving', onChange)
// later:
gateways.removeListener('newValue tempLiving', onChange)
var addrs = parseCsv(file).map(row => ({
name : row.name,
alias : row.alias,
gateway_id : 12,
json : { dpt: row.dpt }
}))
gateways.importAddresses(addrs, function(err, progress){
if(err === 'end') console.log('imported', addrs.length, 'addresses')
else if(err) console.error(err)
else console.log(Math.round(progress*100), '%')
})
gateways.insertRoute({
from : '4/7/25', // KNX
to : '%M1', // Modbus
type : 'write'
}, function(err, id){
console.log('route created:', id)
})
gateways.getGateways(function(gw){ return gw.driver === 'modbus' }, function(err, gws){
var ids = Object.keys(gws)
var i = 0
function next(){
if(i >= ids.length) return console.log('done')
gateways.restartGateway(ids[i++], function(err){
if(err) console.error(ids[i-1], err)
next()
})
}
next()
})