DS2408 mit hoher Frequenz mittels Alarming auslesen

Begonnen von Oliver Vallant, 27 Dezember 2016, 23:05:44

Vorheriges Thema - Nächstes Thema

Oliver Vallant

Liebe Freunde des FHEM/1-wire,

ich habe derzeit mein gesamtes Haus mittels 1-wire Elemente automatisiert und evaluiere gerade, ob ich meine derzeit in Java implementierte Ablaufsteuerung ausscheide und in FHEM nachbaue. Hierzu muss ich ein Detail klären, welches quasi ein Knock-Out Kriterium wäre:

In meinem ca. 70m langem BUS (STP-Kabel) betreibe ich etwa 80 Stk. DS2408 teils als Relais-Schalter im Schaltschrank, teils als Zimmerallzwecksensor: 6-fach Sensor-Taster mit 2 LED-Statuslichter. Von diese 50 Stk. DS2408 kann ich nicht den tatsächlichen Sensed-Input der 6 Kanäle auslesen, denn das dauert etwa: 250ms * 50 = 4sec
Deshalb hat der DS2408 ein Alarming-Bit welches auf high geht, sobald ein Eingang auf high geht, also ein Taster im Zimmer gedrückt wurde. Das scannen des Alarming-Bits aller DS2408 "kostet" etwa 15ms, sodass ich jeden DS2408 in einer Sekunde überwacht habe. Ist ein Alarming-Bit high ließt die Software alle 6 Kanäle aus und setzt das Alarming-Bit auf low zurück. Hierdurch wird das Einschalten des Lichtes in einem Raum relativ ohne Zeitverzögerung ermöglicht.

Leider habe ich in der Beschreibung des OWDevice als Abfrageintervall für den DS2408 lediglich Sekunden (min 1) angeben, dh. bei 50Stk. DS2408 würde ein Durchlauf bis zu 50sek dauern. Gibt es hier eine Möglichkeit das Element schneller zuvor auf Basis des Alarmings vorauszuwerten?

Vielen Dank!


Prof. Dr. Peter Henning

Das hat nichts mit dem OWDevice zu tun. Vielmehr rmüsste das die darunterliegenden OWFS-Instanz machen.

LG

pah

Oliver Vallant

Danke pah für dein Feedback.
Dann präzisiere ich ... gibt es eine schnelle Variante ggf. über das Alarming-Bit des DS2408 über das OWFS mittels OWDevice auf Tastendrücke Aktoren ausführen zu können?
Oder anders, wenn OWFS dies nicht implementiert haben sollte, kann man in eventu ohne das OWFS direkt die Java-APIs von Dallas-Semiconductors als externe Library in FHEM einbinden?

Oliver Vallant

Habe ein Posting aus 2014 von Norbert bzl. Notification  gefunden:
-----------
Antw:1wire mit notify
Zitat von: otto am 09 August 2014, 15:53:57

    Hallo hab jetzt 10 DS1820 Wie kann ich jetzt die Alarme alle auf einmal Als E-Mail weitersenden?

Beantwortet zwar nicht direkt Deine Frage, aber Ich schreib einfach mal das, was tatsächlich implementiert ist:

In OWX_ASYNC kann man ein notify auf das 'alarm'-reading des OWTHERM-devices setzen. Das notify wird nur aufgerufen, wenn sich der alarm-Zustand tatsächlich ändert. Eine regelmäßige Alarm-search wird im nach der im Attribut 'interval' konfigurierten Zahl an Sekunden durchgeführt. Zusätzlich findet man alle aktuell als alarmed geführten Devices im Internal 'ALARMDEVS'.

In OWX ist das nicht implementiert. Da muss man eine Alarm-search mit 'get <owx> alarms' triggern. Anschließend findet man alle Alarmed-devices (so wie bei OWX_ASYNC) im Internal 'ALARMDEVS'. OWX beschreibt kein alarm-reading in den Devices, daher kann man darauf auch kein notify setzen.

Gruß,
Norbert
-----------

Es scheint, dass das OWFS im Falle des  DS1820 als Alarming des Elementes abgreift und an OWServer und dann an OWDevice zur weiteren Auswertung weiterreicht. Oder interpretiere ich das obige falsch? Weis jemand, ob dies auch beim DS2408 analog zum DS1820oä durch die OWFS-Instanz durchgereicht wird, wie Peter Henning anmerkte? Und wenn ja, kann man dann mittels Intervall 1sec die Liste ALARMDEVS dann durchgehen und auswerten, sowie die tatsächlichen Inputwerte des DS2408 auslesen?

Bitte entschuldigt mein Kaffeesatzlesen, aber es müsste doch ein weit verbreitetes Problem darstellen, wenn alle DS2408 eines BUS nur mit minimal 1sec abfragbar wären? Wenn da ein Taster (input high eines Kanals) von der Person, welche zB. das Licht in einem Raum einschalten will, nicht hinreichend lange gedrückt würde, zumindest bis der scan am BUS am DS2408-Element vorbeikommt, versäumt man den Tastendruck vollständig. Von einer Rollo-Steuerung, wo mittels auf/ab-Taster die Schrägstellung der Lamellen verändert werden soll, wo eine halbe Sekunde bereits (zu)viel ist, ganz zu schweigen.

Wie habt ihr das gelöst?


Oliver Vallant

Liebe Kollegen, liebe Freunde des 1-wire-Bus,

ich komme leider mit dem zeitnahen Abfragen der DS2408 nicht weiter:

a) Das Lesen mehrerer DS2408 zB. mittels interval=1 auf Eingangszustand (sensed.0 bis sensed.7) oder Änderungen (latched.0 bis latched.7) hört sich bereits bei 3 Devices auf (wären 24 Input-Kanäle), da dann zB. mein Raspberry PI3 zur Abarbeitung des Front-Ends bereits keine CPU-Zeit mehr hat.
b) Hierfür hat der Hersteller das Alarming eingeführt, sodass bei geeigneter Maskierung der Devices (zB. set_alarm="133333333" dh. bei einer beliebigen Eingangsänderung) die Devices, welches eine Eingangsänderung erleben durften auf ein sehr sehr rasches Conditional-Search des Busmasters antworten. Das heißt man scanned mit hoher Frequenz (1-3 Hz) mittels Conditional-Search und bekommt nur mehr die Devices retour, bei welchen zB. ein Taster gedrückt wurde, liest dann nur mehr bei diesem Device die latch-States aus und kann dann rasch eine Aktion anstoßen. Indem man den latch-State wieder auf 0 setzt, resetet man den Alarm des Devices.
c) Hierfür hat OWFS das Verzeichnis http://server:2121/uncached/alarm bereitgestellt. In diesem sind alle (b) Devices aufgelistet.

In Element OWX scheint dies mittels Liste "alarmdevs" realisiert gewesen zu sein. Aber wenn ich das richtig verstanden habe wurden die OWX-Elemente durch OWServer/OWDevice ersetzt. Im OWServer gibt es leider kein Internal oder Attribut "alarm" oÄ.,  wenngleich es hier auf dieser Ebene angesiedelt sein müsste.
Es scheint aber grundsätzlich vorgesehen zu sein, da OWDevice sehrwohl das alarm-Reading auslesen kann und das "Muster" für die Conditional-Search in Form des set_alarm einstellen lässt. Das alarm-Reading des OWDevices abzufragen bringt nur nichts, da eben das Interval des OWDevices auf <=1 gesetzt werden müsste und wieder jedes DS2408 am Bus abgefragt werden müsste.

Kann man sonst irgendwie auf /uncached/alarm des OWFS darunter zugreifen und danach nur mehr die OWDevices lesen, die dort enthalten sind? Ein externer HTTP-Aufruf (system "wget  http://server:2121/uncached/alarm" an den OWHTTP samt parsen des Ergebnisses dauert jedenfalls viel zu lange.

Prof. Dr. Peter Henning

ZitatAber wenn ich das richtig verstanden habe wurden die OWX-Elemente durch OWServer/OWDevice ersetzt

Sicher nicht.

LG

pah

Oliver Vallant

Kann ich OWX parallel zu OWServer an einem BUS-Master einsetzen um an alarmdevs zu gelangen? Oder OWServer/OWDevices umbauen zu OWX/OWSwitch?

Oliver Vallant

Da OWServer die alarmdevs nicht herausführt habe ich es mit OWX(_ASYNC) und OWSWITCH versucht.

Testaufbau: Habe einen DS2408 mit 8 Inputkanälen an einem 1-wire Busmaster DS2480 an /dev/ttyUSB0.
Dafür habe ich im fhem ein OWX_ASYNC, ein OWSWITCH und je ein Notify auf das "alarms" des OWX_ASYNC und eines auf das "alarm" des OWSWITCH erstellt:


define iBUS OWX_ASYNC /dev/ttyUSB0
attr iBUS buspower real
attr iBUS dokick 0
attr Sensor room OWX

define Sensor OWSWITCH DS2408 433109000000
attr Sensor IODev iBUS
attr Sensor model DS2408
attr Sensor room OWX

define iBUSalarm notify iBUS:alarms { Log 3, "iBUS alarmiert" }
attr iBUSalarm room OWX

define Sensoralarm notify Sensor:alarm { Log 3, "Sensor alarmiert" }
attr Sensoralarm room OWX


Obiges setting liest als OWX noch richtig aus bei eingestelltem interval zB. 1 des OWSWITCH. OWX_ASYNC liefert keine neuen Input-Stati, egal welches interval ich am OWX_async oder OWSWITCH setzte. ALARMED des OWX_ASYNC ist immer 0 und "alarm" des OWSWITCH ist immer 1. "alarms" des OWX_ASYNC zeigt richtiger Weise das alarmierte OWSWITCH. Jetzt stehe ich an. Der Aufbau selbst funktioniert, habe ich mit OWFS manuell via owhttp, sowie OWServer und OWDevice ausprobiert.

Eigentlich müsste folgendes passieren:
1) am OWSWITCH müsste während init das Flag set_alarm="133333333" einmalig gesetzt werden. Das schaltet das Gerät überhaupt erst für alle latch.X (für X=0 bis 7) die Änderungen auf die Conditional Search.
2) danach müssten in init alle latch.X des Gerätes auf 0 gesetzt werden, damit das Alarming des gesamten Gerätes zurückgesetzt wird.
3) wenn jetzt ein Input sich ändert (1>0 oder 0>1) dann wird das entsprechende latch für diesen Input auf 1 gesetzt und es erscheint in der Conditional Search. Dazu müsste aber das OWX_ASYNC einmal oder besser mehrmals pro Sekunde die an sich sehr schnelle Conditional Search des 1-wire durchführen.
4) wenn jetzt ein Notify auf das "alarms" des OWX_ASYNC gesetzt wird, erscheint dort das alamierte Gerät und könnte ein get auf das Gerät selbst durchführen und den Input (sensed.X) auslesen.

