FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: Qualle am 23 April 2020, 14:29:25

Titel: [gelöst] ReadingsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 23 April 2020, 14:29:25
Hallo zusammen,
nachdem ich nun das Forum und andere Internetquellen auf den Kopf gestellt habe, ich finde keine Lösung:

FHEM empfängt Informationen eines ESP (NodeMCU). Der ESP liefert mir per Analog-Eingang die Bodenfeuchte. Die kommt als Reading auch super an

define ESPEasy_NodeMCU_3_BodenfeuchteSensor ESPEasy 192.168.100.233 80 ESPBridge NodeMCU_3_BodenfeuchteSensor
attr ESPEasy_NodeMCU_3_BodenfeuchteSensor IODev ESPBridge
attr ESPEasy_NodeMCU_3_BodenfeuchteSensor Interval 300
attr ESPEasy_NodeMCU_3_BodenfeuchteSensor group ESPEasy Device
attr ESPEasy_NodeMCU_3_BodenfeuchteSensor presenceCheck 1
attr ESPEasy_NodeMCU_3_BodenfeuchteSensor readingSwitchText 1
attr ESPEasy_NodeMCU_3_BodenfeuchteSensor room ESPEasy
attr ESPEasy_NodeMCU_3_BodenfeuchteSensor setState 3


hier das EventLog:
2020-04-22 11:57:19 ESPEasy ESPEasy_NodeMCU_3_BodenfeuchteSensor Analog: 260
2020-04-22 11:57:19 ESPEasy ESPEasy_NodeMCU_3_BodenfeuchteSensor presence: present
2020-04-22 11:57:19 ESPEasy ESPEasy_NodeMCU_3_BodenfeuchteSensor Ana: 260

Nun benötige ich den Bodenfeuchtewert für ein Powershell-Script, welches mein Sprinkleranlage steuert. Ich muss hier also den Wert 260 an das Script übergeben. Sollte eigentlich einfach sein. Habe dieses Device angelegt:

define Feuchte dummy
attr room ESPEasy
set Feuchte ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0)


ReadingsVal liefert aber nicht 260 sondern Datum / Zeit der letzten Abfrage. Also habe ich mit $EVENT / EVTPART experimentiert. Ich bekomme immer nur Datum / Zeit zurück.

Was mache ich falsch?

Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 23 April 2020, 14:31:58
Also was Du über ReadingsVal erzählst kann ich nicht nachvollziehen. Den Zusammenhang mit $EVENT und $EVTPARTx kann ich auch noch nicht sehen, aber Dein code ist falsch!

Entweder
set Feuchte [ESPEasy_NodeMCU_3_BodenfeuchteSensor:Analog]
Oder
set Feuchte {(ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0))}
Besser
set Feuchte {(ReadingsNum("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0))}
bzw
set Feuchte [ESPEasy_NodeMCU_3_BodenfeuchteSensor:Analog:d]
Siehe set magic in der Doku https://fhem.de/commandref_DE.html#set

Und falls Du von Powershell auf FHEM zugreifen willst, da hab ich was (https://github.com/heinz-otto/fhemcl). ;)

Gruß Otto
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 23 April 2020, 15:03:59
Hallo Otto,

DANKE für die rasend schnelle Antwort.  :) Habe [ESPEasy_NodeMCU_3_BodenfeuchteSensor:Analog] jetzt über die GUI erstellt. Damit wird mir tatsächlich der gewünschte Wert in FeuchteState geschrieben. Jetzt hakt es nur noch mit der Aktualisierung. Und es stellt sich die Frage, warum ich den SET Befehl nicht in der fhem.cfg wiederfinden kann. 
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: MadMax-FHEM am 23 April 2020, 15:30:37
Zitat von: Qualle am 23 April 2020, 15:03:59
Hallo Otto,

DANKE für die rasend schnelle Antwort.  :) Habe [ESPEasy_NodeMCU_3_BodenfeuchteSensor:Analog] jetzt über die GUI erstellt. Damit wird mir tatsächlich der gewünschte Wert in FeuchteState geschrieben. Jetzt hakt es nur noch mit der Aktualisierung. Und es stellt sich die Frage, warum ich den SET Befehl nicht in der fhem.cfg wiederfinden kann.

Weil du den einfach "nackt" in FHEMWeb eingegeben hast, er wird ausgeführt und fertig... ;)

Wozu soll da was in der fhem.cfg stehen!?

Frage: wie hast du das herausgefunden!? ;)

Gar nicht erst anfangen/angewöhnen in der cfg rumzuschreiben...
...außer über die fhem-Oberfläche klicken, max. "raw-Definition" Fenster...

EDIT: wenn du eine Aktualisierung möchtest, dann musst du dir überlegen "wann"/"wodurch" soll sie passieren!? Immer wenn sich der "Originalwert" ändert -> notify / immer alle 5min etc. -> at
https://wiki.fhem.de/wiki/Notify
https://wiki.fhem.de/wiki/Event_monitor
https://wiki.fhem.de/wiki/At
(und wie so oft in fhem: viele, viele weitere Möglichkeiten ;)  )

