Ankündigung

Einklappen
Keine Ankündigung bisher.

Scriptable - KNX - Edomi

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

    Scriptable - KNX - Edomi

    Hi,

    kennt hier jemand die Handyapp "Scriptable" ?
    Damit kann man per Javaskript Code am Handy ausführen lassen und das Ergebnis in zb. einem Widget am Iphone (Android sicher auch)
    anzeigen lassen.
    Ich lass mir damit den aktuell Inzidenzwert meines Landkreises anzeigen (https://gist.github.com/kevinkub/46c...403a7f0587f664).
    Oder das verbleibende Datenvolumen bei der Telekom (https://gist.github.com/Sillium/f904...2cfc07b8fa8728)

    Da ist sicher noch deutlich mehr möglich.

    Witzig fänd ich zb. ein Widget das mir bestimmte Werte (aus Edomi/KNX) direkt im Widget anzeigt, ohne die Visu öffnen zu müssen.

    Leider bin ich kein Coder... aber wenn da jemand von euch Ahnung hat, kann er vielleicht was damit anfangen.

    Gruß Martin
    Die Selbsthilfegruppe "UTF-8-Probleme" trifft sich diesmal abweichend im groüen Saal.

    #2
    Zitat von Brick Beitrag anzeigen
    Witzig fänd ich zb. ein Widget das mir bestimmte Werte (aus Edomi/KNX) direkt im Widget anzeigt, ohne die Visu öffnen zu müssen.
    So ähnlich habe ich das für die SolarThermie meines Vaters umgesetzt, aber dort ist die DB bzw. der PHP-Server immer verfügbar (Webserver).

    Bei einem "Einsiedler"-Edomi hast du halt das Problem an die Werte zu kommen. Wenn du willst, stelle ich den Scriptable-Code mal hier rein. Ist kein Hexenwerk.
    Gruß
    Stefan

    Kommentar


      #3
      Klar... wir können hier gern ne kleine Skriptsammlung machen.
      Die Selbsthilfegruppe "UTF-8-Probleme" trifft sich diesmal abweichend im groüen Saal.

      Kommentar


        #4
        Eine Scriptable-Sammlung ist aus meiner Sicht nur im Bezug auf EDOMI und Heimautomatisierung hier sinnvoll, oder?

        Code:
        let widget = await makeWidget()
        
        if (config.runsInWidget) {
        // The script runs inside a widget, so we pass our instance of ListWidget to be shown inside the widget on the Home Screen.
        Script.setWidget(widget)
        } else {
        // The script runs inside the app, so we preview the widget.
        widget.presentMedium()
        }
        Script.complete()
        
        function getColor(value) {
        switch (true){
        case (value < 30):
        return new Color("ccffff")
        break
        case (value < 40):
        return Color.yellow()
        break
        case (value < 50):
        return Color.orange()
        break
        case (value >= 50):
        return Color.red()
        break
        }
        
        }
        async function makeWidget() {
        
        let url = "http://yoururl-with-json-response"
        let widget = new ListWidget()
        widget.spacing = 7
        let gradient = new LinearGradient()
        gradient.locations = [0, 1]
        gradient.colors = [
        new Color("488289"),
        new Color("3A6996")
        ]
        widget.backgroundGradient = gradient
        
        const header = widget.addText("Solar ☀️")
        header.font = Font.mediumSystemFont(24)
        
        let request = new Request(url)
        request.headers = {"Accept":"application/json"}
        
        let fields = []
        fields["puffer_oben"] = "puffer_unten"
        fields["puffer_oben_2"] = "puffer_unten_2"
        fields["holz"] = "holz_abgas"
        
        let names = {"puffer_unten":"Puffer 1", "puffer_unten_2":"Puffer 2", "holz_abgas":"Holzofen"}
        
        let payload = await request.loadJSON()
        // log(payload)
        
        // process all districts
        for (key in fields) {
        try {
        let field = fields[key]
        let stack = widget.addStack()
        
        let name = stack.addText(names[field])
        name.textColor = Color.white()
        name.font = Font.lightSystemFont(18)
        stack.addSpacer(null)
        let index = payload[key].toFixed(0)
        let incidence = stack.addText(index +"°C")
        incidence.font = Font.heavySystemFont(18)
        incidence.textColor = getColor(index)
        // stack.addSpacer(null)
        index = payload[field].toFixed(0)
        incidence = stack.addText(" "+index +"°C")
        incidence.font = Font.heavySystemFont(18)
        incidence.textColor = getColor(index)
        } catch (err) {
        log(err)
        let fault = widget.addText("Reading remote data failed.")
        fault.textColor = Color.red()
        fault.font = Font.heavySystemFont(16)
        }
        }
        let refresh = new Date()
        refresh.setMinutes(refresh.getMinutes()+10)
        widget.refreshAfterDate = refresh
        return widget
        }
        Gruß
        Stefan

        Kommentar


          #5
          Ja, das seh ich auch so.
          wer das „DM Menge an Klopapier“ Skript braucht muss wo anders suchen.

          (nein kein Witz, das gibt es wirklich)

          Die Selbsthilfegruppe "UTF-8-Probleme" trifft sich diesmal abweichend im groüen Saal.

          Kommentar


            #6
            Also das fände ich auch eine interssante Geschichte. Das einzige Problem welches ich bei mir sehe ist das ich Edomi nach Aussen nicht freigegeben habe.
            Dann würde ich Daten nur sehen wenn ich per VPN Verbunden bin, oder gerade zu Hause.

            Gerade für das Beispiel aus dem Scipt würde ich es gebrauchen. Wir heißen auch nur mit Stückholz.

            Kommentar


              #7
              Hi. Ich war jetzt auch fleißig am programmieren und habe ein vorhandenes openWB Script angepasst. Siege Bild.

              die Lösung bzgl. Bereitstellung der Werte im lokalen Netz habe ich mit einem VPN Profil erstellt, welches bei Zugriff auf lokale Hostnames, automatisch ins VPN Netz einwählt. D.h., immer wenn das Skript werde abrufen möchte, öffnet es im Hintergrund auf iOS Ebene eine VPN Verbindung. Nach wenigen Minuten wird diese wieder geschlossen.

              2A96FB3F-7787-481F-87BD-DDFC42A3F125.png

              Kommentar


                #8
                Stark,

                magst du das angepasste Skript evtl. Posten?
                Die Selbsthilfegruppe "UTF-8-Probleme" trifft sich diesmal abweichend im groüen Saal.

                Kommentar


                  #9
                  ja und vor alle wie erstellt man so was? gibts das auch für android?

                  Kommentar


                    #10
                    Für iOS wird die freie App Scriptable benötigt. Mit Hilfe von JavaScript kann man eigene Scripte erstellen und ab iOS 14 auch als Widget einbinden. Bekannt wurde Scriptapple zu Coronazeiten, um zu wissen, wieviel Klopapier um die Ecke im Drogeriemarkt vorrätig ist.

                    Das Originalscript kommt von hier, ist also nicht von mir. Ich habe es aber angepasst bzgl. anzuzeigender Werte sowie Nutzung mit VPN onDemand iOS Profile.
                    Quelle:
                    https://openwb.de/forum/viewtopic.php?f=6&t=2354

                    Hier mein Script:
                    Code:
                    //--------------------------------------------------------------------------------------
                    // Folgende Werte MÜSSEN angepasst werden:
                    //--------------------------------------------------------------------------------------
                    
                    //--------------------------------------------------------------------------------------
                    // IP-Adresse der openWB (von hier holt das Widget die benötigten Daten):
                    let oWBip = "openwb.fritz.box";
                    //--------------------------------------------------------------------------------------
                    // URL, auf die beim Tippen auf das Widget weitergeleitet werden soll (z.B. Home-Website von oWB):
                    let widgetURL = "http://" + oWBip + "/openWB/web/index.php";
                    //--------------------------------------------------------------------------------------
                    
                    //--------------------------------------------------------------------------------------
                    // Folgende Werte KÖNNEN angepasst werden:
                    //--------------------------------------------------------------------------------------
                    
                    //--------------------------------------------------------------------------------------
                    // Speicherleistung oder LP1-Ladeleistung:
                    // 0: Es wird immer die Speicherleistung angezeigt
                    // 1: Wenn Leistung von LP1 != 0 wird statt der Speicherleistung die LP1-Ladeleistung angezeigt:
                    let LP1stattSpeicher = 1;
                    //--------------------------------------------------------------------------------------
                    // Sollen kleine Graphen als Hintergrund angezeigt werden? 0: Nein, 1: Ja
                    let Graphen = 1;
                    //--------------------------------------------------------------------------------------
                    // Sollen die einzelnen Werte und deren Graphen einen Rahmen haben?
                    // 0: Nein, 1-4: Breite der Rahmen
                    let Border = 3;
                    //--------------------------------------------------------------------------------------
                    // Wie sollen Namen, Footnotes und die einzelnen Werte in ihren Bereichen angeordnet sein?
                    // 0: Linksbündig, 1: zentriert
                    let Alignment = 1;
                    //--------------------------------------------------------------------------------------
                    // Soll im Widget-Titel das openWB-Logo angezeigt werden? 0: Nein, 1: Ja
                    let Logo = 1;
                    //--------------------------------------------------------------------------------------
                    // Titel des Widgets (steht hinter Logo wenn dieses angezeigt wird):
                    let Titel = "energy monitor - drego";
                    //--------------------------------------------------------------------------------------
                    // Die maximale Zeit, die für das Holen der Daten verwendet wird. Bei Fehlern kann diese Zeit erhöht werden:
                    let TimeOut = 1.0;
                    //--------------------------------------------------------------------------------------
                    // Soll bei einem Fehler (z.B. Zugriff auf das Widget aus dem Mobilfunk) statt dem Fehler
                    // ein Bild angezeigt werden? 0: Nein, 1: Ja
                    let BildBeiError = 0;
                    //--------------------------------------------------------------------------------------
                    // Name des unter File-Bookmarks hinterlegten Bildes, das bei einem Error angezeigt werden soll:
                    let ErrorImageName = "IMG_4832.jpg";
                    //--------------------------------------------------------------------------------------
                    
                    //--------------------------------------------------------------------------------------
                    // Konfiguration der Tresholds für die Farben der verschiedenen Daten
                    // Speicher Tresholds sind festgelegt auf Laden: Grün, Entladen: Rot, keine Ladung/Entladung: Gelb
                    // Netz Tresholds sind festgelegt auf Einspeisung: Grün, Bezug: Rot, keine Einspeisung/Bezug: Gelb
                    // Timestamp und Ladeleistung LP1 sind immer die Standard-Schriftfarbe (siehe unten)
                    // Im folgenden können die Tresholds für Hausverbrauch und PV festgelegt werden:
                    //--------------------------------------------------------------------------------------
                    // Treshold 1 für PV (über diesem Wert Gelb - darunter Rot), muss kleiner als Treshold2 sein!:
                    let pvTresh1 = 100;
                    //--------------------------------------------------------------------------------------
                    // Treshold 2 für PV (über diesem Wert Grün - darunter Gelb), muss größer als Treshold1 sein!:
                    let pvTresh2 = 5000;
                    //--------------------------------------------------------------------------------------
                    // Treshold 1 für Hausverbrauch (über diesem Wert Gelb - darunter Grün), muss kleiner als Treshold2 sein!:
                    let hausTresh1 = 400;
                    //--------------------------------------------------------------------------------------
                    // Treshold 2 für Hausverbrauch (über diesem Wert Rot - darunter Gelb), muss größer als Treshold1 sein!:
                    let hausTresh2 = 1000;
                    //--------------------------------------------------------------------------------------
                    
                    //--------------------------------------------------------------------------------------
                    // Im folgenden können die Farben des Widgets angepasst werden:
                    // z.B. weis: "FFFFFF", schwarz: "000000"; Eine gute Website dafür: https://htmlcolorcodes.com/
                    //--------------------------------------------------------------------------------------
                    // Standart-Schriftfarbe, für Überschrift, Footnotes usw.:
                    let TextColor = "FFFFFF";
                    //--------------------------------------------------------------------------------------
                    // Art des Widget-Hintergrunds, 0: einfarbig, 1: Farbverlauf
                    let BackgroundType = 1;
                    //--------------------------------------------------------------------------------------
                    // Farbe bei einfarbigem Hintergrund:
                    let BackgroundColor = "000000";
                    //--------------------------------------------------------------------------------------
                    // Verlauffarben bei Farbverlauf als Hintergrund:
                    let BackgroundGradient1 = "000000";
                    let BackgroundGradient2 = "202020";
                    //--------------------------------------------------------------------------------------
                    // Farben der Hintergrundgraphen:
                    let GraphColorPV = "F7DC6F";
                    let GraphColorNetz = "D7DBDD";
                    let GraphColorHaus = "7DCEA0";
                    let GraphColorSpeicher = "85C1E9";
                    let GraphColorSoC = "85C1E9";
                    // Wie blass oder stark sollen die Graphen sein? (Wert zwischen 0.1 und 1.0)
                    let GraphenStaerke = 0.4;
                    //--------------------------------------------------------------------------------------
                    // Farben der Rahmen der einzelnen Werte:
                    let BorderColorPV = "F7DC6F";
                    let BorderColorNetz = "D7DBDD";
                    let BorderColorHaus = "7DCEA0";
                    let BorderColorSpeicher = "85C1E9";
                    let BorderColorSoC = "85C1E9";
                    let BorderColorLP1 = "85C1E9";
                    let BorderColorTS = BorderColorSoC;
                    // Wie blass oder stark sollen die Rahmen sein? (Wert zwischen 0.1 und 1.0)
                    let BorderStaerke = 0.6;
                    //--------------------------------------------------------------------------------------
                    //--------------------------------------------------------------------------------------
                    
                    
                    
                    // Graph von https://kevinkub.de/
                    class LineChart {
                    
                    
                    constructor(width, height, values) {
                    this.ctx = new DrawContext();
                    this.ctx.size = new Size(width, height);
                    this.values = values;
                    }
                    
                    _calculatePath() {
                    let maxValue = Math.max(...this.values);
                    let minValue = Math.min(...this.values);
                    let difference = maxValue - minValue;
                    let count = this.values.length;
                    let step = this.ctx.size.width / (count - 1);
                    let points = this.values.map((current, index, all) => {
                    let x = step*index;
                    let y = this.ctx.size.height - (current - minValue) / difference * this.ctx.size.height;
                    return new Point(x, y);
                    });
                    return this._getSmoothPath(points);
                    }
                    
                    _getSmoothPath(points) {
                    let path = new Path();
                    path.move(new Point(0, this.ctx.size.height));
                    path.addLine(points[0]);
                    for(let i = 0; i < points.length-1; i++) {
                    let xAvg = (points[i].x + points[i+1].x) / 2;
                    let yAvg = (points[i].y + points[i+1].y) / 2;
                    let avg = new Point(xAvg, yAvg);
                    let cp1 = new Point((xAvg + points[i].x) / 2, points[i].y);
                    let next = new Point(points[i+1].x, points[i+1].y);
                    let cp2 = new Point((xAvg + points[i+1].x) / 2, points[i+1].y);
                    path.addQuadCurve(avg, cp1);
                    path.addQuadCurve(next, cp2);
                    }
                    path.addLine(new Point(this.ctx.size.width, this.ctx.size.height));
                    path.closeSubpath();
                    return path;
                    }
                    
                    configure(fn) {
                    let path = this._calculatePath();
                    if(fn) {
                    fn(this.ctx, path);
                    } else {
                    this.ctx.addPath(path);
                    this.ctx.fillPath(path);
                    }
                    return this.ctx;
                    }
                    
                    }
                    
                    
                    //--------------------------------------------------------------------------------------
                    //--------------------------------------------------------------------------------------
                    
                    // Allgemeine Widget-Einstellungen
                    let widget = new ListWidget();
                    //widget.url = widgetURL;
                    
                    widget.setPadding(20, 20, 20, 20);
                    let nextRefresh = Date.now() + 1000*30;
                    widget.refreshAfterDate = new Date(nextRefresh);
                    
                    // aktuellen Timestamp erstellen und formatieren
                    let date = new Date();
                    let df = new DateFormatter();
                    df.dateFormat = "HH:mm";
                    let timestamp = (df.string(date));
                    
                    // Aktuelle Datenn holen und Variablen initialisieren
                    let error = 0;
                    let pvW = (await getData("pvallwatt")*-1); // Wert ist negativ, deswegen *-1
                    let speicherW = (await getData("speicherleistung")*1); // Entladen ist negativ
                    let speicherSoC = (await getData("soc")*1);
                    let hausW = (await getData("hausverbrauch")*1);
                    let evuW = (await getData("wattbezug")*1); // Einspeissung ist negativ
                    let llp1 = (await getData("llaktuell")*1); // Ladeleistung von LP1
                    
                    // drego
                    let dailyPV = (await getData("daily_pvkwhk")*1); // tägl. Sonnenertrag
                    
                    let csv;
                    let data;
                    let pvData;
                    let bezugData;
                    let einspeisungData;
                    let ladenData;
                    let entladenData;
                    let socData;
                    let netzData;
                    let speicherData;
                    let hausData;
                    
                    // Historiedaten für Graphen holen und "aufbereiten"
                    if(Graphen == 1){
                    csv = await getCSV();
                    if(error == 0){
                    data = csvJSON(csv);
                    
                    pvData = getCalc(data, "PV");
                    bezugData = getCalc(data, "Bezug");
                    einspeisungData = getCalc(data, "Einspeisung");
                    ladenData = getCalc(data, "Laden");
                    entladenData = getCalc(data, "Entladen");
                    socData = getCalc(data, "SoC");
                    
                    netzData = [];
                    for(let i=0; i<12; i++){
                    netzData[i] = bezugData[i] - einspeisungData[i];
                    }
                    speicherData = [];
                    for(let i=0; i<12; i++){
                    speicherData[i] = ladenData[i] - entladenData[i];
                    }
                    // Hausverbrauch = Netzbezug + Speicherentladung + PV-Erzeugung - Netzeinspeisung - Speicherladung
                    hausData = [];
                    for(let i=0; i<12; i++){
                    hausData[i] = bezugData[i] + entladenData[i] + pvData[i] - einspeisungData[i] - ladenData[i];
                    }
                    }
                    }
                    
                    // vStackV ist vertikal, vStack0 ist ist Überschrift, vStack1 ist Zeile 1, vStack2 ist Zeile 2
                    let vStackV = widget.addStack();
                    vStackV.layoutVertically();
                    
                    let vStack0 = vStackV.addStack();
                    vStack0.layoutHorizontally();
                    vStack0.centerAlignContent();
                    vStackV.addSpacer();
                    let vStack1 = vStackV.addStack();
                    vStack1.layoutHorizontally();
                    vStackV.addSpacer();
                    let vStack2 = vStackV.addStack();
                    vStack2.layoutHorizontally();
                    let vStack3 = vStackV.addStack();
                    vStack3.layoutHorizontally();
                    
                    // Logo holen und darstellen
                    AlignStack(vStack0, 0);
                    if(Alignment == 1){
                    vStack0.addText(" ");
                    }
                    if(Logo == 1 && error == 0){
                    img = vStack0.addImage(await setLogo());
                    img.imageSize = new Size(50,20);
                    vStack0.addSpacer(10);
                    }
                    // Überschrift des Widgets
                    if(BildBeiError!= 1 || error == 0){
                    let header = vStack0.addText(Titel);
                    header.font = Font.mediumSystemFont(12);
                    header.textColor = new Color(TextColor);
                    }
                    AlignStack(vStack0, 1);
                    
                    // Inhalt des Widgets
                    if(error == 0){
                    // Hintergrundfarbe oder Verlauf festlegen
                    if(BackgroundType == 0){
                    widget.backgroundColor = new Color(BackgroundColor);
                    }
                    else{
                    const gradient = new LinearGradient()
                    gradient.locations = [0, 1]
                    gradient.colors = [ new Color(BackgroundGradient1), new Color(BackgroundGradient2) ]
                    widget.backgroundGradient = gradient
                    }
                    // Daten aufbereiten, berechnen und auf Widget darstellen
                    addDataView(vStack1, pvW.toString() + "W", defineColor(pvTresh1, pvTresh2, pvW), "PV", " ", BorderColorPV, createChart(pvData, GraphColorPV));
                    vStack1.addSpacer();
                    addDataView(vStack1, evuW.toString() + "W", defineColorNegative(-100, 100, evuW), "Netz", defineFootnote(100, -100, "Bezug", "Einspeisen", "Speicherregelung", evuW), BorderColorNetz, createChart(netzData, GraphColorNetz));
                    vStack1.addSpacer();
                    addDataView(vStack1, hausW.toString() + "W", defineColorNegative(hausTresh1, hausTresh2, hausW), "Haus", " ", BorderColorHaus, createChart(hausData, GraphColorHaus));
                    
                    addDataView(vStack2, speicherSoC.toString() + "%", defineColor(30, 70, speicherSoC), "SoC", "id.3", BorderColorSoC, createChart(socData, GraphColorSoC));
                    vStack2.addSpacer();
                    if(llp1 != 0 || LP1stattSpeicher == 1){
                    // Ladeleistung statt Speicherleistung
                    addDataView(vStack2, llp1.toString() + "W", "", "LP1", "Ladeleistung", BorderColorLP1);
                    }
                    else{
                    // Speicherleistung
                    addDataView(vStack2, speicherW.toString() + "W", defineColor(-100, 100, speicherW), "Speicher", defineFootnote(50, -50, "Laden", "Entladen", "Netzregelung", speicherW), BorderColorSpeicher, createChart(speicherData, GraphColorSpeicher));
                    }
                    vStack2.addSpacer();
                    addDataView(vStack2, dailyPV.toString() + "kW", "", "Ertrag", "Tägl. Sonne", BorderColorTS);
                    
                    // Überschrift des Widgets
                    let footer = vStack0.addText(timestamp);
                    footer.font = Font.mediumSystemFont(18);
                    footer.textColor = new Color(TextColor);
                    }
                    else{
                    // Wenn beim Holen der Daten ein Fehler aufgetreten ist
                    if(BildBeiError== 0){
                    // Fehlermeldung anzeigen
                    addDataView(vStack1, "Ein Fehler ist aufgetreten!", "red", "Ist openWB auf der IP " + oWBip + " erreichbar?", " ", 0);
                    addDataView(vStack2, timestamp + " Uhr", "", "Timestamp", " ", 0);
                    }
                    else{
                    // Bild anzeigen
                    let fm = FileManager.local();
                    let path = fm.bookmarkedPath(ErrorImageName);
                    let errorImage = fm.readImage(path);
                    widget.backgroundImage = errorImage;
                    }
                    }
                    
                    Script.setWidget(widget);
                    Script.complete();
                    // Größe der Widget-Vorschau
                    widget.presentMedium();
                    
                    
                    //--------------------------------------------------------------------------------------
                    //--------------------------------------------------------------------------------------
                    
                    
                    // Holt das Logo von oWB und bearbeitet dieses
                    async function setLogo(){
                    let result;
                    try{
                    let imgReq = new Request("http://" + oWBip + "/openWB/web/img/favicons/apple-icon-180x180.png");
                    imgReq.timeoutInterval = TimeOut;
                    let image = await imgReq.loadImage();
                    dc = new DrawContext();
                    dc.opaque = true;
                    dc.size = new Size(180,56);
                    dc.drawImageAtPoint(image, new Point(-0, -54));
                    result = dc.getImage();
                    }
                    catch(err){
                    error = 1;
                    }
                    return(result);
                    }
                    
                    
                    // zentriert/linksbündigt/rechtbündigt Text
                    function AlignStack(stack, pos){
                    if(Alignment == 1 || (Alignment == 0 && pos == 1)){
                    stack.addSpacer();
                    }
                    }
                    
                    
                    // legt ein neues Datenstack an
                    function addDataView(widget, data, color, name, foot, BorderColor, img){
                    let viewStack = widget.addStack();
                    viewStack.layoutVertically();
                    viewStack.cornerRadius = 5;
                    
                    if(BorderColor != 0){
                    viewStack.size = new Size(97, 47);
                    viewStack.borderWidth = Border;
                    viewStack.borderColor = new Color(BorderColor, BorderStaerke);
                    viewStack.setPadding(5, 5, 5, 3);
                    }
                    
                    let labelStack = viewStack.addStack();
                    AlignStack(labelStack, 0);
                    let label = labelStack.addText(name);
                    label.font = Font.mediumSystemFont(12);
                    label.textColor = new Color(TextColor);
                    AlignStack(labelStack, 1);
                    
                    let footnoteStack = viewStack.addStack();
                    AlignStack(footnoteStack, 0);
                    let footnote = footnoteStack.addText(foot);
                    footnote.font = Font.mediumSystemFont(8);
                    footnote.textColor = new Color(TextColor);
                    AlignStack(footnoteStack, 1);
                    
                    let valueStack = viewStack.addStack();
                    AlignStack(valueStack, 0);
                    let value = valueStack.addText(data);
                    value.font = Font.mediumSystemFont(18);
                    value.textColor = colorForString(color);
                    AlignStack(valueStack, 1);
                    
                    if(Graphen == 1){
                    viewStack.backgroundImage = img;
                    }
                    }
                    
                    
                    // holt die aktuellen Daten
                    async function getData(file){
                    let result = 0;
                    try {
                    let url = "http://" + oWBip + "/openWB/ramdisk/" + file;
                    let req = new Request(url);
                    req.timeoutInterval = TimeOut;
                    result = await req.loadString();
                    }
                    catch(err) {
                    result = 0;
                    error = 2;
                    }
                    return(result);
                    }
                    
                    
                    // Legt Farbe fest
                    function defineColor(TreshYellow, TreshGreen, value){
                    if (value >= TreshGreen){
                    return("green");
                    }
                    else if (value >= TreshYellow){
                    return("yellow");
                    }
                    else{
                    return("red");
                    }
                    }
                    
                    
                    // Legt Farbe fest
                    function defineColorNegative(TreshYellow, TreshRed, value){
                    if (value >= TreshRed){
                    return("red");
                    }
                    else if (value >= TreshYellow){
                    return("yellow");
                    }
                    else{
                    return("green");
                    }
                    }
                    
                    
                    // Legt Footnote fest
                    function defineFootnote(groesserAls, kleinerAls, groesserText, kleinerText, sonstText, value){
                    if (value > groesserAls){
                    return(groesserText);
                    }
                    else if (value < kleinerAls){
                    return(kleinerText);
                    }
                    else{
                    return(sonstText);
                    }
                    }
                    
                    
                    //Gibt das entsprechende Color-Objekt zurück
                    function colorForString(colorString){
                    if (colorString == "red") {
                    return Color.red();
                    }
                    if (colorString == "yellow") {
                    return Color.yellow();
                    }
                    if (colorString == "green") {
                    return Color.green();
                    }
                    return (new Color(TextColor));
                    }
                    
                    
                    // Erstellt Graph und liefert Bild davon zurück
                    function createChart(data, color){
                    if(Graphen == 1){
                    let chart = new LineChart(97, 47, data).configure((ctx, path) => {
                    ctx.opaque = false;
                    ctx.setFillColor(new Color(color, GraphenStaerke));
                    ctx.addPath(path);
                    ctx.fillPath(path);
                    }).getImage();
                    return(chart);
                    }
                    }
                    
                    
                    // Holt CSV-Daten von oWB
                    async function csvRequest(date){
                    let txt;
                    let df = new DateFormatter();
                    df.dateFormat = "YYYYMMdd";
                    let fdate = (df.string(date));
                    let url = ("http://" + oWBip + "/openWB/web/logging/data/daily/" + fdate + ".csv");
                    let req = new Request(url);
                    req.timeoutInterval = TimeOut;
                    try{
                    txt = await req.loadString();
                    }
                    catch(err){
                    error = 3;
                    }
                    return(txt);
                    }
                    
                    
                    // Zusammensetzen der CSV-Daten des aktuellen und des vorherigen Tages
                    async function getCSV(){
                    let txt
                    let date = new Date();
                    today = await csvRequest(date);
                    date.setDate(date.getDate()-1)
                    yesterday = await csvRequest(date);
                    result = yesterday + today;
                    return(result);
                    }
                    
                    
                    // Kalkuliert die Differenz zwischen den Werten der letzten Stunde
                    function getCalc(data, key){
                    let result = [];
                    let resultVar = 11;
                    for(let i=0; i<12; i++){
                    if(key != "SoC"){
                    result[resultVar] = Number((data[data.length-2-i][key]) - Number(data[data.length-3-i][key]));
                    }
                    else{
                    result[resultVar] = Number(data[data.length-2-i][key]);
                    }
                    resultVar --;
                    }
                    return(result);
                    }
                    
                    
                    // Konvertiert CSV zu einem Objekt
                    function csvJSON(csv){
                    let lines = csv.split("\n");
                    let result = [];
                    let headers = ["Zeit", "Bezug", "Einspeisung", "PV", "1", "2", "3", "4", "Laden", "Entladen", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "SoC", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32"]
                    for(let i=0;i<lines.length;i++){
                    let obj = {};
                    let currentline=lines[i].split(",");
                    for(let j=0;j<headers.length;j++){
                    obj[headers[j]] = currentline[j];
                    }
                    result.push(obj);
                    }
                    return(result);
                    }

                    Kommentar


                      #11
                      Läßt sich das Widget so programmieren das es eine Webseite in entsprechender Größe von EDOMI anzeigt?
                      Denke damit ist man am flexibelsten.

                      Kommentar


                        #12
                        Nein, dass geht nicht.
                        Die Widgets sind außerdem unter iOS statisch. Aktualisieren sich auch nur aller 5 bis 7 Minuten wegen Batteriemanagement.

                        Kommentar


                          #13
                          vento66 : die Beispiele waren mir alle zu einfach /unflexibel. Es wird hier demnächst ein sehr flexibles, komplett von edomi aus konfigurierbares scriptable-Widget von mir geben. Man kann auch fast völlig frei customizen welcher Werte wo wie dargestellt wird. Es hat wegen der externen Customizingoptionen seine Längen... Dafür muss man nicht auf dem fummeligen Display herum ändern, wenn einem mal eine Farbe oder ein Icon nicht passt - wird komplett von edomi aus per JSON erfolgen. Direkt im LiveView änderbar und peng.

                          Ich kann das gerne hier per copy&paste als Code-Teil einfügen. Oder findest Du das besser im Download-Bereich? Da es vermutlich nur eine überschaubare Anzahl an Scripten geben wird, reicht es vermutlich hier, oder? Hätte auch den Vorteil, dass man es direkt auf dem iPhone hier kopieren und einfügen kann.
                          Nachtrag
                          gaert Darf ich für den knappen Platz im Widget das so wunderbar augenfällige und mit hohem Wiedererkennungswert gestaltetet "O" mit "Dach" aus dem edomi-SVG übernehmen? Bevorzugt das mit dem auffälligen grünen Kranz wie auf Deiner homepage. Für den ganzen Schriftzug ist kein Platz... Ich würde das SVG vermutlich direkt im Widget einbetten.

                          Nachtrag: Hat sich erledigt, Christian. Habe die Struktur des Widgets verändert, jetzt ist Platz für das gesamte Logo. Ich bediene mich (per URL) nun an dem kompletten Logo aus dem Wiki hier bzw. kann jeder selber wählen.

                          Nachtrag: eine aktuelle Arbeitshypothese:
                          23C58207-69A2-4D6B-9F28-A846E694FB84.jpeg
                          Zuletzt geändert von saegefisch; 08.06.2021, 18:34.

                          Kommentar


                            #14
                            Poste es mal hier, im Bedarfsfall schieb ich das in den DL Bereich.

                            Kommentar


                              #15
                              Guten Morgen,

                              saegefisch hattest du hier noch deine arbeit veröffentlich? Oder wurde das Projekt von dir auf Eis gelegt?
                              Wäre stark interessiert

                              Kommentar

                              Lädt...
                              X