Hallo,
ich versuche verzweifelt folgenden Befehl zum Laufen zu bekommen:
pi@raspberrypi ~ $ sudo /opt/fhem/fhem.pl 10.0.0.41:7072 "set Lampe1 on"
Bekomme aber folgende Fehlermeldung:
Use of uninitialized value in numeric gt (>) at /opt/fhem/fhem.pl line 446.
Hab schon mit verschiedenen Rechtevergaben herumprobiert, Perl installiert und upgedated, Raspian upgegraded, ohne hostadresse, ohne sudo.
Fhem hab ich auch upgedated.
Hat alles nicht funktioniert.
Berechtigungen von fhem.pl:
-rwxrwxrwx 1 fhem dialout 129579 Feb 6 21:39 fhem.pl
Der fhem.pl Code ab der Stelle 434 gibt hinweise auf die übergebenen Argumente:
###################################################
# Client code
if(int(@ARGV) > 1 && $ARGV[$#ARGV] ne "-i") {
my $buf;
my $addr = shift @ARGV;
$addr = "localhost:$addr" if($addr !~ m/:/);
my $client = IO::Socket::INET->new(PeerAddr => $addr);
die "Can't connect to $addr\n" if(!$client);
for(my $i=0; $i < int(@ARGV); $i++) {
syswrite($client, $ARGV[$i]."\n");
}
shutdown($client, 1);
while(sysread($client, $buf, 256) > 0) {
$buf =~ s/\xff\xfb\x01Password: //;
$buf =~ s/\xff\xfc\x01\r\n//;
$buf =~ s/\xff\xfd\x00//;
print($buf);
}
exit(0);
}
# End of client code
###################################################
Vielleicht kann mir ja jemand einen Tipp geben.
Vielen lieben Dank. :)
Mal ne ganz blöde Frage: Läuft FHEM überhaupt, während Du das eingibst?
Gruß,
Thorsten
Hallo,
ja FHEM läuft.
Bin gerade am Perl Debuggen. Irgendwie kommt beim der Zeile
while(sysread($client, $buf, 256) > 0) {
nichts in die Variable $buf.
Beim einem Durchgang hab ich es aber über die Zeile geschafft.
Noch ne blöde Frage.....
bei mir sieht das wie folgt aus
perl /opt/fhem/fhem.pl 7072 "set ErrorlevelBackup $?"
Nutze ich lokal, auf dem selben Linux.......dir fehlt das "perl" davor?!
Grüße,
Kharim
geht leider weder mit, noch ohne Perl davor. Immer die selbe Fehlermeldung. :(
Ist SSL im telnet Device eingeschaltet? Wenn ich das mache, dann bekomme ich das Problem auch.
Wenn nicht, dann bitte mal ein list vom telnet Device.
Gruß,
Thorsten
Wenn Du kein SSL an hast, geht folgendes besser:
echo -en "set blablabla\n" | nc -w 5 localhost 7072 >/dev/null
Mit SSL, siehe Doku:
https://fhem.de/commandref.html#telnet (https://fhem.de/commandref.html#telnet)
socat openssl:fhemhost:fhemport,verify=0 readline
ncat --ssl fhemhost fhemport
openssl s_client -connect fhemhost:fhemport
Und wenn du direkt eine telnet session auf 7072 öffnest und dort den Befehl eingibst, geht es dann?
Sent from my iPad using Tapatalk
Hallo,
vielen Dank für die Antworten.
Ich verwende SSL.
Also wenn ich mich mit:
openssl s_client -connect fhemhost:fhemport
verbinde muss ich mein Passwort eingeben.
Danach kann ich mit set XXXXX on Befehle absetzen und fhem reagiert darauf.
pi@raspberrypi /opt/fhem $ openssl s_client -connect 10.0.0.41:7272
CONNECTED(00000003)
depth=0 C = AT, ST = NOE, L = HOLLABRUNN, O = NO, OU = NO
verify error:num=18:self signed certificate
verify return:1
depth=0 C = AT, ST = NOE, L = HOLLABRUNN, O = NO, OU = NO
verify return:1
---
Certificate chain
0 s:/C=AT/ST=NOE/L=HOLLABRUNN/O=NO/OU=NO
i:/C=AT/ST=NOE/L=HOLLABRUNN/O=NO/OU=NO
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDZzCCAk+gAwIBAgIJAMk/RSz9E07yMA0GCSqGSIb3DQEBBQUAMEoxCzAJBgNV
BAYTAkFUMQwwCgYDVQQIDANOT0UxEzARBgNVBAcMCkhPTExBQlJVTk4xCzAJBgNV
BAoMAk5PMQswCQYDVQQLDAJOTzAeFw0xNTExMDIxMDU2NTFaFw0yNTEwMzAxMDU2
NTFaMEoxCzAJBgNVBAYTAkFUMQwwCgYDVQQIDANOT0UxEzARBgNVBAcMCkhPTExB
QlJVTk4xCzAJBgNVBAoMAk5PMQswCQYDVQQLDAJOTzCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAJu1I4Ocrr0OUcQJPulI8qbuGXpHxQtXGanueMTHRdrq
FXbwb2faMP4gedX8OpEjmlx0epinboMCN8YlnMN/KexZB1nH+2kavqSvxw6uTz71
t9JCQXliJ3zbPO8m10PQpwMi8BIEWjdrOW3KxBc8VcoZxP2cIocCnNszuhcmJBmv
ZjRTCR3KoV8SQSl+yU0X0MRrypqGTtcWz8/vw3GMe+lfou7wv2zMWwfbhLDKjldH
VOM+nzpTp6KTnMXYkhdDcfvqyp95e3QBvACW/H9KajqYnWGDgSR4gyRRbj77KAMy
Fna8l2qXu1DXMlYfYGkdrgd4O3y13zbPRKWBHuO7fcECAwEAAaNQME4wHQYDVR0O
BBYEFD7HwDmXSZ1TOmMn0MOLjVtkeWYsMB8GA1UdIwQYMBaAFD7HwDmXSZ1TOmMn
0MOLjVtkeWYsMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAEszTxa7
hOy3MKxXgdzM6wiaDRanekvQ+WOGDDvgAscD+IWZdf2kFfjNVKRsS8teitxKkOkq
bYsGIQECZ6bNhqVIxwrUkWQLHNgkRNJ9vGwj/zcod4Th6QrdW+eeyKPo9kU3DWad
wVCxSBqf52SJJ/U7AVTdsbDj2XzEbZFGyMTlnHkskxXlp+pzc++KllZ/ZP/qiRnH
LHHU7PqQxmgD59Oq6IvQkk1a0f7ZVaUF8SCLUtLB+gtq1BfOtsHPTWlfNx7vdb4V
/6d/h7F9sJAKuWv/evGcOXckxMlNA8bh+YtQFXAi2oLXcO1TGmE979YXF+HoP4fv
nwqZ73Lk1MjLtpk=
-----END CERTIFICATE-----
subject=/C=AT/ST=NOE/L=HOLLABRUNN/O=NO/OU=NO
issuer=/C=AT/ST=NOE/L=HOLLABRUNN/O=NO/OU=NO
---
No client certificate CA names sent
---
SSL handshake has read 1197 bytes and written 616 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
Protocol : TLSv1.2
Cipher : AES256-GCM-SHA384
Session-ID: 5940CB0E953C8ECFC1F3BCFDD30B363985ACF8F090E6300411ACE6BA186AF729
Session-ID-ctx:
Master-Key: D287AADE73DE395186F34AF39A8DA2DB7FDC4F5A334FAFD29ECDED4B8E17116DC92518543ADC90B70081698E5BA62E21
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 74 98 3e ef 80 af b1 f8-13 39 c2 08 8a 43 89 2e t.>......9...C..
0010 - 54 51 9d d0 2b ed 27 06-9f 8e e0 d5 39 7a f0 ae TQ..+.'.....9z..
0020 - 2d 42 2a 6c f8 97 56 ce-c5 aa 4c 30 69 3b fc cf -B*l..V...L0i;..
0030 - e6 b3 29 25 d7 67 45 de-36 6c 2a fe 94 1a 60 07 ..)%.gE.6l*...`.
0040 - 55 4f 43 7e 27 3c dc 45-97 b5 36 a2 aa b3 20 04 UOC~'<.E..6... .
0050 - 28 ca d8 d4 77 73 9a fc-7a 26 8e 9b 0b d4 3b 10 (...ws..z&....;.
0060 - d3 80 f7 7b f0 bf e3 5b-f2 9e 6a a4 7c 5d c7 93 ...{...[..j.|]..
0070 - 1f 87 74 78 5e 0b b0 d6-95 a6 cc b2 c8 89 46 e8 ..tx^.........F.
0080 - 46 6a f9 97 51 42 6e ba-b6 3d 90 d9 95 1e 01 cf Fj..QBn..=......
0090 - ba 3e 9e db 56 9c a3 2d-d0 a6 70 de 29 39 1e 86 .>..V..-..p.)9..
Compression: 1 (zlib compression)
Start Time: 1486454561
Timeout : 300 (sec)
Verify return code: 18 (self signed certificate)
---
Password: XXXXXXXXXXXXXX
set FBH_WZ_SZ_Sw_01_KU on
set FBH_WZ_SZ_Sw_01_KU off
q
Bye...
closed
pi@raspberrypi /opt/fhem $ perl /opt/fhem/fhem.pl 10.0.0.41:7272 "set FBH_WZ_SZ_Sw_01_KU on"
Use of uninitialized value in numeric gt (>) at /opt/fhem/fhem.pl line 446.
Falls sich wer wundert. Ich habe in der zwischenzeit den Port von 7072 auf 7272 umgestellt, nur um zu Testen ob FHEM das mitbekommt.
Heißt das jetzt, dass das Problem gelöst ist?
Gruß,
Thorsten
Leider nein.
pi@raspberrypi /opt/fhem $ perl /opt/fhem/fhem.pl 10.0.0.41:7272 "set FBH_WZ_SZ_Sw_01_KU on"
Use of uninitialized value in numeric gt (>) at /opt/fhem/fhem.pl line 446.
Immer noch derselbe Fehler.
Hier mal das List des telnet devices aus fhem:
Internals:
CONNECTS 2
DEF 7272 global
FD 5
NAME telnetPort
NR 3
PORT 7272
SSL 1
STATE Initialized
TYPE telnet
Attributes:
SSL 1
Muss da irgendwie noch das Passwort mitübergeben werden bei dem Aufruf wenn SSL aktiv ist?
Hier noch das List vom Device: allowed_telnetPort
Internals:
NAME allowed_telnetPort
NR 4
STATE active
TYPE allowed
validFor telnetPort
Readings:
2017-02-07 08:27:42 state active
Attributes:
globalpassword NoPWD
validFor telnetPort
Nochmals:
Warum verwendest Du fhem als Client, wenn es per z.B. openssl kleiner und einfacher geht?
Hmm... habe das Problem leider auch :-(
Hab bisher meine Heizung per python-Skripten abgefragt/gesteuert und die Readings dann per urllib (web) an fhem zurückgegeben.
Funktioniert jetzt auch noch, aber nur wenn ich csrfToken auf none setze - was mir eigentlich nicht gefällt.
Daher wollte ich das per telnet versuchen, was aber in genau dem Fehler mündet, den auch nocks hat.
@Wernieman: was genau meinst Du mit:
ZitatWarum verwendest Du fhem als Client, wenn es per z.B. openssl kleiner und einfacher geht?
Kannst Du das bitte erklären? Vielleicht mit Beispielen? Ist zwar nicht lebensnotwendig, aber wäre schön...
Cheers,
Pula
Siehe:
https://fhem.de/commandref.html#telnet (https://fhem.de/commandref.html#telnet)
Danke, das habe ich bereits gelesen.
Beantwortet aber leider nicht die Frage, wie man per Skript (und nicht interaktiv) per Telnet/ssl ein fhem steuert.
Hast du dazu Beispiele bitte?
Cheers,
Pula
curl --data 'fwcsrf=fhem_53905226430937.4' http://raspib:8083/fhem?cmd=set%20Aktor1%20off
Danke!
Und das csrfToken vorher aus den Header holen? Ich vermute, das ist der fwcsrf=fhem_53905226430937.4?
Cheers,
Pula
Stimmt .. folgendes steht wirklich nicht in der Doku:
SSL
Enable SSL encryption of the connection, see the description here on generating the needed SSL certificates. To connect to such a port use one of the following commands:
socat openssl:fhemhost:fhemport,verify=0 readline
ncat --ssl fhemhost fhemport
openssl s_client -connect fhemhost:fhemport
Und ohne ssl und passwort:
echo -en "set blabla bla\nquit\n" | nc <fhemserver> 7072
und ohne ssl, aber mit Passwort:
echo -en "passwort\nset blabla bla\nquit\n" | nc <fhemserver> 7072
P.S. das "quit\n" ist eine reine Nettigkeit ....
P.P.S. Telnet braucht keinen Token und ist meiner Meinung nach auch optimaler, als fürs schalten über die Weboberfläche zu gehen. Du kannst übrigens auch einstellen, wen FHEM bei telnet reinlässt ....
Zitat von: pula am 28 Februar 2017, 15:33:42
Danke!
Und das csrfToken vorher aus den Header holen? Ich vermute, das ist der fwcsrf=fhem_53905226430937.4?
Cheers,
Pula
Entweder das oder festen Token vergeben.
Super, danke!
Das hilft mir weiter!
@Wernie: ich habe NICHT gesagt, daß etwas nicht in der Doku steht. Sondern, daß es mir nicht weitergeholfen hat.
Grund:
1) socat unterstützt den parameter readline nicht mehr
2 und 3) openssl und ncat sind in der Form zwar interaktiv toll, aber nicht zu scripten
Wie ich weiter oben geschrieben habe, wären BEISPIELE (wie sie CoolTux netterweise geliefert hat) hilfreich gewesen - ein wiederholtes Hinweisen auf die Doku hingegen empfinde ich als nicht hilfreich, besonders, da ich sie auch gelesen habe und nichts damit anfangen konnte (wie ich auch geschrieben habe). Bei allem Hilfswillen: Aber das empfinde ich ein wenig als Copy&Paste-Terrorismus.
RTFM ist mir ein Begriff, aber wenn das nicht hilft, sollte ein Forum auch dazu da sein, um Hilfe zu bitten zu können...
Cheers,
Pula
curl "http://localhost:8083/fhem?cmd=set%20Office%20on&XHR=1&fwcsrf="`curl -s -D - 'http://localhost:8083/fhem&XHR=1' | awk '/X-FHEM-csrfToken/{print $2}'`
Hier ein Beispiel zum automatischen auslesen des Tokens und danach sofortigen schalten.
Super, danke!
werde das mal demnächst in python giessen und die ergebnisse im forum posten - vielleicht hilft es ja jemandem mal...
Cheers,
Pula
Vielleicht kanns mal jemand brauchen. Hab folgende kleine python-Routinen geschrieben, um das mit dem Token hinzubiegen:
import sys
import urllib2
import urllib
import ssl
import urlparse
BASEURL = 'https://user:password@server_ip:8083/fhem?'
url = BASEURL + 'cmd=set+licht+on'
def get_token(url):
nurl = urlparse.urlsplit(url)
username = nurl.username
password = nurl.password
url = url.replace(username + ':' + password + '@', '')
url = url.replace(" ", "%20")
ssl._create_default_https_context = ssl._create_unverified_context
p = urllib2.HTTPPasswordMgrWithDefaultRealm()
p.add_password(None, url, username, password)
handler = urllib2.HTTPBasicAuthHandler(p)
opener = urllib2.build_opener(handler)
urllib2.install_opener(opener)
try:
uu = urllib2.urlopen(
url=url,
data=None,
timeout=10
)
token = uu.read()
token = token[token.find('csrf_'):]
token = token[:token.find("\'")]
return token
except urllib2.URLError, urllib2.URLError.reason:
print('URLError: %s' % urllib2.URLError.reason)
return False
def fire_command(url):
# type: (object) -> object
if "@" in url:
token = get_token(BASEURL)
data = {'fwcsrf': token}
data = urllib.urlencode(data)
nurl = urlparse.urlsplit(url)
username = nurl.username
password = nurl.password
url = url.replace(username + ':' + password + '@', '')
url = url.replace(" ", "%20")
ssl._create_default_https_context = ssl._create_unverified_context
p = urllib2.HTTPPasswordMgrWithDefaultRealm()
p.add_password(None, url, username, password)
handler = urllib2.HTTPBasicAuthHandler(p)
opener = urllib2.build_opener(handler)
urllib2.install_opener(opener)
try:
urllib2.urlopen(
url=url,
data=data,
timeout=10
)
except urllib2.URLError, urllib2.URLError.reason:
print('URLError: %s' % urllib2.URLError.reason)
return False
Funktioniert bei mir soweit gut... Wenn jemand Probleme mit dem Stil hat --> kann sein, als ich das geschrieben hab, hab ich mit Python grade angefangen...
Irgendwann muß ich das Zertifikat-Handling noch einbauen....
Cheers,
Pula
Zitat von: CoolTux am 28 Februar 2017, 18:08:26
curl "http://localhost:8083/fhem?cmd=set%20Office%20on&XHR=1&fwcsrf="`curl -s -D - 'http://localhost:8083/fhem&XHR=1' | awk '/X-FHEM-csrfToken/{print $2}'`
Hier ein Beispiel zum automatischen auslesen des Tokens und danach sofortigen schalten.
Das wird so nicht funktionieren, siehe meinen Beitrag dazu hier (https://forum.fhem.de/index.php/topic,68133.msg599009.html#msg599009).
Habe hier etwas schlankeren python code geschrieben, um einen http request an fhem zu senden. Läuft bei mir unter python3.
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
class FHEM:
def __init__(self, baseURL = None, user='', passw=''):
if baseURL == None:
# Place standard url of your fhem server here
self.__BASEURL = 'https://fhem.your.ip:8083/fhem?'
else:
self.__BASEURL = baseURL
self.__session = requests.session()
self.__session.auth = (user, passw)
# Place your server certificate here if you use https
self.__session.verify = 'server.pem'
# If you do not have a certificate, but want to use https, set verify to False
# self.__session.verify = False
if self.__session.verify == False:
# Suppress error warnings of unverified https requests
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
def get_token(self, url):
try:
r = self.__session.get(url)
token = r.text
token = token[token.find('csrf_'):]
token = token[:token.find("\'")]
except ConnectionError as e:
print('Requests error when getting token: ' + str(e))
return token
def send_command(self, cmd):
# cmd is the FHEM command, eg. cmd='set light on'
url = self.__BASEURL
token = self.get_token(url)
data = {'fwcsrf': token}
url = url + 'cmd=' + cmd
try:
r = self.__session.get(url, data=data)
except ConnectionError as e:
print('Requests error when posting command: ' + str(e))
Nutzung ist recht einfach, z.B.
# use the right credentials here
user=myuser
passw=mysecret
# initialize the object
fhem_server=FHEM('https://my.fhem.com:8083/fhem?', user, passw)
# send your desired command
fhem_server.send_command('set light on')