Blynk Slider Funktion Variable

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Sorry __deeds___ Missverständniss....

Print value innerhalb der Funktion:
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ for Python v0.2.0 (Linux)

['37.9']
['21.8']
['62.0']
['42.8']
['63.8']

Print value ausserhalb:
value not defined ... ob mit oder ohne return innerhalb der Funktion

Code: Alles auswählen

@blynk.VIRTUAL_WRITE(39)
def slider(value):
    value1 = (str(value[0]))
    print(value1)
Ergebnis ist dann folgendes: (Mit neuen slider Bewegungen)
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ for Python v0.2.0 (Linux)

51.1
25.5
66.4
23.6


LG
Stefan
Wer Was Wo... www.tvware.de
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ok, warum auch immer das eine Liste ist. Dann sollte es

Code: Alles auswählen

@blynk.VIRTUAL_WRITE(39)
def slider(value):
    global pwm
    pwm = int(value[0] ) + PWM_BASE
sein. Wobei das natuerlich nur die erste Näherung ist! Deine slider Werte und der Wertebereich der PWM müssen ggf aufeinander abgebildet werden, als klassische Geradengleichung. Bestimme die Werte für PWM, die für den Slider, mal sie in ein Koordinatensystem, und leite Achsenabschnitt b und Steigung a ab.

Und aus gegebenem Anlass: str(..) ist kein Glutamat, das man einfach mal über alles rüber kippt, auf das es schmecke. Du willst hier mit Zahlwerten arbeiten, und da auf Zeichenketten zu setzen ist sinnlos.
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Ich werde das so versuchen und melde mich.... - Es handelt sich nicht um präzisionswerte.... in dem Fall kommt es auf 10% nicht an... :-)

Vielen Dank bis hier hin.
Stefan
Wer Was Wo... www.tvware.de
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

noch nicht ganz des Rätsels Lösung:

Obiger Code ergibt:
invalid literal for int()with base 10: '46.6'

Freund Google sagt dazu: https://stackoverflow.com/questions/138 ... th-base-10
also float (zu pwm_base & oder - value)... aber dann geht gar nichts mehr... weder Fehlermeldung oder sonst was nur Blynk Logo....
Also "Glutamat" :-) drüber... selber Effekt.

Hätte nicht gedacht das sich so ein oberflächlich betrachtet simples Ding so ausbreitet...bzw. in die Länge zieht.

LG
Stefan
Wer Was Wo... www.tvware.de
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ah, mein Fehler. Es ist ein String. Du musst int(float(value)) machen. Als Teil des Ausdrucks!

Und das ganze ist nicht schwer, man findet nur keine vernünftige Dokumentation.
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Ok morgen… hier ist es fast 24Uhr….. Danke Dir und dann reden wir mal über das Knie :-)
Lg Stefan
Wer Was Wo... www.tvware.de
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Du schlägst folgendes vor: (#wenn ich es richtig verstanden habe??)

Code: Alles auswählen

PWM_BASE = 10
pwm = (PWM_BASE)

@blynk.VIRTUAL_WRITE(39)
def slider(value):
    global pwm
    value1=int(float(value))
    pwm = value1 + (PWM_BASE)
    print(pwm)
    
while True:
    blynk.run()
    
Das läuft leider nicht wie gedacht.... Ich hab es wie folgt ergänzt: #value1=int(float(value[0]))

Code: Alles auswählen

PWM_BASE = 10
pwm = (PWM_BASE)

@blynk.VIRTUAL_WRITE(39)
def slider(value):
    global pwm
    value1=int(float(value[0]))
    pwm = value1 + (PWM_BASE)
    print(pwm) #Ergibt den slider wert (47)
    
print(pwm) #Ergibt 10 ... (PWM_BASE)
    
while True:
    blynk.run()
Das ergibt dann z.B. 47 den slider wert. Soweit so gut... aber nur innerhalb der Funktion nicht ausserhalb. Ich habe versucht mit return und dann slider etc. aber ich bekomme den value wert des sliders nicht ausserhalb der Funktion.

print(value1) ausserhalb/unterhalb der Funktion ergibt:
<BlynkLib.BlynkProtocol.VIRTUAL_WRITE.<locals>.Decorator object at 0x7625f6f0>

Bin für vieles offen.... :-)

LG
Stefan
Wer Was Wo... www.tvware.de
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja, da habe ich einfach den Index wieder vergessen. Darum das [0].

Ausserhalb der Funktion geht der Zugriff nicht. Woher soll der Wert kommen? Der existiert nur in der Funktion selbst, denn nur da wird man ueber den aktuellen Wert informiert. Warum willst du den ausserhalb haben? Und woher hast du die Klammern um PWM_BASE in Zeile 2, und in dem Callback? Du streust schon wieder Dinge ueber den Code, die weder helfen, noch von dir verstanden werden.

