<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[[Gelöst] text2command mit Telegram: verkettete Befehle...?]]></title><description><![CDATA[<p dir="auto">Hallo zusammen,</p>
<p dir="auto">ich möchte per Telegram ein Datum in einem Datenpunkt speichern. Um die Eingabe zu erleichtern habe ich mir per Javascript die Arrays für die Telegram-Tastaturen zusammengebaut:</p>
<ol>
<li>Jahr (dieses, sowie 3 folgenden)</li>
<li>Monat (abhängig vom Jahr - dieser Monat bis zum Ende des Jahres oder alle Monate, wenn das gewählte Jahr in der Zukunft liegt)</li>
<li>Tag (abhängig von Jahr und Monat - heute bis zum Ende des Monats, oder alle Tage zukünftiger Monate)</li>
</ol>
<p dir="auto">Das ist meiner Ansicht nach intuitiv und man kann kein Datum aus der Vergangenheit wählen.</p>
<p dir="auto">Jetzt kommt die Schwierigkeit: das ganze muss auch verarbeitet werden und so stelle ich mir das vor:</p>
<ol>
<li>man sendet ein Schlüsselwort als Befehl, auf den Text2Command reagiert, die Tastatur für die Jahresauswahl wird angezeigt</li>
<li>Man wählt das Jahr, gesendet wird zum Beispiel <code>2023</code>, das irgendwo gespeichert wird</li>
<li>Die Tastatur für den Monat wird angezeigt</li>
<li>Man wählt den Monat, zum Beispiel <code>Jan</code>, der wieder irgendwo gespeichert wird</li>
<li>Die Tastatur für den Tag wird angezeigt</li>
<li>Man wählt den Tag, zum Beispiel <code>12</code>, der wieder irgendwo gespeichert wird</li>
</ol>
<p dir="auto">Erst jetzt ist die Eingabe abgeschlossen.</p>
<p dir="auto">Was nicht passieren darf ist, dass ich aus dem Nichts heraus einfach nur <code>23</code> über die ganz normale Tastatur eingebe und dies als Teil des Datums interpretiert wird, wenn ich nicht zuvor das Schlüsselwort gesendet habe.</p>
<p dir="auto">War das irgendwie verständlich? Hat jemand eine Idee, wie man das lösen kann?</p>
]]></description><link>https://forum.iobroker.net/topic/57014/gelöst-text2command-mit-telegram-verkettete-befehle</link><generator>RSS for Node</generator><lastBuildDate>Tue, 19 May 2026 21:07:35 GMT</lastBuildDate><atom:link href="https://forum.iobroker.net/topic/57014.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 09 Aug 2022 12:59:03 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [Gelöst] text2command mit Telegram: verkettete Befehle...? on Wed, 10 Aug 2022 11:43:09 GMT]]></title><description><![CDATA[<p dir="auto">Ich habs hinbekommen :)</p>
<p dir="auto">Laut der Github-Doku des Adapters kann man Regeln auch per Script verarbeiten:<br />
<a href="https://github.com/ioBroker/ioBroker.text2command#external-rules-with-javascript" rel="nofollow ugc">https://github.com/ioBroker/ioBroker.text2command#external-rules-with-javascript</a></p>
<p dir="auto">Das Script reagiert immer auf Telegram-Eingaben, wird aber tatsächlich nur dann aktiv, wenn es das wirklich soll. Und so sieht es dann aus:<br />
<img src="/assets/uploads/files/1660131406334-project-name.gif" alt="Project Name.gif" class=" img-fluid img-markdown" /><br />
(sorry für die schlechte Qualität, das Original war viel zu groß für einen Upload hier)</p>
<p dir="auto">Der initiale Aufruf erfolgt über den text2command-Adapter:<br />
<img src="/assets/uploads/files/1660129164155-bildschirmfoto-2022-08-10-um-12.59.08-resized.png" alt="Bildschirmfoto 2022-08-10 um 12.59.08.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">Damit bei einem Neustart das Script nicht in einen undefinierten Zustand fährt, wird intern nochmal abgefragt, ob wirklich der Befehl gesendet wurde. Man kennt das ja, die ganzen Tastaturscripte werden ausgeführt, sobald man den Javascript-Adapter neustartet, wenn man keine Vorkehrungen trifft.</p>
<p dir="auto">Der Rest erklärt sich glaube ich von selbst. Was jetzt natürlich noch geschehen muss ist, dass das eingegebene Datum weiterverarbeitet werden muss, aber das ist ja ein ganz anderes Thema.</p>
<p dir="auto">Das Script benötigt diese Datenpunkte (bitte manuell anlegen):<br />
<code>0_userdata.0.Telegram.text2command.datePicker_Datum</code> -&gt; String<br />
<code>0_userdata.0.Telegram.text2command.datePicker_Jahr</code> -&gt; Number<br />
<code>0_userdata.0.Telegram.text2command.datePicker_Monat</code> -&gt; Number<br />
<code>0_userdata.0.Telegram.text2command.datePicker_Tag</code> -&gt; Number<br />
<code>0_userdata.0.Telegram.text2command.textProcessor</code> -&gt; String oder mixed</p>
<p dir="auto">Letzterer muss auch in den Einstellungen des text2command-Adapters hinterlegt werden.</p>
<pre><code>var today = new Date();
var currentYear = today.getYear() + 1900;
var currentMonth = today.getMonth();
var currentDay = today.getDate();
var currentWeekday = today.getDay();
const months = ['Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'];

