Page 1 of 1

Colored volume bar

Posted: Tuesday 17 December 2024 19:44
by Beschuitje
Searched the forum and readthedocs but doesn't seem to be there. Tried some stuf but getting nowhere.
Is it possible to make a 'colored volume bar' in Dashticz from lets say the solar panels or P1 like the one on Eneco Toon?

The volume bar showing the actual usage but when you click on it, it opens the 24h graph?

Image

Re: Colored volume bar

Posted: Tuesday 17 December 2024 20:45
by Lokonli
yes :)

Can you find some js and/or CSS examples?

Re: Colored volume bar

Posted: Tuesday 17 December 2024 23:03
by Beschuitje
Nice!

It's a challenging search which got me;
https://stackoverflow.com/questions/621 ... ical-linea
https://www.anychart.com/blog/2021/10/2 ... avascript/

Some on LED gauge meters;
https://www.fusioncharts.com/dev/chart- ... /led-gauge

which has html example;

Code: Select all

<html>
<head>
	<title>My first chart using FusionCharts Suite XT</title>
	<script type="text/javascript" src="https://cdn.fusioncharts.com/fusioncharts/latest/fusioncharts.js"></script>
	<script type="text/javascript" src="https://cdn.fusioncharts.com/fusioncharts/latest/themes/fusioncharts.theme.fusion.js"></script>
	<script type="text/javascript">
		FusionCharts.ready(function(){
			var chartObj = new FusionCharts({
    type: 'hled',
    renderAt: 'chart-container',
    width: '400',
    height: '150',
    dataFormat: 'json',
    dataSource: {
        "chart": {
            "caption": "Fuel Level Indicator",
            "lowerLimit": "0",
            "upperLimit": "100",
            "lowerLimitDisplay": "Empty",
            "upperLimitDisplay": "Full",
            "numberSuffix": "%",
            "valueFontSize": "12",
            "showhovereffect": "1",
            "origW": "400",
            "origH": "150",
            "ledSize": "3",
            "ledGap": "2",
            "manageResize": "1",
            "theme": "fusion"
        },
        //All annotations are grouped under this element
        "annotations": {
            "showbelow": "1",
            "groups": [{
                //Each group needs a unique ID
                "id": "indicator",
                "items": [

                    {
                        "id": "bgRectAngle",
                        //Polygon item
                        "type": "rectangle",
                        "alpha": "90",
                        "radius": "1",
                        "fillColor": "#6baa01",
                        "x": "$gaugeCenterX - 20",
                        "tox": "$gaugeCenterX + 20",
                        "y": "$gaugeEndY + 25",
                        "toy": "$gaugeEndY + 45"
                    }
                ]
            }]

        },
        "colorRange": {
            "color": [{
                "minValue": "0",
                "maxValue": "45",
                "code": "#e44a00"
            }, {
                "minValue": "45",
                "maxValue": "75",
                "code": "#f8bd19"
            }, {
                "minValue": "75",
                "maxValue": "100",
                "code": "#6baa01"
            }]
        },
        "value": "92"
    },
    "events": {
        "drawComplete": function(evt, arg) {
            var i,
                //Annotation
                annotations = evt.sender.annotations,
                //Value
                val = evt.sender.getData(),
                //Color Range Array
                crArr = evt.sender.args.dataSource.colorRange.color;

            for (var i = crArr.length - 1; i >= 0; i--) {
                //When value falls within the color range
                if (val >= crArr[i].minValue && val <= crArr[i].maxValue) {
                    annotations.update('bgRectAngle', {
                        "fillColor": crArr[i].code
                    });
                }
            }

        }
    }

}
);
			chartObj.render();
		});
	</script>
	</head>
	<body>
		<div id="chart-container">FusionCharts XT will load here!</div>
	</body>
</html>
Hope this works?

Re: Colored volume bar

Posted: Wednesday 18 December 2024 8:00
by Lokonli
All the examples above use a paid charting library.

Dashticz is using chart.js, but that doesn't contain a good looking linear gauge chart.

If anyone knows a nice free example, please share here.

Re: Colored volume bar

Posted: Wednesday 18 December 2024 17:32
by HvdW
And this?

Code: Select all

return {
    on = {
        devices = { 'Volume_Sensor' } -- Replace with your actual volume sensor device name
    },
    execute = function(domoticz, device)
        local volume = device.level
        local volumeBar = ""

        if volume <= 20 then
            volumeBar = "<font color='red'>█</font>"
        elseif volume <= 40 then
            volumeBar = "<font color='orange'>██</font>"
        elseif volume <= 60 then
            volumeBar = "<font color='yellow'>███</font>"
        elseif volume <= 80 then
            volumeBar = "<font color='lightgreen'>████</font>"
        else
            volumeBar = "<font color='green'>█████</font>"
        end

        domoticz.devices('Volume_Text_Device').updateText(volumeBar) -- Replace with your actual text device name
    end
}

Re: Colored volume bar

Posted: Wednesday 18 December 2024 19:43
by Beschuitje

Re: Colored volume bar

Posted: Thursday 19 December 2024 21:53
by JBN
Interesting, I made a simple version for temperature (but didn't bother with a click function etc). Perhaps not something to build on, but an example where a linear gauge chart also might be applicable.
Skärmbild 2024-12-19 214749.png
Skärmbild 2024-12-19 214749.png (1.43 KiB) Viewed 2248 times

Re: Colored volume bar

Posted: Thursday 02 January 2025 11:41
by Beschuitje
Been looking into this but not my cup of tea so i used AI and it came up with this HTML code.

Code: Select all

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Live Power Meter</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
    <style>
        :root {
            --container-width: 200px; /* Standaard breedte */
            --container-height: 200px; /* Standaard hoogte */
        }

         body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: flex-start; /* Voor links uitlijning */
            align-items: center;
            height: 94vh;
            margin: 0;
            background-color: transparant;
		}

	.icon {
    	position: absolute;
    	top: 10px;  /* Pas de afstand van de bovenkant aan */
    	left: 10px; /* Pas de afstand van de linkerzijde aan */
    	font-size: 22px; /* Groote van het icoon */
    	color: grey;
   	cursor: pointer; /* Zorg ervoor dat de cursor verandert als je over het icoon beweegt */
	}

	.container {
    	position: relative;
    	width: 200px;
    	height: 180px;
    	display: flex;
    	flex-direction: column;
    	justify-content: center;
    	align-items: center;
    	border: 0px solid #ddd;
    	border-radius: 10px;
    	box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    	padding: 10px;
    	text-align: center;
	}

        .bar {
            display: flex;
            flex-direction: column-reverse;
            align-items: center;
            width: 60px;
            height: calc(var(--container-height) * 0.5); /* Dynamische hoogte */
            gap: 2px;
            cursor: pointer; /* Handje om te laten zien dat je erop kunt klikken */
        }

        .bar-segment {
            width: 100%;
            height: 15px;
            border-radius: 2px;
            background-color: lightgray;
        }

        /* Kleuren voor actieve streepjes */
        .level-1 { background-color: #004d40; } /* Donkergroen */
        .level-2 { background-color: #00796b; } /* Groen */
        .level-3 { background-color: #4caf50; } /* Lichtgroen */
        .level-4 { background-color: #cddc39; } /* Geelgroen */
        .level-5 { background-color: #ffeb3b; } /* Geel */
        .level-6 { background-color: #ffc107; } /* Oranjegeel */
        .level-7 { background-color: #ff9800; } /* Oranje */
        .level-8 { background-color: #f44336; } /* Rood */
        .level-9 { background-color: #d32f2f; } /* Donkerrood */
       
        #chartModal {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: white;
            border: 1px solid #ccc;
            padding: 20px;
            z-index: 1000;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        }

        #chartModal canvas {
            max-width: 100%;
        }

        #chartModal .close {
            position: absolute;
            top: 5px;
            right: 10px;
            font-size: 20px;
            cursor: pointer;
        }

        #overlay {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            z-index: 999;
        }
    	h1 {
    	font-size: 24px;  
    	margin-bottom: 10px;
	}

	.label {
    	margin-top: 10px;
	}
   	 </style>
   	 <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
	</head>
	<body>
    <div class="container" style="--container-width: 200px; --container-height: 180px;">
	<i class="fas fa-bolt icon"></i>
        <h1>Elektra</h1> <div class="bar" onclick="showChart()">
            <div class="bar-segment level-9"></div>
            <div class="bar-segment level-8"></div>
            <div class="bar-segment level-7"></div>
            <div class="bar-segment level-6"></div>
            <div class="bar-segment level-5"></div>
            <div class="bar-segment level-4"></div>
            <div class="bar-segment level-3"></div>
            <div class="bar-segment level-2"></div>
            <div class="bar-segment level-1"></div>
        </div>
        <div class="label" id="power-label">0 Watt</div>
    </div>

    <!-- Modal voor grafiek -->
    <div id="overlay"></div>
    <div id="chartModal">
        <span class="close" onclick="hideChart()">×</span>
        <canvas id="powerChart"></canvas>
    </div>

    <script>
        const historicalData = []; // Array voor historische data
        const maxHistory = 50; // Maximaal aantal datapunten in grafiek

        // Functie om sensorwaarde op te halen via de Domoticz API
        async function fetchSensorData() {
            const domoticzUrl = 'http://Domoticz-IP:8080/json.htm?type=devices&rid=1';
            try {
                const response = await fetch(domoticzUrl);
                const data = await response.json();

                // Controleer of de data correct is
                if (data.result && data.result.length > 0) {
                    const sensorValue = parseFloat(data.result[0].Usage) || 0; // Haal Watt waarde op
                    return sensorValue;
                } else {
                    console.error('Geen sensorgegevens gevonden');
                    return 0;
                }
            } catch (error) {
                console.error('Fout bij het ophalen van sensorgegevens:', error);
                return 0;
            }
        }

        // Update de grafiek met de sensorwaarde
        function updateGraph(power) {
            // Verwerk de waarde en bereken hoeveel streepjes actief moeten zijn
            const maxPower = 10000; // Maximum vermogen
            const numSegments = 9; // Aantal streepjes
            const activeSegments = Math.ceil((power / maxPower) * numSegments);

            // Update de streepjes
            const segments = document.querySelectorAll('.bar-segment');
            segments.forEach((segment, index) => {
                if (index < activeSegments) {
                    segment.style.backgroundColor = getColor(index + 1);
                } else {
                    segment.style.backgroundColor = 'lightgray';
                }
            });

            // Update de wattage-label
            document.getElementById('power-label').textContent = `${power} Watt`;

            // Update historische data
            historicalData.push(power);
            if (historicalData.length > maxHistory) {
                historicalData.shift();
            }
        }

        // Bepaal de kleur op basis van het niveau
        function getColor(level) {
            const colors = [
                '#004d40', '#00796b', '#4caf50',
                '#cddc39', '#ffeb3b', '#ffc107',
                '#ff9800', '#f44336', '#d32f2f'
            ];
            return colors[level - 1];
        }

        // Regelmatige updates van de sensorwaarde
        setInterval(async () => {
            const sensorValue = await fetchSensorData();
            updateGraph(sensorValue);
        }, 1000); // Update elke seconde

        // Functies om de grafiek te tonen/verbergen
        function showChart() {
            const modal = document.getElementById('chartModal');
            const overlay = document.getElementById('overlay');
            const ctx = document.getElementById('powerChart').getContext('2d');

            // Toon de modal
            modal.style.display = 'block';
            overlay.style.display = 'block';

            // Maak een nieuwe Chart.js-grafiek
            new Chart(ctx, {
                type: 'line',
                data: {
                    labels: historicalData.map((_, index) => `T-${historicalData.length - index}s`),
                    datasets: [{
                        label: 'Power Usage (Watt)',
                        data: historicalData,
                        borderColor: '#4caf50',
                        backgroundColor: 'rgba(76, 175, 80, 0.2)',
                        fill: true,
                        tension: 0.2,
                    }],
                },
                options: {
                    scales: {
                        x: { title: { display: true, text: 'Tijd (seconden geleden)' } },
                        y: { title: { display: true, text: 'Watt' } },
                    },
                },
            });
        }

        function hideChart() {
            const modal = document.getElementById('chartModal');
            const overlay = document.getElementById('overlay');
            modal.style.display = 'none';
            overlay.style.display = 'none';
        }
    </script>
</body>
</html>
Made a new file in the image folder of Dashticz, put the code in and saved it as a HTM file.
Made a frame in Dashticz with reference to the HTM file.

Code: Select all

frames.volumegraph = {
	frameurl: "/img/volumegraph.htm",
	height: 215,
	scrollbars: false,
	width: 4
}
It's not ideal but it works, the data from the P1 cable is transfered to the LED gauge graphic. Changing the size of things to fit it nicely into the container and column in Dashticz is some work though. What doesn't work is opening a second graph when you click on the volume graph.

Would be better to do this in Javascript but that's out of my league.
Image