EDIT2: und du wirst es nicht glauben, dann steht dazu auch was in der fhem.cfg ;)

Gruß, Joachim
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 23 April 2020, 15:49:33
Zitat von: Qualle am 23 April 2020, 15:03:59
Jetzt hakt es nur noch mit der Aktualisierung.
Wie willst DU denn aktualisieren? Immer dann wenn ein solcher Wert kommt?

Dann bau Dir ein notify hier steht wie https://wiki.fhem.de/wiki/Notify#Event_Monitor
Also einfach den Event  mit Analog markieren, notify erzeugen, den Befehl reinschreiben fertig. Du kannst auch von dem notify dein Powershell Script aufrufen! ich zeig Dir gern wie :)

Und lass die Finger von der cfg.

Gruß Otto
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 26 April 2020, 21:56:04
Hallo Otto,

ich würde gern Dein Angebot annehmen. Ich kriege die richtige Syntax nicht hin. Ziel ist, das Powershellscript morgens per AT zu starten und ihm den Feuchtewert zu übergeben. Auf der Shell funktioniert dieser Befehl unter User fhem:

sudo pwsh /opt/_me/PwSh/SprinklerController-V2.ps1 -SensorValue 305

Nachdem ich auch Deinen Beitrag zum Thema Start externer Programme aus FHEM gelesen habe und dem neuen Wissen über die Syntax von ReadingsVal, habe ich diese Zeile erstellt:

{ qx "sudo pwsh -File /opt/_me/PwSh/SprinklerController_V2.ps1 -SensorValue (ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0))" }

In der FHEM Kommandozeile liefert das keinen Fehler, aber das Script wird nicht ausgeführt.

Vielen Dank
Frank
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 26 April 2020, 22:19:18
Hallo Frank,

Du nutzt powershell für Linux? Cool ;) Hab ich noch nicht probiert. Ist mir ein scheinbar komplexes Setup, ich arbeite gern mit ssh für Windows ;)
Nachfrage:
Funktioniert denn das in der FHEM Kommandozeile?
{qx(sudo pwsh /opt/_me/PwSh/SprinklerController-V2.ps1 -SensorValue 305)}
Den ReadingsVal kannst Du so nicht in die Zeile packen. Da wird einfach der Ausdruck an das Powershellscript als Parameter übergeben, nicht das Ergebnis. Außerdem beissen sich die " innerhalb von " ".
Eine Variante, extra Variable:
{ my $val=ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0);;qx "sudo pwsh -File /opt/_me/PwSh/SprinklerController_V2.ps1 -SensorValue $val" }
Andere Variante (String concatenation)
{ qx "sudo pwsh -File /opt/_me/PwSh/SprinklerController_V2.ps1 -SensorValue " . ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0)}
Ich bin nicht sicher ob er überhaupt pwsh findet: Was gibt Dir das zurück?
{qx(which pwsh)}

Gruß Otto
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 27 April 2020, 09:13:53
Hallo Otto,

Zeile 1 scheint nicht zu funktionieren. Kein Fehler. Ich habe das Pwsh Script darauf reduziert, dass es mir den SensorValue in eine Log Datei schreibt. Da kommt aber kein neuer Wert rein, wenn ich es aus FHEM versuche. Letzte Zeile gibt mir den Pfad zurück: /usr/bin/pwsh
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 27 April 2020, 09:22:20
Dann probier mal so
{qx(sudo /usr/bin/pwsh /opt/_me/PwSh/SprinklerController-V2.ps1 -SensorValue 305)}
Was hast Du getan damit fhem sudo darf?
Warum muss das ps1 Script überhaupt mit sudo laufen?
Wo braucht das erhöhte Rechte?
Wie hast Du fhem sudo gegeben?
Braucht pwsh höhere Rechte?
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 27 April 2020, 11:56:02
Also, ich habe gestern Abend lange an dem Thema gesessen. (Ja, ich bin kein Linux Experte, habe lediglich Grundkenntnisse) Um alle anderen Fehler auszuschließen, habe ich den Scriptaufruf auf der Shell getestet. Funktioniert mit root, mit sudo PI aber nicht mit FHEM. Mein Script meldete ständig Access denied auf das LogFile. Ich kann mit fhem direkt in das Log schreiben. Mindestberechtigung 666. Keine Ahnung, wo das Problem ist. Daher habe ich mit visudo in letzter Instanz FHEM zum Sudoer gemacht. Dann ging es. Verstehen kann ich das nicht.

Aber nein, es werden keine besonderen Rechte für pwsh benötigt. Standardmäßig geht die Installation ins Home. Ich habe den Ordner nach opt verschoben und einen symbolic link erstellt.
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 27 April 2020, 18:34:05
Kannst Du mal  das Script posten?
Warum machst Du es eigentlich mit Powershell? Weil Du das von Windows her kannst? Ich sehe ja bisher gar keine Verbindung zu Windows? Ich frage rein aus Interesse :)
Ich würde gern verstehen was passiert ;)
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 28 April 2020, 10:07:06
Hallo Otto,

