The main worker file (workers/rack.{devicetype}.wrk.js) extends Level 3. For JSDoc annotation standards, see Code Documentation Standards:
A.5. Abstract Methods Contract
Level 4 templates inherit abstract methods from Level 3 that must be implemented by Level 5 workers:
Method
Purpose
Base Behavior
Level 5 Requirement
async connectThing(thg)
Establish connection to physical device
No-op (empty stub)
Implement connection logic; return 0 on failure
async collectThingSnap(thg)
Collect current device state snapshot
Throws ERR_IMPL_UNKNOWN
Must implement; return Object with stats and config
selectThingInfo()
Select device info for API responses
Returns empty object {}
Override to return device-specific details
async disconnectThing(thg)
Gracefully disconnect from device
Calls thg.ctrl.close() if available
Override only if custom cleanup needed
async releaseIpThing(thg)
Release IP/network resources for device
No-op (empty stub)
Override if device requires IP resource cleanup
Note: connectThing is a no-op stub in Level 3. Level 5 implementations should return 0 from connectThing when connection fails to signal the failure to the snapshot collection loop.
Optional Lifecycle Hooks:
Hook
When Called
Base Behavior
async registerThingHook0(thg)
After new device registration
No-op
async updateThingHook0(thg, thgPrev)
After device configuration update
Stores info changes to DB
async forgetThingHook0(thg)
Before device removal
No-op
async setupThingHook0(thg)
During device setup/loading
No-op
async setupThingHook1(thg)
After loading last state from DB
No-op
async collectSnapsHook0()
After snapshot collection cycle
No-op
async tailLogHook0(logs, req)
During log tail operations
No-op
Optional Extension Methods:
Method
Purpose
Base Behavior
_getWrkExtData(args)
Provide custom worker extension data for getWrkExtData RPC
Returns empty object {}
A.6. Statistics Timeframe Configuration
Level 4 templates can configure additional statistics collection timeframes through two mechanisms:
Code-Defined Timeframes (scheduleAddlStatTfs)
Set in the init() method for timeframes that are integral to the device type:
Level 4 templates must provide testing infrastructure that Level 5 implementations inherit. Test files must use the .spec.js extension to match the glob pattern in package.json. For complete testing guidelines, see Testing & Linting Guidelines.
tests/utils.js
tests/{devicetype}.spec.js
A.9. Worker Entry Point
worker.js
A.10. Level 4 Checklist
Level 4 - Create a Device Type Template Worker
Level 4 workers define device category templates that serve as abstract bases for brand-specific implementations.
miningos-tpl-wrk-powermeter — Power monitoring equipment
miningos-tpl-wrk-miner — Mining hardware
miningos-tpl-wrk-sensor — Environmental sensors
miningos-tpl-wrk-container — Mining containers or racks
The tpl (template) designation distinguishes Level 4 workers from concrete implementations.
A.2. Directory Structure
A Level 4 template repository must follow this structure:
A.3. Package.json Structure
To create a package.json file for a Level 4 template:
Open a text editor and create the following JSON structure:
Replace {devicetype} with your specific device category (e.g., powermeter).
Update the author and maintainers fields with your information.
Save the file as package.json in your repository root.
A.4. Main Template Worker Implementation
The main worker file (workers/rack.{devicetype}.wrk.js) extends Level 3: To implement the main worker file:
Create the file at workers/rack.{devicetype}.wrk.js.
Add the following structure, replacing {DeviceType} with your device category (e.g., PowerMeter):
A.5. Abstract Methods Contract
Level 4 templates inherit abstract methods from Level 3 that must be implemented by Level 5 workers:
Method
Purpose
Base Behavior
Level 5 Requirement
async connectThing(thg)
Establish connection to physical device
No-op (empty stub)
Implement connection logic; return 0 on failure
async collectThingSnap(thg)
Collect current device state snapshot
Throws ERR_IMPL_UNKNOWN
Must implement; return Object with stats and config
selectThingInfo()
Select device info for API responses
Returns empty object {}
Override to return device-specific details
async disconnectThing(thg)
Gracefully disconnect from device
Calls thg.ctrl.close() if available
Override only if custom cleanup needed
async releaseIpThing(thg)
Release IP/network resources for device
No-op (empty stub)
Override if device requires IP resource cleanup
Note: connectThing is a no-op stub in Level 3. Level 5 implementations should return 0 from connectThing when connection fails to signal the failure to the snapshot collection loop.
Optional Lifecycle Hooks:
Hook
When Called
Base Behavior
async registerThingHook0(thg)
After new device registration
No-op
async updateThingHook0(thg, thgPrev)
After device configuration update
Stores info changes to DB
async forgetThingHook0(thg)
Before device removal
No-op
async setupThingHook0(thg)
During device setup or loading
No-op
async setupThingHook1(thg)
After loading last state from DB
No-op
async collectSnapsHook0()
After snapshot collection cycle
No-op
async tailLogHook0(logs, req)
During log tail operations
No-op
Optional Extension Methods:
Method
Purpose
Base Behavior
_getWrkExtData(args)
Provide custom worker extension data for getWrkExtData RPC
Returns empty object {}
A.6. Statistics Timeframe Configuration
Level 4 templates can configure additional statistics collection timeframes through two mechanisms:
Code-Defined Timeframes (scheduleAddlStatTfs)
Set in the init() method for timeframes that are integral to the device type:
In your main worker file, modify the init() method:
Set in base.thing.json for operator-customizable timeframes:
Edit your config/base.thing.json.example file:
Both arrays are merged with the default timeframes from miningos-lib-stats during startup.
A.7. Configuration Templates
base.thing.json.example
Create or edit the config/base.thing.json.example file:
Replace {devicetype} with your device category.
common.json.example
Create the config/common.json.example file:
A.8. Testing Infrastructure
Level 4 templates must provide testing infrastructure that Level 5 implementations inherit. Test files must use the .spec.js extension to match the glob pattern in package.json.
tests/utils.js
To extend the parent test infrastructure:
Create tests/utils.js:
tests/{devicetype}.spec.js
To create the main test file create a tests/{devicetype}.spec.js file:
'use strict'
const WrkRack = require('miningos-tpl-wrk-thing/workers/rack.thing.wrk')
class Wrk{DeviceType}Rack extends WrkRack {
/**
* Initialize the template worker.
* Configure device-category-specific scheduling and facilities.
*/
init () {
super.init()
// Configure additional statistics timeframes via code (optional)
// Example: Real-time data collection every 5 seconds
this.scheduleAddlStatTfs = [
['rtd', '*/5 * * * * *'] // Cron format: second granularity
]
// Note: Additional timeframes can also be configured via config file
// using `scheduleAddlStatConfigTfs` in base.thing.json
}
/**
* Returns the base type identifier for this device category.
* Level 5 implementations extend this with brand suffix.
* @returns {string} Device type identifier
*/
getThingType () {
return '{devicetype}' // e.g., 'powermeter', 'miner', 'sensor'
}
/**
* Returns the base type for statistics aggregation.
* Used by the stats system to group metrics.
* @returns {string} Base type identifier
*/
_getThingBaseType () {
return '{devicetype}'
}
/**
* Returns category-specific tags applied to all devices.
* @returns {string[]} Array of tag strings
*/
getSpecTags () {
return ['{devicetype}']
}
}
module.exports = Wrk{DeviceType}Rack
'use strict'
const WrkRack = require('miningos-tpl-wrk-thing/workers/rack.thing.wrk')
class Wrk{DeviceType}Rack extends WrkRack {
/**
* Initialize the template worker.
* Configure device-category-specific scheduling and facilities.
*/
init () {
super.init()
// Configure additional statistics timeframes via code (optional)
// Example: Real-time data collection every 5 seconds
this.scheduleAddlStatTfs = [
['rtd', '*/5 * * * * *'] // Cron format: second granularity
]
// Note: Additional timeframes can also be configured via config file
// using `scheduleAddlStatConfigTfs` in base.thing.json
}
/**
* Returns the base type identifier for this device category.
* Level 5 implementations extend this with brand suffix.
* @returns {string} Device type identifier
*/
getThingType () {
return '{devicetype}' // e.g., 'powermeter', 'miner', 'sensor'
}
/**
* Returns the base type for statistics aggregation.
* Used by the stats system to group metrics.
* @returns {string} Base type identifier
*/
_getThingBaseType () {
return '{devicetype}'
}
/**
* Returns category-specific tags applied to all devices.
* @returns {string[]} Array of tag strings
*/
getSpecTags () {
return ['{devicetype}']
}
}
module.exports = Wrk{DeviceType}Rack