2025-05-26 17:44:56 +02:00
/ * *
* @ file dashboardapi _class . js
*
* Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation files ( the "Software" ) , to use it for personal
* or non - commercial purposes , with the following restrictions :
*
* 1. * * No Copying or Redistribution * * : The Software or any of its parts may not
* be copied , merged , distributed , sublicensed , or sold without explicit
* prior written permission from the author .
*
* 2. * * Commercial Use * * : Any use of the Software for commercial purposes requires
* a valid license , obtainable only with the explicit consent of the author .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE , AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES , OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT , OR OTHERWISE , ARISING FROM ,
* OUT OF , OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE .
*
* Ownership of this code remains solely with the original author . Unauthorized
* use of this Software is strictly prohibited .
*
* @ summary A class for generating dynamic dashboards for system monitoring .
* @ description The Dashboardapi class facilitates the creation and customization
* of Grafana dashboards using JSON templates . It dynamically updates templating values
* based on provided measurement and bucket configurations , enabling seamless integration
* within monitoring environments .
* @ module dashboardapi _class
* @ exports Dashboardapi
* @ version 0.1 . 0
* @ since 0.1 . 0
*
* Author :
* - Rene De Ren
* Email :
* - rene @ thegoldenbasket . nl
*
* Future Enhancements :
* - Incorporate additional dynamic templating capabilities .
* - Add support for more customization options within dashboard configurations .
* /
//A class to interact and manipulate sampling machines
//load local dependencies
const EventEmitter = require ( 'events' ) ;
2025-09-22 16:04:19 +02:00
const Logger = require ( '../../../generalfunctions/helper/logger' ) ;
2025-05-26 17:44:56 +02:00
//load all config modules
const defaultConfig = require ( './dashboardapiConfig.json' ) ;
2025-09-22 16:04:19 +02:00
const ConfigUtils = require ( '../../../generalfunctions/helper/configUtils' ) ;
2025-05-26 17:44:56 +02:00
//load registration utility
2025-09-22 16:04:19 +02:00
const ChildRegistrationUtils = require ( '../../../generalfunctions/helper/childRegistrationUtils' ) ;
2025-05-26 17:44:56 +02:00
class Dashboardapi {
/*------------------- Construct and set vars -------------------*/
constructor ( config = { } ) {
// basic setup
this . emitter = new EventEmitter ( ) ; // Own EventEmitter
this . configUtils = new ConfigUtils ( defaultConfig ) ;
this . config = this . configUtils . initConfig ( config ) ;
this . child = { } ; // object to hold child information so we know on what to subscribe
// Init after config is set
this . logger = new Logger ( this . config . general . logging . enabled , this . config . general . logging . logLevel , this . config . general . name ) ;
}
//how to handle children like the pump on a machine group node? Do we duplicate the information or fetch the names of the registered children en connect them
//to the dashboard?
//this is a question that needs to be answered in the future.
/*------------------- FUNCTIONS -------------------*/
async getDashboard ( softwareType ) {
try {
let response = await fetch ( ` http://localhost:1880/dashboardapi/config/ ${ softwareType } .json ` ) ;
if ( ! response . ok ) {
this . logger . error ( ` Failed to fetch dashboard template: ${ response . statusText } ` ) ;
}
const jsonDashB = await response . json ( ) ;
return jsonDashB ;
} catch ( error ) {
this . logger . error ( ` Failed to fetch dashboard template: ${ error . message } ` ) ;
}
}
//generate dashboards based on the childs connected
async generateDashB ( config ) {
//define file name
const softwareType = config . functionality . softwareType ;
this . logger . debug ( ` Generating dashboard for ${ softwareType } ` ) ;
const jsonDashB = await this . getDashboard ( softwareType ) ;
// Validate templating structure exists
if ( ! jsonDashB . templating ||
! Array . isArray ( jsonDashB . templating . list ) ||
jsonDashB . templating . list . length < 3 ) {
this . logger . error ( "Dashboard JSON templating structure is not as expected." ) ;
throw new Error ( "Invalid dashboard template structure" ) ;
}
const bucketName = "lvl2" ;
const measurementName = config . general . name ;
// Set properties for a new dashboard
jsonDashB . id = null ;
jsonDashB . uid = null ;
jsonDashB . title = measurementName ;
// Update measurement placeholder (using index 1)
const measurementTpl = jsonDashB . templating . list [ 1 ] ;
measurementTpl . current . text = measurementName ;
measurementTpl . current . value = measurementName ;
if ( Array . isArray ( measurementTpl . options ) && measurementTpl . options . length > 0 ) {
measurementTpl . options [ 0 ] . text = measurementName ;
measurementTpl . options [ 0 ] . value = measurementName ;
}
measurementTpl . query = measurementName ;
// Update bucket placeholder (using index 2)
const bucketTpl = jsonDashB . templating . list [ 2 ] ;
bucketTpl . current . text = bucketName ;
bucketTpl . current . value = bucketName ;
if ( Array . isArray ( bucketTpl . options ) && bucketTpl . options . length > 0 ) {
bucketTpl . options [ 0 ] . text = bucketName ;
bucketTpl . options [ 0 ] . value = bucketName ;
}
bucketTpl . query = bucketName ;
const output = {
dashboard : jsonDashB ,
folderId : 0 ,
overwrite : true
} ;
return output ;
}
} // end of class
module . exports = Dashboardapi ;
/ *
//import a child
const Child = require ( '../../../measurement/dependencies/measurement/measurement' ) ;
//const Child = require('../../../rotatingMachine/dependencies/machine/machine');
console . log ( ` Creating child... ` ) ;
const child = new Child ( config = {
general : {
name : "PT1" ,
logging : {
enabled : true ,
logLevel : "debug" ,
} ,
} ,
functionality : {
softwareType : "measurement" ,
} ,
asset : {
type : "sensor" ,
subType : "pressure" ,
} ,
} ) ;
const d = new Dashboardapi ( ) ;
testGen ( ) ;
function testGen ( ) {
d . generateDashB ( child . config ) . then ( ( res ) => {
console . log ( res ) ;
} ) ;
}
//*/