Hallo,
ich weiss nicht, ob ich auf dem richtigen Weg bin. Ich habe ein Script, welches ich beim Start von FHEM automatisch starte.. Dieses Script funktioniert ganz gut, jedoch wenn ich ein Telnet Passwort (allow_TelnetPort) setze, dann gehts nicht mehr. Da ich vom Scripthersteller keine Antwort kriege, rufe ich hier mal in die Runde.. Ich denke es liegt an..
char perlCmd[] = "perl /opt/fhem/fhem.pl 7072";
Hier muss vermutlich noch ein Passwort hin.. Doch wo?
Das gesamte Script lautet:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define HELLO_PORT 22600
#define HELLO_GROUP "224.192.32.19"
#define MSGBUFSIZE 2000
main(int argc, char *argv[])
{
char perlCmd[] = "perl /opt/fhem/fhem.pl 7072";
struct sockaddr_in addr;
int fd, nbytes;
socklen_t addrlen;
struct ip_mreq mreq;
char msgbuf[MSGBUFSIZE];
char *ptr;
char *ptr2;
int channel = 0;
char txt[100];
char msgFHEM[100 * 20];
u_int yes=1; /*** MODIFICATION TO ORIGINAL */
/* create what looks like an ordinary UDP socket */
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(1);
}
printf("socket opened\n");
/**** MODIFICATION TO ORIGINAL */
/* allow multiple sockets to use the same PORT number */
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) {
perror("Reusing ADDR failed");
exit(1);
}
/*** END OF MODIFICATION TO ORIGINAL */
printf("same port on multiple sockets ok\n");
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY); /* N.B.: differs from sender */
addr.sin_port=htons(HELLO_PORT);
printf("destination address set\n");
/* bind to receive address */
if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
printf("bind to receive address ok\n");
/* use setsockopt() to request that the kernel join a multicast group */
mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP);
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) {
perror("setsockopt");
exit(1);
}
/*printf("join multicast group ok\n");*/
/* now just enter a read-print loop */
while (1)
{
addrlen = sizeof(addr);
if ((nbytes = recvfrom(fd,msgbuf,MSGBUFSIZE,0,(struct sockaddr *) &addr,&addrlen)) < 0)
{
perror("recvfrom");
exit(1);
}
/*printf("OWL multicast packet received\n");*/
msgbuf[nbytes] = 0x00; // null terminate before printing
//puts(msgbuf); // print raw data received
ptr = strtok(msgbuf, "<");
while(ptr != NULL)
{
//printf("Abschnitt gefunden: %s\n", ptr);
// check for channel-id tag
if (strncmp(ptr, "chan id=", strlen("chan id=")) == 0)
{
channel = (ptr[9] - '0');
//printf("found channel %i tag\n", channel);
if (channel == 0)
{
msgFHEM[0] = 0;
strcpy(msgFHEM, perlCmd);
}
} else if (strncmp(ptr, "/electricity", strlen("/electricity")) == 0)
{
/*printf("Sending data to FHEM\n");*/
//printf("%s\n", msgFHEM);
system(msgFHEM);
} else if (channel < 3)
{
if (strncmp(ptr, "curr ", strlen("curr ")) == 0)
{
//printf("found curr data\n");
ptr2 = strchr(ptr, '>');
ptr2++; // discard first char '>'
if (strlen(ptr2) > 0)
{
sprintf(txt, " \"setreading myOWL powerCurr%i %s\"", channel, ptr2);
//printf("%s\n", txt);
strcat(msgFHEM, txt);
}
} else if ((channel < 3) && (strncmp(ptr, "day ", strlen("day ")) == 0))
{
//printf("found day data\n");
ptr2 = strchr(ptr, '>');
ptr2++; // discard first char '>'
if (strlen(ptr2) > 0)
{
sprintf(txt, " \"setreading myOWL powerDay%i %s\"", channel, ptr2);
//printf("%s\n", txt);
strcat(msgFHEM, txt);
}
}
}
ptr = strtok(NULL, "<");
}
}
}
Einfach das Passwort vor den Port:
perl fhem.pl passwort [IP:]7072
Kurz da nur Handy grad...
EDIT: grad noch gefunden https://forum.fhem.de/index.php?topic=53614.0
Gruß, Joachim
char perlCmd[] = "perl /opt/fhem/fhem.pl 7072 PASSWORT";
genau, das wars. Perfekt.. Super, herzlichen Dank Joachim...
Bitte gerne.
Dann noch als gelöst kennzeichnen, umbenennen in beispielsweise "[gelöst] Script mit Telnet Passwort ausführen"
Gruß, Joachim
ist ne weile her. Das script funktioniert gut. Aber ab und dann (nach einem Restart) müllt es mir den Log mit diesen Zeilen..
socket opened
same port on multiple sockets ok
destination address set
bind to receive address ok
join multicast group ok
OWL multicast packet received
Sending data to FHEM
OWL multicast packet received
Sending data to FHEM
OWL multicast packet received
Sending data to FHEM
OWL multicast packet received
Sending data to FHEM
OWL multicast packet received
Sending data to FHEM
OWL multicast packet received
Sending data to FHEM
Das skript wird mit einem Notify ausgelöst.
global:INITIALIZED sleep 10;"/opt/fhem/owl2fhem > /dev/null 2>&1";{Log 1, "Das Notify $NAME hat owl2fhem gestartet. Durch folgenden Event getriggert: $EVENT"}
wisst ihr, wie ich diese Meldungen aus dem Log kriege... sie kommen minütlich. Nicht immer, aber ab und dann. Kein Muster erkennbar.. . Chatgpt hat mir nicht helfen können ;) danke.
lg c
Zitat von: choetzu am 02 Februar 2024, 10:12:17Kein Muster erkennbar
Naja schau dir dein "Script" an:
Zitat von: script...
printf("socket opened\n");
...
/*** END OF MODIFICATION TO ORIGINAL */
printf("same port on multiple sockets ok\n");
...
usw.
D.h. die Ausgaben deines "Scripts" landen in stdout, da das "Script" von fhem aufgerufen wird landen die Ausgaben eben (auch) im fhem Log...
Die Ausgaben bekommst du weg, indem du sie aus dem "Script" rausnimmst ;)
Weil ich denke dadurch dass du dein Script "non-blocking" mittels Doppelter Anführungszeichen aufrufst:
Zitat"/opt/fhem/owl2fhem > /dev/null 2>&1"
funktioniert die Umleitung wohl nicht?
Aufruf über qx() ist allerdings blocking...
...evtl. dann mit einem '&' am Ende in den Hintergrund schicken, evtl. klappt das dann...
Gruß, Joachim
Herzlichen Dank Joachim...
ZitatDie Ausgaben bekommst du weg, indem du sie aus dem "Script" rausnimmst ;)
kann ich auch einfach so machen?
/*** printf("socket opened\n"); */
ZitatAufruf über qx() ist allerdings blocking...
...evtl. dann mit einem '&' am Ende in den Hintergrund schicken, evtl. klappt das dann...
So?
"/opt/fhem/owl2fhem > /dev/null 2>&1&"
Die zweite Variante wäre mir lieber, weil ich bei Fehler sonst im Terminal testen kann.
Eher so?:
qx(/opt/fhem/owl2fhem > /dev/null 2>&1 &)
EDIT: wobei ich eben noch mal bei mir geschaut habe und eine Umleitung mache ich so:
Aufruf 2>&1 > /dev/null
Evtl. würde dann auch das gehen?
"/opt/fhem/owl2fhem 2>&1 > /dev/null"
Vielleicht hilft das weiter: https://heinz-otto.blogspot.com/2018/02/in-fhem-externe-programme-aufrufen.html
Gruß, Joachim[/code]