klar kann ich das Script posten. Warum ich das Mit PoSh mache? Weil ich seit 25 Jahren Windows administriere und PoSH einfach genial ist. Und seit ich eben die Möglichkeit habe PoSh auch auf dem Raspi zu programmieren, freue ich mich, nicht mehr mit Perl oder noch schlimmer (für mich) mit Python arbeiten zu müssen. Und ich habe natürlich auf meinem Noti eine perfekte Entwicklungsumgebung für PoSh und kann meine Bewässerungssteuerung einfach auch von dort starten bis Du  ;) die Lösung für den Raspi gefunden hast.

Zum Script: Auf dem Raspi ist der Linux LogFilePath aktiv

$LogFilePath = "/opt/fhem/log/SprinklerLog-$myToday.log"
# $LogFilePath = "C:\Test\SprinklerLog-$myToday.log"

Und ich sende lediglich den $SensorValue einmal an WriteLog um zu prüfen, ob dieser übergeben wird und das Script auch tatsächlich läuft.



#Input: Bodenfeuchte
#
param(
    [int][parameter(Mandatory=$true)]$SensorValue
)

$DebugPreference = "Continue"
$SprinklerSet = @{VornNord=0; VornSued=2; HintenSued=14; HintenNord=12; Hochbeet=13} # GPIO-Nummernzuordnung Verteiler
$SprinklerProzent = @{VornNord=100; VornSued=100; HintenSued=100; HintenNord=100; Hochbeet=20} # prozentualer Anteil der berechneten Laufzeit
$SprinklerGet = @{GetAllOff=16} # GPIO, die 1 ist, wenn alle Relais AUS sind
$MainWaterSet = @{SetMain1=12; SetMain2=14} # GPIO-Nummernzuordnung; beide GPIOs müssen AN sein, damit das Hauptwasser-Relais zieht
$MainWaterGet = @{GetMain1=13; GetMain2=15} # GPIO-Nummernzuordnung; über diese beiden GPIOs wird der Zustand der MainWaterSet GPIOs überwacht; 12=1 --> 13=0; 14=1 --> 15=1
$EspMainAddress = '192.168.100.232' # IP des NodeMCU2 (Hauptanschluss)
$EspSprinklerAddress = '192.168.100.231' # IP des NodeMCU1 (Verteiler)

$myToday = $(Get-Date -Format('yyyyMMdd'))
#$LogFilePath = "/opt/fhem/log/SprinklerLog-$myToday.log"
$LogFilePath = "C:\Test\SprinklerLog-$myToday.log"

# Unbedingt die Settings in Calculate-Timer beachten!!!

function Set-Gpio{
param(
    [string][parameter(Mandatory=$true,Position=0)]$IpAddress,
    [string][parameter(Mandatory=$true,Position=1)] [ValidateSet('set','longpulse')]$ToDo,
    [int][parameter(Mandatory=$true,Position=2)] [ValidateRange(0,16)]$GpioNo,
    [int][parameter(Mandatory=$true,Position=3)] [ValidateSet(0,1)]$Value,
    [int][parameter(Position=4)] [ValidateRange(0,18000)]$TimerSec
)

if($ToDo -eq 'set'){$Htmlcode = "http://$IpAddress/control?cmd=gpio,$GpioNo,$Value"}
else{$Htmlcode = "http://$IpAddress/control?cmd=longpulse,$GpioNo,$Value,$TimerSec"}
Write-Debug "Set-GPIO: Sende: $htmlcode"
$Message = Invoke-WebRequest -Uri $Htmlcode
Write-Debug "Set-GPIO: Empfange: $Message"
Return $Message
}

function Get-Gpio{
    param(
        [string][parameter(Mandatory=$true,Position=0)]$IpAddress,
        [int][parameter(Mandatory=$true,Position=1)] [ValidateRange(0,16)]$GpioNo
    )

    $Htmlcode = "http://$IpAddress/control?cmd=Status,GPIO,$GpioNo"
    $Message = Invoke-WebRequest -Uri $Htmlcode
    Write-Debug "Get-GPIO: Sende: $htmlcode"
    Write-Debug "Get-GPIO: Empfange: $Message"
    Return $Message
}

function Parse-EspMessage{
# parsed die Nachricht, die der ESP liefert (Kontrolle der GPIO Zustände)
param(
    [string][parameter(Mandatory=$true)][parameter(Position=0)]$IpAddress
)
}