Sinn und Zweck der Uebung war, den pwm-Wert vom Slider anpassen zu lassen. Das passiert jetzt. Warum reicht das nicht?
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Soweit war ich ja schon zu beginn des Threads mit:

Code: Alles auswählen

@blynk.VIRTUAL_WRITE(39)
def slider(value):
    value1= str(value[0])
    print (value1)

Für meine simple Anfänger Logik wäre es wünschenswert diesen Wert auch ausserhalb zu bekommen. Um einen für mich nachvollziehbaren Weg zu gehen / schreiben....

Aber gut wenn es so ist dann ist es so...

Vielen Dank für Deine Mühe Dich mit mir Unwissenden auseinander zu setzten.
Happy Day
Stefan
Wer Was Wo... www.tvware.de
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Jetzt hast du einen durch dem Slider angepassten PWM wert. Was auch immer du damit machen willst. Das war das Ziel. Und der ist außerhalb verfügbar. Was also genau fehlt dir da?
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Jetzt verstehe ich nur Bahnhof....
erst schreibst Du: "Ausserhalb der Funktion geht der Zugriff nicht.Woher soll der Wert kommen? Der existiert nur in der Funktion selbst, denn nur da wird man ueber den aktuellen Wert informiert."

und nun

"Und der (Wert) ist außerhalb verfügbar." ... BITTE BITTE schreib mir wie....
LG
Stefan
Wer Was Wo... www.tvware.de
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was glaubst du ist denn pwm? Warum steht da global? Warum greifst du darauf nicht zu?

Ich stelle im uebrigen in Frage, dass man das muss, du koenntest auch einfach in der Rueckrufaktion die PWM umkonfigurieren. Denn das muss ja nur passieren, wenn der Wert sich aendert, oder nicht?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Wo willst Du denn den Wert "außerhalb" benutzen? Zeig den Code, der das verwenden soll. Den seh ich nämlich nicht.
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Servus,

@__deets__ : Innerhalb der Funktion funktioniert das aber ausserhalb gibt es nichts...

@Sirius3: Mitte erste Seite dieses Threads, ist der Code in dem der slider eingefügt werden soll....

Ich bastel da gerade dran rum. Sowie es etwas sinnvolles ergibt melde ich mich.

Danke
Wer Was Wo... www.tvware.de
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Code: Alles auswählen


#!/usr/bin/python3
#coding= utf-8

import RPi.GPIO as GPIO
import time
import datetime
#import os
#import sys
import BlynkLib


BLYNK_AUTH = 'XY'
blynk = BlynkLib.Blynk(BLYNK_AUTH, server='192.168.10.102', port=8080, heartbeat=30)



GPIO.setmode(GPIO.BCM)  # BCM-Bezeichnung der Pins verwenden
GPIO.setwarnings(False)

    
ts = time.time()
timestamp = datetime.datetime.fromtimestamp(ts).strftime('%d.%m.%Y; %H:%M:%S')

Faktor = 20    # inaktiv -Version 1: wird von der aktuellen CPU Temp. abgezogen als Duty Cycle (z.B. 37Grad minus Faktor= Duty Cycle Luefter)
                        # aktiv -Version 2: wird dem delta (CPU - Innentemp) hinzu gerechnet um Drehzahl anzupassen

Luefter = 17   # GPIO PWM zum Luefter

Regelinterval = 10.0


GPIO.setup(Luefter, GPIO.OUT) # GPIO 17 auf Ausgang setzen
log =    "/media/pi/USB_32GB/Raspi_101_Logs/PWMLuefter.csv"
alog = "/media/pi/USB_32GB/Archiv/PWMLuefter2021.csv"

def aktuelleTemperatur(): # Umgebungstemp Raspi -Technikfach Temp Sensor auslesen
      
    # 1-wire Slave Datei lesen
    file = open('/sys/bus/w1/devices/28-000005bbd5b3/w1_slave')
    filecontent = file.read()
    file.close()
 
    # Temperaturwerte auslesen und konvertieren
    stringvalue = filecontent.split("\n")[1].split(" ")[9]
    temperature = float(stringvalue[2:]) / 1000
 
    # Temperatur ausgeben
    rueckgabewert = '%6.2f' % temperature 
    return(rueckgabewert)

# PWM einschalten
pwm = GPIO.PWM(Luefter, 250); # soll ?? 25kHz Frequenz
pwm.start(10)
print('Start mit 10% ')
time.sleep(3.0)



