diff --git a/server/_widgets/dynamicSVG/blower3.svg b/server/_widgets/dynamicSVG/blower3.svg
new file mode 100644
index 00000000..7d819d78
--- /dev/null
+++ b/server/_widgets/dynamicSVG/blower3.svg
@@ -0,0 +1,260 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ //document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', lightColor);
+ //});
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/blower4.svg b/server/_widgets/dynamicSVG/blower4.svg
new file mode 100644
index 00000000..8e26d33f
--- /dev/null
+++ b/server/_widgets/dynamicSVG/blower4.svg
@@ -0,0 +1,282 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/checkvalve_closed.svg b/server/_widgets/dynamicSVG/checkvalve_closed.svg
new file mode 100644
index 00000000..8f343fff
--- /dev/null
+++ b/server/_widgets/dynamicSVG/checkvalve_closed.svg
@@ -0,0 +1,311 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/checkvalve_open.svg b/server/_widgets/dynamicSVG/checkvalve_open.svg
new file mode 100644
index 00000000..d5c58db1
--- /dev/null
+++ b/server/_widgets/dynamicSVG/checkvalve_open.svg
@@ -0,0 +1,294 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/compressor3.svg b/server/_widgets/dynamicSVG/compressor3.svg
new file mode 100644
index 00000000..f6956749
--- /dev/null
+++ b/server/_widgets/dynamicSVG/compressor3.svg
@@ -0,0 +1,339 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/compressor6.svg b/server/_widgets/dynamicSVG/compressor6.svg
new file mode 100644
index 00000000..c7bf6b13
--- /dev/null
+++ b/server/_widgets/dynamicSVG/compressor6.svg
@@ -0,0 +1,277 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/condensor_3d_h1.svg b/server/_widgets/dynamicSVG/condensor_3d_h1.svg
new file mode 100644
index 00000000..fbb2dd84
--- /dev/null
+++ b/server/_widgets/dynamicSVG/condensor_3d_h1.svg
@@ -0,0 +1,278 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/conveyor.svg b/server/_widgets/dynamicSVG/conveyor.svg
new file mode 100644
index 00000000..b303d025
--- /dev/null
+++ b/server/_widgets/dynamicSVG/conveyor.svg
@@ -0,0 +1,294 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/conveyor4.svg b/server/_widgets/dynamicSVG/conveyor4.svg
new file mode 100644
index 00000000..67182fc3
--- /dev/null
+++ b/server/_widgets/dynamicSVG/conveyor4.svg
@@ -0,0 +1,292 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/conveyor_20degdecline.svg b/server/_widgets/dynamicSVG/conveyor_20degdecline.svg
new file mode 100644
index 00000000..c8606502
--- /dev/null
+++ b/server/_widgets/dynamicSVG/conveyor_20degdecline.svg
@@ -0,0 +1,319 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/conveyor_20degincline.svg b/server/_widgets/dynamicSVG/conveyor_20degincline.svg
new file mode 100644
index 00000000..b337e585
--- /dev/null
+++ b/server/_widgets/dynamicSVG/conveyor_20degincline.svg
@@ -0,0 +1,318 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/cyclonicseparator.svg b/server/_widgets/dynamicSVG/cyclonicseparator.svg
new file mode 100644
index 00000000..27c3a93b
--- /dev/null
+++ b/server/_widgets/dynamicSVG/cyclonicseparator.svg
@@ -0,0 +1,295 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ //document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', darkColor);
+ //});
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/fanblades.svg b/server/_widgets/dynamicSVG/fanblades.svg
new file mode 100644
index 00000000..1ddcf968
--- /dev/null
+++ b/server/_widgets/dynamicSVG/fanblades.svg
@@ -0,0 +1,258 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ //document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', darkColor);
+ //});
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ //document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', lightColor);
+ //});
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/flange_3d_1.svg b/server/_widgets/dynamicSVG/flange_3d_1.svg
new file mode 100644
index 00000000..357f42d4
--- /dev/null
+++ b/server/_widgets/dynamicSVG/flange_3d_1.svg
@@ -0,0 +1,264 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/flowmeter.svg b/server/_widgets/dynamicSVG/flowmeter.svg
new file mode 100644
index 00000000..1b5fd3b4
--- /dev/null
+++ b/server/_widgets/dynamicSVG/flowmeter.svg
@@ -0,0 +1,283 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ //document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', darkColor);
+ //});
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/flowmeter1.svg b/server/_widgets/dynamicSVG/flowmeter1.svg
new file mode 100644
index 00000000..f519a3bf
--- /dev/null
+++ b/server/_widgets/dynamicSVG/flowmeter1.svg
@@ -0,0 +1,259 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/gaugedial_3d_h1.svg b/server/_widgets/dynamicSVG/gaugedial_3d_h1.svg
new file mode 100644
index 00000000..4ea16474
--- /dev/null
+++ b/server/_widgets/dynamicSVG/gaugedial_3d_h1.svg
@@ -0,0 +1,266 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/generator_1.svg b/server/_widgets/dynamicSVG/generator_1.svg
new file mode 100644
index 00000000..bb89b2f5
--- /dev/null
+++ b/server/_widgets/dynamicSVG/generator_1.svg
@@ -0,0 +1,512 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/heatexchanger_pipetopipe.svg b/server/_widgets/dynamicSVG/heatexchanger_pipetopipe.svg
new file mode 100644
index 00000000..8b40c5c2
--- /dev/null
+++ b/server/_widgets/dynamicSVG/heatexchanger_pipetopipe.svg
@@ -0,0 +1,307 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/heatexchanger_shelltube.svg b/server/_widgets/dynamicSVG/heatexchanger_shelltube.svg
new file mode 100644
index 00000000..91db9d02
--- /dev/null
+++ b/server/_widgets/dynamicSVG/heatexchanger_shelltube.svg
@@ -0,0 +1,307 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/heatexchanger_singlepipetopipe.svg b/server/_widgets/dynamicSVG/heatexchanger_singlepipetopipe.svg
new file mode 100644
index 00000000..5b56b084
--- /dev/null
+++ b/server/_widgets/dynamicSVG/heatexchanger_singlepipetopipe.svg
@@ -0,0 +1,277 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/meter_3d_h1.svg b/server/_widgets/dynamicSVG/meter_3d_h1.svg
new file mode 100644
index 00000000..fea5176d
--- /dev/null
+++ b/server/_widgets/dynamicSVG/meter_3d_h1.svg
@@ -0,0 +1,277 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/meter_3d_h2.svg b/server/_widgets/dynamicSVG/meter_3d_h2.svg
new file mode 100644
index 00000000..126b69c2
--- /dev/null
+++ b/server/_widgets/dynamicSVG/meter_3d_h2.svg
@@ -0,0 +1,271 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/mixer1.svg b/server/_widgets/dynamicSVG/mixer1.svg
new file mode 100644
index 00000000..ff07da48
--- /dev/null
+++ b/server/_widgets/dynamicSVG/mixer1.svg
@@ -0,0 +1,347 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/motor.svg b/server/_widgets/dynamicSVG/motor.svg
new file mode 100644
index 00000000..a27c1131
--- /dev/null
+++ b/server/_widgets/dynamicSVG/motor.svg
@@ -0,0 +1,263 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ //document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', darkColor);
+ //});
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ //document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', lightColor);
+ //});
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/motor1.svg b/server/_widgets/dynamicSVG/motor1.svg
new file mode 100644
index 00000000..07cb12f8
--- /dev/null
+++ b/server/_widgets/dynamicSVG/motor1.svg
@@ -0,0 +1,278 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/motor_wshaft.svg b/server/_widgets/dynamicSVG/motor_wshaft.svg
new file mode 100644
index 00000000..516ed7b4
--- /dev/null
+++ b/server/_widgets/dynamicSVG/motor_wshaft.svg
@@ -0,0 +1,303 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pipe_3d_elbow.svg b/server/_widgets/dynamicSVG/pipe_3d_elbow.svg
new file mode 100644
index 00000000..01275d06
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pipe_3d_elbow.svg
@@ -0,0 +1,265 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pipe_3d_elbow2.svg b/server/_widgets/dynamicSVG/pipe_3d_elbow2.svg
new file mode 100644
index 00000000..ecea6e8b
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pipe_3d_elbow2.svg
@@ -0,0 +1,263 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pipe_3d_h1.svg b/server/_widgets/dynamicSVG/pipe_3d_h1.svg
new file mode 100644
index 00000000..efa443e7
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pipe_3d_h1.svg
@@ -0,0 +1,263 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pipe_3d_h2.svg b/server/_widgets/dynamicSVG/pipe_3d_h2.svg
new file mode 100644
index 00000000..678dbd47
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pipe_3d_h2.svg
@@ -0,0 +1,265 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pipe_3d_h3.svg b/server/_widgets/dynamicSVG/pipe_3d_h3.svg
new file mode 100644
index 00000000..c3b92e6d
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pipe_3d_h3.svg
@@ -0,0 +1,263 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pipe_3d_heatexchange1.svg b/server/_widgets/dynamicSVG/pipe_3d_heatexchange1.svg
new file mode 100644
index 00000000..e2067c34
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pipe_3d_heatexchange1.svg
@@ -0,0 +1,276 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pipe_3d_heatexchange2.svg b/server/_widgets/dynamicSVG/pipe_3d_heatexchange2.svg
new file mode 100644
index 00000000..2a088896
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pipe_3d_heatexchange2.svg
@@ -0,0 +1,271 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pipe_3d_heatexchange3.svg b/server/_widgets/dynamicSVG/pipe_3d_heatexchange3.svg
new file mode 100644
index 00000000..8ddbccfd
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pipe_3d_heatexchange3.svg
@@ -0,0 +1,267 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pipe_3d_tjunction.svg b/server/_widgets/dynamicSVG/pipe_3d_tjunction.svg
new file mode 100644
index 00000000..8bb1849e
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pipe_3d_tjunction.svg
@@ -0,0 +1,264 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/piperedirect1.svg b/server/_widgets/dynamicSVG/piperedirect1.svg
new file mode 100644
index 00000000..93d27434
--- /dev/null
+++ b/server/_widgets/dynamicSVG/piperedirect1.svg
@@ -0,0 +1,272 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pressure_regulator.svg b/server/_widgets/dynamicSVG/pressure_regulator.svg
new file mode 100644
index 00000000..0082c0fd
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pressure_regulator.svg
@@ -0,0 +1,352 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pulsationdampener.svg b/server/_widgets/dynamicSVG/pulsationdampener.svg
new file mode 100644
index 00000000..cbbfa5ce
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pulsationdampener.svg
@@ -0,0 +1,278 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pump1.svg b/server/_widgets/dynamicSVG/pump1.svg
new file mode 100644
index 00000000..146301d2
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pump1.svg
@@ -0,0 +1,306 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pump2.svg b/server/_widgets/dynamicSVG/pump2.svg
new file mode 100644
index 00000000..856483fb
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pump2.svg
@@ -0,0 +1,288 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pump_3d_90_1.svg b/server/_widgets/dynamicSVG/pump_3d_90_1.svg
new file mode 100644
index 00000000..2c5d8998
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pump_3d_90_1.svg
@@ -0,0 +1,296 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pump_3d_example.svg b/server/_widgets/dynamicSVG/pump_3d_example.svg
index 804eb0ca..250cfc1e 100644
--- a/server/_widgets/dynamicSVG/pump_3d_example.svg
+++ b/server/_widgets/dynamicSVG/pump_3d_example.svg
@@ -190,10 +190,10 @@
// Function to update the color for the base shape group
function setBaseColor(baseColor) {
// Define color manipulations based on base color
- const darkColor = percentColor(baseColor, -15);
- const shadowColor = percentColor(baseColor, -30);
- const lightColor = percentColor(baseColor, 15);
- const hlightColor = percentColor(baseColor, 30);
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
elem.setAttribute('fill', baseColor);
@@ -212,20 +212,31 @@
});
}
- // Function to manipulate color brightness/darkness
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
function percentColor(color, percent) {
let R = parseInt(color.substring(1, 3), 16);
let G = parseInt(color.substring(3, 5), 16);
let B = parseInt(color.substring(5, 7), 16);
-
- R = parseInt(R * (100 + percent) / 100);
- G = parseInt(G * (100 + percent) / 100);
- B = parseInt(B * (100 + percent) / 100);
- R = (R < 255) ? R : 255;
- G = (G < 255) ? G : 255;
- B = (B < 255) ? B : 255;
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+ // Convert back to hexadecimal
const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
diff --git a/server/_widgets/dynamicSVG/pump_3d_straight1.svg b/server/_widgets/dynamicSVG/pump_3d_straight1.svg
new file mode 100644
index 00000000..ab772578
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pump_3d_straight1.svg
@@ -0,0 +1,299 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/pumphead_profile_3d.svg b/server/_widgets/dynamicSVG/pumphead_profile_3d.svg
new file mode 100644
index 00000000..24f1a6ee
--- /dev/null
+++ b/server/_widgets/dynamicSVG/pumphead_profile_3d.svg
@@ -0,0 +1,281 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/reducer_3d_1.svg b/server/_widgets/dynamicSVG/reducer_3d_1.svg
new file mode 100644
index 00000000..c9af130a
--- /dev/null
+++ b/server/_widgets/dynamicSVG/reducer_3d_1.svg
@@ -0,0 +1,268 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/reducer_3d_2.svg b/server/_widgets/dynamicSVG/reducer_3d_2.svg
new file mode 100644
index 00000000..65e445b8
--- /dev/null
+++ b/server/_widgets/dynamicSVG/reducer_3d_2.svg
@@ -0,0 +1,265 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/sensor_rtd.svg b/server/_widgets/dynamicSVG/sensor_rtd.svg
new file mode 100644
index 00000000..63b6b583
--- /dev/null
+++ b/server/_widgets/dynamicSVG/sensor_rtd.svg
@@ -0,0 +1,369 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/sensor_rtd_silhouette.svg b/server/_widgets/dynamicSVG/sensor_rtd_silhouette.svg
new file mode 100644
index 00000000..6236beeb
--- /dev/null
+++ b/server/_widgets/dynamicSVG/sensor_rtd_silhouette.svg
@@ -0,0 +1,264 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ //document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', darkColor);
+ //});
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ //document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', lightColor);
+ //});
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/strainer_basket.svg b/server/_widgets/dynamicSVG/strainer_basket.svg
new file mode 100644
index 00000000..176cfdaa
--- /dev/null
+++ b/server/_widgets/dynamicSVG/strainer_basket.svg
@@ -0,0 +1,354 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/strainer_basket_r.svg b/server/_widgets/dynamicSVG/strainer_basket_r.svg
new file mode 100644
index 00000000..1892866e
--- /dev/null
+++ b/server/_widgets/dynamicSVG/strainer_basket_r.svg
@@ -0,0 +1,355 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/strainer_wye.svg b/server/_widgets/dynamicSVG/strainer_wye.svg
new file mode 100644
index 00000000..71507070
--- /dev/null
+++ b/server/_widgets/dynamicSVG/strainer_wye.svg
@@ -0,0 +1,379 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/strainer_wye_r.svg b/server/_widgets/dynamicSVG/strainer_wye_r.svg
new file mode 100644
index 00000000..8dfd0398
--- /dev/null
+++ b/server/_widgets/dynamicSVG/strainer_wye_r.svg
@@ -0,0 +1,381 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', shadowColor);
+ });
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/tank_3d_medium_rtop1.svg b/server/_widgets/dynamicSVG/tank_3d_medium_rtop1.svg
new file mode 100644
index 00000000..c3a26957
--- /dev/null
+++ b/server/_widgets/dynamicSVG/tank_3d_medium_rtop1.svg
@@ -0,0 +1,263 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/tank_3d_v1.svg b/server/_widgets/dynamicSVG/tank_3d_v1.svg
new file mode 100644
index 00000000..51a18db6
--- /dev/null
+++ b/server/_widgets/dynamicSVG/tank_3d_v1.svg
@@ -0,0 +1,268 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/tank_3d_v2.svg b/server/_widgets/dynamicSVG/tank_3d_v2.svg
new file mode 100644
index 00000000..49059411
--- /dev/null
+++ b/server/_widgets/dynamicSVG/tank_3d_v2.svg
@@ -0,0 +1,272 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/tank_3d_v4.svg b/server/_widgets/dynamicSVG/tank_3d_v4.svg
new file mode 100644
index 00000000..7691d8e3
--- /dev/null
+++ b/server/_widgets/dynamicSVG/tank_3d_v4.svg
@@ -0,0 +1,267 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/tank_3d_v5.svg b/server/_widgets/dynamicSVG/tank_3d_v5.svg
new file mode 100644
index 00000000..a106267f
--- /dev/null
+++ b/server/_widgets/dynamicSVG/tank_3d_v5.svg
@@ -0,0 +1,272 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/tank_3d_v6.svg b/server/_widgets/dynamicSVG/tank_3d_v6.svg
new file mode 100644
index 00000000..71faa502
--- /dev/null
+++ b/server/_widgets/dynamicSVG/tank_3d_v6.svg
@@ -0,0 +1,267 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/tank_3d_v7.svg b/server/_widgets/dynamicSVG/tank_3d_v7.svg
new file mode 100644
index 00000000..9de1bdd5
--- /dev/null
+++ b/server/_widgets/dynamicSVG/tank_3d_v7.svg
@@ -0,0 +1,269 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/trucking.svg b/server/_widgets/dynamicSVG/trucking.svg
new file mode 100644
index 00000000..3271b85b
--- /dev/null
+++ b/server/_widgets/dynamicSVG/trucking.svg
@@ -0,0 +1,275 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ //document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', darkColor);
+ //});
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ //document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', lightColor);
+ //});
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/turbine1.svg b/server/_widgets/dynamicSVG/turbine1.svg
new file mode 100644
index 00000000..a4df4f00
--- /dev/null
+++ b/server/_widgets/dynamicSVG/turbine1.svg
@@ -0,0 +1,262 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ //document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', darkColor);
+ //});
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/turbine2.svg b/server/_widgets/dynamicSVG/turbine2.svg
new file mode 100644
index 00000000..346fc614
--- /dev/null
+++ b/server/_widgets/dynamicSVG/turbine2.svg
@@ -0,0 +1,307 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/turbinerounded.svg b/server/_widgets/dynamicSVG/turbinerounded.svg
new file mode 100644
index 00000000..86be001e
--- /dev/null
+++ b/server/_widgets/dynamicSVG/turbinerounded.svg
@@ -0,0 +1,269 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ //document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', darkColor);
+ //});
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ //document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', hlightColor);
+ //});
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_1path_down.svg b/server/_widgets/dynamicSVG/valve_1path_down.svg
new file mode 100644
index 00000000..a42030f1
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_1path_down.svg
@@ -0,0 +1,269 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_3way1.svg b/server/_widgets/dynamicSVG/valve_3d_3way1.svg
new file mode 100644
index 00000000..b0680361
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_3way1.svg
@@ -0,0 +1,307 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_3way1_nopipe.svg b/server/_widgets/dynamicSVG/valve_3d_3way1_nopipe.svg
new file mode 100644
index 00000000..5a4fe927
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_3way1_nopipe.svg
@@ -0,0 +1,288 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_4way1.svg b/server/_widgets/dynamicSVG/valve_3d_4way1.svg
new file mode 100644
index 00000000..7aa2551e
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_4way1.svg
@@ -0,0 +1,336 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_4way1_nopipe.svg b/server/_widgets/dynamicSVG/valve_3d_4way1_nopipe.svg
new file mode 100644
index 00000000..d47f5fe8
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_4way1_nopipe.svg
@@ -0,0 +1,306 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_angled1.svg b/server/_widgets/dynamicSVG/valve_3d_angled1.svg
new file mode 100644
index 00000000..fe551f94
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_angled1.svg
@@ -0,0 +1,303 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_angled1_nopipe.svg b/server/_widgets/dynamicSVG/valve_3d_angled1_nopipe.svg
new file mode 100644
index 00000000..3b1e233f
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_angled1_nopipe.svg
@@ -0,0 +1,283 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_angled2.svg b/server/_widgets/dynamicSVG/valve_3d_angled2.svg
new file mode 100644
index 00000000..fca172ad
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_angled2.svg
@@ -0,0 +1,301 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_angled2_nopipe.svg b/server/_widgets/dynamicSVG/valve_3d_angled2_nopipe.svg
new file mode 100644
index 00000000..c1c74176
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_angled2_nopipe.svg
@@ -0,0 +1,279 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_common1.svg b/server/_widgets/dynamicSVG/valve_3d_common1.svg
new file mode 100644
index 00000000..5e5e06da
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_common1.svg
@@ -0,0 +1,299 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_common2.svg b/server/_widgets/dynamicSVG/valve_3d_common2.svg
new file mode 100644
index 00000000..6b5b5fa7
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_common2.svg
@@ -0,0 +1,305 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_common2_nopipe.svg b/server/_widgets/dynamicSVG/valve_3d_common2_nopipe.svg
new file mode 100644
index 00000000..1694f6f2
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_common2_nopipe.svg
@@ -0,0 +1,276 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_common3.svg b/server/_widgets/dynamicSVG/valve_3d_common3.svg
new file mode 100644
index 00000000..41f4bca3
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_common3.svg
@@ -0,0 +1,305 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_common4.svg b/server/_widgets/dynamicSVG/valve_3d_common4.svg
new file mode 100644
index 00000000..aac9e8ab
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_common4.svg
@@ -0,0 +1,307 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_common4_nopipe.svg b/server/_widgets/dynamicSVG/valve_3d_common4_nopipe.svg
new file mode 100644
index 00000000..a6af071e
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_common4_nopipe.svg
@@ -0,0 +1,277 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_h1.svg b/server/_widgets/dynamicSVG/valve_3d_h1.svg
new file mode 100644
index 00000000..1d6cb321
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_h1.svg
@@ -0,0 +1,264 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_h2_closed.svg b/server/_widgets/dynamicSVG/valve_3d_h2_closed.svg
new file mode 100644
index 00000000..a93881c9
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_h2_closed.svg
@@ -0,0 +1,277 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_3d_h2_open.svg b/server/_widgets/dynamicSVG/valve_3d_h2_open.svg
new file mode 100644
index 00000000..cf7062eb
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_3d_h2_open.svg
@@ -0,0 +1,269 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/server/_widgets/dynamicSVG/valve_circle.svg b/server/_widgets/dynamicSVG/valve_circle.svg
new file mode 100644
index 00000000..65399d0a
--- /dev/null
+++ b/server/_widgets/dynamicSVG/valve_circle.svg
@@ -0,0 +1,273 @@
+
+
+ */
+
+ // Global Parameters and Variables
+ //!export-start
+ let _pn_setState = 0;
+ let _pn_setInterval = 1000;
+ let _pc_state0Colour = '#b4b4b4';
+ let _pc_state1Colour = '#00ff00';
+ let _pc_state2Colour = '#ff9500';
+ let _pc_state3Colour = '#ff0000';
+ let _pc_state4Colour = '#3c3c3c';
+ let _pc_state5Colour = '#dcdcdc';
+ //!export-end
+ let stateNumber = 0;
+ let blinkInterval;
+
+ // Function to update the color based on the set state
+ function logic() {
+
+ switch (stateNumber) {
+ case 0: // off
+ setBaseColor( _pc_state0Colour);
+ clearBlinking();
+ break;
+ case 1: // run
+ setBaseColor( _pc_state1Colour);
+ clearBlinking();
+ break;
+ case 2: // warning
+ setBaseColor( _pc_state2Colour);
+ clearBlinking();
+ break;
+ case 3: // fault
+ startBlinking( _pc_state0Colour, _pc_state3Colour, _pn_setInterval );
+ break;
+ case 4: // invalid
+ setBaseColor( _pc_state4Colour);
+ clearBlinking();
+ break;
+ case 5: // spare
+ setBaseColor( _pc_state5Colour);
+ clearBlinking();
+ break;
+ default:
+ console.log('Undefined State');
+ clearBlinking();
+ }
+ }
+
+ // Initial setup
+ function init() {
+ logic(); // Initial state rendering
+ }
+
+ // Function to update values from Fuxa
+ function putValue(id, value) {
+ if (id === '_pn_setState') {
+ stateNumber = value;
+ logic(); // Re-run logic to update state
+ }
+ if (id === '_pn_setInterval' ) _pn_setInterval = value;
+ if (id === '_pc_state0Colour') _pc_state0Colour = value;
+ if (id === '_pc_state1Colour') _pc_state1Colour = value;
+ if (id === '_pc_state2Colour') _pc_state2Colour = value;
+ if (id === '_pc_state3Colour') _pc_state3Colour = value;
+ if (id === '_pc_state4Colour') _pc_state4Colour = value;
+ if (id === '_pc_state5Colour') _pc_state5Colour = value;
+ }
+
+ // Function to send values back to Fuxa (placeholder)
+ function postValue(id, value) {
+ console.error('Not defined!');
+ }
+
+ // Initialize the SVG
+ init();
+
+ // Function to update the color for the base shape group
+ function setBaseColor(baseColor) {
+ // Define color manipulations based on base color
+ const darkColor = percentColor(baseColor, 15);
+ const shadowColor = percentColor(baseColor, -15);
+ const lightColor = percentColor(baseColor, 50);
+ const hlightColor = percentColor(baseColor, 90);
+
+ document.getElementById('shape').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', baseColor);
+ });
+ document.getElementById('dark').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', darkColor);
+ });
+ //document.getElementById('shadow').querySelectorAll('*').forEach(function(elem) {
+ //elem.setAttribute('fill', shadowColor);
+ //});
+ document.getElementById('light').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', lightColor);
+ });
+ document.getElementById('hlight').querySelectorAll('*').forEach(function(elem) {
+ elem.setAttribute('fill', hlightColor);
+ });
+ }
+
+ // Function to manipulate color brightness/darkness (-100% = Black) (0 = unchanged) (100% = White)
+ function percentColor(color, percent) {
+ let R = parseInt(color.substring(1, 3), 16);
+ let G = parseInt(color.substring(3, 5), 16);
+ let B = parseInt(color.substring(5, 7), 16);
+
+ // Calculate the adjustment factor based on the percentage
+ if (percent > 0) {
+ // Lightening - move each channel closer to 255 (white)
+ R = Math.round(R + (255 - R) * (percent / 100));
+ G = Math.round(G + (255 - G) * (percent / 100));
+ B = Math.round(B + (255 - B) * (percent / 100));
+ } else {
+ // Darkening - move each channel closer to 0 (black)
+ R = Math.round(R * (1 + (percent / 100)));
+ G = Math.round(G * (1 + (percent / 100)));
+ B = Math.round(B * (1 + (percent / 100)));
+ }
+
+ // Clamp values to the [0, 255] range
+ R = Math.max(0, Math.min(255, R));
+ G = Math.max(0, Math.min(255, G));
+ B = Math.max(0, Math.min(255, B));
+
+ // Convert back to hexadecimal
+ const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
+ const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
+ const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);
+
+ return "#" + RR + GG + BB;
+ }
+
+ // Function to start blinking between two colors
+ function startBlinking(color1, color2, interval) {
+ clearBlinking(); // Clear any existing blinking interval
+
+ let isColor1 = true;
+ blinkInterval = setInterval(function() {
+ const checkDestroy = document.getElementById('Layer_1'); // Important must be name of the SVG!
+ if (!checkDestroy) {
+ clearBlinking();
+ return;
+ }
+ if (isColor1) {
+ setBaseColor(color1);
+ } else {
+ setBaseColor(color2);
+ }
+ isColor1 = !isColor1;
+ }, interval);
+
+ // Set up the MutationObserver to watch for removal of the SVG element
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ mutation.removedNodes.forEach((node) => {
+ if (node.id === 'Layer_1') { // Important must be name of the SVG!
+ clearBlinking();
+ observer.disconnect();
+ }
+ });
+ });
+ });
+
+ // Start observing the body or a parent element of the SVG
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ // Function to clear the blinking interval
+ function clearBlinking() {
+ if (blinkInterval) {
+ clearInterval(blinkInterval);
+ blinkInterval = null;
+ }
+ }
+
+ ]]>
+
+
+
\ No newline at end of file