Passiert das alles intern in OWX_ASYNC und OWSWITCH oder muss ich das in Perl nachbauen?
dh. wie kann ist die latch-States und damit den alarm eines Gerätes zurücksetzen? Bei OWDevice habe ich latch.(0-7) oder latch.ALL setzten können.
Wie kann ich die Conditional Search manuell, oder sonst über OWX_ASYNC auslösen, bzw. wird diese bei interval=1 dann sekündlich durchgeführt?
Was mache ich im Setting mit OWX_ASYNC ober falsch, dass überhaupt keine Werte mehr gelesen werden?

Jedes Stichwort ist willkommen, auch ein "geht gar nicht" hilft mir weiter,
Oliver

Prof. Dr. Peter Henning

1. OWX_ASYNC wird nach meinem Kenntnisstand nicht weiter entwickelt. Unabhängig davon ist die Idee des "mehrmals pro Sekunde Conditional Search" damit vermutlich nicht umsetzbar.

2. Einen Ausbau von OWSWITCH zu einer erweiterten Initialisierung habe ich nicht auf der Agenda, und werde ihn auch auf absehbare Zeit nicht darauf setzen.

3. Für den Anwendungszweck, bestimmte 1-Wire Buszustände mehrmals pro Sekunde abzufragen, kann man FHEM auf keinen Fall empfehlen - dafür ist es nicht gedacht. Der einzig sinnvolle Weg besteht in diesem Fall darin, den 1-Wire Bus an eine dezidierte Hardware anzuschließen, sagen wir einen Arduino. Der macht die schnellen Busabfragen und alarmiert FHEM nur, wenn er einen entsprechenden Zustand erkannt hat.

LG

pah

P.S.: Der Plural von Status ist nicht Stati...

Oliver Vallant

Hallo pah,

vielen Dank für deine Antwort - hilft mir sehr weiter.
ad 1) Deine Antwort vom 17.3. mit "Sicher nicht" bezog sich demnach auf OWX und nicht auf OWX_ASYNC.
ad 2) alles klar
ad 3) Aus meiner Sicht ist das kein Hardware-Thema, sondern einzig eine Frage des Timings, ob mit fhem in Perl zB. zwei Conditional Searches je Sekunde machbar sind - neben dem restlichen Tasks. Die Abarbeitung des Events selbst, nach Erkennung des einen alarmierten Geräts, kann dann durchaus als Notify länger (1sec) dauern. Ich denke für eine Hausautomatisierung  ist 1-2sec delay vom drücken eines Tasters bis sich das Licht einschaltet zweifelsohne akzeptabel, insbesondere da in einem Einfamilienhaus selten in einer Sekunde mehr als ein Taster gedrückt wird.
Mich würde interessieren wie du die Lichtschalter und Rollotaster oÄ. realisiert hast. Bei einigen Räumen und einigen Fenstern kommen schon mal 50 Tastpunkte (dh. min. 7sec, 7x8ports bei interval=1) zusammen. Auch bei zB. 20Stk. Homematic Funktaster muss es mehrere Sekunden dauern. Da kommt dann auch der sog. WAF (Women Acceptance Factor) zu tragen :-).

Vielen Dank nochmals!
LG Oliver

PS: Richtig, aber Stati klingt halt bedeutend besser als "die Status".


Prof. Dr. Peter Henning

Ich steuere Licht o.ä. nicht über 1-Wire, und die Funktelegramme von Homematic sin dso kurz, dass eine gegenseitige Blockade nicht auftritt. Nochzumal ich 2 Transceiver habe.

Nein, das ist keine Frage von Perl. Sondern eine Frage der Main-Loop von FHEM, die durch das jeweilige Antriggern der Bussuche lahmgelegt wird.

Über den WAF habe ich in den "Smart Home Hacks" ein Kapitel geschrieben - und trage derzeit deshalb einen Fight mit dem Verlag aus...

LG

pah

UweH

Zitat von: Prof. Dr. Peter Henning am 15 April 2017, 13:03:55
Über den WAF habe ich in den "Smart Home Hacks" ein Kapitel geschrieben - und trage derzeit deshalb einen Fight mit dem Verlag aus...
Huch...da steht doch nun wirklich nichts feministisch verfängliches...im Gegenteil. Ist selbst das noch zu viel?  ::) Da ist von Rücksichtnahme die Rede...

Gruß
Uwe

Prof. Dr. Peter Henning

Ernsthaft.

Zwei Figuren, die nachweisbar das Buch nicht gelesen haben, haben jeweils eine Beschwerde-Mail geschrieben, und zwar innerhalb derselben Stunde nach Mitternacht. Der Verlag drängt, diesen Abschnitt für die 2. Auflage "neutraler" zu verfassen - und ich lehne das ab.

Noch ist nicht klar, ob ich mir einen neuen Verlag suchen muss.

LG

pah

Oliver Vallant

Lieber pah, der WAF ist doch keine Erfindung des Menschen, stattdessen ist er ein universell in Zeit und Raum gültiges physikalisches Axiom. Zur Starken und Schwachen Kernkraft, Elektomagnetismus sowie Gravitation, stellt der WAF gleichsam die fünfte Fundamentalkraft im Universum dar. Und des Öfteren wirkt der WAF zweifelsohne stärker als alle 5 Kräfte in Summe!

Schöne Ostern, Oliver

PS: Wie genau kann man im Sinne eines Sachbeweises ein - ich nehme an veröffentlichtes -  Buch "nachweisbar" nicht lesen?

Prof. Dr. Peter Henning

Indem man den angegriffenen Satz übereinstimmend falsch zitiert.

LG

pah

cwagner

Auch wenn wir jetzt ein wenig OT werden: Habe mir den Abschnitt auch mit der beruflichen Erfahrung in einem Massenmedium (unter einer halben Million täglicher Leser sind sehr viele sehr unterscheidlich empfindsame Menschen) durchgelesen und meiner "besten aller Ehefrauen" gezeigt. Es stimmt auch: Für viele (überwiegend Männer) ist beim Smarthome der Weg das Ziel und die Funktion die Krönung, für viele (überwiegend Frauen) ist die Funktion gegebenenfalls nützlich und muss dann aber auch ohne Gefrickel stets nutzbar sein.
In dem Abschnitt wird sehr richtig drauf verwiesen, dass die Makes auch ohne den rettenden Eingriff des Makers laufen müssen.
Schwachpunkt des "WAF" ist das Stereotyp: Es gibt auch (reichlich) Männer, die Technik gerne einsetzen, aber keinerlei Probleme damit vertragen und es gibt eben auch Frauen, die eben auch gerne "basteln".

Das möchte ich noch um einen Aspekt aus der eigenen Erfahrung ergänzen: Bei meinem Eltern hatte ich auch manch smartes Gadget eingebaut, um ihnen das Leben in den anstrengensten letzten Lebensjahren zu erleichtern. Auch hier zeigte sich: Nur die Lösung ist gut, die schlimmstenfalls durch "Steckerziehen" wieder in Funktion gesetzt werden kann. Man muss einfach akzeptieren, dass ein(e) 90jähige(r) durchgefroren es nicht unbedingt unfallfrei in den Heizkeller schafft, um dort "Restart" zu drücken.

WAF ist ein Stereotyp, dass die Welt in Männer und Frauen teilt. Eigentlich sind aber in unserem Thema die beiden Seiten der Medaille die Maker (Bastler), die für Komfort und Zusatznutzen "schrauben" wollen, und die Nutzungsorientierten, die einfach Komfort genießen wollen.
PI 2B+/3B+ Raspbian 12, Perl 5.36.0, FHEM 6.3: 295 Module in ConfigDB: Steuerung Heizkessel, FBH, Solarthermie, kontr. Lüftung mit WRG. Smarthome u.a. HMCUL, 1-Wire (FT232RL ; DS2480B), EnOcean (TCM EPS3), MQTT2. DOIF, PID20, Threshold, OWX; Micropelt IRTV, Volkszähler, SolarForecast; MariaDB

Oliver Vallant

Zwischenzeitlich habe ich eine Lösung für das Alarming des DS2408 gefunden. Anbei die Beschreibung, falls jemand das Problem hat viele DS2408 zB. als Wandschalter (Taster) für Raumlicht in zumindest einer Sekunde abzutasten und ggf. einen Schaltvorgang (zB. Licht ein) auszulösen.

Grundsätzlich ist das fhem Device OWServer bereits in der Lage den OWFS Dienst owserver und dessen OWFS Verzeichnisse auszulesen. Es fehlt jedoch das Alarm-Verzeichnis in welchem OWFS die 1-wire Geräte auflistet, welche der Conditional Search entsprechen.

1) Ergänzung in 10_OWServer.pm

ab Zeile 80 einfügen:

"/uncached/alarm"                    => "",


Zeile 492 einfügen:

  } elsif($cmd eq "/uncached/alarm") {
        my $path= $cmd;
        my @devices= split(",", $owserver->dir($path));
        my $ret;
        for my $device (@devices) {
          my $name= "";
          my $address= substr($device, rindex($device, "/")+1);
          my $type= $owserver->read($device . "/type");
          foreach my $p (keys %defs) {
             $name= concatc(", ", $name, $p) if($defs{$p}{TYPE} eq "OWDevice" and $defs{$p}{fhem}{address} eq $address);
          }
          $ret .= sprintf("%s %10s %s\n", $address, $type, $name);
        }
        return $ret;


Die Abfrage "get <OWServer-Device> /uncached/alarm" liefert nun alle 1-wire Geräte, welche das Alarm-Flag gesetzt haben. Habe hier den Aufbau des Internals "devices" übernommen, sodass die Auswertung analog erfolgen kann.

2) Initialisierung der Conditional-Search:
Damit ein 1-wire Gerät überhaupt bei Änderung der Eingänge auf die Conditional Search antwortet müssen folgende Grundeinstellungen für jedes 1-wire Gerät durchgeführt werden:

a) por 0 ... Power On Reset. Das Bit zeigt an, dass das 1-wire Gerät nach Stromeinschalten initialisiert wurde. Es wird normalerweise beim ersten full-bus-scan gelöscht. Da OWFS das (zumindest bei mir) nur dann macht, wenn das erste Mal mittels OWFS/owhttp geöffnet wird, ist es sinnvoll manuell zu löschen.

b) set_alarm xyyyyyyyy ... Hier kann man kodieren, bei welchem Event und welchem Eingang das 1-wire Gerät auf die Conditional Search getriggert werden soll.

X  1 latch OR
Y  3 Selected HIGH

Für unseren Zweck demnach 133333333, Details siehe http://owfs.org/uploads/DS2408.html

c) latch.Y 0 ... Zum Unterschied des sensed.Y, welche die aktuellen Inputs des DS2408-Eingangs anzeigen, zeigt latch.Y die Veränderungen je Eingang an. Sobald ein einziges latch gesetzt ist, ist das gesamte Gerät alarmiert und reagiert auf die Conditional Search. Demnach müssen alle latches zuvor gelöscht werden.

d) restlichen 1-wire Geräte ... um die Conditional Search effektiv nutzen zu können, sollten naturgemäß alle anderen Geräte "schweigen", dh ich setzte bei mir die Alarm-Schranken der alarmfähigen Temperaturgeräte zB. DS18S20 auf nicht (schwer) erreichbar, mit temphigh 125, templow -50.

Folgende Funktion in 99_myUtils.pm geht die devices Liste des OWServer durch und setzt die Parameter (a-d). Die Liste muss auf die eigenen Geräte angepasst werden, ich verwende alarmfähig nur DS2408 und DS18S20:


####################################################################
#  Setzt die Grundeinstellungen für das Alarming bei 1-wire Geräten
#  Parameter: OWServer

sub initBUSalarm($) {
   my ($bus) = @_;
   my $res = fhem("get ".$bus." devices");
   my @devices= split("\n", $res);

   #---proceed device at this 1-wire---
   for my $device (@devices) {
     my @line = split(" ", $device);
     my $type = @line[1];
     my $name = @line[2];
     if ($type eq "DS2408") {
       fhem("set ".$name." set_alarm .133333333");
       fhem("set ".$name." por 0");
       fhem("set ".$name." latch.BYTE ".owOFF);
       Log3 $name, 3, "Init alarming (set_alarm 133333333, por 0, latch.BYTE 0) at device: ".$name." type: ".$type;
     }
     if ($type eq "DS18S20") {
       fhem("set ".$name." temphigh .125");
       fhem("set ".$name." templow .-50");
       Log3 $name, 3, "Init alarming (temphigh 125, templow -50) at device: ".$name." type: ".$type;
     }
   }
}


3) Abfrage der Conditional-Search:
Ich war überrascht, aber die Conditional-Search via zusätzlichem layer OWFS kann einfach mittels at einmal pro Sekunde abgefragt werden. Folgende Funktion in 99_myUtils.pm liest die Alarmliste aus und sobald dort ein Gerät gemeldet wird, werden für dieses Gerät alle latches bewertet und wenn ein latch.Y eine Änderung anzeigt, dann und nur dann wird das entsprechende sensed.Y gelesen. Dh. es bleiben alle weiteren Notifies etc. für das OWDevice gleich, es kann jedoch das interval auf 1000000 gesetzt werden (ausschalten habe ich nicht gefunden), sodass auch zahlreiche DS2408 nicht mehr periodisch abgefragt werden müssen.


####################################################################
#  Auslesen der Alarm-Liste vom OWFS-Server
#  Wird ein alamierter DS2408 gefunden werden alle latch ausgelesen und
#  das betroffene sensed mit get geholt.
#  Falls für das DS2408 userattr=autoClearAlarm:01234567 gesetzt ist
#  wird das latch auch wieder rückesetzt, alternativ muss dies das Notify
#  nach Ausführung dessen Auftrag manuell durchführen.
#
#  Diese Funktion muss per at sekündlich aufgerufen werden.
#
#  Parameter: OWServer

sub getBUSalarm($) {
   my ($bus) = @_;
   my $res = fhem("get ".$bus." /uncached/alarm");
   my @devices= split("\n", $res);

   #---proceed alarmed device at this 1-wire---
   for my $device (@devices) {
     my @line = split(" ", $device);
     my $type = @line[1];
     my $name = @line[2];
     Log3 $name, 4, "Alarmed: ".$name." Type: ".$type;

     #--- device dependant treatment---
     if ($type eq "DS2408") {

       #---Relais without Notifies needs to clear all latches automatically by userattr=autoClearAlarm---
       my @autoClearList=split(" ", AttrVal($name, "userattr",""));
       my $autoClear = "";
       for my $entry (@autoClearList) { if (index($entry,"autoClearAlarm") >= 0) { $autoClear=$entry; last; } }
       Log3 $name, 4, "AutoAlarmClear at device ".$name.": ".$autoClear ;

       #--- DS2408 has 8 ports---
       for (my $port=0; $port <= 7; $port++) {
         my $isLatched = fhem("get ".$name." latch." .$port);
         Log3 $name, 4, "Port at device ".$name.": ".$port." isLatched: ".$isLatched;
         #---Port ist latched, then get the input value---
         if ($isLatched == 1) {
           fhem("get ".$name." sensed.".$port);

           #---Port gets cleared if autoClearAlarm---
           if (index($autoClear,$port) >=0) {
             fhem("set ".$name." latch." .$port." ".owOFF);
             Log3 $name, 4,"autoClearedAlarm on Port: ".$port;
           }
         }
       }
     }
   }
   return undef;
}


Der aufmerksame Leser wird sich nun fragen, wie das Alarm-Flag gelöscht wird und hierfür gibt es zwei Methoden für unterschiedliche Anwendungsfälle:

a) Es geht nur um das Einlesen via get des Eingangs selbst und hierfür kann dem OWDevice ein userattr mitgegeben werden:

attr <OWDevice> userattr=autoClearAlarm:<0..Y..7>
Löscht nach alarming die angegeben latch.Y selbstständig, zB. "autoClearAlarm:0127" löscht latch.0 latch.1 latch.2 latch.7 alle anderen bleiben alarmiert.

b) Es hängt zB. ein Notify an diesem Eingang und das alarming soll erst bei positiver Ausführung des Notifies bewusst gelöscht werden. Dann in (a) den Eingang nicht angeben und im Notify mit "set <OWDevice> latch.Y 10> selbst löschen.

Es fehlt noch das at:


define checkBUSalarm at +*00:00:01 {getBUSalarm("<OWServer>")}
attr checkBUSalarm group System
attr checkBUSalarm room hidden


Ergebnis
In meinem Testaufbau hatte ich 5Stk. DS2408 mit somit 40 Tastpunkten und jedes OWDevice mit interval=2 abgetastet, was bereits grenzwertig (Stichwort WAF) für eine normale Bedingung zB. eines Lichtschalters ist. FHEM ist auf einem Raspberry PI3 mit einem DS2408 BUS-Master via USB bereits mit sichtbaren Verzögerungen zB. bei Web-Zugriffen - insbesondere bei Plots - gelaufen. Durch die Umstellung auf Alarming wie oben angeführt merkt man subjektiv keine Last und die Reaktionszeit auf Tastpunkte liegt bei einer Sekunde. Ich bin gespannt wie es im Echtbetrieb mit 50Stk DS2408 aussieht...

LG Oliver

habeIchVergessen

Beim conditional search kann doch das erste Byte der Adresse (0x29; Family Code) die Einschränkung übernehmen. Ob owserver dies unterstützt, kann ich aber nicht sagen. Dann muss "nur" noch geprüfte werden, ob der erste Treffer mit dem gesuchten Family Code beginnt.

Welches PCB benutzt du für den DS2408?

Oliver Vallant

Was ich gesehen habe ist der Family Code im OWFS nicht in die Conditional Search einstellbar. Und nur wenn es Geräte in der Conditional Search im 1-wire Protokoll ausschließen kann bringt es was. Denn die Suche am Bus ist "teuer", das nachträgliche Entfernen der nicht benötigten Family Codes in der Alarmliste "billig".

Ich habe selbst zwei Design:

Ein Sensor-Board mit einem DS2408S frei beschaltbar zB. 6 Tasteingängen und 2 LED Ausgängen im Format 50x50, sodass es hinter der potentialfreie Kontakte-Schaltergruppe (bei mir Gira S55) in eine Unterputzdose passt. Als Stecker verwende ich normale RJ45, als Kabel cat5e. Darüber ziehe ich jeweils verdrillt, 2x 12v, 2x 1-wire, 2x 5v, 2x Aux (bei mir tlw. Audio mono) in normaler Typ A Beschaltung. jeweils 2 Ports durchgereicht pro Print, sodass weiterverbunden werden kann.

Ein Relais-Board mit jeweils 2 DS2408S mit 12V max. 200mA Ausgängen auf welche ich dann je nach Bedarf 16 Finder Relais, Opto oder 8 Stromstoßrelais (2 Kanal, 1x Last und 1x Rückkanal) hänge. Jumper für Aux-Power, dann kann man auf Aux 24V einspeisen und die Ausgänge direkt zB. im Gartenbereich Magnetventile ohne Relais verwenden. Stecker/Verkabelung analog.

Mein Problem war die SOftware. In Java geschrieben hat sie Grundfunktionen aber eben nicht mehr. Als Einzelkämpfer es sinnlos diese auf einen auch nur annähernd Feature-Stand eines Fhem zu bekommen. Deshalb freut es mich sehr auf Fhem gestoßen zu sein, vor allem mit engagierter Community.

LG Oliver


Oliver Vallant

Was verwendest du? Hast du analoge Geräte im Einsatz ADC DAC?

LG Oliver

habeIchVergessen

Ich habe die 1-wire-wlan-bridge von hexenmeister im Einsatz. Aktuell sind div. Temperatur-Sensoren, DS2423 (auf ATtiny-Basis) und DS2406 implementiert. DS2408 auf ATtiny-Basis funktioniert nicht so recht. Deshalb meine Frage nach dem PCB. Kannst du mir eine Bezugsquelle benennen?

eldrik

Zitat von: Oliver Vallant am 18 April 2017, 21:03:14
Zwischenzeitlich habe ich eine Lösung für das Alarming des DS2408 gefunden. Anbei die Beschreibung, falls jemand das Problem hat viele DS2408 zB. als Wandschalter (Taster) für Raumlicht in zumindest einer Sekunde abzutasten und ggf. einen Schaltvorgang (zB. Licht ein) auszulösen.

Grundsätzlich ist das fhem Device OWServer bereits in der Lage den OWFS Dienst owserver und dessen OWFS Verzeichnisse auszulesen. Es fehlt jedoch das Alarm-Verzeichnis in welchem OWFS die 1-wire Geräte auflistet, welche der Conditional Search entsprechen.

1) Ergänzung in 10_OWServer.pm

ab Zeile 80 einfügen:

"/uncached/alarm"                    => "",


