Zeiteingabe wie auf dem smartphone

Begonnen von derHeimwerker, 17 Februar 2021, 07:32:59

Vorheriges Thema - Nächstes Thema

derHeimwerker

Hallo,

für diverse zeitgesteuerte Device möchte ich eine komfortable Eingabefunktion anbieten, so wie man sie vom Smartphone her kennt. Im Netz finden sich dafür diverse jquery-Widgets. Wie verbinde ich nun aber diesen Code mit FHEMWEB? Es gibt ja schon das DateTimePicker-widget, allerdings finde ich da die Zeit-Funktionalität nicht so ansprechend.

Hat da jemand einen Deckanstoß oder schon eine passende Lösung?
Vielen Dank!
Gruß Thomas

juergen012

#1
ich habe das über ein en dummy und eine ReadingsGroup gelöst:

defmod du_frueh_timer dummy
attr du_frueh_timer DbLogExclude .*
attr du_frueh_timer alias Früh Timer:
attr du_frueh_timer group Kalender
attr du_frueh_timer room Hilfsprogramme
attr du_frueh_timer setList state:05:00,05:15,05:30,05:45,06:00,06:15,06:30,06:35,06:40,06:45,06:50,06:55,07:00,07:05,07:10,07:15,07:20,07:25,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00,10:15,10:30,10:45,11:00,11:15,11:30,11:45,12:00,12:15,12:30,12:45,13:00,13:15,13:30,13:45,14:00,14:15,14:30,14:45,15:00,15:15,15:30,15:45,16:00,16:15,16:30,16:45,17:00,17:15,17:30,17:45,18:00,18:15,18:30,18:45,19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00,22:15,22:30,22:45,23:00,23:15,23:30,23:45,00:00,00:15,00:30,00:45,01:00,01:15,01:30,01:45,02:00,02:15,02:30,02:45,03:00,03:15,03:30,03:45,04:00,04:15,04:30,04:45
attr du_frueh_timer verbose 2
attr du_frueh_timer webCmd state


defmod FruehTimer readingsGroup du_frueh_timer:!state
attr FruehTimer DbLogExclude .*
attr FruehTimer commands { state => 'state:' }
attr FruehTimer group Kalender
attr FruehTimer noheading 1
attr FruehTimer nonames 1
attr FruehTimer notime 1
attr FruehTimer room Hilfsprogramme,Home
attr FruehTimer valuePrefix um:
attr FruehTimer valueSuffix Uhr
attr FruehTimer verbose 2

Fhem unter Proxmox

derHeimwerker

@juergen

Vielen Dank für den Code. Eine ReadingsGroup geht sicher auch, aber da hast du halt auch nur ein Dropdownmenü, als dem du die Werte ziehen kannst und nicht zb. eine schicke Uhr, die du minutengenau einstellen kannst.

Porsti

Hi,

würde es nicht über eine Liste machen sondern als time:

attr du_frueh_timer setList state:time

finde ich schöner und man kann auch zwischenzeiten nehmen die nicht in einer Liste sind.
____________________________________
fhem 6.2  auf Raspberry 3b
Homematic HM-CC-RT-DN / HM-TC-IT-WM-W-EU / HM-SEC-SCo / HM-LC-SW1-PL2
SIGNALduino, KNX (Merten, MDT, Siemens, ABB)

derHeimwerker

Ich dachte mehr an so eine Sache.
https://www.npmjs.com/package/jquery-clock-timepicker

Kann soetwas in den FHEMWEB eingebaut werden?

rudolfkoenig

ZitatKann soetwas in den FHEMWEB eingebaut werden?
Klar, man muss nichtmal die "offiziellen" Dateien dafuer anfassen.

Man erstellt eine Datei /opt/FHEM/www/pgm2/fhemweb_timePicker.js, und man laesst sich dabei von den anderen fhemweb_*.js Dateien im gleichen Verzeichnis inspirieren (z.Bsp. fhemweb_knob.js). Danach FHEM neu starten, und schon kann man das neue Widget ansprechen.

Ich vermute, die Frage wurde nicht optimal gestellt :)

derHeimwerker

Zitat von: rudolfkoenig am 17 Februar 2021, 20:27:29
Ich vermute, die Frage wurde nicht optimal gestellt :)

