Ankündigung

Einklappen
Keine Ankündigung bisher.

Logik Problem: bh1750 Wert an Item übergeben

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Logik Problem: bh1750 Wert an Item übergeben

    Mahlzeit zusammen,

    ich möchte den ermittelten Wert eines bh1750 Helligkeitssensor (I2C Bus) an ein Item übergeben.
    Hört sich harmlos an, ich kriegs nicht hin...!

    hier die Logik:

    #!/usr/bin/ python
    import smbus
    import time

    # Define some constants from the datasheet
    DEVICE = 0x23 # Default device I2C address
    POWER_DOWN = 0x00 # No active state
    POWER_ON = 0x01 # Power on
    RESET = 0x07 # Reset data register value
    ONE_TIME_HIGH_RES_MODE = 0x20

    bus = smbus.SMBus(1) # Rev 2 Pi uses 1

    def convertToNumber(data):
    # Simple function to convert 2 bytes of data
    # into a decimal number
    return ((data[1] + (256 * data[0])) / 1.2)

    def readLight(addr=DEVICE):
    data = bus.read_i2c_block_data(addr,ONE_TIME_HIGH_RES_MOD E)
    return convertToNumber(data)

    def main():

    luxtp = '{:3.1f}'.format(readLight())
    sh.raum.lux(luxtp)

    if __name__=="__main__":
    main()
    mit sh.raum.lux(luxtp) hätt ichs versucht zu übergeben, aber ohne Erfolg.
    Ich habe natürlich verschiedene Code Varianten versucht.

    Ich bin jetzt auch nicht der python Profi, vielleicht kann mir hier jemand weiterhelfen.

    #2
    Deine Übergabe ist prinzipiell schon richtig.
    Wie sieht deine Item-Definition aus?
    Bist du sicher, dass der Wert zu diesem Zeitpunkt korrekt gesetzt ist?
    Hast du etwas im Log?

    Kommentar


      #3
      Guten Morgen,

      sorry für die wenigen Infos..

      Meine Umgebung sieht wie folgt aus:
      Hardware: Raspberry Pi 3, Sensor bh1750 per GPIO am I2C Bus angeschlossen
      Software: aktuelles Image von Onkelandy

      Wenn ich das oben genannte Script mit dem print befehl modifiziere und per Hand ausführe, wird der Lux Wert richtig ausgegeben.

      Je nachdem welche script Anpassung ich vornehme, bekomme ich im sh.log entsprechende Fehlermeldungen oder auch nicht...
      Im oben genannten logic Beispiel, gibts im sh.log keine Meldung und es passiert auch nichts. Geprüft wurde der Item Wert übers Backend Plugin.

      Item.yaml:
      Code:
      raum:
          lux:
              type: num
              cache: 'true'
              send_nw: 1
      Verändere ich die Logik wie folgt, dann erhalte ich im Log folgenden Fehler:
      logic.py:
      Code:
      #!/usr/bin/ python
      import smbus
      import time
      import os
      
      # Define some constants from the datasheet
      DEVICE     = 0x23 # Default device I2C address
      POWER_DOWN = 0x00 # No active state
      POWER_ON   = 0x01 # Power on
      RESET      = 0x07 # Reset data register value
      ONE_TIME_HIGH_RES_MODE = 0x20
      
      bus = smbus.SMBus(1)  # Rev 2 Pi uses 1
      
      def convertToNumber(data):
        # Simple function to convert 2 bytes of data
        # into a decimal number
        return ((data[1] + (256 * data[0])) / 1.2)
      
      def readLight(addr=DEVICE):
        data = bus.read_i2c_block_data(addr,ONE_TIME_HIGH_RES_MODE)
        return convertToNumber(data)
      
      def main():
      
        luxtp = '{:3.1f}'.format(readLight())
      sh.raum.lux(luxtp)
      if __name__=="__main__":
      
        main()
      sh.log:
      Code:
      2018-02-19  08:45:06 ERROR    logics.Logic_Raum_Lux Logic: logics.Logic_Raum_Lux, File: /usr/local/smarthome/logics/bh1750.py, Line: 43, Method: <module>, Exception: name 'luxtp' is not defined
      Traceback (most recent call last):
        File "/usr/local/smarthome/lib/scheduler.py", line 425, in _task
          exec(obj.bytecode)
        File "/usr/local/smarthome/logics/bh1750.py", line 43, in <module>
          sh.raum.lux(luxtp)
      NameError: name 'luxtp' is not defined

      Kommentar


        #4
        Da hat der interpreter recht...

        nur in der main methode ist das
        luxtp = '{:3.1f}'.format(readLight()) zu finden.

        so sollte es als logick gehen.

        Code:
        def readLight(addr=DEVICE):
           data = bus.read_i2c_block_data(addr,ONE_TIME_HIGH_RES_MODE)  
           return convertToNumber(data)  
        
        luxtp = '{:3.1f}'.format(readLight())
        sh.raum.lux(luxtp)

        Kommentar


          #5
          hm,

          wenn ich aber anstatt der übergabe (sh.raum.lux...) den Wert der Variable per print Befehl ausgebe in der main, dann geht's..

          btw:
          ist es möglich einen Wert per c-script an ein Item zu übergeben, oder muss dies per python script passieren?

          Kommentar


            #6
            @heckmannju,

            wie müsste ich denn dann die variable definieren damit er zurecht kommt?

            Kommentar


              #7
              Führst du das als Logik in SHNG aus oder als standalone Python Script?

              Zumindest so wie hier dargestellt stimmen deine Einrückungen irgendwie nicht.

              Du übergibst übrigens einen String an ein num Item. Das funktioniert dank implizitem casting zwar, macht aber wenig Sinn. Statt luctp per format zu füllen, solltest du besser runden (darum gehts anscheinend bei dem format).

              Kommentar


                #8
                ich würde es per Logik in SHNG ausführen.
                Ja, ich kürze per .Format die kommastellen zusammen

                Kommentar


                  #9
                  @heckmannju,

                  nach Änderung der logic.py wie folgt, bekomme ich nun eine entsprechende Meldung im Log:

                  Code:
                  #!/usr/bin/ python
                  import smbus
                  import time
                  import os
                  
                  # Define some constants from the datasheet
                  DEVICE     = 0x23 # Default device I2C address
                  POWER_DOWN = 0x00 # No active state
                  POWER_ON   = 0x01 # Power on
                  RESET      = 0x07 # Reset data register value
                  ONE_TIME_HIGH_RES_MODE = 0x20
                  
                  bus = smbus.SMBus(1)  # Rev 2 Pi uses 1
                  
                  def convertToNumber(data):
                    # Simple function to convert 2 bytes of data
                    # into a decimal number
                    return ((data[1] + (256 * data[0])) / 1.2)
                  
                  def readLight(addr=DEVICE):
                    data = bus.read_i2c_block_data(addr,ONE_TIME_HIGH_RES_MODE)
                    return convertToNumber(data)
                  
                  # def main():
                  
                  luxtp = '{:3.1f}'.format(readLight())
                  sh.raum.lux(luxtp)
                  
                  if __name__=="__main__":
                  
                    main()
                  Log:
                  Code:
                  2018-02-19  10:58:46 ERROR    logics.Logic_Raum_Lux Logic: logics.Logic_Raum_Lux, File: /usr/local/smarthome/logics/bh1750.py, Line: 21, Method: readLight, Exception: name 'bus' is not defined
                  Traceback (most recent call last):
                    File "/usr/local/smarthome/lib/scheduler.py", line 425, in _task
                      exec(obj.bytecode)
                    File "/usr/local/smarthome/logics/bh1750.py", line 42, in <module>
                      luxtp = '{:3.1f}'.format(readLight())
                    File "/usr/local/smarthome/logics/bh1750.py", line 21, in readLight
                      data = bus.read_i2c_block_data(addr,ONE_TIME_HIGH_RES_MODE)
                  NameError: name 'bus' is not defined

                  Kommentar


                    #10
                    bus ist ja auch nur im Hauptteil definiert und nicht in der Funktion readLine.

                    Deinen Aufbau finde ich reichlich kompliziert. Theoretisch könntest du alles in einer Zeile schreiben. Der Übersichtlichkeit halber würde ich etwa folgendes vorschlagen:
                    Code:
                    #!/usr/bin/ python
                    import smbus
                    
                    # Define some constants from the datasheet
                    DEVICE     = 0x23 # Default device I2C address
                    ONE_TIME_HIGH_RES_MODE = 0x20
                    
                    def convertToNumber(data):
                      # Simple function to convert 2 bytes of data into a decimal number
                      return ((data[1] + (256 * data[0])) / 1.2)
                    
                    bus = smbus.SMBus(1)  # Rev 2 Pi uses 1
                    data = bus.read_i2c_block_data(DEVICE, ONE_TIME_HIGH_RES_MODE)
                    luxtp = round(convertToNumber(data), 1)
                    sh.raum.lux(luxtp)
                    Du hast Imports und Konstanten, welche gar nicht benötigt werden und ich sehe keinen Vorteil, die eine Zeile zum Lesen des I2C in eine Funktion zu kapselnDie Konstante DEVICE, welche dann als Standardwert für addr verwendet wird, macht es auch nicht übersichtlicher.

                    Kommentar


                      #11
                      tja smai,

                      wie nicht anders zu erwarten, klappts mit deiner Lösung wunderbar.

                      Ich bedanke mich an dieser Stelle wieder bei allen beteiligten.
                      Ich habe meinen Code aus dem Internet kopiert, da ich einfach zu wenig Ahnung habe wie mans kurz und richtig schreibt.

                      Super, nun kann ich mit den Werten endlich arbeiten und in die Smartvisu mit einbauen!

                      Kommentar

                      Lädt...
                      X