Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. Blocky: Benachrichtigung bzgl. Mülltonne am Vorabend

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Blocky: Benachrichtigung bzgl. Mülltonne am Vorabend

    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      tempestas last edited by

      Das Problem, das ich sehe ist, dass es schwierig ist zu bestimmen, welchen Bereich aus dem Kalender man quasi "ausschneiden" muss, um die korrekte Antwort zu liefern.

      'Morgen' zu suchen und eine Telegram Message zu senden ist kein Thema, den entsprechenden Müll dazu wird schwieriger, aber ich hab eine Idee. Wird aber kein Blockly.

      Aber JS zu importieren wirst du ja schaffen

      1 Reply Last reply Reply Quote 0
      • T
        tempestas last edited by

        So, hier das Skript in der v1, die in der Basis schonmal funktioniert (habs mit nem Teststring ausprobiert).

        Wird noch nicht laufen, wenn es mehrfach "morgen müll xyz" gibt.

        Bedingung: es muss ein eigener Kalender für den Müll sein

        ! ````
        ! // Skript schaut täglich um 18h, ob im Müllkalender das Wort "Morgen" vorkommt. Wenn ja, wird ein Telegram geschickt mit der betreffenden Müllsorte
        ! function muellWarnung() {
        ! var inhalt = getState("ical.0.data.html").val.toString(); // hier deine Müll-Kalender Instanz eingeben
        var posStart = inhalt.indexOf( 'Morgen', 0);
        ! if(posStart != -1) { // falls "Morgen" nicht gefunden wird, passiert nichts weiter
        ! var stringShort = inhalt.substring(posStart, inhalt.length);
        var pos2 =stringShort.indexOf('
        ', 0);
        var stringCut = stringShort.substring(0, pos2);
        ! log("gekürzter String: "+stringCut);
        ! // aufbereiten für telegram, entfernen von HTML Tags
        ! // remove all inside SCRIPT and STYLE tags
        stringCut=stringCut.replace(/<script.>[\w\W]{1,}(.?)[\w\W]{1,}</script>/gi, "");
        stringCut=stringCut.replace(/<style.>[\w\W]{1,}(.?)[\w\W]{1,}</style>/gi, "");

            // remove BR tags. Werden durch sinnlose Zeichenkette ersetzt, nach der später gesucht wird
            stringCut=stringCut.replace(/
        

        /gi, "");
        stringCut=stringCut.replace(/<br\s>/gi, "");
        stringCut=stringCut.replace(/<br>/gi, "");

            // remove all else
            stringCut=stringCut.replace(/<(?:.|\s)*?>/g, "");
        
            // get rid of html-encoded characters:
            stringCut=stringCut.replace(/ /gi," ");
            stringCut=stringCut.replace(/&/gi,"&");
            stringCut=stringCut.replace(/"/gi,'"');
            stringCut=stringCut.replace(//gi,'>');
        

        !
        sendTo('telegram', stringCut);

        }
        

        }

        ! // Trigger Schedule
        ! schedule('0 18 * * ', function(){
        ! muellWarnung();
        });</br></br\s></style.
        ></script.*>

        
        Für das Thema mit 2x Müll morgen habe ich aber auch schon eine Idee. Kommt nachher
        1 Reply Last reply Reply Quote 0
        • T
          tempestas last edited by

          Hier die v2, funktioniert auch für mehrere Müllsorten 'Morgen'.

          Lass hören, ob es Fehler gibt.

          Ich konnte es natürlich nur mit einem Testrstring ausprobieren, das hat wie gewünscht funktioniert.

          ! ````
          ! // Skript schaut täglich um 18h, ob im Müllkalender das Wort "Morgen" vorkommt. Wenn ja, wird ein Telegram geschickt mit der betreffenden Müllsorte
          ! // Skripteinstellungen
          ! var debug = false;
          ! // Suchfunktion für Termin-Cutoff

          function nthIndex(str, pat, n){
          var L= str.length, i= -1;
          while(n-- && i++ <l){ i="str.indexOf(pat," i);/if/(i/</0)/break;/}/i_search="i;" müll-funktion/function/muellwarnung()/{/var/inhalt="getState("ical.0.data.html").val.toString();" hier/deine/müll-kalender/instanz/eingeben/count="inhalt.split("Morgen").length" -1;/wie/häufig/wird/"morgen"/gefunden?/posstart="inhalt.indexOf(" 'morgen',/0);/sucht/das/erste/mal/if(debug)/log("posstart/"+posstart);/if(posstart/!="-1){" falls/gefunden/wurde/gehts/weiter/stringshort="inhalt.substring(posStart," inhalt.length);/abschneiden/von/allem,/was/links/vom/ersten/treffer/steht/log("gekürzt/:"/+stringshort);/nthindex(stringshort,/'</span="">', count); // hier wird nun geschaut, wo es rechts abgeschnitten werden muss
          stringCut = stringShort.slice(0,i_search); // hier wird alles rechts abgeschnitten und so der finale String extrahiert

          if(debug) log("Fast Final: "+stringCut);
          

          ! // aufbereiten für telegram, entfernen von HTML Tags
          ! stringCut = stringCut.replace('
          ',"\n"); // Zeilenumbruch html durch telegram umbruch ersetzen
          ! // remove all inside SCRIPT and STYLE tags
          stringCut=stringCut.replace(/<script.>[\w\W]{1,}(.?)[\w\W]{1,}</script>/gi, "");
          stringCut=stringCut.replace(/<style.>[\w\W]{1,}(.?)[\w\W]{1,}</style>/gi, "");

              // remove BR tags. Werden durch sinnlose Zeichenkette ersetzt, nach der später gesucht wird
              stringCut=stringCut.replace(/
          

          /gi, "");
          stringCut=stringCut.replace(/<br\s>/gi, "");
          stringCut=stringCut.replace(/<br>/gi, "");

              // remove all else
              stringCut=stringCut.replace(/<(?:.|\s)*?>/g, "");
          
              // get rid of html-encoded characters:
              stringCut=stringCut.replace(/ /gi," ");
              stringCut=stringCut.replace(/&/gi,"&");
              stringCut=stringCut.replace(/"/gi,'"');
              stringCut=stringCut.replace(//gi,'>');
          

          !
          sendTo('telegram', stringCut);

          }
          

          }

          ! // Trigger Schedule
          ! schedule('0 18 * * ', function(){ // Täglich um 18h
          ! muellWarnung();
          });
          ! // Bei Start
          ! muellWarnung();</br></br\s></style.
          ></script.*></l){>

          1 Reply Last reply Reply Quote 0
          • K
            Kuddel last edited by

            Bisher habe ich den Telegram Adapter nicht am laufen.

            Ich müsste wenn dann auf den E-Mail Adapter ausweichen…

            1 Reply Last reply Reply Quote 0
            • T
              tempestas last edited by

              Vielleicht liegts ja an mir, aber ein "…." am Ende wirkt für mich in der Schriftsprache immer wie ein latenter Vorwurf. So wie ALLES IN GROß wie rumschreien wirkt.

              den Email adapter kenne ich nicht, aber ich rate mal dass das hier

                     sendTo('telegram', stringCut);       
              

              einfach

                      sendTo('email', stringCut);       
              

              heißen muss.

              und wahrscheinlich ist die Aufbereitung nicht notwendig.

              Ob eine E-Mail täglich um 18h sinnig ist, ist ja dir überlassen. Ist ja nicht gerade die direkteste Form der Kommunikation

              1 Reply Last reply Reply Quote 0
              • K
                Kuddel last edited by

                Habe es jetzt auf "email" geändert und den Trigger auf 10:35 geändert. Ich bin gespannt was passiert.

                Auch wenn ich das JavaScript so gut wie gar nicht verstehe, vielen Dank schon einmal bis hier her.

                EDIT:

                Ergebnis nach dem ersten Lauf:

                Der Betreff der Mail ist leider leer.

                Im Body der Mail stehen alle Termine aus ical.data.html.

                Mir würde es quasi reichen wenn im Betreff steht: "Morgen gelber Sack" und der Body leer ist.

                Das reich mir als Erinnerung.

                1 Reply Last reply Reply Quote 0
                • T
                  tempestas last edited by

                  ich habs oben in dem Skript nochmal erläutert, was da passiert.

                  Aber gerne nochmal mein Gedankenansatz erläutert:

                  im ical html steht z.B. sowas hier drinnen

                  "Heute  Bioabfall(14-täglich)
                   Morgen  Gelber Sack (14-täglich) 
                   Morgen   Bioabfall(14-täglich) 
                   21.09.2017   Restabfall 40L-80L(4-wöchentlich)  
                  ";
                  ````(das war übrigens mein Teststring).
                  
                  Es gilt also:
                  
                  a) zu prüfen wie häufig "Morgen" auftaucht
                  
                  b) alles links davon und alles rechts davon abzuschneiden, denn wir wollen ja nur den Bereich haben, der sich auf morgen bezieht.
                  
                  Dazu zählt das Skript zunächst, wie häufig "Morgen" auftaucht.
                  
                  Danach sucht es die Position im String des ersten "Morgen" raus und schneidet alles links davon ab.
                  
                  Der so geschaffene Zwischenstring (stringShort) sieht dann erstmal so aus:
                  

                  Morgen Gelber Sack (14-täglich)
                  Morgen Bioabfall(14-täglich)
                  21.09.2017 Restabfall 40L-80L(4-wöchentlich)
                  ";

                  
                  muss also auch noch bearbeitet werden.
                  
                  Wir haben eine Variable (count), die gezählt hat, wie häufig das wort "Morgen" auftaucht. Hier 2x.
                  
                  mit der Funktion nthIndex passiert jetzt folgendes:
                  
                  Die Funktion sucht nach dem 2ten mal (entsprechend der Variable "count"), an dem diese Zeichenkette auftaucht und merkt sich die Position.
                  
                  ich mache mir hier zu nutze, dass der ical adapter die einzelnen Termine mit dieser Zeichenkette trennt.
                  
                  Über die gemerkte Position ("i_search") schneide ich dann aus dem gekürzten String (stringShort) alles ab, was rechts von dieser Position kommt.
                  
                  Damit bleibt dann der stringFinal, der nur noch etwas aufbereitet wird für die Versendung via Telegram
                  1 Reply Last reply Reply Quote 0
                  • T
                    tempestas last edited by

                    @Kuddel:

                    Habe es jetzt auf "email" geändert und den Trigger auf 10:35 geändert. Ich bin gespannt was passiert.

                    Auch wenn ich das JavaScript so gut wie gar nicht verstehe, vielen Dank schon einmal bis hier her.

                    EDIT:

                    Ergebnis nach dem ersten Lauf:

                    Der Betreff der Mail ist leider leer.

                    Im Body der Mail stehen alle Termine aus ical.data.html.

                    Mir würde es quasi reichen wenn im Betreff steht: "Morgen gelber Sack" und der Body leer ist.

                    Das reich mir als Erinnerung. `

                    wie gesagt, den email adapter kenne ich nicht.

                    Hast du die Instanz des ical an deinen Müllkalender angepasst? Du schreibst nämlich grundsätzlich ohne die Instanz, das macht es schwer zu raten, welche Nummer die relevante Instanz hat.

                    1 Reply Last reply Reply Quote 0
                    • T
                      tempestas last edited by

                      Habe den Fehler gefunden

                      Der cutoff muss nicht bei

                      heißen sondern

                      damit sollte es gehen.

                      Habs oben im Skript korrigiert und es jetzt mal mit meinem eigenen Kalender und nicht mit einem Teststring ausprobiert, funktioniert

                      1 Reply Last reply Reply Quote 0
                      • T
                        tempestas last edited by

                        Hier nun mit email, ungetestet mangels adapter

                        Dran denken, deine ical instanz noch einzustellen

                        ! ````
                        ! // Skript schaut täglich um 18h, ob im Müllkalender das Wort "Morgen" vorkommt. Wenn ja, wird ein Telegram geschickt mit der betreffenden Müllsorte
                        ! // Skripteinstellungen
                        ! var debug = false;
                        ! // Suchfunktion für Termin-Cutoff

                        function nthIndex(str, pat, n){
                        var L= str.length, i= -1;
                        while(n-- && i++ <l){ i="str.indexOf(pat," i);/if/(i/</0)/break;/}/i_search="i;" müll-funktion/function/muellwarnung()/{/var/inhalt="getState("ical.0.data.html").val.toString();" hier/deine/müll-kalender/instanz/eingeben/count="inhalt.split("Morgen").length" -1;/wie/häufig/wird/"morgen"/gefunden?/posstart="inhalt.indexOf(" 'morgen',/0);/sucht/das/erste/mal/if(debug)/log("posstart/"+posstart);/if(posstart/!="-1){" falls/gefunden/wurde/gehts/weiter/stringshort="inhalt.substring(posStart," inhalt.length);/abschneiden/von/allem,/was/links/vom/ersten/treffer/steht/log("gekürzt/:"/+stringshort);/nthindex(stringshort,/'</span="">', count); // hier wird nun geschaut, wo es rechts abgeschnitten werden muss
                        stringCut = stringShort.slice(0,i_search); // hier wird alles rechts abgeschnitten und so der finale String extrahiert

                        if(debug) log("Fast Final: "+stringCut);
                        

                        ! // aufbereiten für email, entfernen von HTML Tags
                        ! stringCut = stringCut.replace('
                        ',"\n"); // Zeilenumbruch html durch telegram umbruch ersetzen
                        ! // remove all inside SCRIPT and STYLE tags
                        stringCut=stringCut.replace(/<script.>[\w\W]{1,}(.?)[\w\W]{1,}</script>/gi, "");
                        stringCut=stringCut.replace(/<style.>[\w\W]{1,}(.?)[\w\W]{1,}</style>/gi, "");

                            // remove BR tags. Werden durch sinnlose Zeichenkette ersetzt, nach der später gesucht wird
                            stringCut=stringCut.replace(/
                        

                        /gi, "");
                        stringCut=stringCut.replace(/<br\s>/gi, "");
                        stringCut=stringCut.replace(/<br>/gi, "");

                            // remove all else
                            stringCut=stringCut.replace(/<(?:.|\s)*?>/g, "");
                        
                            // get rid of html-encoded characters:
                            stringCut=stringCut.replace(/ /gi," ");
                            stringCut=stringCut.replace(/&/gi,"&");
                            stringCut=stringCut.replace(/"/gi,'"');
                            stringCut=stringCut.replace(//gi,'>');
                        

                        ! sendTo("email", {
                        from: "iobroker@mydomain.com", // anpassen
                        to: "aabbcc@gmail.com", // anpassen
                        subject: stringcut,
                        text: "Die freundliche Müll-Erinnerung"
                        });

                        }
                        }

                        ! // Trigger Schedule
                        ! schedule('0 18 * * ', function(){ // Täglich um 18h
                        ! muellWarnung();
                        });
                        ! // Bei Start
                        ! muellWarnung();</br></br\s></style.
                        ></script.*></l){>

                        1 Reply Last reply Reply Quote 0
                        • K
                          Kuddel last edited by

                          Ich hab das Ganze jetzt mit einem kleinen Umweg anders geregelt.

                          Ich habe eine weitere Instanz des Ical Adapters installiert und dort dann wie schon bei Ical.0 den "Müllkalender" eingetragen.

                          Aktuell wird aber immer nur der nächste Tag abgefragt.

                          Somit habe ich jetzt im Datenpunkt Ical.3.data.html immer nur einen bzw. keinen Eintrag:

                          Morgen gelber Sack
                          

                          Damit konnte ich jetzt auch mit Blockly eine entsprechende Abfrage bauen und eine Info-Mail versenden:
                          3467_skript.png

                          Skript Export:

                          ! ````
                          <xml xmlns="http://www.w3.org/1999/xhtml"><block type="schedule" id="VgJIE04UN8-6)0#sjl!/" x="-538" y="2112"><field name="SCHEDULE">0 18 * * </field>
                          <statement name="STATEMENT"><block type="controls_if" id="zpuAP)!W[.:x5x9t/~H-"><value name="IF0"><block type="logic_operation" id="GX4/::!!:4q.fk52Cg4s" inline="false"><field name="OP">OR</field>
                          <value name="A"><block type="logic_operation" id="r6)BxDTC.m+Xo?_aimH%" inline="false"><field name="OP">OR</field>
                          <value name="A"><block type="logic_compare" id="[^7h}t-)va+M3z_O(C5V"><field name="OP">EQ</field>
                          <value name="A"><block type="get_value" id="U9|2o/#_T{gb}U^o||Io"><field name="ATTR">val</field>
                          <field name="OID">ical.3.data.html</field></block></value>
                          <value name="B"><block type="text" id="#Dxj=vdvB:sI#ZKMWjn;"><field name="TEXT">Morgen Gelber Sack</field></block></value></block></value>
                          <value name="B"><block type="logic_compare" id="zT@NwiS%sPq-0g6t-}tO"><field name="OP">EQ</field>
                          <value name="A"><block type="get_value" id="V!pf?iJ4T~-rMfJ]pb
                          P"><field name="ATTR">val</field>
                          <field name="OID">ical.3.data.html</field></block></value>
                          <value name="B"><block type="text" id="@{aLO,T~L7%.%TcuemQp"><field name="TEXT">Morgen Altpapier</field></block></value></block></value></block></value>
                          <value name="B"><block type="logic_compare" id="cHVZ3d;[%Wqd?J^6q?U:"><field name="OP">EQ</field>
                          <value name="A"><block type="get_value" id="7{zN}%4rF5(,3aR8HIEV"><field name="ATTR">val</field>
                          <field name="OID">ical.3.data.html</field></block></value>
                          <value name="B"><block type="text" id=":rsXSbD(UZe.+37T,l@3"><field name="TEXT">Morgen Hausmüll 4-wöchentlich</field></block></value></block></value></block></value>
                          <statement name="DO0"><block type="comment" id="XCm=T,]SrE(PrPW:[)~x"><field name="COMMENT">Mail-Betreff setzen</field>
                          <next><block type="comment" id="BMVF]PPyKjkgJL?~[H2C"><field name="COMMENT">Gelber Sack</field>
                          <next><block type="controls_if" id="DnfGOFnsi+TCY!qm4t|^"><value name="IF0"><block type="logic_compare" id="K;D,/5%J#NB([M1q/nj"><field name="OP">EQ</field> <value name="A"><block type="get_value" id="n;,=06D:RWw9/sem3EU"><field name="ATTR">val</field>
                          <field name="OID">ical.3.data.html</field></block></value>
                          <value name="B"><block type="text" id="JV^x}[CFgCwi}6]U,tPf"><field name="TEXT">Morgen Gelber Sack</field></block></value></block></value>
                          <statement name="DO0"><block type="variables_set" id="(p/}(x,Ies0{FZU1]SiA"><field name="VAR">betreff_1</field>
                          <value name="VALUE"><block type="text" id="71|?g1O+]!pX6)@7KKU"><field name="TEXT">+++ Morgen Gelber Sack ++</field></block></value>
                          <next><block type="variables_set" id="|EI{gjF
                          3~Zqt7rJwxYt"><field name="VAR">body</field>
                          <value name="VALUE"><block type="text" id="h6^DGXj9B(wWFrK:2,n!"><field name="TEXT">Die gelben Säcke werden morgen abgeholt. Bitte an die Straße stellen</field></block></value></block></next></block></statement>
                          <next><block type="comment" id="9Kr:U?4MF.DnS]B+.)j"><field name="COMMENT">Altpapier</field>
                          <next><block type="controls_if" id="lfcdJ3](HHt@xM7=/Eae"><value name="IF0"><block type="logic_compare" id="U=VHQ#(tMyr25TQ_4pcu"><field name="OP">EQ</field>
                          <value name="A"><block type="get_value" id="VAF(D/astXbskBtI7rDL"><field name="ATTR">val</field>
                          <field name="OID">ical.3.data.html</field></block></value>
                          <value name="B"><block type="text" id="FhQRTPmL!:-B1yX~SVl4"><field name="TEXT">Morgen Altpapier</field></block></value></block></value>
                          <statement name="DO0"><block type="variables_set" id="uBei+UsEUR[
                          xUfptEk"><field name="VAR">betreff_1</field>
                          <value name="VALUE"><block type="text" id="aRjXrdl=g3kx,CM(U%5o"><field name="TEXT">+++ Morgen Altpapier ++</field></block></value>
                          <next><block type="variables_set" id="yb%Ur#|=AEcwG%=_O%}"><field name="VAR">body</field>
                          <value name="VALUE"><block type="text" id="R;I3d@AujObt}0Z3j9)v"><field name="TEXT">Das Altpapier wird morgen abgeholt. Bitte die Tonne an die Straße stellen</field></block></value></block></next></block></statement>
                          <next><block type="comment" id="OgMJu6fn+YLg
                          c4h_3-u"><field name="COMMENT">Hausmüll</field>
                          <next><block type="controls_if" id="g~sMnV8~]448x6Cv.N"><value name="IF0"><block type="logic_compare" id="0UfpCkGXEb~^pgy7kDP!"><field name="OP">EQ</field> <value name="A"><block type="get_value" id="cD?5q=pH4kAC;i_)c.E("><field name="ATTR">val</field> <field name="OID">ical.3.data.html</field></block></value> <value name="B"><block type="text" id="f/6Tz_,l:aA)lxlu8Bz"><field name="TEXT">Morgen Hausmüll 4-wöchentlich</field></block></value></block></value>
                          <statement name="DO0"><block type="variables_set" id="XKt(zy?pP]Z6
                          4IxeS8x"><field name="VAR">betreff_1</field>
                          <value name="VALUE"><block type="text" id="{Gu8t-odK!c{r}X0/?%C"><field name="TEXT">+++ Morgen Hausmüll ++</field></block></value>
                          <next><block type="variables_set" id="P9gq]pKX5jIvhgd8A7C?"><field name="VAR">body</field>
                          <value name="VALUE"><block type="text" id="=h]S%uFCO(#J;;*x?w/R"><field name="TEXT">Die Mülltonne wird morgen abgeholt. Bitte die Tonne an die Straße stellen</field></block></value></block></next></block></statement>
                          <next><block type="email" id=":]m[.k![
                          ?EDqwcVFi]z"><field name="IS_HTML">FALSE</field>

                                                              <value name="TO"><shadow type="text" id="Fff@n}|]KO[!@EWniLQG"><field name="TEXT">test@test.de</field></shadow></value> 
                                                              <value name="TEXT"><shadow type="text" id="c]8|_`9OE9T;rt(!17_v"></shadow> 
                                                                <block type="variables_get" id="j)o(;{#e.1B1R*2LY~7{"><field name="VAR">body</field></block></value> 
                                                              <value name="SUBJECT"><shadow type="text" id="kE0d_2]I(bZ=ns%bhsE6"></shadow> 
                                                                <block type="variables_get" id="!6+=^wd;B6NRusxh3Miu"><field name="VAR">betreff_1</field></block></value></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></statement></block></statement></block></xml> 
                          

                          ! ````

                          1 Reply Last reply Reply Quote 0
                          • T
                            tempestas last edited by

                            Schön!

                            Das funktioniert jetzt aber imho natürlich nur, wenn alles 100% ist wie bei dir (falls jemand anderes das kopieren will)

                            1 Reply Last reply Reply Quote 0
                            • K
                              Kuddel last edited by

                              @tempestas:

                              Schön!

                              Das funktioniert jetzt aber imho natürlich nur, wenn alles 100% ist wie bei dir (falls jemand anderes das kopieren will) `

                              Das stimmt natürlich.

                              Man müsste sicherlich den Ical Dapter anpassen und die Benennung der Einträge im Kalender.

                              Mein Vorschlag ist auch eher an die Leute gedacht, die wie ich noch keine Kenntnisse in Java haben und sich daher mit Blockly helfen

                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post

                              Support us

                              ioBroker
                              Community Adapters
                              Donate

                              816
                              Online

                              31.9k
                              Users

                              80.2k
                              Topics

                              1.3m
                              Posts

                              2
                              18
                              1965
                              Loading More Posts
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes
                              Reply
                              • Reply as topic
                              Log in to reply
                              Community
                              Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                              The ioBroker Community 2014-2023
                              logo