Zeile 492 einfügen:

  } elsif($cmd eq "/uncached/alarm") {
        my $path= $cmd;
        my @devices= split(",", $owserver->dir($path));
        my $ret;
        for my $device (@devices) {
          my $name= "";
          my $address= substr($device, rindex($device, "/")+1);
          my $type= $owserver->read($device . "/type");
          foreach my $p (keys %defs) {
             $name= concatc(", ", $name, $p) if($defs{$p}{TYPE} eq "OWDevice" and $defs{$p}{fhem}{address} eq $address);
          }
          $ret .= sprintf("%s %10s %s\n", $address, $type, $name);
        }
        return $ret;


Die Abfrage "get <OWServer-Device> /uncached/alarm" liefert nun alle 1-wire Geräte, welche das Alarm-Flag gesetzt haben. Habe hier den Aufbau des Internals "devices" übernommen, sodass die Auswertung analog erfolgen kann.

2) Initialisierung der Conditional-Search:
Damit ein 1-wire Gerät überhaupt bei Änderung der Eingänge auf die Conditional Search antwortet müssen folgende Grundeinstellungen für jedes 1-wire Gerät durchgeführt werden:

a) por 0 ... Power On Reset. Das Bit zeigt an, dass das 1-wire Gerät nach Stromeinschalten initialisiert wurde. Es wird normalerweise beim ersten full-bus-scan gelöscht. Da OWFS das (zumindest bei mir) nur dann macht, wenn das erste Mal mittels OWFS/owhttp geöffnet wird, ist es sinnvoll manuell zu löschen.

b) set_alarm xyyyyyyyy ... Hier kann man kodieren, bei welchem Event und welchem Eingang das 1-wire Gerät auf die Conditional Search getriggert werden soll.

X  1 latch OR
Y  3 Selected HIGH

Für unseren Zweck demnach 133333333, Details siehe http://owfs.org/uploads/DS2408.html

c) latch.Y 0 ... Zum Unterschied des sensed.Y, welche die aktuellen Inputs des DS2408-Eingangs anzeigen, zeigt latch.Y die Veränderungen je Eingang an. Sobald ein einziges latch gesetzt ist, ist das gesamte Gerät alarmiert und reagiert auf die Conditional Search. Demnach müssen alle latches zuvor gelöscht werden.

d) restlichen 1-wire Geräte ... um die Conditional Search effektiv nutzen zu können, sollten naturgemäß alle anderen Geräte "schweigen", dh ich setzte bei mir die Alarm-Schranken der alarmfähigen Temperaturgeräte zB. DS18S20 auf nicht (schwer) erreichbar, mit temphigh 125, templow -50.

Folgende Funktion in 99_myUtils.pm geht die devices Liste des OWServer durch und setzt die Parameter (a-d). Die Liste muss auf die eigenen Geräte angepasst werden, ich verwende alarmfähig nur DS2408 und DS18S20:


####################################################################
#  Setzt die Grundeinstellungen für das Alarming bei 1-wire Geräten
#  Parameter: OWServer

sub initBUSalarm($) {
   my ($bus) = @_;
   my $res = fhem("get ".$bus." devices");
   my @devices= split("\n", $res);

   #---proceed device at this 1-wire---
   for my $device (@devices) {
     my @line = split(" ", $device);
     my $type = @line[1];
     my $name = @line[2];
     if ($type eq "DS2408") {
       fhem("set ".$name." set_alarm .133333333");
       fhem("set ".$name." por 0");
       fhem("set ".$name." latch.BYTE ".owOFF);
       Log3 $name, 3, "Init alarming (set_alarm 133333333, por 0, latch.BYTE 0) at device: ".$name." type: ".$type;
     }
     if ($type eq "DS18S20") {
       fhem("set ".$name." temphigh .125");
       fhem("set ".$name." templow .-50");
       Log3 $name, 3, "Init alarming (temphigh 125, templow -50) at device: ".$name." type: ".$type;
     }
   }
}


3) Abfrage der Conditional-Search:
Ich war überrascht, aber die Conditional-Search via zusätzlichem layer OWFS kann einfach mittels at einmal pro Sekunde abgefragt werden. Folgende Funktion in 99_myUtils.pm liest die Alarmliste aus und sobald dort ein Gerät gemeldet wird, werden für dieses Gerät alle latches bewertet und wenn ein latch.Y eine Änderung anzeigt, dann und nur dann wird das entsprechende sensed.Y gelesen. Dh. es bleiben alle weiteren Notifies etc. für das OWDevice gleich, es kann jedoch das interval auf 1000000 gesetzt werden (ausschalten habe ich nicht gefunden), sodass auch zahlreiche DS2408 nicht mehr periodisch abgefragt werden müssen.


####################################################################
#  Auslesen der Alarm-Liste vom OWFS-Server
#  Wird ein alamierter DS2408 gefunden werden alle latch ausgelesen und
#  das betroffene sensed mit get geholt.
#  Falls für das DS2408 userattr=autoClearAlarm:01234567 gesetzt ist
#  wird das latch auch wieder rückesetzt, alternativ muss dies das Notify
#  nach Ausführung dessen Auftrag manuell durchführen.
#
#  Diese Funktion muss per at sekündlich aufgerufen werden.
#
#  Parameter: OWServer

sub getBUSalarm($) {
   my ($bus) = @_;
   my $res = fhem("get ".$bus." /uncached/alarm");
   my @devices= split("\n", $res);

   #---proceed alarmed device at this 1-wire---
   for my $device (@devices) {
     my @line = split(" ", $device);
     my $type = @line[1];
     my $name = @line[2];
     Log3 $name, 4, "Alarmed: ".$name." Type: ".$type;

     #--- device dependant treatment---
     if ($type eq "DS2408") {

       #---Relais without Notifies needs to clear all latches automatically by userattr=autoClearAlarm---
       my @autoClearList=split(" ", AttrVal($name, "userattr",""));
       my $autoClear = "";
       for my $entry (@autoClearList) { if (index($entry,"autoClearAlarm") >= 0) { $autoClear=$entry; last; } }
       Log3 $name, 4, "AutoAlarmClear at device ".$name.": ".$autoClear ;

       #--- DS2408 has 8 ports---
       for (my $port=0; $port <= 7; $port++) {
         my $isLatched = fhem("get ".$name." latch." .$port);
         Log3 $name, 4, "Port at device ".$name.": ".$port." isLatched: ".$isLatched;
         #---Port ist latched, then get the input value---
         if ($isLatched == 1) {
           fhem("get ".$name." sensed.".$port);

           #---Port gets cleared if autoClearAlarm---
           if (index($autoClear,$port) >=0) {
             fhem("set ".$name." latch." .$port." ".owOFF);
             Log3 $name, 4,"autoClearedAlarm on Port: ".$port;
           }
         }
       }
     }
   }
   return undef;
}


Der aufmerksame Leser wird sich nun fragen, wie das Alarm-Flag gelöscht wird und hierfür gibt es zwei Methoden für unterschiedliche Anwendungsfälle:

a) Es geht nur um das Einlesen via get des Eingangs selbst und hierfür kann dem OWDevice ein userattr mitgegeben werden:

attr <OWDevice> userattr=autoClearAlarm:<0..Y..7>
Löscht nach alarming die angegeben latch.Y selbstständig, zB. "autoClearAlarm:0127" löscht latch.0 latch.1 latch.2 latch.7 alle anderen bleiben alarmiert.

b) Es hängt zB. ein Notify an diesem Eingang und das alarming soll erst bei positiver Ausführung des Notifies bewusst gelöscht werden. Dann in (a) den Eingang nicht angeben und im Notify mit "set <OWDevice> latch.Y 10> selbst löschen.

Es fehlt noch das at:


define checkBUSalarm at +*00:00:01 {getBUSalarm("<OWServer>")}
attr checkBUSalarm group System
attr checkBUSalarm room hidden


Ergebnis
In meinem Testaufbau hatte ich 5Stk. DS2408 mit somit 40 Tastpunkten und jedes OWDevice mit interval=2 abgetastet, was bereits grenzwertig (Stichwort WAF) für eine normale Bedingung zB. eines Lichtschalters ist. FHEM ist auf einem Raspberry PI3 mit einem DS2408 BUS-Master via USB bereits mit sichtbaren Verzögerungen zB. bei Web-Zugriffen - insbesondere bei Plots - gelaufen. Durch die Umstellung auf Alarming wie oben angeführt merkt man subjektiv keine Last und die Reaktionszeit auf Tastpunkte liegt bei einer Sekunde. Ich bin gespannt wie es im Echtbetrieb mit 50Stk DS2408 aussieht...

LG Oliver

Hallo Oliver,

schöne Entwicklung die hier dank deiner Initiative stattgefunden hat!

Vielleicht magst du noch den Modul Maintainer auf die Erweiterung aufmerksam machen, damit diese ggfs. offiziell in das Modul aufgenommen wird.

Ich stand seinerzeit vor dem selben Problem meine DS2408 sekündlich abfragen zu wollen (Meldekontakt für Fenster, Tür, Bewegungsmelder etc. ) jedoch waren die Verzögerungen zu groß als das der gewünschte Komfortanspruch und Stabiltät darüber erreicht werden konnte.

Zwischenzeitlich habe ich meine reinen Meldekontakte DS2408 aus dem Bus herausgetrennt und frage je Stockwerk die entsprechenden Devices (ca. 5 Stück) mittels eines Ethernet angebundenen Arduino mit 1Wire Sketch ab, der die Status per mqtt meldet, klappt im Abfrageintervall von 250ms problemlos und zuverlässig, jedoch bin ich natürlich weiterhin daran interessiert, meine Umgebung möglichst homogen zu halten, daher werde ich auf deiner Basis demnächst ein paar Tests durchführen, ob hierüber die benötigten Reaktionszeit und Stabilität erreicht wird, die ich für meine Szenarien benötige.

Ist dein PCB selber entwickelt und würdest du dieses evtl. vorstellen und wäre dieses offen?

Greetz
Eldrik

habeIchVergessen

Zitat von: Oliver Vallant am 18 April 2017, 23:06:34
Und nur wenn es Geräte in der Conditional Search im 1-wire Protokoll ausschließen kann bringt es was. Denn die Suche am Bus ist "teuer"

ich habe mit dem DS2406 die Erfahrung gemacht, dass ein conditional search ca. 50ms kostet, wenn kein Device auf dem Bus anwortet.
Wenn mind. ein Temperatur-Sensor anwortet, dann vergehen ca. 160ms. Mit der Antwort ist auch klar, dass kein gesuchtest Device antwortet.

