Ethersex (AVR-NET-IO) Eingänge/Inputs automatisch an FHEM senden (via ECMD?)

Begonnen von andreas_n, 16 Mai 2015, 15:18:38

Vorheriges Thema - Nächstes Thema

andreas_n

Hallo

Suche nach einer Möglichkeit, Eingänge direkt (also kein pollen) von FHEM auszuwerten.
Dies Thema wurde bereits hier (http://forum.fhem.de/index.php/topic,21636.20/wap2.html) etwas abgehandelt aber nicht wirklich gelöst.

1te Möglichkeit (nicht ideal)
Bekannt ist die Möglichkeit, Eingänge mit Ethersex und "Watch io changes and react" auf globale FHEM Variablen abzubilden.
-> Nachteil "notify" geht nicht, und etwas unzuverlässig ansonsten sehr schnell

2te Möglicheit (wäre gut, konnte ich nicht umsetzen)
Gemäß den Kommentar1  in der classdef: ECMD91A/C könnte es möglich sein, dass Eingänge direkt gesendet werden können.
Aber nun sendet Ethersex diese Daten nicht automatisch oder? Kann hier evt etwas C-Code bzw. Control6 auf dem AVR-NET-IO verantwortlich sein.
Oder liegt hier ein Missverständnis auf meiner Seite vor?

Toll wäre es, wenn jemand ein laufendes Konfigurations-Pärchen  (Einstellungen auf Ethersex, classdef und evt. das define) posten könnte.

Schon mal Danke im voraus ...

1ECMD91A:
# In FHEM festlegen => define PORT91A1 ECMDDevice ECMD91A 0 0
# Uebergabeparameter port (0-3) pin (0-7)
params port pin

# Controller sendet die Portzustände bei Änderung. Werden über reading verarbeitet
#reading on match {"^port %port %pin 0\n$"}
#reading off match {"^port %port %pin 1\n$"}
reading power match "port %port %pin \d\n$"
reading power postproc { s/.*port %port %pin (\d)\n.*/$1/s; $_ ? "on" : "off" }

# Abfrage nicht nötig
get state cmd {"getporta\r"}
get state postproc {"%PINA $_";}

#get state postproc {\
# my $retval = "off";\
# my $portwert = substr($_, 10, 2);\
# $portwert = hex($portwert) & hex($PINA);\
# $retval = "on" if ($portwert > 0);\
# $retval;}

kpwg

Hallo Andreas,

Zitat von: andreas_n am 16 Mai 2015, 15:18:38
Suche nach einer Möglichkeit, Eingänge direkt (also kein pollen) von FHEM auszuwerten.
Dies Thema wurde bereits hier (http://forum.fhem.de/index.php/topic,21636.20/wap2.html) etwas abgehandelt aber nicht wirklich gelöst.
Nein, zu dem Zeitpunkt war mir Vieles noch sehr fremd. Auch gab es hier keine wirkliche Anwendung dafür. In dem Thema hatten wir bezüglich "ECMD read" wohl verschiedene Denkansätze.  ;D
Vielleicht lösen wir das in diesem Thread? Ich versuche hier mal, meine Erkenntnisse (und Ideen) einzubringen.

Zitat von: andreas_n am 16 Mai 2015, 15:18:38
1te Möglichkeit (nicht ideal)
Bekannt ist die Möglichkeit, Eingänge mit Ethersex und "Watch io changes and react" auf globale FHEM Variablen abzubilden.
-> Nachteil "notify" geht nicht, und etwas unzuverlässig ansonsten sehr schnell
Mit WatchIO ist das so eine Sache. Ich habe es recht zuverlässig zum Laufen bekommen, indem ich damit direkt einen FHEM Befehl in ein Dummy oder Device absetze. Dabei lief es nur mit \n\n nachvollziehbar gut, ansonsten ging der Befehl genau einmal abzusetzen. Besser klappt die ganze Sache mit einem kleinen Contro6-Script und ESEND- die Möglichkeiten bzw. Abhängigkeiten sind da einfach besser handhabbar. Hier ergibt sich allerdings noch eine Tücke: Ethersex erwartet für sein gesendetes ESEND Paket ein OK. Kommt da nichts, weil FHEM das so nicht macht oder die Verbindung hakt, stürzt Ethersex irgendwann ab. Aus dieser Sicht ist es daher ungeschickt, mit ESEND zu arbeiten (obwohl der Ansatz so schön einfach ist  8))

Startseite zu Control6: http://old.ethersex.de/index.php/Control6
Viele Beispiele für Control6: http://old.ethersex.de/index.php/Kategorie:Control6_Examples

Zitat von: andreas_n am 16 Mai 2015, 15:18:382te Möglicheit (wäre gut, konnte ich nicht umsetzen)
Gemäß den Kommentar1  in der classdef: ECMD91A/C könnte es möglich sein, dass Eingänge direkt gesendet werden können.
Aber nun sendet Ethersex diese Daten nicht automatisch oder? Kann hier evt etwas C-Code bzw. Control6 auf dem AVR-NET-IO verantwortlich sein.
Oder liegt hier ein Missverständnis auf meiner Seite vor?
Nein, das muss man E6 schon per C6 sagen, was warum wo gesendet werden soll. Anders kommt da nix raus. Wegen watchIO siehe oben.
Der Bessere Ansatz dafür ist der message handler mit einem TCP connect. Dabei wird genauso eine Verbindung zu FHEM aufgebaut, man könnte aber hier eingreifen, wenn die Verbindung stirbt und auch Variablen (Meßwerte) übermitteln, die man sonst nicht gesendet bekommt. Beispielcode: http://old.ethersex.de/index.php/GPS-Logging oder http://old.ethersex.de/index.php/Interrupt_Zaehler

Zitat von: andreas_n am 16 Mai 2015, 15:18:38
Toll wäre es, wenn jemand ein laufendes Konfigurations-Pärchen  (Einstellungen auf Ethersex, classdef und evt. das define) posten könnte.
Das scheint es nicht zu geben oder wurde nicht veröffentlicht. Ich sauge ja alle Infos zum Thema auf, aber mir ist nichts bekannt.  :'(

Viele Grüße, Ricardo

andreas_n

Danke fürs Feedback

Hatte ja gehofft, dass es eine Lösung geben könnte.
1)
Daten per TCP/IP zu FHEM zu senden sollte aus Ethersex machbar sein - aber wohin? Jedenfalls weiß ich nicht wie ich das aufgebaute Telnet-Fenster von FHEM in Ethersex erreichen könnte. Dies ist aber zwingend erforderlich wenn ECMD dies verarbeiten soll.
2)
WatchSyn hat meines Erachten den großen Nachteil, das Notify nicht geht. (oder gibt es hier einen Trick?) Denn Eingänge möchte man gerne zur Automatisierung nutzen.
Mit einer kleine Codeänderung (watchcat.c) könne Ethersex bestimmt auch dazu gebracht werden, die Eingänge zusätzlich auch periodisch zu senden - also nicht nur bei Änderungen. Damit wäre gewährleistet, dass der Datenstand in FHEM Konsistenz ist. Aber schön ist was anderes.