try:
  while True:
  
    # CPU1 Temp  
    tempData = "/sys/class/thermal/thermal_zone0/temp" 
    dateilesen = open(tempData, "r")
    CPURPi1 = dateilesen.readline(2)
    dateilesen.close()  
    
    # CPU2 Temp
    CPUtempRPi2 = open('/home/pi/Termo_Sensoren/CPUtempRPi2.txt')
    CPURPi2 = CPUtempRPi2.read()
    CPUtempRPi2.close()

    ts = time.time()
    timestamp = datetime.datetime.fromtimestamp(ts).strftime('%d.%m.%Y; %H:%M:%S')
    
    #Temperatur Technikfach
    messdaten = aktuelleTemperatur()
    
    # Die waermere CPU steuert den Lüfter
    if CPURPi1 >= CPURPi2:
        print("1 ist waermer")
        CPUWert = CPURPi1
        CPU = 'RPi1'
    elif CPURPi1 < CPURPi2:
        print("2 ist waermer")
        CPUWert = CPURPi2
        CPU = 'RPi2'
    
    global rpm
    global rpmf
    rpmf = 1
    #rpm = float(temperatur)-Faktor #feste Stellgrösse - Version 1    
    delta = (float(CPUWert))-(float(messdaten))
    rpm = delta + Faktor # Variable delta steuert Duty Cycle - Version 2
    #rpmf = round(rpm, 0)
    #print(rpm)
    #print(rpmf)
    
    @blynk.VIRTUAL_WRITE(39)
    def slider(value):
        value1= int(float(value[0]))
        value2 = value1 + rpm
        rpmf = round(value2, 0)
        print(value1)
        print(value2)
        print(rpmf)
        pwm.ChangeDutyCycle(rpmf)
        
    #pwm.ChangeDutyCycle(100)
    

        print (timestamp, "CPU1: " + CPURPi1 + " °C ", "CPU2: " + CPURPi2 + " °C ","DutyCycle:", rpmf, "%", " Technikfach:", messdaten,"°C  ","Delta:","{0:.2f}".format(delta),"°C") 
    
    #Log file
    logfile = open(log, 'a')
    logfile.write(timestamp+";  CPU 1: " + CPURPi1 +"°C;  "+" CPU 2: " + CPURPi2 +"°C;   "+ (str(rpmf))+"% DutyCycle;  " +"Technikfach:"+ messdaten +"°C;"+"  Delta: "+"{0:.2f}".format(delta)+"°C;   "+ CPU +"\n")
    logfile.close()

    #alog file
    logfile = open(alog, 'a')
    logfile.write(timestamp+";  CPU 1: " + CPURPi1 +"°C;  "+" CPU 2: " + CPURPi2 +"°C;   "+ (str(rpmf))+"% DutyCycle;  " +"Technikfach:"+ messdaten +"°C;"+"  Delta: "+"{0:.2f}".format(delta)+"°C;   "+ CPU +"\n")
    logfile.close()
    
    
    if CPURPi1 >= ('65'):   # ab ca. 60C CPU Luefter 100%
        pwm.ChangeDutyCycle(100)
    
    elif CPURPi2 >= ('65'):  # CPU Temp des RPi2 Luefter auf 100% 
        pwm.ChangeDutyCycle(100)
    
    
    
    blynk.run()
    
    time.sleep(Regelinterval) #Regelintervall
   
    
   
# Abbruch durch Taste Strg-C
except KeyboardInterrupt:
    pwm.stop()
    GPIO.cleanup()

Das ist die aktuellste Version, die noch nicht so perfekt ist, wie sie sein könnte. . . . .

Zum Verständnis: Es ist ein relativ kleiner Raum indem unter anderem zwei Rapberry ihren Job machen. Ein 100mm PWM gesteuerter Lüfter versorgt diese mit Umluft die auch mal 40Grad und etwas mehr erreichen kann...

LG und Danke bis hier hin....
Stefan

P.S. Ich bin nicht Beratungsresistent ... und eher ein kreativer Pensionist mit 2 Jahren Python try and error :-)
Wer Was Wo... www.tvware.de
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Shabang-Zeile muß die erste Zeile in der Datei sein, die Leerzeile am Anfang ist ein Fehler.
Die coding-Zeile ist überflüssig, da Python3 defaultmäßig utf8 erwartet.
`as` bei `import` ist zum umbenennen da, GPIO wird aber gar nicht umbenannt.
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 2 und mal 4.
Warnungen sind dazu da, dass man sie behebt, nicht dass man sie ignoriert.
Dazu muß aber auch cleanup verlässlich aufgerufen werden, nicht nur bei Ctrl+C.
Variablennamen schreibt man komplett klein, Konstanten dagegen KOMPLETT GROSS.
Das erste `timestamp` wird gar nicht benutzt.
Dateien öffnet man innerhalb des with-Statements.
Temperaturen sind Zahlen, keine Strings, da funktionieren die Vergleiche nicht.
Funktionen definiert man nicht innerhalb von while-Schleifen.
Und vergiss gleich wieder, dass es global überhaupt gibt, es funktioniert sowieso nicht, wie Du es benutzt.
`readline` mit einem Parameter ist eigentlich nie sinnvoll. Und schon wieder kein robustes Lesen von Temperaturen.
Man stückelt keine Strings per + zusammen, sondern benutzt Formatstrings.
Um mit einem Callback zu kommunizieren braucht man eine Queue.