Wenn der DS2406 antwortet, dann entsteht natürlich mehr Kommunikation (mit Rücksetzen 2 Aufrufe), die zusätzlich Zeit benötigt.

Ggf. beruhen meine Beobachtungen auf unzureichenden Testszenarien (kleine Testumgebung mit max. 5 Devices).

Oliver Vallant

Hallo Eldrik,

vielen Dank für dein nettes Feedback - für einen kurzen Moment habe ich gedacht ich wäre der Einzige mit diesem Problem. Das DS2408 stellt für mich neben den Temperatursensoren und Counter eines der Schlüsselgeräte des 1-wire dar, da mit diesem ein echter Feldbus mit abgesetzten Relais und Sensoren mit großer Anzahl von In/Outputs erst möglich wird.

ad Modul) Ich werde die Lösung noch mit einer größeren Anzahl von Elementen testen, denn nur hierfür macht das Alarming Sinn. Verläuft dies positiv werde ich bei Dr.Neubert und M.Fischer bzl. Interesse an einer Integration anklopfen.
Grundsätzlich wäre noch interessant die Conditional Search (OWServer -> /uncached/alarm) nicht mittels at sondern im Zuge des Main Loops auszuführen, dann wäre vielleicht eine Abfrage jenseits der Sekundengrenze des at möglich. Da kenne ich mich leider nicht aus - müsste man ausprobieren. Dann wäre deine externe Lösung wieder rückführbar in fhem. Wie gesagt fängt für mich die Usability in diesem Bereich bei einer Sekunde an, eine Verbesserung unter 1Hz wäre wünschenswert aber keine Voraussetzung. Für mich überwiegt hier der reiche Fundus der fhem-Funktionalität vs. Reaktionszeit.

ad deine Tests) Bin schon sehr gespannt, vielleicht fällt dir noch eine elegantere Lösung ein.

ad PCB) Ja ist eine Eigenentwicklung. Da mehrere an der Entwicklung beteiligt waren, möchte ich nicht ohne Rücksprache veröffentlichen. Ich werde in den kommenden Tagen bei Tageslicht einige Fotos machen.

LG Oliver

Prof. Dr. Peter Henning

ich bleibe dabei, dass für diese Anwendung FHEM nicht gedacht ist. Der Missbrauch der Hauptschleife für die schnelle Busabfrage sorgt dafür, dass eine sinnvolle Integration mit anderen Sensoren und Aktoren nicht mehr machbar ist.

Nicht zuletzt deshalb sind alle brauchbaren Interfaces für schnelle Benutzerinteraktioinen mit separaten Protokollprozessoren versehen - sei es der CUL, oder z.B. ein HMLAN-Interface.

Es macht auch wenig Unterschied, ob man einen dezidierten Busmaster mit USB-Anschluss und DS2480B einsetzt (Kosten ca. 20 €), oder einen Arduino einsetzt, der alle 250 ms den Bus bedient und irgendwie (WLAN, oder USB) mit dem Haupsystem kommuniziert. Letzterer ist in der Regel sogar billiger.

LG

pah

Oliver Vallant

Hallo habeIchVergessen,

deine gemessenen 160ms für die Contitional Search mit einem Gerät ist eh optimal, da dies der Erwartungsfall ist. Wann werden schon in einem normalen Haus zwei Taster im identen 160ms Zeit-Slot gleichzeitig gedrückt? Und dann sind halt 2 Geräte mit 4 Zugriffen mit 300ms notwendig. Interessant ist nicht die Summenbetrachtung, sondern die kritische Verarbeitungskette: Tasterdruck -> Alarming -> Conditional Search -> latches auslesen bzl. Veränderung -> Aktor betätigen via Notify -> Aktor schaltet. Nachrangig weil unkritisch: auslesen des tatsächlichen Eingangs (sensed) -> quitieren des Alarms durch löschen des latch -> Betriebsstundenzähler aktualisieren-> protokollieren des Ereignisses in DB.
Die Temperatur-Sensoren würde ich gänzlich aus dem Alarming entfernen, da diese nichts wirklich bringen. Erstens müssen diese im asynchronen Betrieb zur (1) Messung "angestoßen" werden, sodass dann das Ergebnis 1s später (2) abgeholt werden kann. Alternativ meldet demnach (1) das Gerät via Alarming, wenn temphigh/maxlow Grenzen unter/überschritten wurden. Ich kann mir keinen Einsatz im Bereich Hausautomatisierung vorstellen, wo das Vorteile gegenüber einer periodischen Abfrage (zB. interval=300 Raumtemperatur oÄ) haben soll. Am ehesten noch eine Motortemperaturüberwachung mit temphigh, aber hier muss auch nicht im ms Bereich abgeschalten werden.

LG Oliver

Oliver Vallant

Hallo pah,

ist sicherlich eine Architekturfrage, welche zeitrelevanten Systemteile man als eigene Hardware herauszieht. Es hängt naturgemäß schlussendlich auch davon ab, was fhem auf der eingesetzten Hardware noch alles erledigen muss.
Ich für meinen Teil kann mit der 1Hz at-Variante sehr gut leben - gesetzt den Fall, dass die Abfragezeit nicht linear mit der Anzahl der Geräte steigt, was aber gegen die Lösung des alarming durch DalSemi grundsätzlich sprechen würde.

LG Oliver

Oliver Vallant

Hallo Eldrik,

wie versprochen mein Setting sowie meine Komponenten.

Connector-Board
Beinhaltet den BusMaster DS2480, Sicherung, Pegelumwandlung 12V auf 5V. Ein 1-wire Serial DS2401 zur eindeutigen Identifikation des USB-Stranges ist ebenfalls enthalten, da der DS2480 selbst nicht als Device erscheint und bei mehreren Connectors an einem PC, Linux gerne die /dev/ttyUSBx durcheinander bringt. Der Taster schaltet ein Master-Reset, falls notwendig.
Zusätzlich gibt es 3 Klemmböcke:
1) 12V und Masse Eingang
2) Akku Aus-/Eingang, falls man buffern möchte (permanent Ladegerät an 1 notwendig)
3) Aux (durch alle Geräte geschliffen, zB. für 1-Kanal Audio, zusätzlichen 24V etc.

An der Oberseite gibt es 3 RJ45 durchgeschliffene Busausgänge die folgend auf ein LAN-Kabel (ich verwende ungeschirmtes Cat5e):
Drillpaare: 2x 12v, 2x 1-wire, 2x 5v, 2x Aux

Und natürlich der USB-Anschluss an den PC. Bei mir verrichtet ein Kontron 1GHz Intel mit 1GB RAM und 8GB microSD passiv gekühlt auf Hutschine mit Ubuntu 11.04 und einer eigenentwickelten Fireware in Java, 5 Jahren störungsfrei seinen Dienst. Stammt noch aus einer Zeit vor einem brauchbaren Raspberry PI.

Relais-Board
Bestückt mit jeweils 2 DS2408S mit 12V max. 200mA Ausgängen auf welche ich dann je nach Bedarf 16 Finder Relais, Opto oder 8 Stromstoßrelais (2 Kanal, 1x Last und 1x Rückkanal) hänge. Jumper für Aux-Power, dann kann man auf Aux 24V einspeisen und die Ausgänge direkt zB. im Gartenbereich Magnetventile ohne Relais verwenden.

Anschlüsse:
2x RJ45 durchgeschliffen
1x Eingang DS2408(a) ... bei Verwendung von Stromstoßrelais als Rückkanäle 0 bis 7
1x Ausgang DS2408(a) ... bei Stromstoßrelais offen, bei Relais oder Opto, MosFET etc. Kanäle 0 bis 7
1x Ausgang DS2408(b) ... bei Stromstoßrelais Steuerkanäle 0 bis 7, bei Relais Kanäle 8-15

Dh. man kann jeden Kanal separat nach Notwendigkeit beschalten, das Relais lässt sich direkt mit 12V schalten oder man muss eben über Aux die notwendige Schaltspannung einspeisen:
- Finder Magnetrelais 34.51.7.012 (halbe Einbaubreite): verwende ich für kurzgeschaltene Lasten bis 6A wie Nebenlichter, Rollos etc.
- Finder Stromstoßrelais 20.22.9.012 für Lasten bis 16A, oder bei langfristigen Einschaltdauern, zB. Pelletsofen 1x ein im Herbst 1x aus im Frühjahr.
- Finder 34.81.7.024 MosFET (halbe Einbaubreite): für kleine Lasten, öftere Lastwechsel wie Lichter, Fussbodenheizungsventile etc., keine LEDs, die erreichen den notwendigen Schaltstrom zumeist nicht.
(Hab ein größeres (zu großes) Los gekauft als benötigt - bitte melden wenn jemand oben angeführte Relais benötigt, wären günstig abzugeben :-) )

Sensor-Board
Bestückt mit einem DS2408S frei beschaltbar zB. 6 Tasteingängen und 2 LED Ausgängen im Format 50x50, sodass es hinter der potentialfreie Kontakte-Schaltergruppe (bei mir Gira S55) in eine Unterputzdose passt. Hier verwende ich auch öfters einen Eingang statt der zweiten LED für einen Bewegungsmelder PIR Rev.B von Parallax im 2er Rahmen oben das Tastfeld und unten den PIR eingebohrt in der  Gira Blindabdeckung. Der PIR verfügt über eine frontseitige rote LED in der Kuppel, die die Detektion signalisiert.

Anschlüsse:
2x RJ45 durchgeschliffen
2x 10pin IDE Pfostenstecker für eine Kabelpeitsche je nach verwendeten Tastenfeld, mit 8 Sensorleitungen, 8 LED-Ausgängen (Widerstände bereits am Board), 1x 12V mit Masse und 1x 5V mit Masse.

Hub 3 Kanal
Aus einer Not heraus entstanden, gibt es mittlerweile günstig bis 8 Kanal zu kaufen. Am Board ist zusätzlich ein Temperatursensor DS18S20, dh. ich verwende das Board auch für Raumtemperatur in einer Installationsdose hinter einer geschlitzten Gira Blindabdeckung.