Gruß Andreas




kpwg

Zitat von: andreas_n am 17 Mai 2015, 11:19:06
Daten per TCP/IP zu FHEM zu senden sollte aus Ethersex machbar sein - aber wohin? Jedenfalls weiß ich nicht wie ich das aufgebaute Telnet-Fenster von FHEM in Ethersex erreichen könnte. Dies ist aber zwingend erforderlich wenn ECMD dies verarbeiten soll.
Nun, das hat mit ECMD bzw. ECMD Read nichts mehr zu tun. Hier wird einfach der Port (2701) parallel geöffnet und dort direkt auf FHEM Befehle gelauscht. Nachteil: E6 muss bereits den passenden FHEM Befehl senden (z.B. "set Lampe1 on\n\n"). Es ist keine Nachbearbeitung wie in der classdef möglich.

Zitat von: andreas_n am 17 Mai 2015, 11:19:06
WatchSyn hat meines Erachten den großen Nachteil, das Notify nicht geht. (oder gibt es hier einen Trick?) Denn Eingänge möchte man gerne zur Automatisierung nutzen.
Mit einer kleine Codeänderung (watchcat.c) könne Ethersex bestimmt auch dazu gebracht werden, die Eingänge zusätzlich auch periodisch zu senden - also nicht nur bei Änderungen. Damit wäre gewährleistet, dass der Datenstand in FHEM Konsistenz ist. Aber schön ist was anderes.

Man könnte das per C6 bewerkstelligen, indem dort periodisch abgefragt wird. Hier gibts wieder Beispielcode: http://old.ethersex.de/index.php/PIN-Befehle
Damit kann eine "Statusmeldung" regelmäßig angestoßen werden. Eigene lokale Änderungen am Code sollten immer der letzte Ausweg sein. Wenn die Idee taugt, dann bei git einpflegen. Die E6-Community ist offen für neue Ideen!  8)

Viele Grüße, Ricardo

andreas_n

ZitatNun, das hat mit ECMD bzw. ECMD Read nichts mehr zu tun. Hier wird einfach der Port (2701) parallel geöffnet und dort direkt auf FHEM Befehle gelauscht.
Stimmt, hatte nur Telnet-Fenster dazu gesagt, weil es sich über Telnet bedienen lässt.
Evt. könnte ja folgender Ansatz gehen:

  • Über Control6 könnte ein weiterer Port evt. 2702 als (Listen Socket / TCP/IP Server) geöffnet werden.
  • Über diesen werden Änderungen in der Form: "port <port> <pin>" mit port=0,1,2,3 und pin=0..7 selbständig (an FHEM) versendet.
  • Danach sollte man mit der classdef "ECMD91?" auf FHEM doch weitermachen können.
Aber so was in der Form müsste es eigentlich schon geben, weil es schon ein passende classdef auf Basis von ECMD schon gibt.

Gruß Andreas

kpwg

Zitat von: andreas_n am 17 Mai 2015, 12:35:51
Evt. könnte ja folgender Ansatz gehen:

  • Über Control6 könnte ein weiterer Port evt. 2702 als (Listen Socket / TCP/IP Server) geöffnet werden.
  • Über diesen werden Änderungen in der Form: "port <port> <pin>" mit port=0,1,2,3 und pin=0..7 selbständig (an FHEM) versendet.
  • Danach sollte man mit der classdef "ECMD91?" auf FHEM doch weitermachen können.
Das muss gar nicht auf einem extra Port laufen. TCP unterscheidet die Verbindung auch anhand des Quellport. Da darf ruhig der gleiche Zielport drin stehen. Das FHEM-verständliche Format kann dann per C6 generiert werden. Auf dem  ECMD Ziel-Port 2701 in E6 geht auch nur ECMD; es lässt sich da leider nichts "mitsenden" oder zusätzlich abfragen. Ausschließlich die per "help" gelisteten Befehle haben eine Funktion.

Zitat von: andreas_n am 17 Mai 2015, 12:35:51
Aber so was in der Form müsste es eigentlich schon geben, weil es schon ein passende classdef auf Basis von ECMD schon gibt.
Gut möglich! Es wurde nur nicht publiziert. Ich habe auch nichts dazu gefunden. Generell steckt in der classdef-Lösung sehr großes Potential. ::)

EDIT: ECMD wird in FHEM ja nicht nur für Ethersex genutzt, sondern auch für einige andere Geräte mit seriellen oder Telnet-Schnittstellen.

andreas_n

Aktueller Stand:

  • Der Control6 Code ist sendet den Status Eingänge (Port A) und Ausgänge (Port C) sofort nach Änderung
  • und zusätzlich auch periodisch. (Dies um sicher zu sein, das FHEM immer den richtigen Status hat)
  • Die Ausgänge können ebenso hierüber gesetzt werden.

Ändert sich nun ein Eingang wird dies sofort in FHEM sichtbar und sogar die notify Funktion arbeitet.
Meine Hardware avr-net-io/atmega644p und mit Ethersex.
Eingebunden in FHEM wird das Ganze mit: (Man beachte die abgeänderte Portnummer)
define IP93_IO ECMD telnet 192.168.1.93:2702