function Calculate-Timer{
    # Berechnet aus dem Wert der Bodenfeuchte die Sekunden für longpulse
    param(
        [int][parameter(Mandatory=$true)]$mySensorValue 
    )
    $Trocken = 450
    $Nass = 300
    $MaxTime = 30 #Minuten
    $MinTime = 10 #Minuten
   
    Write-Debug "Calculate-Timer: SensorValue: $mySensorValue"
    # gt Trocken = Fehler; lt Nass = keine Bewässerung nötig
    if(($mySensorValue -gt $Trocken) -or ($mySensorValue -lt $Nass)){$SprinklerTime = 0}
    else{
        $myFeuchteProzent = ($mySensorValue - $Nass)*100 / ($Trocken - $Nass)
        $mySprinklerTime = (($MaxTime - $MinTime)*$myFeuchteProzent / 100) + $MinTime
    }
    Write-Debug "Calculate-Timer: FeuchteProzent: $myFeuchteProzent"
    Write-Debug "Calculate-Timer: SprinklerZeit: $mySprinklerTime"
    return $mySprinklerTime
}
function Get-AllGpioOff {
    # Sicherstellen, dass alles AUS ist
    $myReturnVal = 0
    $StateString = "*`"state`": 1*"
    $StateString15 = "*`"state`": 0*"

    # für das Hauptventil gilt: GPIO 13 = 1, GPIO 15 = 0 in $MainWaterGet, dann sind die Relais sicher geschlossen, daher werden diese GPIOs explizit abgefragt
    foreach ($GPIO in $MainWaterGet.GetEnumerator()){

        $ReturnMsg = Get-Gpio -IpAddress $EspMainAddress -GpioNo $GPIO.Value
        $PinString = "*`"pin`": $($GPIO.Value)*"

        If($GPIO.Value -eq 13){
        Write-Debug "Reset-GPIO Main: Empfange: $ReturnMsg"
            If($ReturnMsg.Content -like $PinString -and $ReturnMsg.Content -like $StateString ){
                Write-Debug "Reset-GPIO Main: Auswertung: OK"
            } else {
                $myReturnVal =+1
                Write-Debug "Reset-GPIO Main: Auswertung: Fehler"
            }
       
        } else {
            If($ReturnMsg.Content -like $PinString -and $ReturnMsg.Content -like $StateString15 ){
                Write-Debug "Reset-GPIO Main: Auswertung: OK"
            } else {
                $myReturnVal =+2
                Write-Debug "Reset-GPIO Main: Auswertung: Fehler"           
            }
        }
    }
    # jetzt den Wasserverteiler abfragen
    # hier gilt: Wenn alle Relais geschlossen sind ist GPIO "GetAllOff" = 1
    foreach ($GPIO in $SprinklerGet.GetEnumerator()){
       
        $PinString = "*`"pin`": $($GPIO.Value)*"
        $ReturnMsg = Get-Gpio -IpAddress $EspSprinklerAddress -GpioNo $GPIO.Value
        Write-Debug "Reset-GPIO Verteiler: Empfange: $ReturnMsg"
       
        If($ReturnMsg.Content -like $PinString -and $ReturnMsg.Content -like $StateString ){
            Write-Debug "Reset-GPIO Verteiler: Auswertung: OK"
        } else {
            $myReturnVal =+4
            Write-Debug "Reset-GPIO Verteiler: Auswertung: Fehler"   
        }
       
        Return $myReturnVal
    }
}
Function Write-Log{
  param
  (
    [String]
    [Parameter(Mandatory=$true)]
    $File,
    [Parameter(Mandatory=$True)]
    $Line
  ) 
  If(!(Test-Path -Path $File)){
    New-Item -ItemType File -Force -Path $File
  }
  $LogLine = [string]::concat($(Get-Date -Format('yyyy-MM-dd_HH:mm:ss')),' - ',$Line)
  Add-Content $File $LogLine
  Write-Host $LogLine
}

# Hauptschleife
# Setze alle Relais auf 0
# Hauptventil
foreach ($GPIO in $MainWaterSet.GetEnumerator()){
    Set-Gpio -IpAddress $EspMainAddress -ToDo set -GpioNo $GPIO.Value -Value 0
    Write-Debug "Reset-GPIO Main: Rufe Set-GPIO"
}
# Verteilerventile
foreach ($GPIO in $SprinklerSet.GetEnumerator()){
    Set-Gpio -IpAddress $EspSprinklerAddress -ToDo set -GpioNo $GPIO.Value -Value 0
    Write-Debug "Reset-GPIO Main: Rufe Set-GPIO"
}