Die Frage wurde schon optimal gestellt. Ich wollte nur erst einmal wissen, ob soetwas möglich ist.

Jetzt kann ich mir die "Inspiration" holen. Allerdings wäre es schön, wenn mich jemand dabei an die Hand nehmen könnte.

derHeimwerker

HILFE :-)

Ich bin damit wohl doch etwas überfordert. Gibt es da eine "Anleitung", wie ich die Verbindung zum fhemweb grundsätzlich herstelle und wie ich die Daten , dann aus dem Widget in die richtigen Devices/Attribute/Readings bekomme?

Alternativ würde ich eine fertige Version natürlich auch übernehmen.
Vielen Dank!

rudolfkoenig

Da lag ich doch richtig mit meiner Vermutung, obwohl die Huerde tief lag, ich habe Folgendes durch Kopieren von fhemweb_knob.js nach fhemweb_timepicker.js und leichtes Anpassen erstellt:
// Wrapper for the jquery timepicker widget.
FW_widgets['timepicker'] = { createFn:FW_timepickerCreate, };

function
FW_timepickerCreate(elName, devName, vArr, currVal, set, params, cmd)
{
  if(!vArr.length || vArr[0] != "timepicker" || (params && params.length))
    return undefined;

  var conf = {};
  for(var i1=0; i1<vArr.length; i1++) {
    var kv = vArr[i1].split(":");
    conf[kv[0]] = kv[1];
  }

  var newEl = $("<div style='display:inline-block'>").get(0);
  $(newEl).append('<input type="text" id="timepicker.'+devName+'-'+set +'" >');

  var inp = $(newEl).find("input");
  if(elName)
    $(inp).attr("name", elName);
  for(c in conf)
    $(inp).attr("data-"+c, conf[c]);

  loadScript("pgm2/jquery-clock-timepicker.min.js",
  function() {
    $(inp).clockTimePicker();
  });

  return newEl;
}


Voraussetzung: jquery-clock-timepicker.min.js von der verlinkten Seite nach www/pgm2 kopieren
Anwendung:
define d dummy
attr d setList time:timepicker

Parameter sind analog zu knob anzugeben (Komma separierte Liste von Key:Value Paaren), d.h. die Doku liegt auf der verlinkten Seite.

roelleke

Hallo,
ich bin durch Zufall auf diesen Forumsbeitrag gestoßen. Ich finde den Timpicker ganz Klasse und für reine Zeiteingaben viel besser als den datetimpicker.
Nur leider funktioniert er in folgendem Beispiel nicht. Die Zeit wird nicht in das Reading time übernommem wenn.


defmod TimepickerTest dummy
attr TimepickerTest readingList time
attr TimepickerTest setList time:timepicker
attr TimepickerTest stateFormat time
attr TimepickerTest webCmd time

Mache ich da was falsch oder geht das so nicht?

Viele Grüße

derHeimwerker

Vielen Dank rudolfkoenig, das sieht ja wirklich klasse aus.
Allerdings habe ich auch das Problem, dass die Zeit nicht ins reading übernommen wird.

derHeimwerker

Hallo roelleke,

bist du bei deinem Problem schon weiter gekommen?
Gruß
Thomas

roelleke

Nein, ich hab es versucht, aber JavaScript ist für mich ein Buch mit sieben Siegeln. Ich verstehe einfach nicht was da passiert.

derHeimwerker

