Python Forum

Full Version: ByteArray outside while true
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,

I have got a question.
I'm trying to define a bytearray outside an While: True loop

while True:
    byte = bytearray(57) # Dataarray
This works fine, but then I'm losing every cycle the values.

byte = bytearray(57) # Dataarray

while True:
This only survives the first cycle, second cycle program goes in error
Error:
_bytearray[byte_index:2] = _bytes TypeError: 'NoneType' object does not support item assignment
I've expected the next program to work, but is have the same result.
byte = bytearray(57) # Dataarray

while True:
    global byte
Thanks for a reply
post your full code in code tags (minimal runnable example, that reproduce the error)
I've tried to make an example code to reproduce the failure

import datetime
import struct
from time import sleep

def set_real(_bytearray, byte_index, real):
    """
    Set Real value

    make 4 byte data from real

    """
    real = float(real)
    real = struct.pack('>f', real)
    _bytes = struct.unpack('4B', real)
    for i, b in enumerate(_bytes):
        _bytearray[byte_index + i] = b

def get_real(_bytearray, byte_index):
    """
    Get real value. create float from 4 bytes
    """
    x = _bytearray[byte_index:byte_index + 4]
    real = struct.unpack('>f', struct.pack('4B', *x))[0]
    return real

byte = bytearray(70) # Dataarray

while True:
    x = int(datetime.datetime.now().strftime("%S"))
    byte[x] = int(datetime.datetime.now().strftime("%S"))
    print byte[x]
    print byte[x-1] # read a different byte test if value still in memory
    
    value = 0.3333
    set_real(byte, 65, value)

    print get_real(byte , 65)
    sleep(0.5)
But this example doesn't give the failure, so it's something else I think.

My code for the program I give in the next part. But I think it is difficult to test it for others because it reading out my smart power supply meter and sending the value's to a Siemens PLC with a library called Snap7, the functions like set_real are in the libary. I'n the example above there is a part of the source for the set_real function.

# DSMR v4.2 p1 uitlezen
# (c) 10-2012 - 2016 GJ - gratis te kopieren en te plakken
versie = "1.1"
import sys
import serial
import snap7
from snap7.util import *
import struct

##############################################################################
#Main program
##############################################################################

#Set COM port config
ser = serial.Serial()
ser.baudrate = 115200
ser.bytesize=serial.EIGHTBITS
ser.parity=serial.PARITY_NONE
ser.stopbits=serial.STOPBITS_ONE
ser.xonxoff=0
ser.rtscts=0
ser.timeout=50
ser.port="/dev/ttyUSB0"

#Set plc
plc = snap7.client.Client()
byte = bytearray(57) # Dataarray