Was mir noch fehlt zum Glück ist die Unterstützung von OnwireSensoren (auch event gesteuert), Zähler und Ultraschallsensor (zur Entfernungs- und Objekterkennung)

C6_HEADER(`/* This will be in control6.h */')

CONTROL_START
  TCP_HANDLER(message_handler)
clock_datetime_t datetime;
uint8_t nCnt,nPrt;
static uint8_t last_minute;
static uint8_t PinStatus[4][8];
for (;;) {
dnl force the system to send input/output status every minute
clock_localtime(&datetime, clock_get_time());
if (datetime.min != last_minute) {
last_minute = datetime.min;
if (last_minute&1)
PinStatus[0][0]=PinStatus[0][1]=PinStatus[0][2]=PinStatus[0][3]=PinStatus[0][4]=PinStatus[0][5]=PinStatus[0][6]=3;
        else PinStatus[2][0]=PinStatus[2][1]=PinStatus[2][2]=PinStatus[2][3]=PinStatus[2][4]=PinStatus[2][5]=PinStatus[2][6]=PinStatus[2][7]=3;
                }

dnl check what input or output is changed and set it
for (nCnt=0;nCnt<8;nCnt++) {                     
     if (nCnt<7 && PinStatus[0][nCnt] != (PINA & 1<<nCnt)) {
TCP_SEND("port 0 %d %s\n",nCnt, (PinStatus[0][nCnt] = (PINA & 1<<nCnt))?"1":"0");
break;
     }  else if (nCnt<8 && PinStatus[2][nCnt] != (PINC & 1<<nCnt)) {
TCP_SEND("port 2 %d %s\n",nCnt, (PinStatus[2][nCnt] = (PINC & 1<<nCnt))?"1":"0");
break;
     }
}

// not used
                if (uip_connected()) {
}


dnl instruction from extern (Input: get <port> <pin>; Output: set <port> <pin>, clr <port> <pin>
                if (uip_newdata ()) {
                     char *ptr = (char *) uip_appdata;
                     ptr[uip_len] = 0;
                     if (uip_len>=7) {
nCnt = ptr[6]-'0'; 
nPrt = ptr[4]-'0'; 
                        if (nCnt<8 && nPrt<4) {
if (!strncmp(ptr,"set",3)) { dnl set any output
    switch (nPrt) {
case 0: PORTA |=  (1<<nCnt);break;
case 1: PORTB |=  (1<<nCnt);break;
case 2: PORTC |=  (1<<nCnt);break;
case 3: PORTD |=  (1<<nCnt);break;
    }
} else if (!strncmp(ptr,"clr",3)) { dnl clr any output
    switch (nPrt) {
case 0: PORTA &= ~(1<<nCnt);break;
case 1: PORTB &= ~(1<<nCnt);break;
case 2: PORTC &= ~(1<<nCnt);break;
case 3: PORTD &= ~(1<<nCnt);break;
    }
}else if (!strncmp(ptr,"tog",3)) { dnl toogle any output
    switch (nPrt) {
case 0: PORTA ^=  (1<<nCnt);break;
case 1: PORTB ^=  (1<<nCnt);break;
case 2: PORTC ^=  (1<<nCnt);break;
case 3: PORTD ^=  (1<<nCnt);break;
    }
} else  TCP_SEND("ERROR\n");
                        }  else TCP_SEND("ERROR\n");
                     } else TCP_SEND("ERROR\n");
                }
                PT_YIELD(pt);
       }
  TCP_HANDLER_END();

  ON STARTUP DO
  // Enable enable the inputs  Port A - all of them expect PA7 (used for 1Wire Temp sensor)
DDRA   &= ~_BV(PA0);
DDRA   &= ~_BV(PA1);
DDRA   &= ~_BV(PA2);
DDRA   &= ~_BV(PA3);
DDRA   &= ~_BV(PA4);
DDRA   &= ~_BV(PA5);
DDRA   &= ~_BV(PA6);

// switch on pull up resistor (Sensor must switch again GND)
PORTA |= _BV(PORTA0);
PORTA |= _BV(PORTA1);
PORTA |= _BV(PORTA2);
PORTA |= _BV(PORTA3);
PORTA |= _BV(PORTA4);
PORTA |= _BV(PORTA5);
PORTA |= _BV(PORTA6);

  // Enable enable the ouputs Port C
DDRC  |= ~_BV(PC0);
DDRC  |= ~_BV(PC1);
DDRC  |= ~_BV(PC2);
DDRC  |= ~_BV(PC3);
DDRC  |= ~_BV(PC4);
DDRC  |= ~_BV(PC5);
DDRC  |= ~_BV(PC6);
DDRC  |= ~_BV(PC7);


// Listen to Port 2702
        TCP_LISTEN(2702, message_handler);
  END


CONTROL_END

Ich habe etwas Problem mit dem Umgang von Control6 aber dennoch scheint es zu arbeiten.


# Uebergabeparameter port (0-3) pin (0-7)
params port pin


# handling to set an output
set off cmd {"set %port %pin\n"}

# handling to clr an output
set on cmd {"clr %port %pin\n"}


reading on match "port %port %pin 0\n"
reading off match "port %port %pin 1\n"
reading on postproc { s/.*port %port %pin 0\n.*//s; "$_" eq "" ? "" : "Fehler" }
reading off postproc { s/.*port %port %pin 1\n.*//s; "$_" eq "" ? "" : "Fehler"

Wurde im wesentlichen zusammengesucht.


kpwg

Andreas, Vielen Dank für die Mühe. Es ist genial gelöst...  8)

Ich teste das bei Gelegenheit auch mal und berichte hier wieder. Leider scheint sich sonst niemand zu finden, der eine ähnliche Konstellation betreibt.

Ich würde jetzt noch testen, ob E6 stabil bleibt, wenn FHEM die Daten nicht abnehmen kann. Der TCP_HANDLER sollte das aber "abkönnen". Finden wir's heraus.

Viele Grüße, Ricardo

andreas_n

      Danke für die Blumen.

      Bis jetzt (ca. 1Woche mit 3 x AVR-NET-IO) ist alles gut.
      Mittlerweile habe ich das Ganze erweitert und benötige nur noch den Port 2702.

      Neben den Eingänge und Ausgängen gibt es nun auch:

      • 1 Wire -Temperatursensoren (Dallas) und
      • DH22 Temperatur/Feuchte Sensoren.
      • US100 Ultraschallentfernungsmessung (Update / 10.06.2015).

      (Und danke für den Tip mit %1 %2 zur Datenfilterung in der classdef)

      Anmerkung: Mit Ethersex erfasse ich auch 7 x S0 Zähler. Die Erfassung und Verwaltung überlasse ich bis jetzt allerdings dem Volkzählerprojekt. Die Daten hole ich aber von dort aus in FHEM.
      Jedenfalls kenne ich kenne ich bis jetzt keine bessere Lösung.

      Werde alles nach Fertigstellung vorstellen - auch wenn es nicht viele Interessenten gibt.

      Gruß
      Andreas


leguan08

Bin schon sehr gespannt auf deine komplette Anleitung ;D

Gute Arbeit !

Viele Grüße

andreas_n

#10
Das System arbeitet nun seit 4 Wochen zur meiner vollsten Zufriedenheit.
Unterstützt werden

  • US100 Ultraschallsensor (us_ethersex.classdef)
  • 1-wire Temperatur Messung (temp_ethersex.classdef)
  • DHT22 Messung Temperatur und Luftfeuchte (dht22_ethersex.classdef)
  • Ein/Ausgänge (io_ethersex.classdef)


# Uebergabeparameter  devID (devID) (immer 1)
params devID

reading D match "US100 %devID\n([0-9]*)\n"
reading D postproc {\
s/US100 %devID\n([0-9]*)\n/D: $1/;\
my $hash  = $defs{%NAME};\
my $dist  = $1 * 0.24;\
\
readingsSingleUpdate($hash, "dest", $dist, 1);\
readingsSingleUpdate($hash, "signaltime",$1, 1);\
readingsSingleUpdate($hash, "state", $dist, 1);\
\
}
us_ethersex.classdef


# Uebergabeparameter  devID (15dig)
params devID

reading T match "temp %devID \n([-0-9]*[.][0-9])\n"
reading T postproc {\
s/temp %devID\n([-0-9]*[.][0-9])\n/T: $1/;\
my $hash  = $defs{%NAME};\
my $temperature = $1;\
my $state = $1;\
\
readingsSingleUpdate($hash, "temperature", $temperature, 1);\
readingsSingleUpdate($hash, "state", $state, 1);\
\
}
temp_ethersex.classdef

# Uebergabeparameter  devID (0.. )
params devID


reading T match "DHT22 %devID\n([-0-9]*[.][0-9])\n([0-9]*[.][0-9])\n([0-9]*[.][0-9])\n([0-9]*[.][0-9])\n"
reading T postproc {\
s/DHT22 %devID\n([-0-9]*[.][0-9])\n([0-9]*[.][0-9])\n([0-9]*[.][0-9])\n([0-9]*[.][0-9])\n/T: $1 H: $2 D: $3 W: $4/;\
my $hash  = $defs{%NAME};\
my $temperature = $1;\
my $humidity = $2;\
my $dewpoint = $3;\
my $waterqm = $4;\
my $state = $1;\
\
readingsSingleUpdate($hash, "temperature", $temperature, 1);\
readingsSingleUpdate($hash, "humidity", $humidity, 1);\
readingsSingleUpdate($hash, "dewpoint", $dewpoint, 1);\
readingsSingleUpdate($hash, "waterqm", $waterqm, 1);\
readingsSingleUpdate($hash, "state", $state, 1);\
\
}
dht22_ethersex.classdef

# Uebergabeparameter port (0-3) pin (0-7)
params port pin


# handling to clr an output
set off cmd {"clr %port %pin\n"}

# handling to set an output
set on cmd {"set %port %pin\n"}


reading on match "port %port %pin 1\n"
reading off match "port %port %pin 0\n"
reading on postproc { s/.*port %port %pin 1\n.*//s; "$_" eq "" ? "" : "Fehler" }
reading off postproc { s/.*port %port %pin 0\n.*//s; "$_" eq "" ? "" : "Fehler" }
io_ethersex.classdef


C6_HEADER(`/* This will be in control6.h */')

#include <stdlib.h>
#include "hardware/dht/dht.h"
#include <util/delay.h>
#include <math.h>

#define INVERT_OUTPUT
dnl this is required for me because I have two differnt relais board behind the AVR-NET-IO. One is swithing on ON the other on OFF

#define MAX_DHT22_SENSORS 4

void US100_config(void)
{
  DDR_CONFIG_OUT(US100_Out);
  DDR_CONFIG_IN(US100_In);
}

int US100_get(void)
{
  PIN_CLEAR(US100_Out);
  _delay_us(5);
  PIN_SET(US100_Out);
  _delay_us(10);
  PIN_CLEAR(US100_Out);

// check pin is low
    if (PIN_HIGH(US100_In)) return 0;

// wait until pin high
  uint16_t i=0;
  for (i=0; i < 30000; i++){
    if (PIN_HIGH(US100_In)) break;
    _delay_us(1);
  }
//  loop delay max 30ms
  for (i=0; i < 30000; i++){
    if (!PIN_HIGH(US100_In)) break;
    _delay_us(1);
  }

  // now check value, might be not usefull...
  if (i == 30000) {
return 0;
  }
  return i;
}

  static char onewire_name[OW_SENSORS_COUNT][17];
  static int  onewire_value_old[OW_SENSORS_COUNT];
  static int  onewire_value_new[OW_SENSORS_COUNT];
  static int us100_old, us100_new;
  static int  dth22_temp_old[MAX_DHT22_SENSORS];
  static int  dth22_huma_old[MAX_DHT22_SENSORS];
  static uint8_t PinStatus[4][8];   
  static uint8_t nSendCnt;
  static uint8_t nReSendMatrixPrt[]= {0,0,0,0,0,0,0,3,3,2,2,2,2,2,2,2,2,9};
  static uint8_t nReSendMatrixPin[]= {0,1,2,3,4,5,6,6,7,0,1,2,3,4,5,6,7,9};
  static uint8_t nResendMatrixCnt=0;

void ProcessNewData(int nLength, char * ptr)
{
    if (nLength) {
    uint8_t  nCnt = ptr[6]-'0'; 
    uint8_t  nPrt = ptr[4]-'0'; 
    if (nCnt<8 && nPrt<4) {
#ifndef INVERT_OUTPUT
  if (!strncmp(ptr,"set",3)) {
#else
if (!strncmp(ptr,"clr",3)) {
#endif
   switch (nPrt) {   dnl set any output
case 0: PORTA |=  (1<<nCnt);break;
case 1: PORTB |=  (1<<nCnt);break;
case 2: PORTC |=  (1<<nCnt);break;
case 3: PORTD |=  (1<<nCnt);break;
   }
#ifndef INVERT_OUTPUT
    } else if (!strncmp(ptr,"clr",3)) {
#else
    } else if (!strncmp(ptr,"set",3)) {
#endif
   switch (nPrt) { dnl clr any output
case 0: PORTA &= ~(1<<nCnt);break;
case 1: PORTB &= ~(1<<nCnt);break;
case 2: PORTC &= ~(1<<nCnt);break;
case 3: PORTD &= ~(1<<nCnt);break;
   }
       } else
                   debug_printf("Error Instruktion nicht erkannt\n");
           } else
                   debug_printf("Error Port %d Pin %d\n",nPrt,nCnt);
     }
}


char * CheckStatus(char * pSendData)
{
  uint8_t nCnt;
  nSendCnt=++nSendCnt>6?1:nSendCnt;
  switch (nSendCnt) {
case 1: for (nCnt=0;nCnt<7;nCnt++) {                     
     if (PinStatus[0][nCnt] != (PINA & 1<<nCnt)) {
                                sprintf(pSendData,"port 0 %d %s\n",nCnt, (PinStatus[0][nCnt] = (PINA & 1<<nCnt))?"0":"1");
return pSendData;
     }
}     
break;
case 2: for (nCnt=6;nCnt<8;nCnt++) {                     
           if (PinStatus[3][nCnt] != (PIND & 1<<nCnt)) {
sprintf(pSendData,"port 3 %d %s\n",nCnt, (PinStatus[3][nCnt] = (PIND & 1<<nCnt))?"0":"1");
return pSendData;
           }
}
break;
case 3: if (abs(us100_old-us100_new)>50) {
sprintf(pSendData,"US100 0\n%d\n",us100_old = us100_new);
return pSendData;
        }
break;
case 4: for (nCnt=0;nCnt<OW_SENSORS_COUNT;nCnt++) {                     
    if (onewire_value_old[nCnt] != onewire_value_new[nCnt]) {
div_t dv = div((onewire_value_old[nCnt] = onewire_value_new[nCnt]),10);
sprintf(pSendData,"temp %s \n%d.%d\n",onewire_name[nCnt],dv.quot,(dv.rem<0)?-dv.rem:dv.rem);
return pSendData;
    }
        }
break;
case 5: for (nCnt=0;nCnt<MAX_DHT22_SENSORS;nCnt++) {                     
    if (dth22_temp_old[nCnt] != dht_sensors[nCnt].temp || dth22_huma_old[nCnt] != dht_sensors[nCnt].humid) {
double a,b,T,r,v,SDD,DD,TD,AF; dnl Ref.http://www.wetterochs.de/wetter/feuchte.html
T=dht_sensors[nCnt].temp/10.0;
r=dht_sensors[nCnt].humid/10.0;
if (T<0) {a=7.6; b=240.7;}  else {a=7.5; b=237.3;}
SDD=6.1078 * pow(10,(a*T)/(b+T));
DD = r/100 * SDD;
v = log10(DD/6.1078);
TD = b*v/(a-v);
AF = pow(10,5) * 18.016/8314.3 * DD/(T + 273.15);

div_t dvt = div(dth22_temp_old[nCnt]=dht_sensors[nCnt].temp,10);
div_t dvh = div(dth22_huma_old[nCnt]=dht_sensors[nCnt].humid,10);
div_t dvd = div((int)(TD*10+5),10);
div_t dvf = div((int)(AF*10+5),10);

sprintf(pSendData,"DHT22 %d\n%d.%d\n%d.%d\n%d.%d\n%d.%d\n",nCnt,
dvt.quot,(dvt.rem<0)?-dvt.rem:dvt.rem,
dvh.quot,(dvh.rem<0)?-dvh.rem:dvh.rem,
dvd.quot,(dvd.rem<0)?-dvd.rem:dvd.rem,
dvf.quot,(dvf.rem<0)?-dvf.rem:dvf.rem);
return pSendData;
    }
        }
break;
case 6: for (nCnt=0;nCnt<8;nCnt++) {                     
    if ( PinStatus[2][nCnt] != (PINC & 1<<nCnt)) {
#ifndef INVERT_OUTPUT
sprintf(pSendData,"port 2 %d %s\n",nCnt, (PinStatus[2][nCnt] = (PINC & 1<<nCnt))?"1":"0");
#else
sprintf(pSendData,"port 2 %d %s\n",nCnt, (PinStatus[2][nCnt] = (PINC & 1<<nCnt))?"0":"1");
#endif
return pSendData;
    }
        } 
break;
}
  return NULL;
}


CONTROL_START
  TCP_HANDLER(message_handler)
        char pSendData[40];
for (;;) {           
           if (uip_newdata ())
    ProcessNewData(uip_len,(char*)uip_appdata);
   if (CheckStatus(pSendData))
      uip_send (pSendData, strlen (pSendData));
           PT_YIELD(pt);
        }
  TCP_HANDLER_END();

  THREAD(onewire)
     WAIT(30);
     int nI;
     if (nI=0) ONEWIRE_GET(0000000000000000); dnl dummy to load header files - will never be called
     while (get_id_code(nI++)>0 && nI<OW_SENSORS_COUNT) {
int16_t T = ow_read_temp(&ow_global.current_rom);
if (T!=0x7FFF) {
      onewire_value_new[nI] = T;
      snprintf_P(onewire_name[nI], 17,
      PSTR("%02x%02x%02x%02x%02x%02x%02x%02x"),
      ow_global.current_rom.bytewise[0],
      ow_global.current_rom.bytewise[1],
      ow_global.current_rom.bytewise[2],
      ow_global.current_rom.bytewise[3],
      ow_global.current_rom.bytewise[4],
      ow_global.current_rom.bytewise[5],
      ow_global.current_rom.bytewise[6],
      ow_global.current_rom.bytewise[7]);
         }
    }
    PT_YIELD(pt);
  THREAD_END(onewire)

  THREAD(us100)
     WAIT(1);
     us100_new =US100_get();   
    PT_YIELD(pt);
  THREAD_END(us100)

  dnl force the system to send input/output status every 10 sec
  THREAD(resend)
     WAIT(10);
     if (nReSendMatrixPrt[nResendMatrixCnt]<9) {
PinStatus[nReSendMatrixPrt[nResendMatrixCnt]][nReSendMatrixPin[nResendMatrixCnt]]=3;
nResendMatrixCnt++;
     } else nResendMatrixCnt=0;
     PT_YIELD(pt);
  THREAD_END(resend)

  ON STARTUP DO
   for (int nI=0;nI<10;nI++)
onewire_value_new[nI]=onewire_value_old[nI]=0x7FFF;
   for (int nI=0; nI<MAX_DHT22_SENSORS;nI++)
dth22_huma_old[nI] = dth22_temp_old[nI] = 0;
   nResendMatrixCnt=0;
   US100_config();

  // Enable enable some inputs  Port A,D (PA8=OneWire, PD2,3,4,5=DHT22
DDRA   &= ~_BV(PA0);
DDRA   &= ~_BV(PA1);
DDRA   &= ~_BV(PA2);
DDRA   &= ~_BV(PA3);
DDRA   &= ~_BV(PA4);
DDRA   &= ~_BV(PA5);
DDRA   &= ~_BV(PA6);
DDRD   &= ~_BV(PD6);
DDRD   &= ~_BV(PD7);

// switch on pull up resistor (Sensor must switch again GND)
PORTA |= _BV(PORTA0);
PORTA |= _BV(PORTA1);
PORTA |= _BV(PORTA2);
PORTA |= _BV(PORTA3);
PORTA |= _BV(PORTA4);
PORTA |= _BV(PORTA5);
PORTA |= _BV(PORTA6);
PORTD |= _BV(PORTD6);
PORTD |= _BV(PORTD7);

  // Enable enable the ouputs Port C
DDRC  |= ~_BV(PC0);
DDRC  |= ~_BV(PC1);
DDRC  |= ~_BV(PC2);
DDRC  |= ~_BV(PC3);
DDRC  |= ~_BV(PC4);
DDRC  |= ~_BV(PC5);
DDRC  |= ~_BV(PC6);
DDRC  |= ~_BV(PC7);
#ifdef INVERT_OUTPUT
PORTC=0xff;
#else
PORTC=0;
#endif

// Listen to Port 2702
        TCP_LISTEN(2702, message_handler);

// geting us100 data
THREAD_START(us100)

// geting data from onewire sensors
THREAD_START(onewire)

// Resending data
THREAD_START(resend)

  END


CONTROL_END
control6.src

#ifdef ONEWIRE_POLLING_SUPPORT
static int16_t
ow_read_temp(ow_rom_code_t *rom)
{
  /*Search the sensor...*/
  for(uint8_t i=0;i<OW_SENSORS_COUNT;i++)
  {
    /*Maybe check here whether the device is a temperature sensor*/
    if(ow_sensors[i].ow_rom_code.raw == rom->raw)
    {
      /*Found it*/
      ow_temp_t temp = ow_sensors[i].temp;
      return (temp.twodigits ? (temp.val+5) / 10 : temp.val);
    }
  }
  /*Sensor is not in list*/
  return 0x7FFF;  /* error */

}
Eine kleine Änderung habe ich in der Routine ow_read_temp aus control6/lang.d/50.onewire.m4 durchgeführt. Hintergrund war, das korrekte Runden von Sensoren, die zwei Stellen hinter dem Komma liefern können.

Anmerkungen:
Der Ultraschallsensor US100 (2.5Euro incl Versand via AliExpress/China) benötigt einen Aus- und Eingang.
Diese Pinbezeichnung muss in der Pin Configuration im Ethersex Projekt definiert werden.
(Ansonsten braucht im Ethersex nichts konfiguriert oder eingeschaltet werden)
Bei mir:
#   Named Pin Configuration File
#
# You can assign names to your microcontroller's pins here.
# Keep in mind that this names must consist of alphanumeric
# characters only!
#
# Every line starting with a hash sign (#) is a comment.
#
#
# PIN | IN/OUT | When active? | Name
#-----+--------+--------------+----------------
PB0     INPUT    HIGH       US100_In
PB3     OUTPUT   HIGH       US100_Out


Bei den 1Wire Sensoren muss im Ethersex Projekt "Onwire Polling" eingeschaltet werden.

  • Onewire device detection support -> Einschalten
  • Onewire Polling -> Einschalten
  • (600) Time between 1w-bus discoveries in 1s steps
  • (30) Time between polling in 1s steps
  • (10) Maximum sensor count
Ansonsten war es das. Die Sensoren werden automatisch erkannt und an FHEM gemeldet.

Die Anzahl der DHT22 wird in der "define" Anweisung festgelegt. (0 wenn keine vorhanden.)
Im C-Quellcode kann man erkennen, das dort Taupunkt usw errechnet werden. Hiermit ist es dann möglich eine optimale Lüfter oder Klimasteuerung aufzubauen.
(Anmerkung: Taupunkt -> die Temperatur bei der sich die Luftfeuchte niederschlägt.)
Damit das Ganze unterstützt wird muss das Ethersex-Projekt entsprechend konfiguriert sein.

  • (30) Time between polling in 1s steps
  • [X] temp
  • [X] humid
  • [X] list
  • [X] list with values
(DHT22/AM2302) Sensor type

#
# DHT Configuration File
#
# You can assign pins and names to your sensors here.
#
# Keep in mind that this names must consist of alphanumeric
# characters only!
#
# Every line starting with a hash sign (#) is a comment.
#
#
# PIN | Name
#-----+--------------------------
PD2     PD2
PD3     PD3
PD4     PD4
PD5     PD5
(meine Pin configuration)

Ein/Ausgänge
Alle Ein/Ausgänge werden periodisch gemeldet! Somit weiß FHEM immer den aktuellen Stand - auch wenn mal was schief läuft.
Ich selber nutze zwei Type von Relaisboards - welche die positiv schalten und welche die negativ schalten.
Wird der negative Type genutzt muss  #define INVERT_OUTPUT vorhanden sein.
Wie im C-Code zu erkennen nutze ich den kompletten Port-A als Eingänge (plus Pin6,7 aus PortD) und Port-C aus Ausgänge.

Allgemein
Dieses Script nutzt Port 2702.
Alles wird Ereignis-gesteuert and FHEM gemeldet.

Des-weiteren sind noch S0-Zähler am AVR-NET-IO Board angeschlossen. Diese Daten werden an das Volkszählerprojekt (bei mir auf einer Synology realisiert) übermittelt. Die Auswertung findet dann über über die entsprechende classdef statt. So kann die z.B. die momentane Leitung einer Solaranlage zu Steuerungszwecken genutzt werden..

Eine schöne Diagnose, um zu ermitteln was zwischen AVR-NET-IO zum FHEM gesendet wird ist der Befehl: "sudo tcpdump -A -q -i eth0 host 192.168.1.91". Bei mir läuft FHEM auf einem Rasberry und diese Anweisung wird infolgedessen auf der Linux-Console eingegeben.

Als nächstes kommen noch Bodenfeuchtesensoren (Vegetronix) dazu ...

Bestimmt ist dies kein Plug and Play Projekt. Auch wird hier nicht alles optimal umgesetzt worden sein. (Verbesserungen sind willkommen).


Gruß Andreas






duke-f

Zitat von: andreas_n am 04 Juni 2015, 20:18:50
Werde alles nach Fertigstellung vorstellen - auch wenn es nicht viele Interessenten gibt.
Ich schließe mich dem Interessentenkreis an - muss es nur noch verstehen und selber umsetzen können. Aber jetzt schon mal besten Dank für die Mühe, alles soweit durchzutesten und zusammenzustellen.
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite

Tom_S

hi andreas_n

sorry, habe den Trade erst jetzt bemerkt. Um ECMD ging es sonst immer unter sonstige Systeme.
Die oben erwähnten Classdefs sind von mir und um das Rätsel zu lösen, bei dem Controller handelt es sich zwar um so ein Pollin-Teil, aber nicht um Ethersex. Angefangen hat damals (2008) alles damit
http://www.mikrocontroller.net/topic/109988
der Controller sendet bei Änderung den Zustand des veränderten Pin und einmal pro Minute alle Ein- und Ausgänge, die ADC Werte und die Temperaturen der OW. Und davon alle 10 Sekunden etwas, und weil damals der String nicht beliebig lang sein konnte auch sehr verkürzt in der Form T114.1 T223.0 oder P201 P210 P220.

Prinzipiell kann man das auch in Ethersex einbauen und das wollte ich auch mal machen, aber es läuft jetzt seit Jahren so, und ob man an die alten Dinger noch hinlangen sollte?

LG Tom_S
RaspberryPI2 + pilight, 3x AVR-NetIO, LW12, LW12HX, LW12FC; MAX-Lan, ESP8266, Arduino, H801, Neopixel, Solaredge, Modbus

ennofm

Hallo Andreas_n,

habe das mal bei mir auf einen freien AVR-Netio gebracht und versucht das ein meinen fhem (5.6) einzubinden.
Leider läuft das ganze gar nicht. Im fhem bekomme ich für den Port 2702 keine Antwort vom netio.
telnet auf den port in einem CMD- Fenster bleibt auch ohne Reaktion...
In fhem habe ich das ganze nur mit der Definition mit dem telnetport 2702 und anschließen den classdefs eingebunden.
Problem scheint aber eher zu sein, dass das Control6- Script im Netio nicht antwortet.
Hab deine 2. Version control6.src geflasht mit eingeschaltetem control6 in menueconfig...
Gibt es noch zusätzliche Tips wo ich mal schauen könnte?


andreas_n

Zitat von: ennofm am 18 September 2015, 14:07:24
Hallo Andreas_n,

habe das mal bei mir auf einen freien AVR-Netio gebracht und versucht das ein meinen fhem (5.6) einzubinden.
Leider läuft das ganze gar nicht. Im fhem bekomme ich für den Port 2702 keine Antwort vom netio.
telnet auf den port in einem CMD- Fenster bleibt auch ohne Reaktion...
In fhem habe ich das ganze nur mit der Definition mit dem telnetport 2702 und anschließen den classdefs eingebunden.
Problem scheint aber eher zu sein, dass das Control6- Script im Netio nicht antwortet.
Hab deine 2. Version control6.src geflasht mit eingeschaltetem control6 in menueconfig...
Gibt es noch zusätzliche Tips wo ich mal schauen könnte?
Hallo.  Evtl könnte es helfen, wenn ich ein lauffähiges Projekt hochlade ?  Geht das hier im Forum ? Es müßte dann nur noch angepasst werden. Es wird aber noch ne Weile dauern da ich zur Zeit nicht zu Hause bin

duke-f

#15
Das wäre schon fast grandios!  ;D
Wollte mich dem Thema in der dunklen Jahreszeit nämlich auch wieder verstärkt annehmen. Konkret möchte ich einen vorhandenen Wasserzähler mit Hallsensor über das ARV-NET-IO mit Ethersex einbinden. Da werde ich um Control6 nicht herumkommen, denke ich.
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite

andreas_n

Hier das Projekt / Upload 1

andreas_n

Und nun der zweite Teil
Beide Teile zusammen müssen entpackt werden und ergeben das Projekt.
Das Aufteilen war leider wegen der Größenbeschränkung im Forum notwendig.


duke-f

Besten Dank, ich hoffe, ich verstehe alles. Werde mich die nächsten Tage/Wochen damit auseinandersetzen.
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite

duke-f

@andreas_n
Kannst Du mir einen Tipp geben zu sinnvollen Dokumentationen? Hab' da etwas Probleme, den Inhalt der control6.src zu verstehen.
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite

Tueftler1983

Hallo auch wenn das Thema schon älter ist hört es sich sehr gut an. Ich habe jetzt das AVR NET IO ausgebaut weil mir die eingangs Erkennung zu ungenau war. Hatte die Türklingel und einen TürKontakt daran angeschlossen aber klingel und öffnen der Türe wurde öfters nicht erkannt.
Zudem war die relais steuerung zu unzuverlässig in FHEM wurde angezeigt Relais geschaltet und es war aber aus und umgekehrt.

Vielleicht werde ich jetzt im Winter mit euren Modulen das Net IO fürs Gartenhaus reaktivieren

Maxl

Hallo,

bin ebenfalls an dem Projekt interessiert, leider bekomme ich beim Aufruf des
Konfigurationsmenüs folgende Meldung,
ich hätte versucht das Projekt unter dem RASPI zu kompilieren.

root@raspberrypi:/opt/fhem/ethersex# make menuconfig
make -C scripts/lxdialog all
make[1]: Entering directory '/opt/fhem/ethersex/scripts/lxdialog'
make[1]: Leaving directory '/opt/fhem/ethersex/scripts/lxdialog'
/bin/bash scripts/Menuconfig config.in
Using defaults found in .config
Preparing scripts: functions, parsing...done.
#

Dann bleibt alles hängen, ein Menü erscheint leider nicht  :(
Kann mir jemand kurz weiterhelfen?
FHEM auf Raspberry mit HM, HMC und AVR Netios.

Florian_GT

Zitat von: Maxl am 03 Januar 2017, 21:13:33
Hallo,

bin ebenfalls an dem Projekt interessiert, leider bekomme ich beim Aufruf des
Konfigurationsmenüs folgende Meldung,
ich hätte versucht das Projekt unter dem RASPI zu kompilieren.

root@raspberrypi:/opt/fhem/ethersex# make menuconfig
make -C scripts/lxdialog all
make[1]: Entering directory '/opt/fhem/ethersex/scripts/lxdialog'
make[1]: Leaving directory '/opt/fhem/ethersex/scripts/lxdialog'
/bin/bash scripts/Menuconfig config.in
Using defaults found in .config
Preparing scripts: functions, parsing...done.
#

Dann bleibt alles hängen, ein Menü erscheint leider nicht  :(
Kann mir jemand kurz weiterhelfen?

Hast du das von einem anderen System kopiert?

Mache mal ein Backup!

Versuche dann ein "make mrproper" oder "make fullclean". Das hat bei mir in einer solchen Situation geholfen.
FHEM: Proxmox Server, FHEM in VM, pgSQL DB
Hardware: Ethersex (Pollin NETIO Boards), Diverse Tasmota MQTT Devices, Raspberry Pi Zero W Kameras, (Github RaspberryPiStreamingCamera), Zigbee2MQTT, ESPEasy

Development: UBA (Umwelt Bundesamt), BFS (Bundesamt für Strahlenschutz)

gelbwichtel

Hi,
bin eher zufällig auf diesem Thread gelandet.
Ich benutze seit ca. 1 Jahr auf dem AVR-Net-IO mit Ethersex OneWire zum Abfragen von ca. 20 1W 18DS20 Sensoren, sowie 3 Ports zum EInlesen und 1 Port zum Schalten eines Relais.
Die Zustandsänderungen der Ports hab ich bislang über "Watch io changes and react" ausgewertet. Funktionierte eigentlich zeitnah und ohne Aussetzer.   
Leider Gottes ist es so, dass Ethersex scheinbar seit einem mir nicht bekannten Quellstand nicht mehr sauber funktioniert, wenn ich das Pollen der 1W Sensoren einschalte. Ab dem Moment funktioniert das Handling über Watch-IO nicht mehr. Keine Ahnung warum.
Ich werde jetzt mal  andreas_n's Projekt auf einem freien Net-IO umsetzen und checken.

Da die letzten hier geposteten C6 Quellen schon knapp 15 Monate alt sind, wollte ich mal fragen, ob sich hier noch was geändert hat und wenn ja, ob die Änderungen hier nochmal gepostet werden können.

@afloria: Hatte zwar nicht die gleichen Fehler wie Maxl, aber deine Tips
Zitat
Versuche dann ein "make mrproper" oder "make fullclean". Das hat bei mir in einer solchen Situation geholfen.
haben mir geholfen.

Danach musste halt nur nochmal die .config zurückgespielt werden und das make 2x ausgeführt werden.

Eine Frage hätte ich da noch: Wo erfolgt die Defintion, an welchem Port die 1W Sensoren angeschlossen werden ?

Danke
cu
gelbwichtel

Tom_S

RaspberryPI2 + pilight, 3x AVR-NetIO, LW12, LW12HX, LW12FC; MAX-Lan, ESP8266, Arduino, H801, Neopixel, Solaredge, Modbus

gelbwichtel

Danke Tom_S,
aber ich hatte eigentlich die control6.src-Modifikationen von andreas_n gemeint.
Wenn ich nicht ganz falsch liege, sind die ja nicht ins E6 eingeflossen.

cu
gelbwichtel
cu
gelbwichtel

frober

Hallo gelbwichtel,

wie funktioniert das Hardwareseitig?

ZitatDie Zustandsänderungen der Ports hab ich bislang über "Watch io changes and react" ausgewertet. Funktionierte eigentlich zeitnah und ohne Aussetzer.

Wenn ich einen Taster benutze, muß ich dann nach Masse ziehen und brauche ich einen pullup?


Raspi 3b mit Raspbian Buster und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

duke-f

Zitat von: gelbwichtel am 21 Februar 2017, 21:50:36
Eine Frage hätte ich da noch: Wo erfolgt die Defintion, an welchem Port die 1W Sensoren angeschlossen werden ?
Ist etwas her, dass ich über die Frage stolpere und sicher hast Du das Problem mittlerweile gelöst. Aber falls sonst noch jemand danach sucht:
Die Definition ist im Verzeichnis
ethersex/pinning/hardware
beispielsweise im file
netio.m4
zu finden.
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite