Ankündigung

Einklappen
Keine Ankündigung bisher.

eHZ Visu Beispiel mit neuem Widget Stacked Column Bar Chart

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Mike01
    antwortet
    Hab mitlerweile auch auf develop umgestellt, und den counter-patch installiert, seitdem werden bei mir die Plots generiert, allerdings auch anfangs mehrere Datenpunkte pro Tag. Man kann mit dem vorletzten Wert aber bestimmen, wieviel Datenpunkte generiert werden sollen, dann klappt es mit der Darstellung auch.

    Meine Plot-Zeilen sehen so aus:

    Code:
    <h3>Stromverbrauch pro Stunde (kwh)</h3>
    {{ plot.stacked('pstunde', 'zaehler1.verbrauch.stuendlich', 'max', '48h', '', '', '', 'Haushalt', 'true', '', 'column', '48', false) }}
    
    <h3>Stromverbrauch pro Tag (kwh)</h3>
    {{ plot.stacked('ptag', 'zaehler1.verbrauch.gestern', 'avg', '8d', '', '', '', 'Haushalt', 'true', '', 'column', '8', true) }}
    
    <h3>Kosten pro Tag (EUR)</h3>
    {{ plot.stacked('pkost', ['zaehler1.kosten.gestern', 'zaehler1.kosten.gestern.weekly_avg'], 'max', '8d', '', '', '', ['Haushalt', 'Wochendurchschnitt'], 'true', '', ['column', 'line'], '8', true) }}
    evtl. hilft es ja.
    Gruß, Mike

    Einen Kommentar schreiben:


  • Shai
    antwortet
    Zitat von hhhc Beitrag anzeigen
    Das war bei mir anfangs auch so. Hintergrund ist, dass die Zeitwerte nicht gleich sind, so dass Highcharts nicht weiss, wie es die Werte gruppieren (stapeln) soll. Aus diesem Grund hatte ich die 2. Korrektur im Code gemacht
    Code:
    // 2) timestamp is in milliseconds, harmonize last 3 figures to 000
     var newTimestamp = timestamp.toString().substring(0, 9).concat('0000');
    Da das Millisekunden sind ist die Genauigkeit somit auf 10 Sekunden reduziert. Sollte das nicht reichen, einfach mal mit 5 Nullen probieren (=100 Sekunden), bei Tageswerten sicher kein Problem.
    Ohne ausprobiert zu haben sähe das dann wie folgt aus:
    Code:
     var newTimestamp = timestamp.toString().substring(0, 8).concat('00000');
    Leider scheint das keine Auswirkungen auf meinen Plot zu haben und Highchart stacked trotzdem nicht


    Ich werde morgen mal weiter probieren.
    ---
    Zu allem Überfluss scheint momentan der Closure Compiler nicht zu funktionieren und "php make.php" produziert gerade nur Müll in Form von "console.log(...)" ausgaben

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Zitat von hhhc Beitrag anzeigen
    Kann mir jemand sagen, ob / wie ich ein 2. Smarthome.py parallel zum PROD als DEV environment laufen lassen kann? Kann ich den Port ändern? Da ich in meinem Haus auf dem DEV-Zweig bin könnte ich somit auf dem Master arbeiten und Euch ein wenig konkreter helfen...
    Einfach in einem anderen Ordner das git ziehen und dort manuell starten. Ports für Visu und CLi müssen natürlich angepasst werden damit dort nichts kollidiert.

    btw. ich bin auch auf develop

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Plot geht ... aber eben mit mehren Werten pro Tag.

    Das liegt aber wohl an der sql und bedarf der Korrektur in den items ?
    Muss ich mal testen.

    Einen Kommentar schreiben:


  • hhhc
    antwortet
    Kann mir jemand sagen, ob / wie ich ein 2. Smarthome.py parallel zum PROD als DEV environment laufen lassen kann? Kann ich den Port ändern? Da ich in meinem Haus auf dem DEV-Zweig bin könnte ich somit auf dem Master arbeiten und Euch ein wenig konkreter helfen...

    Einen Kommentar schreiben:


  • hhhc
    antwortet
    Zitat von Shai Beitrag anzeigen
    Das hat bei mir zu nem Plot geführt, aber leider stacked dieser nicht so schön wie im 1. Post, sondern zeigt mir mehrere Balken pro Tag an.
    Das war bei mir anfangs auch so. Hintergrund ist, dass die Zeitwerte nicht gleich sind, so dass Highcharts nicht weiss, wie es die Werte gruppieren (stapeln) soll. Aus diesem Grund hatte ich die 2. Korrektur im Code gemacht
    Code:
    // 2) timestamp is in milliseconds, harmonize last 3 figures to 000
     var newTimestamp = timestamp.toString().substring(0, 9).concat('0000');
    Da das Millisekunden sind ist die Genauigkeit somit auf 10 Sekunden reduziert. Sollte das nicht reichen, einfach mal mit 5 Nullen probieren (=100 Sekunden), bei Tageswerten sicher kein Problem.
    Ohne ausprobiert zu haben sähe das dann wie folgt aus:
    Code:
     var newTimestamp = timestamp.toString().substring(0, 8).concat('00000');

    Einen Kommentar schreiben:


  • Shai
    antwortet
    Versuch mal in deiner plot.html

    "tmax|default('now')" durch "tmax|default('0')" zu ersetzen.


    Das hat bei mir zu nem Plot geführt, aber leider stacked dieser nicht so schön wie im 1. Post, sondern zeigt mir mehrere Balken pro Tag an.

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Also ich hab das eben nochmal von vorn gemacht:

    1) Logiken funktionieren
    2) items funktionieren
    3) ehz.html
    Code:
    {{ plot.stacked('p3', ['zaehler.haushalt.kosten.gestern', 'zaehler.haushalt.kosten.gestern.weekly_avg'], 'max', '2w', '', '', '', ['Haushalt', 'Wochendurchschnitt'], 'true', '', ['column', 'line'], '', true) }}
    4)widget.js
    Code:
    // ----- plot.stacked ----------------------------------------------------------
    $(document).delegate('div[data-widget="plot.stacked"]', {
    	'update': function (event, response) {
    		// response is: [ [ [t1, y1], [t2, y2] ... ], [ [t1, y1], [t2, y2] ... ], ... ] 
    
    		var label = $(this).attr('data-label').explode();
    		var color = $(this).attr('data-color').explode();
    		var exposure = $(this).attr('data-exposure').explode();
    		var axis = $(this).attr('data-axis').explode();
    		var zoom = $(this).attr('data-zoom');
    		var showStacklabels = JSON.parse($(this).attr('data-stacklabels'));
    		var correctdate = JSON.parse($(this).attr('data-correctdate'));
    		var series = Array();
    
    		for (var i = 0; i < response.length; i++) {
    		    // 1) werte werden um Mitternacht für den Vortag generiert, Anzeige von Highcharts auf dem Folgetag, ABzug von 24h in millisekunden
    		    // 2) timestamp is in milliseconds, harmonize last 3 figures to 000
    		    // sollte also hiermit auf 10sec "ungenau" werden => notwendig für gruppierung von highcharts
                // 3) remove last value as it is a during the day value 
    		    var oneResponse = response[i]; // [[1420526954593,0],[1420554301019,6.21],[1420585202298,6.7],[1420671601499,7.4],[1420671601527,7.12],[1420747423682,7.12]]
        		for (var k = 0; k < oneResponse.length; k++) {
        		    var timestamp = oneResponse[k][0];
        		    // 1)
        		    if (correctdate) {
            		    timestamp = timestamp - 1000 * 60 * 60 * 24;
            		}
        		    // 2)
        		    var newTimestamp = timestamp.toString().substring(0, 9).concat('0000'); 
                    oneResponse[k][0] = parseInt(newTimestamp);
                }
                oneResponse.pop(); // 3) 
                response[i] = oneResponse; 
    
    			series[i] = {
    				type: (exposure[i] != 'stair' ? exposure[i] : 'line'),
    				step: (exposure[i] == 'stair' ? 'left' : false),
    				name: label[i],
    				data: response[i],
    				color: (color[i] ? color[i] : null)
    			}
    		}
    		
    
    		// draw the plot
    
            $('#' + this.id).highcharts({
    				chart: { type: 'column' },
    				series: series,
    				xAxis: { type: 'datetime', title: { text: axis[0] } },
    				yAxis: { min: $(this).attr('data-ymin'), max: $(this).attr('data-ymax'), title: { text: axis[1] }, stackLabels: { 
    				    enabled: showStacklabels, 
    				    style: { color: '#fff', 'font-size': '13px', 'line-height': '14px' } } 
    				    },
                    plotOptions: {
                        column: {
                            stacking: 'normal',
                            dataLabels: { enabled: false }
                        }
                    }
            });
    		
    	},
    
    	'point': function (event, response) {
    
    		var count = $(this).attr('data-count');
    		if (count < 100) {
    			count = 100;
    		}
    		for (var i = 0; i < response.length; i++) {
    			if (response[i]) {
    				var chart = $('#' + this.id).highcharts();
    
    				// more points?
    				for (var j = 0; j < response[i].length; j++) {
    					chart.series[i].addPoint(response[i][j], false, (chart.series[i].data.length >= count));
    				}
    				chart.redraw();
    			}
    		}
    	}
    });
    4b) php make.php
    5)smartvisu/widgets/plot.html
    Code:
    /**
    * A simple widget for plotting stacked charts
    *
    * @param unique id for this widget
    * @param series of item/s. More item/s in array form: [ item1 , item2 ]
    * @param the mode: 'avg', 'sum', 'min', 'max'
    * @param the minimum time (x-axis): '1h', '2h'... (duration-format)
    * @param the maximum time (x-axis): '', '1h', '2h'... (duration-format, default: now)
    * @param the minimum y-axis (optional)
    * @param the maximum y-axis (optional)
    * @param label/s for each series (optional)
    * @param stacklabel if the aggregated values should be shown, true/false (optional, default true)
    * @param color/s for each series e. g. '#f00' for red (optional, default: sutiable for design)
    * @param type/s for each series (exposure): 'line', 'stair', 'spline', 'area', 'areaspline', 'column' (optional, default 'line')
    * @param count number of data points to load, default 100
    * @param correctdate whether to delete last data point (if stats from previous
    *
    * @see misc/fundamentals#Array-Form
    * @see misc/fundamentals#Duration-Format
    */
    {% macro stacked(id, gad, mode, tmin, tmax, ymin, ymax, label, stacklabels, color, exposure, count, correctdate) %}
    
    	<div id="{{ uid(page, id) }}" data-widget="plot.stacked" data-item="{{ implode(gad, [mode|default('avg'), tmin|default('1h'), tmax|default('now')]) }}"
    		{% if ymin is not empty %} data-ymin="{{ ymin }}" {% endif %} {% if ymax is not empty %} data-ymax="{{ ymax }}" {% endif %}
    		data-label="{{ implode(label) }}" data-stacklabels="{{ stacklabels|default(true) }}" data-correctdate="{{ correctdate|default('false') }}"
    		data-color="{{ implode(color) }}" data-exposure="{{ implode(exposure) }}" data-axis="{{ implode(axes) }}"
    		{% if count is not empty %} data-count="{{ count }}" {% endif %}
    		class="plot"></div>
    
    {% endmacro %}
    Das Diagramm wird nicht angezeigt. Von sh.py bekomme ich aber die Daten:
    Code:
    {"series":[[1421091070755,5.32],[1421114600300,5.23],[1421190080085,4.77],[1421260758067,4.5],[1421276480509,4.25],[1421287400396,4.22],[1421362878915,4.05],[1421449279926,3.83],[1421484250092,3.75],[1421535680849,3.55],[1421546599989,3.57],[1421577362385,3.59],[1421609601216,3.73],[1421622079688,3.76],[1421708479927,3.84],[1421794880801,3.82],[1421805920713,3.79],[1421881280244,3.64],[1421954616068,3.66],[1421967679421,3.71],[1421978600767,3.69],[1422140480043,3.69],[1422151401073,3.68],[1422214664368,3.65],[1422237800363,3.7],[1422300670755,3.7]],"cmd":"series","sid":"zaehler.haushalt.kosten.gestern.weekly_avg|max|2w|now"}
    Code:
    {"series":[[1421091070749,5.31],[1421103678902,3.41],[1421114600222,3.42],[1421190080007,2.43],[1421276480461,3.17],[1421287399628,3.18],[1421362878602,2.58],[1421449279880,2.39],[1421535680762,6.02],[1421546599960,6.03],[1421609601219,6.03],[1421622079645,6.88],[1421708479822,3.23],[1421794880719,2.38],[1421805920687,2.39],[1421881280167,2.5],[1421967679333,2.38],[1421978600717,2.39],[1422054080159,2.42],[1422140479976,5.72],[1422151400385,5.73],[1422226879997,6.4],[1422237800308,6.41],[1422300670749,6.41]],"cmd":"series","sid":"zaehler.haushalt.kosten.gestern|max|2w|now"}
    Nur dargestellt wir leider nix. Jemand noch ne Idee ?

    Einen Kommentar schreiben:


  • hhhc
    antwortet
    Hallo,

    hab gesehen, dass hier wohl noch einige Probleme sind. Bin zur Zeit in Kiew unterwegs und hab nicht so viel Zeit.

    Wie weiter oben geschrieben nutze ich DEV Zweig sowie den count patch. Da hatte ich ja auch bereits das Problem vermutet.

    Ich hab im JS Code auch ein wenig dokumentiert aber bin halt kein JS Entwickler sondern google mir das immer nur zusammen.
    Ggf gibt es ja ein paar Möglichkeiten den Code sauberer und für mehrere Versionen zu erstellen...

    Freut mich aber, dass das Bsp so sein Interesse findet. Denke, dass wir Eure Visus auch zum laufen kriegen 😄

    Einen Kommentar schreiben:


  • Shai
    antwortet
    Also:


    Ich habe den Code von oben in meine "widgets/plot.html" eingefügt. Das ist die Abwandlung von dem Widget was hhhc gepostet hat, die ohne Patch auskommt.

    Im HTML binde ich das Widget dann so ein:
    Code:
    {{ plot.stacked('p3', ['ehz.haus.kosten.gestern', 'ehz.kosten.gestern.weekly_avg'], 'max', '2w', '', '', '', ['Haushalt', 'Wochendurchschnitt'], 'true', '', ['column', 'line'], '', true) }}

    Das JavaScript ist unverändert zu dem von hhhc. Ebenso sind die Items.conf unverändert. Die Logik für die Zeit Items habe ich aus dem Beitrag auf den am Anfang vom Thread ebenfalls verwiesen wird.


    Lange Rede kurzer Sinn:

    Ich habe alles unverändert gelassen und bin der Anleitung von hccc gefolgt. Nur die "plot.html" habe ich angepasst. (und für meinen Fall die Wärmepumpe rausgeworfen, da ich nur 1 Zähler bzw. 1 Schnittstelle habe)


    Grüße,

    Lars

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Ich stell mich zu dämlich an ... hier kommt nix raus, wie sieht denn dein widget in der html aus ?
    Ich sehe mittlerweile auch nicht mehr bei dem count-patch durch, hier ist nur querlesen angesagt.

    Zeit für ein ordentliches Repo in dem die Erfahrungen/Änderungen der letzten 2 Jahre mal gesammelt werden.

    Einen Kommentar schreiben:


  • Shai
    antwortet
    UPDATE:

    Meine Vermutung und der Hinweis von Jan waren richtig, es lag an "now".

    Mit folgendem Widget-Code werden bei mir Plots rausgerendert:

    HTML-Code:
    /**
    * A simple widget for plotting stacked charts
    *
    * @param unique id for this widget
    * @param series of item/s. More item/s in array form: [ item1 , item2 ]
    * @param the mode: 'avg', 'sum', 'min', 'max'
    * @param the minimum time (x-axis): '1h', '2h'... (duration-format)
    * @param the maximum time (x-axis): '', '1h', '2h'... (duration-format, default: now)
    * @param the minimum y-axis (optional)
    * @param the maximum y-axis (optional)
    * @param label/s for each series (optional)
    * @param stacklabel if the aggregated values should be shown, true/false (optional, default true)
    * @param color/s for each series e. g. '#f00' for red (optional, default: sutiable for design)
    * @param type/s for each series (exposure): 'line', 'stair', 'spline', 'area', 'areaspline', 'column' (optional, default 'line')
    * @param count number of data points to load, default 100
    * @param correctdate whether to delete last data point (if stats from previous
    *
    * @see misc/fundamentals#Array-Form
    * @see misc/fundamentals#Duration-Format
    */
    {% macro stacked(id, gad, mode, tmin, tmax, ymin, ymax, label, stacklabels, color, exposure, count, correctdate) %}
    
    	<div id="{{ uid(page, id) }}" data-widget="plot.stacked" data-item="{{ implode(gad, [mode|default('avg'), tmin|default('1h'), tmax|default('now')]) }}"
    		{% if ymin is not empty %} data-ymin="{{ ymin }}" {% endif %} {% if ymax is not empty %} data-ymax="{{ ymax }}" {% endif %}
    		data-label="{{ implode(label) }}" data-stacklabels="{{ stacklabels|default(true) }}" data-correctdate="{{ correctdate|default('false') }}"
    		data-color="{{ implode(color) }}" data-exposure="{{ implode(exposure) }}" data-axis="{{ implode(axes) }}"
    		{% if count is not empty %} data-count="{{ count }}" {% endif %}
    		class="plot"></div>
    
    {% endmacro %}

    Aktuell sieht das bei mir noch ein wenig krude aus, was ich vorerst mal darauf schiebe dass mein Sensor erst seit Sonntag läuft und mir daher Vergangenheitswerte fehlen, ich werde das mal beobachten.
    Wenn es nicht besser wird, dann liegt es vielleicht an dem "count" Patch den ich nicht eingespielt habe oder an meinem "Master" Stand.


    @JuMi2006
    Ggfs kannst Du ja mal berichten wie das mit dem Widget bei Dir aussieht.


    Grüße,

    Lars
    Angehängte Dateien

    Einen Kommentar schreiben:


  • Shai
    antwortet
    Hallo Jan,

    das 'now' hatte ich heute morgen nach 2 weitere Blicken in den Code im Verdacht. Den Patch kannte ich aber nicht. ;-)

    Ich probiere heute Abend mal aus das now wieder durch ne 0 zu ersetzen und werde berichten.


    Danke für den Hinweis.

    Grüße

    Lars

    Einen Kommentar schreiben:


  • JanT
    antwortet
    Hallo,

    ohne es jetzt getestet so haben: es zieht so aus, als arbeite hhhc mit Alex's count patch. Entsprechen muss und wird im Widget tmax='now' gesetzt. Das Problem ist wenn man ohne den Patch arbeitet, darf tmax nicht gesetzt werden. Dann muss die Widgetzeile wie folgt aussehen:

    Code:
    <div id="{{ uid(page, id) }}" data-widget="plot.stacked" data-item="{{ implode(gad, [mode|default('avg'), tmin|default('1h'), tmax|default('[COLOR=Red]0[/COLOR]'), count|default(100)]) }}"
    sonnst fehlt der Plot und die Fehlermeldung auch!

    Vielleicht wäre es eine Idee den Patch in den beiden develop Repositories aufzunehmen?

    Viele Grüße,

    Jan

    Einen Kommentar schreiben:


  • Shai
    antwortet
    Hm, okay ich bin auf dem Master Stand. - Dann haben wir vermutlich 2 verschiedene Probleme mit ähnlichen Auswirkungen ;-)
    Ich probiere heute Abend auch noch mal rum, was mich wundert ist das das "update" Event nicht ausgelöst wird, ggfs. versuch ich da mal was zu Debuggen.



    Wenn Du auf Develop bist, dann könnte es noch daran liegen: (Wobei das eigentlich keine Auswirkungen haben solle, da es ja ein anderes Widget und entsprechend anderes JavaScript ist)
    https://knx-user-forum.de/452332-post19.html


    Ich habe ausserdem die Änderung von "Zoomable Plot" bzgl der zu übertragenden Count Variablen eingebaut (- √ - Neues Widget: zoomable Plot)



    Grüße,

    Lars

    Einen Kommentar schreiben:

Lädt...
X