# Prüfe Startzustand (alles AUS)
$GPIOerror = Get-AllGpioOff
# $GPIOError muss 0 sein, dann sind alle Relais AUS
If($GPIOerror -eq 0){
    Write-Log -File $LogFilePath -Line 'Alle Ventile geschlossen, starte Sprinklerlauf'
    # Berechne die Laufzeit
    $SprinklerTime = Calculate-Timer -mySensorValue $SensorValue
    Write-Log -File $LogFilePath -Line "Bodenfeuchtewert: $SensorValue --> sprenge $SprinklerTime min pro Strang"
    if ($SprinklerTime -gt 0){       
        # Starte Sprinklerlauf
        foreach ($SprinklerGPIO in $SprinklerSet.GetEnumerator()){
            # Ordne die passenden Prozente zu
            $TimePercent = $SprinklerProzent.GetEnumerator() | Where-Object {$_.Key -eq $SprinklerGPIO.Key}
            # Öffne Hauptventil für die ermittelte Zeit
            foreach ($MainGPIO in $MainWaterSet.GetEnumerator()){
                Set-Gpio -IpAddress $EspMainAddress -ToDo longpulse -GpioNo $MainGPIO.Value -Value 1 -TimerSec $($SprinklerTime * 60 * $TimePercent.Value / 100) 
            }
            # Öffne Verteilerventil für die ermittelte Zeit
            $ReturnMsg = Set-Gpio -IpAddress $EspSprinklerAddress -ToDo longpulse -GpioNo $SprinklerGPIO.Value -Value 1 -TimerSec $($SprinklerTime * 60 * $TimePercent.Value / 100)
            # Warte Timer ab (plus 10 Sekunden)
            Write-Debug "Main: Warte $($SprinklerTime * 60 + 10) Sekunden"
            Start-Sleep -Seconds $($SprinklerTime * 60 + 10)
            # Prüfe, ob alle Ventile geschlossen sind; warte 5 Minuten, damit Das Hauptventil abkühlen kann oder Abbruch
            $GPIOerror = Get-AllGpioOff
            If($GPIOerror -eq 0){
                Write-Debug "Main: Warte 5 Minuten (Abkühlung Hauptventil)"
                Start-Sleep -Seconds 300
            } else {
                if($GPIOerror -lt 4){
                    Write-Debug "Main: Fehler: $GPIOerror"
                    Write-Log -File $LogFilePath -Line "Fehler in Hauptventilsteuerung"
                } else {
                    Write-Debug "Verteiler: Fehler: $GPIOerror"
                    Write-Log -File $LogFilePath -Line "Fehler in Verteilerventilsteuerung"                   
                }
                Write-Log -File $LogFilePath -Line "Zyklus beendet"
                break
            }
        }
        Write-Log -File $LogFilePath -Line "Zyklus beendet"   
    } else {
        if($GPIOerror -lt 4){
            Write-Debug "Main: Fehler: $GPIOerror"
            Write-Log -File $LogFilePath -Line "Fehler in Hauptventilsteuerung"
        } else {
            Write-Debug "Verteiler: Fehler: $GPIOerror"
            Write-Log -File $LogFilePath -Line "Fehler in Verteilerventilsteuerung"                   
        }
        Write-Log -File $LogFilePath -Line "Zyklus beendet"
        break
    }
}
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 28 April 2020, 15:23:01
Du willst, dass ich Powershell für Linux installiere 8)
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 28 April 2020, 15:29:33
Ich kann es zumindest empfehlen. Obwohl mein Raspi 2 schon ein paar Sekunden braucht, bis die PoSh Umgebung ansprechbar ist. Aber: Ich kann auch ein kleines Perl Script bauen, das mir den SensorValue in ein Log schreibt. Meine Heizungssteuerung habe ich mit Perl gemacht. Ich hatte nur noch nie die Anforderung, eine FHEM Variable an ein Script zu übergeben. Das ist ja das eigentliche Problem.
Theoretisch könnte ich auch den Bodenfeuchtesensor direkt abfragen, aber ich will, dass der schläft und nur einmal pro Stunde wach wird und den aktuellen Wert sendet. Ich hab da draußen keinen Strom. Und genau das kann nur FHEM übernehmen.
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 28 April 2020, 15:46:36
Naja ich versuche das mal, interessiert mich.
Dein Problem wird ein reines Berechtigungsthema sein, man müsste an mehren Stellen schauen.
Und ich bin immer misstrauisch mit den Fehlermeldungen, nur allzu oft in meinem Leben bedeutete der Fehler: "Kann im Ziel nicht schrieben" in Wahrheit: "kann die Quelle nicht lesen" :o
Die Befehle {qx(...)} sind alle für die FHEM Kommandozeile im Browser!
Das Logfile wird ja jeden Tag erzeugt. Wie sind die Rechte?
{qx(ls -lha /opt/fhem/log/SprinklerLog-20200428.log)}
Darf fhem pwsh ausführen und findet er es? Dazu fällt mir kein test ein, aber mach ein Script mit write-output "Hello World" und für es aus:
{qx(pwsh /opt/_me/PwSh/test.ps1)}
da sollte ja die Ausgabe im Browser landen?