:-( das geht mir leider auch so. Habe den Teil aus der fhemweb.js der sich mit dem Time Widget befasst einmal näher betrachtet. Das erschließt sich mir aber leider auch nicht.

roelleke

Ich denke es liegt daran wie die fhemweb-timpicker.js die Daten zurückgibt. Ich habe es mit der fhemweb-knob verglichen und mal die dortigen Funktionen ohne Erfolg ausprobiert. Wir werden wohl warten müssen bis sich jemand der Sache animmt der etwas davon versteht.

OdfFhem

Ich habe den Code ein wenig erweitert. Damit gilt:

  • das Widget kann mit vielen Attributen konfiguriert werden. Einzig die colors- bzw. font-Attribute erfordern noch eine kleine Korrektur durch den Plug-In-Entwickler. "Verkonfiguriert" könnte das dann z.B. aussehen wie auf dem angehängten Screenshot.
  • der eingestellte Wert wird übernommen
  • "unschön": Abbruch (z.B. via ESC) führt zu einer leeren Anzeige; Reading bleibt aber zum Glück unverändert


// Wrapper for the jquery timepicker widget.
FW_widgets['timepicker'] = { createFn:FW_timepickerCreate, };

function FW_timepickerCreate(elName, devName, vArr, currVal, set, params, cmd)
{
  if(!vArr.length || vArr[0] != "timepicker" || (params && params.length))
    return undefined;

  var conf = {};
  for(var i1=0; i1<vArr.length; i1++) {
    var kv = vArr[i1].split("=");
    if ((kv[0] == "initial") && (!currVal)) { currVal = kv[1]; }
    else if (kv[1]) { conf[kv[0]] = kv[1]; }
  }

  var newEl = $("<div style='display:inline-block'>").get(0);
  $(newEl).append('<input type="text" id="timepicker.'+devName+'-'+set +'" >');

  var inp = $(newEl).find("input");
  if (elName) $(inp).attr("name", elName);
  for(c in conf) $(inp).attr("data-"+c, conf[c]);

  loadScript("pgm2/jquery-clock-timepicker.min.js",
  function() {
    $(inp).clockTimePicker({
      onChange: function(newVal, oldVal) { if(cmd && !inp.block) cmd(newVal); }
    });
    newEl.setValueFn = function(arg){ inp.val(arg); inp.block=true; inp.trigger('change'); inp.block=false; };
    newEl.setValueFn(currVal);
  });

  return newEl;
}



defmod TestTimePicker2 dummy
attr TestTimePicker2 readingList timeTest1 timeTest2 timeVon timeBis
attr TestTimePicker2 room Test
attr TestTimePicker2 setList timeTest1:timepicker timeTest2:timepicker,initial=12:00 timeVon:timepicker,minimum=06:00,maximum=09:00,precision=15 timeBis:timepicker,minimum=15:00,maximum=18:00,precision=15
attr TestTimePicker2 stateFormat { return '';; }
attr TestTimePicker2 webCmd timeTest1:timeTest2:timeVon:timeBis
attr TestTimePicker2 webCmdLabel Test: \
:Von :Bis&nbsp;;
attr TestTimePicker2 widgetOverride setList:textField-long

derHeimwerker

So funktioniert es nun. Durch einen zusätzlichen Button-Click wird die Zeit jetzt ins reading/attr übernommen. Wahrscheinlich steht da noch viel zu viel im code. War nur ein try-and-error. Vielleicht kann ihn ja noch jemand optimieren.


// Wrapper for the jquery timepicker widget.
FW_widgets['timepicker'] = { createFn:FW_timepickerCreate, };

function
FW_timepickerCreate(elName, devName, vArr, currVal, set, params, cmd)
{
var closed="Set";
var newEl = document.createElement('div');
$(newEl).append('<input type="text" size="5">');
$(newEl).append('<input type="button" value="'+closed+'">');

var inp = $(newEl).find("[type=text]");
var btn = $(newEl).find("[type=button]");
currVal = (currVal ? currVal : "12:00")
.replace(/[^\d]*(\d\d):(\d\d).*/g,"$1:$2");
$(inp).val(currVal)

if(elName)
$(inp).attr("name", elName);

var hh, mm;   

newEl.setValueFn = function(arg) {
  arg = arg.replace(/[^\d]*(\d\d):(\d\d).*/g,"$1:$2");
  $(inp).val(arg);
  var hhmm = arg.split(":");
  if(hhmm.length == 2 && hh && mm) {
  hh.setValueFn(hhmm[0]);
  mm.setValueFn(hhmm[1]);
}
};

$(btn).click(function(){     
var v = $(inp).val();
  hh = mm = undefined;
 
  if(cmd)
cmd(v);
 
  if(v.indexOf(":") < 0) {
  v = "12:00";
  $(inp).val(v);
}

var hhmm = v.split(":");

function
tSet(idx, arg)
{
  if((""+arg).length < 2)
arg = '0'+arg;
  hhmm[idx] = arg;
  $(inp).val(hhmm.join(":"));
}

});

loadScript("pgm2/jquery-clock-timepicker.min.js",
function() {
$(inp).clockTimePicker();

});
return newEl;
}