Heizungsseitig habe ich meine Sonnenkraft 16port Steuerung mittels RS232 angebunden und der Rest steuer ich über einfache Relaiskontakte (Pelletsofen-Wärmeanforderung, Party-Schalter (für Nachtabschaltung), Thermostat-Schalteingänge für die Mischkreise (Radiatoren, Fussbodenhzg., 3000Ltr Bufferspeicher Mgt-Mitteleinspeisung, Boiler-Speisung umschaltbar via Buffer oder 400V Heizregister, Umschaltung bei Störung Pelletsofen 25kW auf 3x50A Elektrokessel (Backup).
Als Steckhülsentemperatursensoren verwende ich die wasserdichten Tauchsensoren von Demiawaking mit einem eingegossenen DS18B20 (grundsätzlich sehr gut, jedoch Messbereich von +125°C für Solaranlage zu gering).

Poolsteuerung mit Berechnung (Temp) Filterzeiten und Entkeimungszeiten, Filterpumpentemperaturüberwachung, Steuerung thermische Solaranlage 24m² und Poolheizung über 50kW Wärmetauscher via Buffer. Trafo 2x300W Unterwasserlicht temperaturüberwacht.

Zu den coolen Dingen wie Wetterstation, Fingerprint, Kindle-Display, Fenstersensoren etc. bin ich limitiert durch die eigene Software noch nicht gekommen, das wird sich mit FHEM jetzt ändern :-)

LG Oliver


Prof. Dr. Peter Henning

Zitatbei mehreren Connectors an einem PC, Linux gerne die /dev/ttyUSBx durcheinander bringt

Das ist ein Gerücht - Linux bringt da gar nichts durcheinander. Und wie man einen bestimmten Adapter genau und fest einem I/O-Device zuordnet, ist schon ungefähr 2 Millionen Mal gefragt und beschrieben worden.

LG

pah

Oliver Vallant

Ich habe diesbezüglich nichts gefragt und habe die Zuordnung auch nicht zum 2.000.001ten Male beschrieben. Ich habe meine Motivation dargelegt, warum ich einen zusätzlichen DS2401 zur eindeutigen Identifikation des USB-Stranges, jenseits der Einstellungsmöglichkeiten und Erkennungsreihenfolge des OS und zukünftigen Versionen des OS erreichen kann. Hierdurch ist es möglich, bei Ausfall der Hardware kurzfristig nur durch restoren der letzten Konfiguration auf ein Ersatzgerät zu wechseln. Auch die Strangaufteilung kann ich jederzeit bequem ohne Änderung der OS Einstellungen auf mehrere PCs aufteilen, da jede Konfiguration immer auf den richtigen Strang angewendet wird. Letztlich wieder eine Architekturfrage.

Prof. Dr. Peter Henning

Da muss ich widersprechen. Jeder USB-Adapter hat eine eindeutige Seriennummer, die zur Identifikation des Stranges vollkommen ausreicht. Der zusätzliche DS2401 ist also überflüssig.
Sie kann darüber hinaus fest mit einem (Linux) I/O-Device verbunden werden, das unabhängig von der USB Enumeration beim Systemstart ist.

So ist z.B. bei meinen fünf 1-Wire Bussen derjenige im Dachgeschoss immer unter /dev/OWX_OG zu finden.

LG

pah


Dr. Boris Neubert

Das Feature get ... /uncached/alarm von Oliver ist ins Modul übernommen und steht ab morgen per Update zur Verfügung.
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

Oliver Vallant


eldrik

#33
Hi,

kann es sein, dass in den myUtils Beispielen

       fhem("set ".$name." latch.BYTE ".owOFF);

             fhem("set ".$name." latch." .$port." ".owOFF);

das owOFF unbeabsichtigt hineingeraten ist und hier eine 0 stehen müsste?

Ich habe tatsächlich erst heute einen Test in der Richtung machen können und bräuchte einen Tipp wie ich die nachfolgende Situation lösen könnte?

Einen Test DS2408 habe ich hierfür herangezogen, an dem einige Reed Kontakte hängen.

Diesem habe ich das userattr autoClearAlarm:01234567 gegeben und per por 0 und set_alarm 133333333 entsprechend aktiviert.

Öffne ich nun ein Fenster bei dem ich über zwei Kontakte (sensed.0 und sensed.1 Fenster geschlossen beide jeweils Status 0) erkenne, ob dieses gekippt oder vollständig geöffnet ist, wird mir nur die Änderung des sensed.0 (1) angezeigt, der Status von sensed.1 bleibt bei 0 und der geänderte Status an sensed.1 (1) wird erst angezeigt wenn ich das userattr abändere auf autoClearAlarm:234567 hierdurch bleibt der Sensor dann aber dauerhaft im Alarm State was ja nicht Sinn und Zweck der Übung war :)

Wahrscheinlich liegt es daran, dass beide Kontakte gleichzeitig unterbrochen werden?

Greetz
Eldrik

habeIchVergessen

#34
mit 2 Lesezugriffen können alle latches und sensed Werte gelesen werden.
dies bitweise in einer Schleife zu tun ist nicht resourcenschonend.
auch das Rücksetzen aller latches nach der Verarbeitung der ersten gesetzten, ist suboptimal und auch der Grund, warum nur 1x sensed ausgelesen wird (isLatched muss dafür gesetzt sein; funktioniert also genau 1x!).

eldrik

Zitat von: habeIchVergessen am 14 Dezember 2017, 20:09:00
mit 2 Lesezugriffen können alle latches und sensed Werte gelesen werden.
dies bitweise in einer Schleife zu tun ist nicht resourcenschonend.
auch das Rückseiten aller latches nach der Verarbeitung der ersten gesetzten, ist suboptimal.

ich wäre an einer optimaleren Variante gemäß deiner Beschreibung interessiert!

Greetz
Eldrik

habeIchVergessen

#36
so sieht es nach meinem dafürhalten besser aus (ungetestet, da kein OWX/OWFS im Einsatz)

sub getBUSalarm($) {
   my ($bus) = @_;
   my $res = fhem("get ".$bus." /uncached/alarm");
   my @devices= split("\n", $res);

   #---proceed alarmed device at this 1-wire---
   for my $device (@devices) {
     my @line = split(" ", $device);
     my $type = @line[1];
     my $name = @line[2];
     Log3 $name, 4, "Alarmed: ".$name." Type: ".$type;

     #--- device dependant treatment---
     if ($type eq "DS2408") {
       my $latches = fhem("get ".$name." latch.ALL");
       my $sensed = fhem("get ".$name." sensed.ALL");

       #--- DS2408 has 8 ports---
       # ggf. Daten konvertieren, damit indiziert zugegriffen werden kann
       for (my $port=0; $port <= 7; $port++) {
         Log3 $name, 4, "Port at device ".$name.": ".$port." isLatched: ".$isLatched;
       }
       #---Port gets cleared if autoClearAlarm---
       # hier fehlt noch die Auswertung der Bits
       if ($autoClear != "")  {
         fhem("set ".$name." latch.ALL 1");
         Log3 $name, 4,"autoClearedAlarm on Port: ".$port;
       }
   }
   return undef;
}

eldrik

Hi,

die Variante will ich wohl gerne testen, jedoch teile ich die einzelnen Pins eines ds2408 bisher per readingsProxy (ds2408:sensed.1) in einzelne Geräte auf.

Wenn nun nur noch das reading latch.all oder sensed.all gefüllt wird wie kann ich geschickt darauf reagieren, ohne das jetzige Konstrukt massiv umbauen zu müssen?

Kann ich für die valuefn des readingsProxy eine Regex definieren, dass z.B. nur der Wert (0/1) der ersten Stelle ausgewertet wird?

Greetz
Eldrik

habeIchVergessen

latch.0 ... .7 enthalten Werte die von latch.ALL abweichen?

Wenn dem so sein sollte, dann geht immer noch ein manuelles Update der readings + event_on_changed_reading

eldrik

verstehe ich nicht oder nur halb :o

Mit get latch.ALL oder sensed.All erhält man ein 8 Zeichen langes Reading im FHEM OWDevice, dies ist die ressourcenschonendere Methode um sich den Zustand aller Pins auf einmal zu holen.

Meine readingsProxy Geräte reagieren, in ihrer Definition, aber nur auf den jeweiligen latch.0,1,2,3 usw. oder halt sensed.x Wert wenn sich dieser ändert, dafür müsste sich das jeweilige Einzelreading aber erst einmal im Fhem OWDevice ändern was nur geschieht wenn dieses explizit per get latch.0,1,2,3 usw. geholt werden würde (eine direkte Umsetzung des latch.ALL Wertes, auf die einzelnen latch.0 Readings, über das OWDevice Modul, wäre natürlich der Hit) was ja dem ressourcenschonenden Ansatz wiederspräche oder nicht?

Daher suche ich gerade nach einer geschickten Variante mit der es möglich ist nur auf den Wert X an Stelle Y des readings latch.ALL oder sensed.ALL zu reagieren.

Ohne dafür ein notify erstellen zu müssen, welches das latch oder sensed.ALL reading nimmt, in einen Array überführt und die einzelnen Werte mit einer Schleife wieder in passende latch.0,1,2,3 usw. Readings eines neu zu erstellenden Dummy Devices, welches ich anstelle des originalen ds2408 owdevice, für die readingsProxy Definition verwende, schreibt.  :D

Greetz
Eldrik

habeIchVergessen

#40
Zitat von: eldrik am 15 Dezember 2017, 12:32:36
eine direkte Umsetzung des latch.ALL Wertes, auf die einzelnen latch.0 Readings, über das OWDevice Modul, wäre natürlich der Hit)
ich würde erwarten, das sich immer beide Werte ändern (also latch.0 und latch.ALL, wenn ich einen der beiden lese). Warum das nicht so ist, kann nur Prof. P.H. beantworten.

mal aus 36_KeyValueProtocoll kopiert

      readingsBeginUpdate($rhash);

      my @kvPairs;
      my @data = split(',', substr($msg, 12 + length($parts[0]) + length($parts[1])));
      for my $i (0 .. $#data) {
        if(@kvPairs && index($data[$i], "=") == -1) {
          splice(@kvPairs, @kvPairs -1, 1, $kvPairs[@kvPairs -1] . "," . $data[$i]);
        }
        else {
          push(@kvPairs, $data[$i]);
        }
      }

      while (@kvPairs) {
        my $kvPairString = shift(@kvPairs);
        my @kvPair = split('=', $kvPairString, 2);

        my $value = $kvPair[1];

        my $key = $kvPair[0];
        $key =~ s/^\s+|\s+$//g;
        if (%mappings) {
          my $newKey = $mappings{$key};
          $key = $newKey if ($newKey);
        }

        readingsBulkUpdate($rhash, $key, $value);
      }

      readingsEndUpdate($rhash, 1);


interessant sind die drei Aufrufe
- readingsBeginUpdate($rhash);
- readingsBulkUpdate($rhash, $key, $value);
- readingsEndUpdate($rhash, 1);

damit werden alle neuen Werte in die entsprechenden readings geschrieben.
event_on_change_reading sorgt dafür, dass nur dann ein event geworfen wird, wenn sich der Wert ändert.