var year = 0;
var month = 0;
var day = 0;

function go() {
    // Bei Auslösung Status schreiben damit klar ist, dass reagiert werden muss
    setState("0_userdata.0.Telegram.text2command.datePicker_Datum", 'running');

    // Mit Jahreseingabe beginnen
    keyboardYear();
};

function keyboardYear () {
	// Tastatur für die Jahresauswahl zusammenbauen
	var yearKeys =
		[
			[currentYear.toString(), (currentYear + 1).toString()],
			[(currentYear + 2).toString(), (currentYear + 3).toString()],
	        ["Abbrechen", ""]
		]

	// Tastatur senden
	sendTo('telegram.0', {
		text:   'Jahr wählen',
		reply_markup: {
			keyboard: yearKeys,
			resize_keyboard:   true,
			one_time_keyboard: false
		}
	});
};

function keyboardMonth () {
    // Tastatur für die Monatsauswahl zusammenbauen
    var avMonths = new Array(11);
    var monthKeys = new Array(4);

    year = getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val;

    for (let i = 0; i &lt; 12; i++) {
        if (year == currentYear) {
            if (i &lt; currentMonth) {
                avMonths[i] = " ";
            } else {
                avMonths[i] = months[i];
            }
        } else {
            avMonths = months;
        }
    }

    monthKeys[0] = avMonths.slice(0,4);
    monthKeys[1] = avMonths.slice(4,8);
    monthKeys[2] = avMonths.slice(8);
    monthKeys[3] = ["Abbrechen",""];

    // Tastatur senden
    sendTo('telegram.0', {
        text:   'Monat wählen',
        reply_markup: {
            keyboard: monthKeys,
            resize_keyboard:   true,
            one_time_keyboard: false
        }
    });
};

function keyboardDay () {
    // Tastatur für die Tagesauswahl zusammenbauen
    var days = new Array();
    var dayKeys = new Array(8);

    year = getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val;
    month = getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val;

    let firstDay = new Date(year, month, 1).getDay();
    let daysInMonth = new Date(year, month + 1, 0).getDate()

    // Tages-Array mit " " füllen, falls erster Tag nicht Montag
    if (firstDay == 0) {
        for (let i = 0; i &lt; 6; i++) {
            days.push(" ");
        }
    } else if (firstDay &gt; 1) {
        for (let i = 1; i &lt; firstDay; i++) {
            days.push(" ");
        }
    }

    // Tage zum Array hinzufügen
    for (let i = 1; i &lt;= daysInMonth; i++) {
        if (getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val == currentYear &amp;&amp; getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val == currentMonth) {
            if (i &lt; currentDay) {
                days.push(" ");
            } else {
                days.push(i.toString());
            }
        } else {
            days.push(i.toString());
        }
    }

    // Rest mit " " füllen
    for (let i = days.length; i &lt; 42; i++) {
        days.push(" ");
    }

    dayKeys[0] = ['M','D','M','D','F','S','S'];
    dayKeys[1] = days.slice(0,7);
    dayKeys[2] = days.slice(7,14);
    dayKeys[3] = days.slice(14,21);
    dayKeys[4] = days.slice(21,28);
    dayKeys[5] = days.slice(28,35);
    dayKeys[6] = days.slice(35);
    dayKeys[7] = ["Abbrechen"];

    // Tastatur senden
    sendTo('telegram.0', {
        text:   'Tag wählen',
        reply_markup: {
            keyboard: dayKeys,
            resize_keyboard:   true,
            one_time_keyboard: false
        }
    });
};