Findet fhem das Script?
{qx(ls -lha /opt/_me/PwSh/SprinklerController-V2.ps1}
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 28 April 2020, 16:48:00
Hallo Otto,

ich fang nochmal von vorn an...
Ich habe das Script jetzt reduziert auf eine Ausgabe auf dem Schirm und eine Log-Eintrag:

#Input: Bodenfeuchte
#
param(
    [int][parameter(Mandatory=$false)]$SensorValue
)
$myToday = $(Get-Date -Format('yyyyMMdd'))
$LogFilePath = "/opt/_me/log/SprinklerLog-$myToday.log"
$DebugPreference = "Continue"

Function Write-Log{
  param
  (
    [String]
    [Parameter(Mandatory=$true)]
    $File,
    [Parameter(Mandatory=$True)]
    $Line
  ) 
  If(!(Test-Path -Path $File)){
    New-Item -ItemType File -Force -Path $File
  }
  $LogLine = [string]::concat($(Get-Date -Format('yyyy-MM-dd_HH:mm:ss')),' - ',$Line)
  Add-Content $File $LogLine
  Write-Host $LogLine
}

# Hauptschleife
write-Host 'Hallo'
Write-Log -File $LogFilePath -Line "Script gestartet"
Write-Log -File $LogFilePath -Line "Bodenfeuchtewert: $SensorValue"


Ich führe jetzt das Script auf der Shell als root aus...

root@raspberrypi:~# pwsh -File /opt/_me/PwSh/SprinklerController-Test.ps1 -SensorValue 200
Hallo


    Directory: /opt/_me/log

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
------          28.04.20    16:32              0 SprinklerLog-20200428.log
2020-04-28_16:32:55 - Script gestartet
2020-04-28_16:32:56 - Bodenfeuchtewert: 200

root@raspberrypi:~#

8)

Jetzt passen natürlich die Rechte nicht für FHEM, also setze ich RW für alle (666) auf das Logfile. Aber selbst auf de rShell kriege ich diese Fehler:

Test-Path : Access to the path '/opt/_me/log/SprinklerLog-20200428.log' is denied.
At /opt/_me/PwSh/SprinklerController-Test.ps1:19 char:8
+   If(!(Test-Path -Path $File)){
+        ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : PermissionDenied: (/opt/_me/log/SprinklerLog-20200428.log:String) [Test-Path], UnauthorizedAccessException
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.TestPathCommand
##########
New-Item : Access to the path '/opt/_me/log/SprinklerLog-20200428.log' is denied.
At /opt/_me/PwSh/SprinklerController-Test.ps1:20 char:5
###########
Add-Content : Access to the path '/opt/_me/log/SprinklerLog-20200428.log' is denied.
At /opt/_me/PwSh/SprinklerController-Test.ps1:23 char:3
###########

nix geht, "Hallo" wird gedruckt.

In der Kommandozeile:
{ qx "sudo pwsh -File /opt/_me/PwSh/SprinklerController-Test.ps1 -SensorValue 200)" }
keine Ausgabe
{qx(ls -lha /opt/_me/log/SprinklerLog-20200428.log)}
keine Ausgabe






Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 28 April 2020, 16:53:10
Bedeutet für mich: für fhem ist das Logfile gar nicht vorhanden

Und mal den Befehl  auf Systemebene:
ls -lha /opt/_me/log

Bei dem Pfad (der ist mir suspect :) ) spielt ja noch der symlink eine Rolle? Wenn von vorn dann doch lieber einfach ... ;)
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 28 April 2020, 20:40:05
Mein erster Ausflug zu pwsh :) ich weiß hat jetzt noch nichts mit deinem Problem zu tun, gibt aber erstmal gute Grundlagen in Sachen Sicherheit. Kurz mein Setup
Pi3 mit Ubuntu 18.04 LTS 64 bit - Ich dachte ja super wird direkt unterstützt (https://docs.microsoft.com/de-de/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7) - aber ich hatte die Rechnung ohne Arm gemacht ;)
Egal, Archive heruntergeladen und Setup wie hier gemacht (https://docs.microsoft.com/de-de/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7#raspbian).
Mein User ist ubuntu der ist normaler user. Das homedir ist /home/ubuntu
Deshalb ist powershell jetzt so aufrufbar /home/ubuntu/powershell/pwsh
Es gibt bei diesem setup keinen Pfad Eintrag, ich muss also immer den kompletten Pfad angeben!

Ein kurzer Test:
/home/ubuntu/test.ps1 mit Inhalt write-output "Hello world"
Funktioniert.

Der gleiche Test in FHEM
{qx(/home/ubuntu/powershell/pwsh /home/ubuntu/test.ps1)}
Funktioniert :) Ausgabe im Browser - dauert allerdings "ewig" bzw 11 sec :)

Ergo: bisher kein sudo nötig! Aufruf aus fhem ohne Probleme.

Jetzt: LogFile schreiben ;)

Gruß Otto
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: amenomade am 28 April 2020, 20:51:42
Also... ich habe nicht das ganze in Details gelesen, aber ein Paar Anmerkungen.

