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:

Einen angenehmen Tag in die Gemeinde...
ja wieder mal ein Gruft... der es wissen will... bzw. lernen darf :-)

Ich versuche seit 2 Tagen folgende "Lappalie" zum leben zu erwecken:

..

Code: Alles auswählen

# Blynk..... der ganze Blynk kram...


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

while True:
    blynk.run()
ich bekomme die Variable "value1" nicht ausserhalb der Funktion zum printen bzw. anderes....das print innerhalb der Funktion geht einwandfrei und es druckt den in der App eingestellten "Slider" Wert...
So wie ich das Laienhaft verstehe, übergibt Blynk den wert in der Variable "value" denn ich kann diesen ja printen innerhalb der Funktion. value ist ein list Typ. Wenn einer der Wissenden sich äussern könnte...

Vielen herzlichen Dank
Stefan
Wer Was Wo... www.tvware.de
Benutzeravatar
Dennis89
User
Beiträge: 1123
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

'global' zu verwenden löst nicht das Problem, sondern schafft neue. Schreibe deine Programme ohne 'global', denn was eine Funktion benötigt bekommt sie als Argumente übergeben (der Name in den Klammern) und wenn eine Funktion etwas zurück geben soll, dann macht sie das über den Rückgabewert (return)

Code: Alles auswählen

def mit_übergebenen_werten_rechnen(wert):
    berechneter_wert = wert * 2
    print(berechneter_wert)
    return berechneter_wert

def main():
    funktionsrückgabewert = mit_übergebenen_werten_rechnen(2)
    print(funktionsrückgabewert)

if __name__ == '__main':
    main()
Ich hoffe das Beispiel ist verständlich.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

@Dennis deine Ausfuehrungen sind in diesem Kontext nicht wirklich passend. Denn es handelt sich hier, aehnlich wie bei tkinter, um eine Ereignisschleife. Da gibt es keinen Returnwert, und auch keine beliebigen Argumente.

Zusaetzlich ist das Framework das hier genutzt wird auch nicht besonders flexibel was die Angabe von Rueckruffunktionen angeht.

Und zu guter Letzt gelten in der Embedded-Programmierung auch andere Regeln. Da ist ein bisschen globaler Zustand manchmal pragmatisch.

@JSStefan: du zeigst nicht, was du eigentlich erreichen willst. Am besten (um den globalen Zustand *wenn moeglich* zu vermeiden) ist einfach, in der Rueckrufaktion eine weitere Funktion aufzurufen. Alternativ den Wert einer globalen Variablen zuweisen. Aber etwas machen kannst du mit der nicht irgendwann vorher, sondern nur waehrend gleichzeitig die Ereignisschleife laeuft.
Benutzeravatar
Dennis89
User
Beiträge: 1123
Registriert: Freitag 11. Dezember 2020, 15:13

Oh, das war mir gar nicht bewusst. Vielen Dank für den Hinweis @__deets__.
@JSStefan sorry, überlese meinen Beitrag einfach.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Erstmal Dankeschön das Ihr euch das Problem angesehen habt...
@__deed__ mit Ereignisschleife ist die obige Funktion ("def slider(value):") gemeint?

Was will ich erreichen?... OK... Ich möchte den Wert des Blynk Sliders zu einem anderen Wert (Duty cycle der PWM Steuerung) hinzu addieren. Es geht um 2 Raspis die von einem Lüfter gekühlt werden und der jeweils wärmere steuert die Drehzahl des Lüfters in Abhängigkeit der Umgebung Temperatur. Also nichts aufregendes.
Es gibt einen Grundwert den ich über den Spider einstellen / beeinflussen möchte. Somit sollte der Sliderwert ausserhalb dieser Funktion zur Verfügung stehen. Ausser dem - SliderWert - läuft das Script seit Monaten problemlos.

Bild
....Versuch gescheitert ein Bild einzustellen....sorry

https://www.dropbox.com/s/im3k2n9dcit73 ... 6.jpg?dl=0

Mit meinem try and error Verfahren stosse ich an eine Grenze... und Google war diesbezüglich auch nicht mein Freund...

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

Nein, mit Ereignisschleife ist die Schleife in deinem Code gemeint, in der Blynk immer wieder dazu aufgefordert wird, seine Arbeit zu machen, und bei Bedarf eben ein Ereignis auszuloesen.