// Auf Eingabe reagieren
on({id: "0_userdata.0.Telegram.text2command.textProcessor", change: "ne"}, async function (obj) {

    try {
        var task = JSON.parse(obj.state.val);

        // Start
        if (isNaN(task.command) &amp;&amp; task.command == "Abwesenheit planen") {

            go();
        }

        // Jahr eingegeben
        else if (!isNaN(task.command) &amp;&amp; task.command &gt;= currentYear &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.textProcessor").val != "" &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Datum").val == 'running' &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val == 0 &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val == 0 &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Tag").val == 0) {

            // Jahr abspeichern
            setState("0_userdata.0.Telegram.text2command.datePicker_Jahr", Number(task.command), true);

            //Bestätigung an textProcessor
            setState("0_userdata.0.Telegram.text2command.textProcessor", 'Jahr gespeichert', true);

            // Monat aufrufen
            keyboardMonth();
        }

        // Monat eingegeben
        else if (isNaN(task.command) &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.textProcessor").val != "" &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Datum").val == 'running' &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val &gt; 0 &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val == 0 &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Tag").val == 0) {

            // Monat abspeichern
            setState("0_userdata.0.Telegram.text2command.datePicker_Monat", months.indexOf(task.command), true);

            //Bestätigung an textProcessor
            setState("0_userdata.0.Telegram.text2command.textProcessor", 'Monat gespeichert', true);

            // Tag aufrufen
            keyboardDay();
        }

        // Tag eingegeben
        else if (!isNaN(task.command) &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.textProcessor").val != "" &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Datum").val == 'running' &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val &gt; 0 &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val &gt; 0 &amp;&amp;
            getState("0_userdata.0.Telegram.text2command.datePicker_Tag").val == 0) {

            //Tag abspeichern
            setState("0_userdata.0.Telegram.text2command.datePicker_Tag", Number(task.command), true);

            //Bestätigung an textProcessor
            setState("0_userdata.0.Telegram.text2command.textProcessor", 'Tag gespeichert', true);

            //Datum zusammenbauen und in Datenpunkt schreiben
            setState("0_userdata.0.Telegram.text2command.datePicker_Datum",
                getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val
                + "-"
                + (getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val + 1)
                + "-"
                + getState("0_userdata.0.Telegram.text2command.datePicker_Tag").val
                , true);

            //Einzel-DP für Datum zurücksetzen
            setState("0_userdata.0.Telegram.text2command.datePicker_Jahr", 0, true);
            setState("0_userdata.0.Telegram.text2command.datePicker_Monat", 0, true);
            setState("0_userdata.0.Telegram.text2command.datePicker_Tag", 0, true);

            //Bestätigung senden
            sendTo("telegram", "send", {
                text: 'Datum gespeichert'
            });

            //zurück ins Hauptmenü
            setState("javascript.0.scriptEnabled.Telegram-Menu.000_menu", true);
        }

        //Abbrechen
        else if (isNaN(task.command) &amp;&amp; task.command == "Abbrechen") {

            //Einzel-DP für Datum zurücksetzen
            setState("0_userdata.0.Telegram.text2command.datePicker_Jahr", 0, true);
            setState("0_userdata.0.Telegram.text2command.datePicker_Monat", 0, true);
            setState("0_userdata.0.Telegram.text2command.datePicker_Tag", 0, true);

            //Datum zurücksetzen
            setState("0_userdata.0.Telegram.text2command.datePicker_Datum", "", true);

            //Bestätigung an textProcessor
            setState("0_userdata.0.Telegram.text2command.textProcessor", 'Abbruch', true);

            //zurück ins Hauptmenü
            setState("javascript.0.scriptEnabled.Telegram-Menu.000_menu", true);
        }

        // Rückmeldung geben, dass das Script nicht reagieren wird
        else {
            setState("0_userdata.0.Telegram.text2command.textProcessor", '', true);
        }

    } catch {
        // do nothing
    }
});
</code></pre>
<p dir="auto">Was mich derzeit noch stört ist, dass im Log immer eine Warnung auftaucht, wenn ein Befehl gesendet wurde, auf den das Script nicht reagieren wird. Das halte ich aber für einen Bug, da die Rückmeldung, dass das Script nichts tun wird, ja korrekt ausgeführt wird.</p>
<pre><code>text2command.0 	 2022-08-10 13:27:06.692	warn	Timeout for external processor: 0_userdata.0.Telegram.text2command.textProcessor
</code></pre>
<p dir="auto">Was mich außerdem stört ist, dass die Aufforderung zur nächsten Eingabe eher kommt, als die Bestätigung der letzten Eingabe. Das sieht im Chat-Verlauf echt komisch aus, aber ich habe noch keine Idee, woran das liegt und wie man das lösen könnte.</p>
<p dir="auto">Vielleicht kann das Ganze ja jemand gebrauchen - viel Spaß damit :)<br />
Für Verbessungsvorschläge bin ich offen, falls jemand welche hat.</p>
]]></description><link>https://forum.iobroker.net/post/840219</link><guid isPermaLink="true">https://forum.iobroker.net/post/840219</guid><dc:creator><![CDATA[Hiltex]]></dc:creator><pubDate>Wed, 10 Aug 2022 11:43:09 GMT</pubDate></item></channel></rss>