- 666 auf einer Datei reicht nicht immer. Ggf muss man noch x für alle auf dem Verzeichnis setzen, damit man den Folder "browsen" kann.
- sudo Befehle brauchen entspr. Einträge in sudoers. Und bitte NICHT ALL ALL ALL!
- ls ohne sudo braucht entspr. Berechtigungen auf der Datei UND auf dem Verzeichnis (siehe 1. Punkt)
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 28 April 2020, 21:01:37
Nächster Schritt: Dein Script als /home/ubuntu/test1.ps1
Einzige Änderung $LogFilePath = "/opt/fhem/log/SprinklerLog-$myToday.log"
Dazu ein Device in FHEM damit ich die Logdatei anzeigen kann:
define Testlog FileLog ./log/SprinklerLog-%Y%m%d.log fakelog
Die Ausgabe im Browser wie bei Dir. bei dem Aufruf (blockiert FHEM!)
{qx(/home/ubuntu/powershell/pwsh /home/ubuntu/test.ps1 -SensorValue 200)}
Aufruf so in der FHEM Kommandozeile (komplett mit " ") erzeugt die Ausgabe im FHEM Log blockiert aber nicht!
"/home/ubuntu/powershell/pwsh /home/ubuntu/test.ps1 -SensorValue 200"
Die Ausgabe im Testlog
2020-04-28_18:48:48 - Script gestartet
2020-04-28_18:48:48 - Bodenfeuchtewert: 200


Alles wie es soll :)
Ausgabe von
{qx(ls -lha ./log/SprinklerLog-20200428.log)}
-rw-r--r-- 1 fhem dialout 83 Apr 28 18:48 ./log/SprinklerLog-20200428.log

So habe ich es erwartet.

Also das mit deinem Test auf Systemebene erzeugt falsche Berechtigungen, der Aufruf des Powershell Scripts muss mit kompletten Pfad Angaben erfolgen, wo das Script liegt ist relativ egal, fhem muss es nur lesen können.

Ich habe das mit deinem ominösen Pfad /opt/_me noch nicht verstanden, dort liegt eventuell das Schlüsselproblem.
{qx(ls -lha /opt/_me)}

Hab ich das plausibel dargestellt? Frag einfach ;)

Gruß Otto
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 28 April 2020, 21:12:01
Jetzt habe ich das ursprüngliche Problem noch nicht ganz verstanden.
Du willst den Wert auslesen und an das Script übergeben?
Das könnte man so machen:
{my $SensorValue = ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0);;fhem("\"kompletterPfad/pwsh kompletterPfad Script -SensorValue $SensorValue \"")}

Der Teil fhem("\" Aufruf \"") erzeugt eine Blockingfreien Aufruf. Allerdings sollten dann Ausgaben auf der Konsole (write-host) unterbleiben, die landen im Log. Die \" erzeugen geschützte " für den Aufruf. ;)

Wie wolltest Du das Script aufrufen? Wenn sich der SensorValue ändert?
Dann erzeugst Du ein notify :)

Gruß Otto
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 28 April 2020, 21:51:01
:) :) :) :)
Jetzt funktioniert es bei mir auch. Raspi neu gestartet. FHEM wollte nicht mehr starten. Ich habe einfach mal alle Berechtigungen neu gesetzt. Bekomme jetzt die Scriptausgaben im Browser. Werde jetzt mal deine ganzen Ideen bzgl. der Wertübergabe testen.
:) :) :) :)
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 28 April 2020, 22:17:59
Hallo Otto,

Dein letzter Tipp für den gesamten Aufruf sieht jetzt so aus:

{my $SensorValue = ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0);;fhem("\"/opt/powershell/pwsh /opt/_me/PwSh/SprinklerController-Test.ps1 -SensorValue $SensorValue \"")}


Leider passiert dabei wieder nichts mehr im Browser. Zuletzt hatte ich ja Erfolg beim Aufruf des Scripts. Dabei erscheint ja der Donat auf der Browserlasche. da arbeitet also was. Das ist jetzt nicht mehr der Fall.
Das Escapen der Gänsefüßchen verstehe ich. Aber den Aufbau "\" nicht. Und warum geht der Aufruf jetzt nicht mehr mit qx?

Schon mal ganz vielen Dank für Deine unermüdliche Hilfe!!!!
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 28 April 2020, 22:35:37
Du kannst das auch  mit qx machen - aber das blockiert (Dabei erscheint ja der Donat auf der Browserlasche. da arbeitet also was.) den gesamten Aufruf FHEM. (Varianten zum lesen (https://heinz-otto.blogspot.com/2018/02/in-fhem-externe-programme-aufrufen.html))
{my $SensorValue = ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0);;qx(/opt/powershell/pwsh /opt/_me/PwSh/SprinklerController-Test.ps1 -SensorValue $SensorValue )}
Du kannst auch system() nehmen. Das & am Ende wird verhindern das FHEM blockiert . Aber du bekommst nichts im Browser sondern die Ausgabe geht ins Log
{my $SensorValue = ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0);;system("/opt/powershell/pwsh /opt/_me/PwSh/SprinklerController-Test.ps1 -SensorValue $SensorValue  &")}

Die Gänsefüsschen Variante ist die einfache Version von FHEM zum Aufruf https://fhem.de/commandref_DE.html#command

