HILFE: Fhem befehle von Bash(shell) auf einem Raspberry Pi ausführen

Begonnen von nocks, 07 Februar 2017, 07:09:14

Vorheriges Thema - Nächstes Thema

pula

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
fhem (debian auf proxmox), HM-LAN und wired, MySensors, FritzBoxes, Kodi, vdr, Onkyo, squeezeplayers, nanoCUL, wifilight (Ethernet-Bridge), Heizungssteuerung (python/vncdotool), doorpi, ESP/Arduinos/MQTT, Alexa, HomeConnect, Sonoff/Tasmota, espRGBWW, esphome, Telegram

CoolTux


curl --data 'fwcsrf=fhem_53905226430937.4' http://raspib:8083/fhem?cmd=set%20Aktor1%20off
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

pula

Danke!
Und das csrfToken vorher aus den Header holen? Ich vermute, das ist der fwcsrf=fhem_53905226430937.4?

Cheers,
Pula
fhem (debian auf proxmox), HM-LAN und wired, MySensors, FritzBoxes, Kodi, vdr, Onkyo, squeezeplayers, nanoCUL, wifilight (Ethernet-Bridge), Heizungssteuerung (python/vncdotool), doorpi, ESP/Arduinos/MQTT, Alexa, HomeConnect, Sonoff/Tasmota, espRGBWW, esphome, Telegram

Wernieman

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 ....
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

CoolTux

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.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

pula

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
fhem (debian auf proxmox), HM-LAN und wired, MySensors, FritzBoxes, Kodi, vdr, Onkyo, squeezeplayers, nanoCUL, wifilight (Ethernet-Bridge), Heizungssteuerung (python/vncdotool), doorpi, ESP/Arduinos/MQTT, Alexa, HomeConnect, Sonoff/Tasmota, espRGBWW, esphome, Telegram

CoolTux


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.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

pula

Super, danke!
werde das mal demnächst in python giessen und die ergebnisse im forum posten - vielleicht hilft es ja jemandem mal...

Cheers,

Pula
fhem (debian auf proxmox), HM-LAN und wired, MySensors, FritzBoxes, Kodi, vdr, Onkyo, squeezeplayers, nanoCUL, wifilight (Ethernet-Bridge), Heizungssteuerung (python/vncdotool), doorpi, ESP/Arduinos/MQTT, Alexa, HomeConnect, Sonoff/Tasmota, espRGBWW, esphome, Telegram

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
fhem (debian auf proxmox), HM-LAN und wired, MySensors, FritzBoxes, Kodi, vdr, Onkyo, squeezeplayers, nanoCUL, wifilight (Ethernet-Bridge), Heizungssteuerung (python/vncdotool), doorpi, ESP/Arduinos/MQTT, Alexa, HomeConnect, Sonoff/Tasmota, espRGBWW, esphome, Telegram

Christoph Morrison

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.

MEitelwein

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')