while True:
    #byte = bytearray(57) # Dataarray
    #Open PLC connection
    try:
            plc.connect("192.168.178.100",0,2)
            #print "Connected to PLC"
    except:
            error.error("Connection PLC lost")
            pass
    
    #Open COM port
    try:
        ser.open()
    except:
        sys.exit ("Fout bij het openen van %s. Aaaaarch."  % ser.name)      

    #Initialize
    #p1_teller is mijn tellertje voor van 0 tot 38 te tellen
    p1_teller=0

    while p1_teller < 38:
        p1_line=''
    #Read 1 line van de seriele poort
        try:
            p1_raw = ser.readline()
        except:
            sys.exit ("Seriele poort %s kan niet gelezen worden. Aaaaaaaaarch." % ser.name )      
        p1_str=str(p1_raw)
        p1_line=p1_str.strip()

        if p1_line[0:9] == "1-0:1.8.1":
                set_real(byte, 0, float(p1_line[10:20]))
                print "daldag                ", float(p1_line[10:20]), " kWh"
                       
        elif p1_line[0:9] == "1-0:1.8.2":
                set_real(byte, 4, float(p1_line[10:20]))
                print "piekdag               ", float(p1_line[10:20]), " kWh"
                        
        elif p1_line[0:9] == "1-0:2.8.1":
                set_real(byte, 8, float(p1_line[10:20]))
                print "dalterug              ", float(p1_line[10:20]), " kWh"
            
        elif p1_line[0:9] == "1-0:2.8.2":
               set_real(byte, 12, float(p1_line[10:20]))
               print "piekterug             ", float(p1_line[10:20]), " kWh"
                      
        elif p1_line[0:11] == "0-0:96.14.0":
                set_int(byte, 16, int(p1_line[15:16]))
                if int(p1_line[15:16]) == 1:
                    print "Piek/Dal Tarief:       Dal"
                elif int(p1_line[15:16]) == 2:
                    print "Piek/Dal Tarief:       Piek" 

        elif p1_line[0:9] == "1-0:1.7.0":
                set_int(byte, 18, int(float(p1_line[10:16])*1000))
                print "Act. vermogen         ", int(float(p1_line[10:16])*1000), " W"
            

        elif p1_line[0:9] == "1-0:2.7.0":
                set_int(byte, 20, int(float(p1_line[10:16])*1000))
                print "Act. vermogen terug   ", int(float(p1_line[10:16])*1000), " W"
            

        elif p1_line[0:10] == "1-0:32.7.0":
                set_real(byte, 22, float(p1_line[11:16]))
                print "Voltage L1            ", float(p1_line[11:16]), "V"
                                                  
        elif p1_line[0:10] == "1-0:52.7.0":
                set_real(byte, 26, float(p1_line[11:16]))
                print "Voltage L2            ", float(p1_line[11:16]), "V"
                                                  
        elif p1_line[0:10] == "1-0:72.7.0":
                set_real(byte, 30, float(p1_line[11:16]))
                print "Voltage L3            ", float(p1_line[11:16]), "V"
                                                  
        elif p1_line[0:10] == "1-0:31.7.0":
                set_int(byte, 34, int(p1_line[11:14]))
                print "Current L1            ", int(p1_line[11:14]), "A"

        elif p1_line[0:10] == "1-0:51.7.0":
                set_int(byte, 36, int(p1_line[11:14]))
                print "Current L2            ", int(p1_line[11:14]), "A"

        elif p1_line[0:10] == "1-0:71.7.0":
                set_int(byte, 38, int(p1_line[11:14]))
                print "Current L3            ", int(p1_line[11:14]), "A"
        
        elif p1_line[0:10] == "1-0:21.7.0":
                set_int(byte, 40, int(float(p1_line[11:17])*1000))
                print "Power L1              ", int(float(p1_line[11:17])*1000), " W"
            
        elif p1_line[0:10] == "1-0:41.7.0":
                set_int(byte, 42, int(float(p1_line[11:17])*1000))
                print "Power L2              ", int(float(p1_line[11:17])*1000), " W"
            
        elif p1_line[0:10] == "1-0:61.7.0":
                set_int(byte, 44, int(float(p1_line[11:17])*1000))
                print "Power L3              ", int(float(p1_line[11:17])*1000), " W"
            
        elif p1_line[0:10] == "1-0:22.7.0":#(00.000*kW)
                set_int(byte, 46, int(float(p1_line[11:17])*1000))
                print "Geleverd vermogen L1: ", int(float(p1_line[11:17])*1000), " W"
            
        elif p1_line[0:10] == "1-0:42.7.0":#(00.000*kW)
                set_int(byte, 48, int(float(p1_line[11:17])*1000))
                print "Geleverd vermogen L2: ", int(float(p1_line[11:17])*1000), " W"
            
        elif p1_line[0:10] == "1-0:62.7.0":#(00.000*kW)
                set_int(byte, 50, int(float(p1_line[11:17])*1000))
                print "Geleverd vermogen L3: ", int(float(p1_line[11:17])*1000), " W"
            
        elif p1_line[0:10] == "0-1:24.2.1":#(180216191004W)(00000.004*m3)
                set_real(byte, 52, float(p1_line[26:35]))
                print "Gasstand:             ", float(p1_line[26:35]), " m3"
   
        p1_teller = p1_teller +1

    #Close port and show status
    try:
        ser.close()
    except:
        sys.exit ("Oops %s. Programma afgebroken. Kon de seriele poort niet sluiten." % ser.name )

    #Send Data to PLC
    #set_int(byte, 56, 1) #Set value 1 in byte 56, to PLC as mark new data recieved
    byte[56] = 1 #Set value 1 in byte 56, to PLC as mark new data recieved
    byte = plc.db_write(11, 600, byte)
    plc.disconnect()
The Error is the next
Error:
Traceback (most recent call last): File "/home/pi/Projects/Slimme Meter uitlezen/test4.py", line 64, in <module> set_real(byte, 4, float(p1_line[10:20])) File "/usr/local/lib/python2.7/dist-packages/snap7/util.py", line 163, in set_real _bytearray[byte_index + i] = b TypeError: 'NoneType' object does not support item assignment
not 100% sure but I believe the problem is line 155. I would guess Client (pls) db_write() method returns None, so this error would pop-up only after first time you execute line155
Thanks that was it!
I was searching completly wrong!
Silly mistake!
If I were you, now I would look for ways to refactor this long if/elif block, using dict