Eigentlich willst Du ja nichts im Browser zurück, Du willst ja was im Logfile. Aber zum Testen musst Du immer qx() nehmen, sonst "siehst" Du nichts ;)
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 28 April 2020, 22:59:10
OK, wieder einen Schritt weiter...
Dieser Test:
{my $SensorValue = ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0);;fhem("\"/opt/powershell/pwsh /opt/_me/PwSh/SprinklerController-Test.ps1 -SensorValue $SensorValue \"")}
liefert im Log einen Scriptfehler:
/opt/_me/PwSh/SprinklerController-Test.ps1 : A positional parameter cannot be found that accepts argument ''.
+ CategoryInfo          : InvalidArgument: (:) [SprinklerController-Test.ps1], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : PositionalParameterNotFound,SprinklerController-Test.ps1

Da kommt offensichtlich ein neuer Parameter um die Ecker, der vom Script nicht erwartet wird.

Dein letzter Vorschlag lässt das Script laufen:
{my $SensorValue = ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0);;system("/opt/powershell/pwsh /opt/_me/PwSh/SprinklerController-Test.ps1 -SensorValue $SensorValue  &")}

Jetzt steht im Log:
Hallo
2020-04-28_22:45:51 - Script gestartet

Da die zweite Logzeile fehlt, schließe ich daraus, dass jetzt kein SensorValue übergeben wird. Ich hoffe hier mal, dass das ReadingsVal auch dann funktioniert, wenn der Bodenfeuchtesensor ABSENT meldet. Der letzte Wert steht ja noch im Reading.

Aber Du wolltest noch wissen, wie das Script später starten soll. Das geht einfach per AT. Ich will ja nicht gerade im Garten stehen, wenn die Sprinkleranlage losgeht. deshalb soll das ganze morgens um 3:00Uhr aufgerufen werden. Die Auswertung, ob und wie lange gesprengt wird, findet im Script selbst statt. Dafür brauche ich den SensorValue.
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 28 April 2020, 23:04:33
Was liefert Dir das in der FHEM Kommandozeile?
{ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0)}
Du redest vom FHEM Logfile oder von deinem LogFile?

Wie  gesagt, die write-host Ausgaben kommen bei der "" und der system() Variante ins FHEM Log, bei der qx() Variante ins Browserfenster (wenn von dort aufgerufen).
Dein Logfile vom Script wird unabhängig gefüllt.

Auch wenn der Parameter leer ist wird doch die Zeile geschrieben?
Write-Log -File $LogFilePath -Line "Bodenfeuchtewert: $SensorValue"
Versteh ich nicht ...
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 29 April 2020, 21:10:34
 :) :) :)
Hallo Otto, es funktioniert! Dein Lösungsvorschlag
{my $SensorValue = ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0);;fhem("\"/opt/powershell/pwsh /opt/_me/PwSh/SprinklerController-Test.ps1 -SensorValue $SensorValue \"")}
ist genau richtig  (wäre ich nie draufgekommen). Das hattest Du ja schon recht früh so vorgeschlagen. Aber da waren wohl noch ein paar andere Probleme, die ich gestern beim Troubleshooting gelöst habe. Nebenbei hast Du mir auch noch gezeigt, wie ich mein Logfile in FHEM anzeigen kann. Ich werde es aber auch aus dem Posh Script noch per Mail versenden. Den aktuellen Wetterbericht werde ich jetzt auch noch einbauen, damit ich nicht sprenge, wenn es drei Stunden später sowieso regnet.

VIELEN VIELEN DANK! Jetzt kann ich loslegen. 8) 8) 8)
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 29 April 2020, 21:21:46
Zitat von: Qualle am 29 April 2020, 21:10:34
Nebenbei hast Du mir auch noch gezeigt, wie ich mein Logfile in FHEM anzeigen kann.
Dacht ich mir :)

Und ich muss mal noch testen was mit pwsh so geht.  ;)

Edit: hätt ich nicht gedacht, mein fhemcl.ps1 Script (https://github.com/heinz-otto/fhemcl) funktioniert :)
Also wenn Du aus deinem powershell Script über HTTP in Dein FHEM schreiben willst, oder Abfragen machen willst :)

Probier es aus, so in etwa (in der Systemkonsole):
./powershell/pwsh ./fhemcl.ps1 http://deinFehmServer:8083 "{ReadingsVal("ESPEasy_NodeMCU_3_BodenfeuchteSensor","Analog",0)}"
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Qualle am 29 April 2020, 21:34:21
Mit PwSh geht alles. Alle Urentwickler kommen aus der Linux Ecke und haben die Vorteile beider Welten zu Powershell verarbeitet. Zuerst ja nur für Windows. Dort geht ohne PoSh heute nichts mehr. Und jetzt eben auch wieder für Linux. So komme ich besser damit klar.

PS: Gab es nicht irgendwo einen GELÖST Button? Ich finde den nicht.
Titel: Antw:ReadinsVal, $EVENT, $EVTPart funktionieren nicht wie gedacht...
Beitrag von: Otto123 am 29 April 2020, 21:35:38
Im ersten Post einfach den Betreff editieren :) [gelöst]
hatte meinen letzten Post noch editiert :)