/** * @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'); const Logger = require('../../../generalFunctions/helper/logger'); //load all config modules const defaultConfig = require('./dashboardapiConfig.json'); const ConfigUtils = require('../../../generalFunctions/helper/configUtils'); //load registration utility const ChildRegistrationUtils = require('../../../generalFunctions/helper/childRegistrationUtils'); 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); }); } //*/