Bibliothéques en python


#1

Bonjour Sébastien,
Après l’étape de création de l’environnement constellation et création d’une sentinelle (une raspberry PI2).
Je tente des essais de programmation. L’étape en utilisant ton tuto LightSensor a été un réussite alors allont un peu plus lion.
J’ai suivi le très bon tuto http://hardware-libre.fr/2014/03/raspberry-pi-utiliser-un-lcd-4x20/ pour piloter un afficheur 2x16caractères et à nouveau une réussite.
Par contre le faire dans l’environnement constellation, et bien là c’est un achec. C’est là que j’ai besoin de tes conseils.
Je suis dans VS2015 voici mes codes:
Dans le Scripts: Constellation.py;i2c_lib.py; lcddriver.py et lightsensor.py.

i2c_lib.py:


import Constellation
import smbus
from time import *

class i2c_device:
def init(self, addr, port=1):
self.addr = addr
self.bus = smbus.SMBus(port)

Write a single command

def write_cmd(self, cmd):
self.bus.write_byte(self.addr, cmd)
sleep(0.0001)

Write a command and argument

def write_cmd_arg(self, cmd, data):
self.bus.write_byte_data(self.addr, cmd, data)
sleep(0.0001)

Write a block of data

def write_block_data(self, cmd, data):
self.bus.write_block_data(self.addr, cmd, data)
sleep(0.0001)

Read a single byte

def read(self):
return self.bus.read_byte(self.addr)

Read

def read_data(self, cmd):
return self.bus.read_byte_data(self.addr, cmd)

Read a block of data

def read_block_data(self, cmd):
return self.bus.read_block_data(self.addr, cmd)
Constellation.WriteInfo("Librairie i2c_lib est chargée !")
Constellation.Start()

lcddriver.py:

import Constellation
import i2c_lib
from time import *

# LCD Address
ADDRESS = 0x3f

# commands
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETCGRAMADDR = 0x40
LCD_SETDDRAMADDR = 0x80

# flags for display entry mode
LCD_ENTRYRIGHT = 0x00
LCD_ENTRYLEFT = 0x02
LCD_ENTRYSHIFTINCREMENT = 0x01
LCD_ENTRYSHIFTDECREMENT = 0x00

# flags for display on/off control
LCD_DISPLAYON = 0x04
LCD_DISPLAYOFF = 0x00
LCD_CURSORON = 0x02
LCD_CURSOROFF = 0x00
LCD_BLINKON = 0x01
LCD_BLINKOFF = 0x00

# flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
LCD_MOVERIGHT = 0x04
LCD_MOVELEFT = 0x00

# flags for function set
LCD_8BITMODE = 0x10
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_1LINE = 0x00
LCD_5x10DOTS = 0x04
LCD_5x8DOTS = 0x00

# flags for backlight control
LCD_BACKLIGHT = 0x08
LCD_NOBACKLIGHT = 0x00

En = 0b00000100 # Enable bit
Rw = 0b00000010 # Read/Write bit
Rs = 0b00000001 # Register select bit