Und deine Rueckrufaktion wird doch aufgerufen. Addier doch darin den slider-value den du uebergeben bekommst auf deinen pwm-Wert.

Code: Alles auswählen

PWM_BASE = 10

pwm = PWM_BASE # minimalwert

@blynk.VIRTUAL_WRITE(39)
def slider(value):
    global pwm
    pwm = slider + PWM_BASE
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Das war aber schnell... Problem für mich wird sein: Den "pwm" wert aus der Funktion heraus zu bekommen... analog zu value1... Ich werde es versuchen.
Danke erstmal
Wer Was Wo... www.tvware.de
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Ich bekomme es nicht gebacken... innerhalb der Funktion geht es wunderbar...
Es kann doch nicht angehen, das man den Wert des Silders nicht aus der Funktion auslesen kann... Was ich versuche schlägt fehl...

Hier ist mal das gesamte Script ( welches sicherlich schöner und besser gemacht werden könnte... ich bin froh es so hinbekommen zu haben...) Es läuft bis auf den Punkt "Faktor" den ich gerne über den Slider von Blynk, beeinflussen möchte. Ich hab wohl gerade einen Tunnelblick der das ganze nur teilweise betrachtet....

LG Stefan

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)

#@blynk.VIRTUAL_WRITE(39)
#def slider(value):
    #value1 = "".join(value[0])
    #value2 = str(value1)
    #value3 = float(value1)
    #print(value2)
    
# - - - - da sollte jetzt eine Variable stehen mit der ich später weiter basteln kann - - - -       

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 = 120.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'
        
    #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)
    
    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()

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

Der von __deed__ vorgeschlagene Ansatz:

Code: Alles auswählen

PWM_BASE = 10

pwm = PWM_BASE # minimalwert

@blynk.VIRTUAL_WRITE(39)
def slider(value):
    global pwm
    pwm = slider + PWM_BASE 
ergibt: BlankLib.BlynkProtocol.VIRTUAL_WRITE.<locals>. Decorator object at ox762dd730> # - was mir gar nicht sagt -

Habe das dann abgeändert auf:

Code: Alles auswählen


PWM_BASE = 10
pwm = PWM_BASE # minimalwert

@blynk.VIRTUAL_WRITE(39)
def slider(value):
    global pwm
    #print (value)
    value1 = (str(value[0]))
    #print (value1)
    pwm = str(value1) + str(PWM_BASE)
    return pwm
#slider()    
#print(slider)
print(pwm)

Ergibt: 10

eine Änderung des Silders wird nicht registriert. Wie könnte ich da weiter kommen? Über einen Schubs in die richtige Richtung wäre ich dankbar.

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

Ich habe mich verschrieben, es muss natuerlich

Code: Alles auswählen

pwm = value + PWM_BASE
heissen.

Dieses ganze rumgestringe - warum machst du das? Was glaubst du bewirkt das? "10" + "20" ist "1020", nicht 30, wie es wohl gewuenscht waere in diesem Zusammenhang.
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Danke für die schnelle Antwort. Ich mache das um dieses:
___ __ __


/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ for Python v0.2.0 (Linux)

<BlynkLib.BlynkProtocol.VIRTUAL_WRITE.<locals>.Decorator object at 0x762bf6b0>

zu verhindern. Ich weiss es nicht besser wie sonst.
LG
Stefan
Wer Was Wo... www.tvware.de
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

Nach bewegen des Spiders (value) kommt:

"pwm = value + PWM_BASE
TypeError: can only concatenate list (not "int") to list
>>>"
Wer Was Wo... www.tvware.de
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Meh. Was gibt denn ein simples

Code: Alles auswählen

print(value)


aus, ohne alles andere? Und das mal ueber mehrere Werte deines Sliders.
JSStefan
User
Beiträge: 18
Registriert: Donnerstag 22. April 2021, 19:45
Kontaktdaten:

ohne alles andere? Und das mal ueber mehrere Werte deines Sliders.
Genau das ist meine Wissenslücke, die ich hoffe mit eurer Hilfe schliessen zu können. Wie müsste die Zeile lauten um den Wert des sliders zu bekommen?

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

print(value). Habe ich doch geschrieben. Ich will das sehen.
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.
Antworten