Code: Alles auswählen

#!/usr/bin/python3
import time
import datetime
from functools import partial
from queue import Queue
from RPi import GPIO
import BlynkLib


BLYNK_AUTH = 'XY'

LUEFTER_PIN = 17
FAKTOR = 20
REGEL_INTERVAL = 10

LOGFILENAME = "/media/pi/USB_32GB/Raspi_101_Logs/PWMLuefter.csv"
ARCHIVE_LOGFILENAME = "/media/pi/USB_32GB/Archiv/PWMLuefter2021.csv"

def read_temperature_slave():
    # Umgebungstemp Raspi -Technikfach Temp Sensor auslesen
    with open('/sys/bus/w1/devices/28-000005bbd5b3/w1_slave') as data:
        _, t, temperature = data.read().rpartition('t=')
    if not t:
        return float('nan')
    return float(temperature) / 1000

def read_temperature_cpu1():
    with open("/sys/class/thermal/thermal_zone0/temp") as data:
        return float(data.read()) / 1000


def read_temperature_cpu2():
    with open('/home/pi/Termo_Sensoren/CPUtempRPi2.txt') as data:
        return float(data.read()) # warum hier kein / 1000?

def slider(queue, value):
    queue.put(float(value[0]))

def main():
    try:
        queue = Queue()
        blynk = BlynkLib.Blynk(BLYNK_AUTH, server='192.168.10.102', port=8080, heartbeat=30)
        blynk.on('V39', partial(slider, queue))
        GPIO.setmode(GPIO.BCM)  # BCM-Bezeichnung der Pins verwenden
        GPIO.setup(LUEFTER_PIN, GPIO.OUT) # GPIO 17 auf Ausgang setzen

        # PWM einschalten
        pwm = GPIO.PWM(LUEFTER_PIN, 250); # soll ?? 25kHz Frequenz
        pwm.start(10)
        print('Start mit 10% ')
        time.sleep(3.0)

        rpmf = 1
        while True:
            now = datetime.datetime.now()
            cpu1_temperature = read_temperature_cpu1()
            cpu2_temperature = read_temperature_cpu2()
            slave_temperature = read_temperature_slave()

            max_temperature = max(cpu1_temperature, cpu2_temperature)
            cpu = "RPi1" if cpu1_temperature > cpu2_temperature else "RPi2"

            while not queue.empty():
                rpmf = queue.get()
            delta = max_temperature - slave_temperature
            rpm = delta + FAKTOR + rpmf

            log_line = f"{now:%Y-%m-%d %H:%M:%S}; CPU 1: {cpu1_temperature:.2f}°C; CPU 2: {cpu2_temperature:.2f}°C; {rpm}% DutyCycle; Technikfach: {slave_temperature:.2f}°C;  Delta: {delta:.2f}°C; {cpu}\n"
            with open(LOGFILENAME, "a") as output:
                output.write(log_line)
            with open(ARCHIVE_LOGFILENAME, "a") as output:
                output.write(log_line)

            pwm.ChangeDutyCycle(100 if max_temperature >= 65 else rpm)
            blynk.run()
            time.sleep(REGEL_INTERVAL)
    except KeyboardInterrupt:
        # Abbruch durch Taste Strg-C
        pass
    finally:
        pwm.stop()
        GPIO.cleanup()

if __name__ == '__main__':
    main()
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Da bin jetzt erstmal Baff.... DANKE für die Nachhilfe....
Ich muss mir das jetzt alles mal im Detail ansehen um meine "Fehler / Deine Verbesserungen" zu erkennen. Sieht wesentlich aufgeräumter aus. Etliche der Begriffe die Du in den ersten Zeilen verwendest hab ich noch nie gelesen... da ist dann Google mein Freund :-)

Einfach stark zu lesen, wieviel einfacher man manche Sachen ausdrücken kann, wenn man weiss wie.

Bei meinen Versuchen bin ich schon froh wenn es funktioniert... aber auch bei Profis (falls Du einer bist) funktioniert nicht alles auf Anhieb :-) Ich versuche dem jetzt erstmal alleine auf die Schliche zu kommen.

Nochmals Danke
Stefan
Wer Was Wo... www.tvware.de
Antworten