vor der for-Schleife (#--- DS2408 has 8 ports---) readingsBeginnUpdate aufrufen. in der Schleife readingsBulkUpdate für latch.x und sensed.x. Nach der Schleife readingsEndUpdate.

$rhash wirst du aus $defs lesen müssen. bitte mal testen (OW_29. entsprechend setzen)

{ Dumper $defs{"OW_29.xxxx"};; }

eldrik

Zitat von: habeIchVergessen am 15 Dezember 2017, 13:20:52
ich würde erwarten, das sich immer beide Werte ändern (also latch.0 und latch.ALL, wenn ich einen der beiden lese). Warum das nicht so ist, kann nur Prof. P.H. beantworten.

Nee die Module OWDevice und owserver sind nicht von PAH.


Zitat

mal aus 36_KeyValueProtocoll kopiert

      readingsBeginUpdate($rhash);

      my @kvPairs;
      my @data = split(',', substr($msg, 12 + length($parts[0]) + length($parts[1])));
      for my $i (0 .. $#data) {
        if(@kvPairs && index($data[$i], "=") == -1) {
          splice(@kvPairs, @kvPairs -1, 1, $kvPairs[@kvPairs -1] . "," . $data[$i]);
        }
        else {
          push(@kvPairs, $data[$i]);
        }
      }

      while (@kvPairs) {
        my $kvPairString = shift(@kvPairs);
        my @kvPair = split('=', $kvPairString, 2);

        my $value = $kvPair[1];

        my $key = $kvPair[0];
        $key =~ s/^\s+|\s+$//g;
        if (%mappings) {
          my $newKey = $mappings{$key};
          $key = $newKey if ($newKey);
        }

        readingsBulkUpdate($rhash, $key, $value);
      }

      readingsEndUpdate($rhash, 1);


interessant sind die drei Aufrufe
- readingsBeginUpdate($rhash);
- readingsBulkUpdate($rhash, $key, $value);
- readingsEndUpdate($rhash, 1);

damit werden alle neuen Werte in die entsprechenden readings geschrieben.
event_on_change_reading sorgt dafür, dass nur dann ein event geworfen wird, wenn sich der Wert ändert.

vor der for-Schleife (#--- DS2408 has 8 ports---) readingsBeginnUpdate aufrufen. in der Schleife readingsBulkUpdate für latch.x und sensed.x. Nach der Schleife readingsEndUpdate.

$rhash wirst du aus $defs lesen müssen. bitte mal testen (OW_29. entsprechend setzen)

{ Dumper $defs{"OW_29.xxxx"};; }


uff da muss ich mal schauen ob ich damit zurechtkomme!

Greetz
Eldrik

habeIchVergessen

Zitat von: eldrik am 15 Dezember 2017, 15:45:29
Nee die Module OWDevice und owserver sind nicht von PAH.
ich hatte auf 21_OWSWITCH.pm getippt.


Zitat von: eldrik am 15 Dezember 2017, 15:45:29
uff da muss ich mal schauen ob ich damit zurechtkomme!

ich habe mal das Beispiel von oben ergänzt

sub getBUSalarm($) {
   my ($bus) = @_;
   my $res = fhem("get ".$bus." /uncached/alarm");
   my @devices= split("\n", $res);

   #---proceed alarmed device at this 1-wire---
   for my $device (@devices) {
     my @line = split(" ", $device);
     my $type = @line[1];
     my $name = @line[2];
     Log3 $name, 4, "Alarmed: ".$name." Type: ".$type;

     #--- device dependant treatment---
     if ($type eq "DS2408" && defined($defs{"\"" . $name . "\""})) {
   my $rhash=$defs{"\"" . $name . "\""};
       my $latches = fhem("get ".$name." latch.ALL");
       my $sensed = fhem("get ".$name." sensed.ALL");

       Log3 $name, 4, "ports at device $name: latches $latches, sensed: $sensed";
   
   readingsBeginUpdate($rhash);
       #--- DS2408 has 8 ports---
       for (my $port=0; $port <= 7; $port++) {
readingsBulkUpdate($rhash, "latch." . $port, substr($latches, $port, 1));
readingsBulkUpdate($rhash, "sensed." . $port, substr($sensed, $port, 1));
       }
   readingsEndUpdate($rhash, 1);
   
       #---Port gets cleared if autoClearAlarm---
       # hier fehlt noch die Auswertung der Bits
       #if ($autoClear != "")  {
         fhem("set ".$name." latch.ALL 11111111");
         Log3 $name, 4,"autoClearedAlarm on Port: ";
       #}
   }
   return undef;
}



eldrik

mit dem Beispiel geht er nicht

in die if Abfrage

if ($type eq "DS2408" && defined($defs{"\"" . $name . "\""})) {

nehme ich den && Teil weg kommen folgende Fehlermeldungen (den Rest habe ich abgeschnitten):

Zitat2017.12.15 16:36:54.266 1: ports at device DS2408_6D5E04000000: latches 1,1,0,0,0,0,0,0, sensed: 1,1,0,0,1,1,1,1
2017.12.15 16:36:54.266 1: ERROR: empty name in readingsBeginUpdate
2017.12.15 16:36:54.266 1: eval: {getBUSalarm3("myOWFS")}
2017.12.15 16:36:54.266 1: stacktrace:
2017.12.15 16:36:54.266 1:     main::readingsBeginUpdate           called by ./FHEM/99_myUtils.pm (86)
2017.12.15 16:36:54.266 1:     main::getBUSalarm3                  called by (eval 82502) (1)
2017.12.15 16:36:54.266 1:     (eval)                              called by fhem.pl (1090)
2017.12.15 16:36:54.266 1:     main::AnalyzePerlCommand            called by fhem.pl (1113)
2017.12.15 16:36:54.266 1:     main::AnalyzeCommand                called by fhem.pl (1037)
2017.12.15 16:36:54.266 1:     main::AnalyzeCommandChain           called by ./FHEM/90_at.pm (179)
2017.12.15 16:36:54.266 1:     main::at_Exec                       called by fhem.pl (3079)
2017.12.15 16:36:54.266 1:     main::HandleTimeout                 called by fhem.pl (630)

Greetz
Eldrik

habeIchVergessen

#44
- Zugriff auf $defs geändert


sub getBUSalarm($) {
   my ($bus) = @_;
   my $res = fhem("get ".$bus." /uncached/alarm");
   my @devices= split("\n", $res);

   #---proceed alarmed device at this 1-wire---
   for my $device (@devices) {
     my @line = split(" ", $device);
     my $type = @line[1];
     my $name = @line[2];
     Log3 $name, 4, "Alarmed: ".$name." Type: ".$type;

     #--- device dependant treatment---
     if ($type eq "DS2408" && defined($defs{"$name"})) {
   my $rhash=$defs{"$name"};
       my $latches = fhem("get ".$name." latch.ALL");
       my $sensed = fhem("get ".$name." sensed.ALL");

       Log3 $name, 4, "ports at device $name: latches $latches, sensed: $sensed";
   
   readingsBeginUpdate($rhash);
       #--- DS2408 has 8 ports---
       for (my $port=0; $port <= 7; $port++) {
readingsBulkUpdate($rhash, "latch." . $port, substr($latches, $port * 2, 1));
readingsBulkUpdate($rhash, "sensed." . $port, substr($sensed, $port * 2, 1));
       }
   readingsEndUpdate($rhash, 1);
   
       #---Port gets cleared if autoClearAlarm---
       # hier fehlt noch die Auswertung der Bits
       #if ($autoClear != "")  {
         fhem("set ".$name." latch.ALL 11111111");
         Log3 $name, 4,"autoClearedAlarm on Port: ";
       #}
   }
   return undef;
}


Nachtrag: Zugriff auf $latches und $sensed geändert

Test:

{ Dumper $defs{"DS2408_6D5E04000000"};; }

eldrik

#45
jo hatte zwischenzeitlich (vor 10 sek.) auch ein positives Ergebnis in dem ich

die if Abfrage nach if ($type eq "DS2408" && defined($defs{$name})) {

abgeändert hatte.

Da die latch.ALL und sensed.ALL Ausgabe getrennt durch Komma werden steht jetzt in jedem zweiteren latch und sensed ein Komma :D

Edit: ah das ist in deiner letzten Version schon geändert :)

Ich musste jetzt nur noch

fhem("set ".$name." latch.ALL 11111111");

nach

fhem("set ".$name." latch.ALL 1,1,1,1,1,1,1,1");

abändern, damit der DS2408 nicht weiter als alarmed gekennzeichnet ist.

Greetz
Eldrik

habeIchVergessen

die Hochkommata werden notwendig, wenn Sonderzeichen im Namen stehen.

event_on_change_reading und die proxies funktionieren wie erwartet?

eldrik

Zitat von: habeIchVergessen am 15 Dezember 2017, 17:22:15
die Hochkommata werden notwendig, wenn Sonderzeichen im Namen stehen.

event_on_change_reading und die proxies funktionieren wie erwartet?

Proxies reagieren wie gewohnt, für event-on-change-reading habe ich bisher noch nicht gesetzt.

Besten Dank soweit für die Unterstützung!

Greetz
Eldrik

Oliver Vallant

Hallo endik,
mein Fehler. Hatte die Konstanten nicht in meinem Snippet mitkopiert.

Zitat
kann es sein, dass in den myUtils Beispielen
Code:
       fhem("set ".$name." latch.BYTE ".owOFF);
Code:
       fhem("set ".$name." latch." .$port." ".owOFF);

das owOFF unbeabsichtigt hineingeraten ist und hier eine 0 stehen müsste?

Es fehlt natürlich...

# 1-wire Values für on/off
use constant owON => 11;
use constant owOFF => 10;


Oliver

Oliver Vallant

Hallo Eldrik,

Zitat von: eldrik am 14 Dezember 2017, 18:29:06
Diesem habe ich das userattr autoClearAlarm:01234567 gegeben und per por 0 und set_alarm 133333333 entsprechend aktiviert.

Öffne ich nun ein Fenster bei dem ich über zwei Kontakte (sensed.0 und sensed.1 Fenster geschlossen beide jeweils Status 0) erkenne, ob dieses gekippt oder vollständig geöffnet ist, wird mir nur die Änderung des sensed.0 (1) angezeigt, der Status von sensed.1 bleibt bei 0 und der geänderte Status an sensed.1 (1) wird erst angezeigt wenn ich das userattr abändere auf autoClearAlarm:234567 hierdurch bleibt der Sensor dann aber dauerhaft im Alarm State was ja nicht Sinn und Zweck der Übung war :)

Dafür hätte ich wie oben geschrieben zwei Einsatzfälle unterschieden:
1) Du brauchst nur den Sensed-State nach dem getriggerten Alarm: Dann kann das latch sofort danach zurückgesetzt werden, wofür im userattr autoClearAlarm die entsprechende channel Nummer eingetragen haben muss. Ich verwende dies zB. bei 2Kanal Stomstoßrelais, an welchem ich bei 2.Kanal den aktuellen Schaltzustand (kann ja auch von Hand betätigt werden, oder unklarer Einschaltzustand) einlese. Um mir hier für jeden Kanal ein notify zu sparen, nutze ich das autoClearAlarm.
2) Für Aktionen nach einem latch State, führe ich als erste Aktion im notify ein set <OWDevice> latch.Y 10> aus, um das latch des  channels wieder rückzusetzen.

Oliver

Oliver Vallant

Hallo HabeIchVergessen,

Zitat von: habeIchVergessen am 14 Dezember 2017, 20:09:00
mit 2 Lesezugriffen können alle latches und sensed Werte gelesen werden.
dies bitweise in einer Schleife zu tun ist nicht resourcenschonend.
auch das Rücksetzen aller latches nach der Verarbeitung der ersten gesetzten, ist suboptimal und auch der Grund, warum nur 1x sensed ausgelesen wird (isLatched muss dafür gesetzt sein; funktioniert also genau 1x!).

Ist richtig. Da einerseits OWServer via OWHTTP auf OWFS zugreift und OWFS ohnedies cached und die Abfrage nicht auf den BUS selbst hinausläuft, bin ich gar nicht auf die Idee gekommen. Auch setze ich den DS2408 für Zimmerschalter (Licht, Rollos etc.) ein und da werden selten innerhalb einer Sek. mehr als eine Taste betätigt. Deine Lösung ist aber eleganter ... werde asap bei mir umstellen.
Oliver

Oliver Vallant

Hallo Eldrik und HabIchVergessen,

das größte Optimierungspotential bzl. Reaktionszeit zwischen Schalterbetätigung und Schalten eines Relais (zB. Licht im Raum) besteht in der zyklischen Abfrage des Alarms (1-wire Conditional Search) selbst. Ich habe derzeit ein at pro Sekunde laufen, welches über OWServer den Parameter /uncached/alarm des OWFS holt. Bei Eldiks Fenster ist 1sec+Aktion ausreichend, beim Lichteinschalten des Raumlichtes oder bei Rollos, also unmittelbarer User-Interaktion, gerade noch akzeptabel.
Ich kenne Leider FHEM intern zu wenig. Wo im System könnte man am elegantesten "get <OWServer>  /uncached/alarm" abfragen, um zumindest 2x besser 3x Sekunde den Alarm-State zu bekommen und gleichzeitig das System nicht unnötig zu blockieren.

Danke, Oliver

Dr. Boris Neubert

       my $latches = fhem("get ".$name." latch.ALL");
       my $sensed = fhem("get ".$name." sensed.ALL");


Ich weiß nicht genau, wie der Prozess aussieht, in welchem die Daten ausgelesen werden.

get liest immer den augenblickliche Wert vom Server, und zwar entweder ungecachete oder gecachete Daten, je nachdem, ob das Attribut uncached gesetzt ist oder nicht.

Wenn das OWDevice mit Polling definiert wurde, liegen die Werte ja schon vor, mit einem maximalen Alter wie das Polling-Intervall. Dann ist

ReadingsVal($name, "latch.ALL")

effizienter.
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

habeIchVergessen

bzgl. Effizienz ist ein Roundtrip zum 1Wire-Device mit Auslesen aller latch- und sensed-Werte + Rücksetzen der latches das Optimum.

Im Zusammenhang mit ConditionalSearch macht ein "cached"-Zugriff keinen Sinn. Das die gecachten Daten veraltet sind, triff mit hoher Wahrscheinlichkeit zu.

Oliver Vallant

#54
Nach meinen Tests funktioniert interessanter Weise set <OWServer latch.ALL 0,0,0,0,0,0,0,0 (alarm flags müssen ja zurückgesetzt werden) nicht. Wohl aber kann ich mit get latch.ALL die latches mit Komma getrennt auslesen. Was funktioniert ist set latch.BYTE 10 für alle Löschen und set latch.BYTE 11 für alle setzten. Mir ist bereits bei set PIO,Y aufgefallen, dass beim Setzten immer 10 statt 0 und 11 statt 1 verwendet werden muss. Keine Ahnung, ob dies im OWServer oder in OWFS so erforderlich ist.

Bei mir funktioniert demnach folgender Code:


# 1-wire Values für on/off
use constant owON => 11;
use constant owOFF => 10;

sub getBUSalarm($) {
  my ($bus) = @_;
  my $res = fhem("get ".$bus." /uncached/alarm");
  my @devices= split("\n", $res);

  #---proceed alarmed device at this 1-wire---
  for my $device (@devices) {
    my @line = split(" ", $device);
    my $type = @line[1];
    my $name = @line[2];
    Log3 $name, 4, "Alarmed: ".$name." Type: ".$type;

    #--- device dependant treatment---
    if ($type eq "DS2408" && defined($defs{"$name"})) {
      my $rhash=$defs{"$name"};
      my $latches = fhem("get ".$name." latch.ALL");
      my $sensed = fhem("get ".$name." sensed.ALL");
      Log3 $name, 4, "ports at device $name: latches $latches, sensed: $sensed";
   
      readingsBeginUpdate($rhash);
      #--- DS2408 has 8 ports---
      for (my $port=0; $port <= 7; $port++) {
        readingsBulkUpdate($rhash, "latch." . $port, substr($latches, $port * 2, 1));
        readingsBulkUpdate($rhash, "sensed." . $port, substr($sensed, $port * 2, 1));
      }
      readingsEndUpdate($rhash, 1);

      #---Port gets cleared---
      fhem("set ".$name." latch.BYTE ".owOFF);
      Log3 $name, 4, "Alarm cleared for " .$name;
    }
  } 
  return undef;
}


Vorteile:

  • Die Unterscheidung autoClearedAlarm und explizites rücksetzen des Alarms im Notify entfällt, da nun die Notifies jedenfalls getriggert werden. Dh. die autoClearedAlarm Attribut Definition und Behandlung entfällt
  • Auch mehrere gleichzeitige Inputs am DS2408 werden abgearbeitet

Das ultima ratio wäre natürlich, dass man das gesamte Auslesen der latch states eigentlich entfallen lassen kann (und gewinnt ein paar ms), da es ohnedies am Ende zurückgesetzt wird. Dh. wenn man nur auf sensed Notifys nutzt und die latched Trigger nicht benötigt kann man reduzieren auf:


# 1-wire Values für on/off
use constant owON => 11;
use constant owOFF => 10;

sub getBUSalarmWithoutLatches($) {
  my ($bus) = @_;
  my $res = fhem("get ".$bus." /uncached/alarm");
  my @devices= split("\n", $res);

  #---proceed alarmed device at this 1-wire---
  for my $device (@devices) {
    my @line = split(" ", $device);
    my $type = @line[1];
    my $name = @line[2];
    Log3 $name, 4, "Alarmed: ".$name." Type: ".$type;

    #--- device dependant treatment---
    if ($type eq "DS2408" && defined($defs{"$name"})) {
      my $rhash=$defs{"$name"};
      my $sensed = fhem("get ".$name." sensed.ALL");
      Log3 $name, 4, "Ports at device $name: sensed: $sensed";
   
      readingsBeginUpdate($rhash);
      #--- DS2408 has 8 ports---
      for (my $port=0; $port <= 7; $port++) {
        readingsBulkUpdate($rhash, "sensed." . $port, substr($sensed, $port * 2, 1));
      }
      readingsEndUpdate($rhash, 1);

      #---Port gets cleared---
      fhem("set ".$name." latch.BYTE ".owOFF);
      Log3 $name, 4, "Alarm cleared for " .$name;
    }
  } 
  return undef;
}


Oliver

Oliver Vallant

Hallo Boris,

ließe sich aus deiner Sicht die nunmehr optimierte getBUSalarm($) in dein Modul OWServer so integrieren, dass dieses zB. 2x pro Sekunde (vielleicht als Attribut einstellbar) aufgerufen wird. Wenn noch als set initBUSalarm die Initialisierung unten hinzukäme , hätte das Modul somit kompakt die 1-wire Alarming Behandlung integriert.

Oliver


sub initBUSalarm($) {
   my ($bus) = @_;
   my $res = fhem("get ".$bus." devices");
   my @devices= split("\n", $res);

   #---proceed device at this 1-wire---
   for my $device (@devices) {
     my @line = split(" ", $device);
     my $type = @line[1];
     my $name = @line[2];
     if ($type eq "DS2408") {
       fhem("set ".$name." set_alarm .133333333");
       fhem("set ".$name." por ".owOFF);
       fhem("set ".$name." latch.BYTE ".owOFF);
       Log3 $name, 3, "Init alarming (set_alarm 133333333, por 0, latch.BYTE 0) for device: ".$name." type: ".$type;
     }
     if ($type eq "DS18S20") {
       fhem("set ".$name." temphigh .125");
       fhem("set ".$name." templow .-50");
       Log3 $name, 3, "Init alarming (temphigh 125, templow -50) at device: ".$name." type: ".$type;
     }
   }
}

habeIchVergessen

Zitat von: Oliver Vallant am 16 Dezember 2017, 17:14:24
Das ultima ratio wäre natürlich, dass man das gesamte Auslesen der latch states eigentlich entfallen lassen kann (und gewinnt ein paar ms), da es ohnedies am Ende zurückgesetzt wird. Dh. wenn man nur auf sensed Notifys nutzt und die latched Trigger nicht benötigt kann man reduzieren auf:

Der IC kann die Zustandsänderung im Interval detektieren (latch) und den Zustand selbst (sensed).
Ich bezweifele, dass die reine Betrachtung von sensed zuverlässige Ergebnisse liefert, wenn  pro Interval eine Änderung mehr als 1x auftritt.

bzgl. neuer Funktion in OWSERVER/-DEVICE würde ich eine Funktion vorschlagen, die den Alarm zurücksetzt und die Werte zu latches sensed mitliefert. Also ein roundtrip zum Device (OWSERVER/OWHTTP/OWFS/Busmaster).

hat das schonmal jemand gemessen (roundtrip)?

Oliver Vallant

Ja richtig. Wenn zB. ein Impuls (sehr viel kleiner als das Abfrageintervall von /uncached/alarms) am pin anliegt, würde latch triggern und sensed nicht.