class lcd:
   #initializes objects and lcd
   def __init__(self):
      self.lcd_device = i2c_lib.i2c_device(ADDRESS)

      self.lcd_write(0x03)
      self.lcd_write(0x03)
      self.lcd_write(0x03)
      self.lcd_write(0x02)

      self.lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE)
      self.lcd_write(LCD_DISPLAYCONTROL | LCD_DISPLAYON)
      self.lcd_write(LCD_CLEARDISPLAY)
      self.lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT)
      sleep(0.2)

   # clocks EN to latch command
   def lcd_strobe(self, data):
      self.lcd_device.write_cmd(data | En | LCD_BACKLIGHT)
      sleep(.0005)
      self.lcd_device.write_cmd(((data & ~En) | LCD_BACKLIGHT))
      sleep(.0001)

   def lcd_write_four_bits(self, data):
      self.lcd_device.write_cmd(data | LCD_BACKLIGHT)
      self.lcd_strobe(data)

   # write a command to lcd
   def lcd_write(self, cmd, mode=0):
      self.lcd_write_four_bits(mode | (cmd & 0xF0))
      self.lcd_write_four_bits(mode | ((cmd < MAX_READING):
            break
        reading += 1
    return reading
 
def Start():
    global INTERVAL
    GPIO.setmode(GPIO.BCM)
    Constellation.OnExitCallback = OnExit
    lastSend = 0
    currentValue = 0
    count = 0
    Constellation.WriteInfo("LightSensor + afficheur 2x16: status: Ok !")
    while Constellation.IsRunning:
        currentValue = currentValue + RCtime(LIGHT_SENSOR_GPIO)
        count = count + 1
        ts = int(round(time.time()))
        if ts - lastSend >= int(Constellation.GetSetting("Interval")):
            avg = int(round(currentValue / count))
            # on initialise le lcd
            lcd = lcddriver.lcd()
            # on reinitialise le lcd
            lcd.lcd_clear()
            # on affiche des caracteres sur chaque ligne
            lcd.lcd_display_string("   essai avec", 1)
            lcd.lcd_display_string("   Constellation", 2)
            #lcd.lcd_display_string("        un", 3)
            #lcd.lcd_display_string("   Raspberry Pi !", 4)
            Constellation.PushStateObject("Light", avg, "int")
            currentValue = 0
            count = 0
            lastSend = ts
        time.sleep(MEASURE_INTERVAL)
Constellation.Start(Start)
Dans App.config j'ai:

et dans le PackageInfo.xml j’ai fait évolué la version pour n’y retrouver.

Je fais une télédistribution dans la constellation et dans les log j’ai:

[raspfred1/LightSensor] 13:34:57 : ‘/opt/constellation-sentinel/Packages/LightSensor/Scripts/LightSensor.py’ is running
[raspfred1/LightSensor] 13:34:58 : Starting script ‘/opt/constellation-sentinel/Packages/LightSensor/Scripts/i2c_lib.py’
[raspfred1/LightSensor] 13:35:04 : Starting script ‘/opt/constellation-sentinel/Packages/LightSensor/Scripts/lcddriver.py’
[raspfred1/LightSensor] 13:35:04 : ‘/opt/constellation-sentinel/Packages/LightSensor/Scripts/i2c_lib.py’ is running
[raspfred1/LightSensor] 13:35:04 : ‘/opt/constellation-sentinel/Packages/LightSensor/Scripts/lcddriver.py’ is running
[raspfred1/LightSensor] 13:35:04 : Starting script ‘/opt/constellation-sentinel/Packages/LightSensor/Scripts/Script1.py’
[raspfred1/LightSensor] 13:35:04 : Librairie i2c_lib est chargée !
[raspfred1/LightSensor] 13:35:04 : Librairie i2c_lib est chargée !
[raspfred1/LightSensor] 13:35:04 : Librairie i2c_lib est chargée !
[raspfred1/LightSensor] 13:35:04 : ‘/opt/constellation-sentinel/Packages/LightSensor/Scripts/Script1.py’ is running
[raspfred1/LightSensor] 13:35:04 : Hi I’m ‘LightSensor’ and I currently running on raspfred1 and connected to Constellation
Mais l’afficheur n’affiche pas le bon message “essais avec constelletion”
Ce qui est bizzare est que le message “Librairie lcddriver est chargée !” n’est pas dans le Log, par contre il y a 3 messages “Librairie i2c_lib est chargée !”.

Qu’est ce que je n’ai pas fait correctement?
Merci de ton aide.

Fréd


Suite Bibliothéques Python
#2

Après avoir refait le publish vers constellation j’ai plus d’insulte dans le log:

[FRED-WIN10_UI/Sentinel] 14:34:38 : Receiving 1 package(s) from the Constellation Server

[Controller/ControlCenter:Admin] 14:34:38 : Pushing packages list to FRED-WIN10

[Controller/ControlCenter:Admin] 14:34:38 : Pushing packages list to raspfred1

[FRED-WIN10/Sentinel] 14:34:38 : Receiving 0 package(s) from the Constellation Server

[raspfred1/Sentinel] 14:34:38 : Receiving 1 package(s) from the Constellation Server

[raspfred1/Sentinel] 14:34:38 : Adding 'LightSensor'

[raspfred1/Sentinel] 14:34:38 : Downloading LightSensor (URI:http://xxx.xxx.xxx.xxx:8088/packages/LightSensor.zip)

[Server/PackageMiddleware] 14:34:38 : 'raspfred1' getting '/packages/LightSensor.zip' (Local path: C:\Program Files (x86)\Constellation Platform\Packages\LightSensor.zip)

[raspfred1/Sentinel] 14:34:38 : Unzipping LightSensor

[raspfred1/Sentinel] 14:34:39 : LightSensor (Package 'LightSensor' version 3.0) is started with the PID 3182 (/opt/constellation-sentinel/Packages/LightSensor/LightSensor.exe)

[raspfred1/LightSensor] 14:34:43 : Package connected (Package:3.0 Constellation:1.8.3.17238)

[raspfred1/LightSensor] 14:34:43 : Declaring PackageDescriptor for LightSensor

[raspfred1/LightSensor] 14:34:43 : Waiting for settings ...

[raspfred1/LightSensor] 14:34:43 : Updating 0 setting(s)

[raspfred1/LightSensor] 14:34:44 : Loading the default value from the manifest for the setting 'Interval'

[raspfred1/LightSensor] 14:34:44 : Calling OnStart on Constellation.PythonProxy.PythonPackage

[raspfred1/LightSensor] 14:34:44 : Starting script '/opt/constellation-sentinel/Packages/LightSensor/Scripts/i2c_lib.py'

[raspfred1/LightSensor] 14:34:46 : '/opt/constellation-sentinel/Packages/LightSensor/Scripts/i2c_lib.py' is running

[raspfred1/LightSensor] 14:34:46 : Starting script '/opt/constellation-sentinel/Packages/LightSensor/Scripts/lcddriver.py'

[raspfred1/LightSensor] 14:34:48 : '/opt/constellation-sentinel/Packages/LightSensor/Scripts/lcddriver.py' is running

[raspfred1/LightSensor] 14:34:48 : Starting script '/opt/constellation-sentinel/Packages/LightSensor/Scripts/LightSensor.py'

[raspfred1/LightSensor] 14:34:51 : Error on receiving data from '/opt/constellation-sentinel/Packages/LightSensor/Scripts/i2c_lib.py' : System.ArgumentNullException: Value cannot be null.
Parameter name: returnLabel
  at System.Dynamic.DynamicMetaObjectBinder.Bind (System.Object[] args, System.Collections.ObjectModel.ReadOnlyCollection`1[T] parameters, System.Linq.Expressions.LabelTarget returnLabel) [0x00190] 
in <26aedeede9534b948c539f8734c8492d>:0 
  at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T] (System.Runtime.CompilerServices.CallSite`1[T] site, System.Object[] args) [0x00019] in <26aedeede9534b948c539f8734c8492d>:0 
  at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet] (System.Runtime.CompilerServices.CallSite site, T0 arg0) [0x000f1] in <26aedeede9534b948c539f8734c8492d>:0 
  at Constellation.PythonProxy.ScriptContext.<Start>b__25_7 () [0x001b3] in <0f1bff111d8942af8f6c1264dcf9e9e3>:0 

[raspfred1/LightSensor] 14:34:51 : '/opt/constellation-sentinel/Packages/LightSensor/Scripts/LightSensor.py' is running

[raspfred1/LightSensor] 14:34:51 : Librairie i2c_lib est chargée !

[raspfred1/LightSensor] 14:34:51 : Librairie i2c_lib est chargée !

#3

Bonjour Sébastien,

Peux tu me fournir ton aide s’il te plais?

Fréd


#4

Hello Fred,

Ton fichier “i2c_lib.py” est une librairie Python et non un scrpit Python Constellation, il ne doit donc pas être démarré par ton package, juste inclus car utilisé par lcddriver.py !

Ainsi vires la ligne 1 (import Constellation) et le deux dernière lignes (Constellation.WriteInfo et Start). De plus supprime-le de ton fichier App.config.

Comme ca dans le app.config, tu auras lcddriver.py et lightsensor.py qui seront référencés et donc démarrés par le package, ta librairie sera quant à ellle bien présente dans ton package pour être chargée par lcddriver.py.

Bien à toi


#5

Bonjour Sébastien,

J’ai ouvert à nouveau ma question sur l’import de bibliothèques dans un package Python.
Tout d’abord je te remercie de m’avoir répondu. Tu as fermer le sujet mais je n’ai pas résolu mon problème.
Tu m’indique:
"Hello Fred,

Ton fichier « i2c_lib.py » est une librairie Python et non un scrpit Python Constellation, il ne doit donc pas être démarré par ton package, juste inclus car utilisé par lcddriver.py !

Ainsi vires la ligne 1 (import Constellation) et le deux dernière lignes (Constellation.WriteInfo et Start). De plus supprime-le de ton fichier App.config.

Comme ca dans le app.config, tu auras lcddriver.py et lightsensor.py qui seront référencés et donc démarrés par le package, ta librairie sera quant à ellle bien présente dans ton package pour être chargée par lcddriver.py.

Bien à toi"

J’ai fais ce que tu m’as conseillé mais dans les log j’ai un message :
“[raspfred1/Detection_lumiere] 20:29:32 : Traceback (most recent call last):
[raspfred1/Detection_lumiere] 20:29:32 : File “/opt/constellation-sentinel/Packages/Detection_lumiere/Scripts/Detecteur_lumiere.py”, line 3, in
[raspfred1/Detection_lumiere] 20:29:32 : import lcddriver
[raspfred1/Detection_lumiere] 20:29:32 : ImportError: No module named lcddriver”

Dans mon prog Python j’ai inscrit l’appel de la bibliothèque lcddriver en ligne 3.
Les modules LCDdriver.py et i2c_lib.py sont dans la partie script de ma solution.
Je ne trouve pas où les mettre ailleur! Comment mettre les deux fichiers en référence, est ce que je dois ajouter des lignes dans le fichier app.config pour que lors de la compilation mes deux bibliothèques soient accessibles à mon programme? ou y a t’il une fonction dans VS2017 pour importer ces réference à bibliothèques?

Merci de me mettre sur le bon chemin, tu me trouves peut être nul avec mes questions mais je suis sur que d’autre n’ose pas te les poser et abandonne…
Moi j’insiste…hihi. et puis je sais que je suis nul, c’est un avantage.

Fred.
Au fait pour une autre question au sujet de linky, je veux bien te donner acces à mon compte utilisateur mais en MP, transfere moi ton lien MP dans ma boite mail.


#6

Bonjour,

Sujet à fermer.

Merci à Sébastien pour ton aide, il me manquait seulement dans ta réponse le choix “toujours copier” dans les propriétés du fichier bibliothèques.

Fred