简体   繁体   中英

python AttributeError: 'mHID' object has no attribute 'dict'

I am trying to make a makeblock mblock implementation with python and i found this api on github but it uses python 2.7 and i am using python 3.8 so i am trying to configure the code so it can run on python 3.8 but i ran into an error which is init mBot bot

<lib.mBot.mSerial object at 0x02CE9898>
start with serial


<lib.mBot.mHID object at 0x02E2B310>
self.device = mHID()


'mHID' object has no attribute 'dict'
Exception in thread Thread-2:
self.start()

Traceback (most recent call last):

File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 154, in __onRead
start with HID


--------------------

    n = self.device.inWaiting()
<lib.mBot.mBot object at 0x002FF640>
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 96, in inWaiting
--------------------

Error in sys.excepthook:
    buf = self.dict.device.read(64)
Traceback (most recent call last):
AttributeError: 'mHID' object has no attribute 'dict'
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 134, in excepthook

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
    self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
    self.device.close()
    self.run()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
    self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'

Original exception was:
Traceback (most recent call last):
File "c:/Users/abdsak11/OneDrive - Lärande/Dokument/GitHub/python-for-mbot/test.py", line 15, in <module>
    self._target(*self._args, **self._kwargs)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 163, in __onRead
    bot.doMove(50,50)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 179, in doMove
    self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
    self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x5]+self.short2bytes(-leftSpeed)+self.short2bytes(rightSpeed)))
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 278, in short2bytes
    self.device.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
    return [ord(val[0]),ord(val[1])]
TypeError: ord() expected string of length 1, but int found
    self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'
'mHID' object has no attribute 'dict'
Exception in thread Thread-1:
Traceback (most recent call last):
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 154, in __onRead
    n = self.device.inWaiting()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 96, in inWaiting
    buf = self.dict.device.read(64)
AttributeError: 'mHID' object has no attribute 'dict'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
    self.run()
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 163, in __onRead
    self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
    self.device.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
    self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'

So what i am trying to do is to control and upload code to my mbot via usb COM3 serial and thats the error that i am getting i tried everthing but its not working and i cant seem to figure out the cause of the error.

mbot.py

this is the main api that i found

import serial
import sys,time
import signal
from time import ctime,sleep
import glob,struct
from multiprocessing import Process,Manager,Array
import threading
import hid

class mSerial():
    ser = None
    def __init__(self):
        print (self)

    def start(self, port):
        self.ser = serial.Serial(port,115200)

    def device(self):
        return self.ser

    def serialPorts(self):
        if sys.platform.startswith('win'):
            ports = ['COM%s' % (i + 1) for i in range(256)]
        elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
            ports = glob.glob('/dev/tty[A-Za-z]*')
        elif sys.platform.startswith('darwin'):
            ports = glob.glob('/dev/tty.*')
        else:
            raise EnvironmentError('Unsupported platform')
        result = []
        for port in ports:
            s = serial.Serial()
            s.port = port
            s.close()
            result.append(port)
        return result

    def writePackage(self,package):
        self.ser.write(package)
        sleep(0.01)

    def read(self):
        return self.ser.read()

    def isOpen(self):
        return self.ser.isOpen()

    def inWaiting(self):
        return self.ser.inWaiting()

    def close(self):
        self.ser.close()

class mHID():
    def __init__(self):
        print (self)

    def start(self):
        print ("starting start \n\n")
        self.manager = Manager()
        print("manager pass \n\n")
        self.dict = self.manager.dict()
        print("dict pass \n\n")
        self.dict.device = hid.device()
        print("dict device pass \n\n")
        self.dict.device.open(0x0416, 0xffff)
        print("dict device open pass \n\n")
        self.dict.device.hid_set_nonblocking(self.device,1)
        print ("start")
        self.buffer = []
        self.bufferIndex = 0

    def enumerate(self):
        print ("enumerate")
        for dev in self.dict.device.enumerate():
            print ('------------------------------------------------------------')
            print (dev.description())

    def writePackage(self,package):
        buf = []
        buf += [0, len(package)]
        for i in range(len(package)):
            buf += [package[i]]
        n = self.dict.device.write(buf)
        sleep(0.01)

    def read(self):
        c = self.buffer[0]
        self.buffer = self.buffer[1:]
        return chr(c)

    def isOpen(self):
        return True

    def inWaiting(self):
        buf = self.dict.device.read(64)
        l = 0
        if len(buf)>0:
            l = buf[0]
        if l>0:
            for i in range(0,l):
                self.buffer += [buf[i+1]]
        return len(self.buffer)

    def close(self):
        self.dict.device.close()

class mBot():
    def __init__(self):
        print ("init mBot")
        signal.signal(signal.SIGINT, self.exit)
        self.manager = Manager()
        self.__selectors = self.manager.dict()
        self.buffer = []
        self.bufferIndex = 0
        self.isParseStart = False
        self.exiting = False
        self.isParseStartIndex = 0

    def startWithSerial(self, port):
        self.device = mSerial()
        self.device.start(port)
        self.start()

    def startWithHID(self):
        self.device = mHID()
        print ("self.device = mHID()\n \n")
        self.device.start()
        print ("self.device.start()\n \n")
        self.start()
        print ("self.start()\n \n")

    def excepthook(self, exctype, value, traceback):
        self.close()

    def start(self):
        sys.excepthook = self.excepthook
        th = threading.Thread(target=self.__onRead,args=(self.onParse,))
        th.start()

    def close(self):
        self.device.close()

    def exit(self, signal, frame):
        self.exiting = True
        sys.exit(0)

    def __onRead(self,callback):
        while 1:
            if(self.exiting==True):
                break
            try:    
                if self.device.isOpen()==True:
                    n = self.device.inWaiting()
                    for i in range(n):
                        r = ord(self.device.read())
                        callback(r)
                    sleep(0.01)
                else:   
                    sleep(0.5)
            except Exception as ex:
                print (str(ex))
                self.close()
                sleep(1)

    def __writePackage(self,pack):
        self.device.writePackage(pack)

    def doRGBLed(self,port,slot,index,red,green,blue):
        self.__writePackage(bytearray([0xff,0x55,0x9,0x0,0x2,0x8,port,slot,index,red,green,blue]))

    def doRGBLedOnBoard(self,index,red,green,blue):
        self.doRGBLed(0x7,0x2,index,red,green,blue)

    def doMotor(self,port,speed):
        self.__writePackage(bytearray([0xff,0x55,0x6,0x0,0x2,0xa,port]+self.short2bytes(speed)))

    def doMove(self,leftSpeed,rightSpeed):
        self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x5]+self.short2bytes(-leftSpeed)+self.short2bytes(rightSpeed)))

    def doServo(self,port,slot,angle):
        self.__writePackage(bytearray([0xff,0x55,0x6,0x0,0x2,0xb,port,slot,angle]))

    def doBuzzer(self,buzzer,time=0):
        self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x22]+self.short2bytes(buzzer)+self.short2bytes(time)))

    def doSevSegDisplay(self,port,display):
        self.__writePackage(bytearray([0xff,0x55,0x8,0x0,0x2,0x9,port]+self.float2bytes(display)))

    def doIROnBoard(self,message):
        self.__writePackage(bytearray([0xff,0x55,len(message)+3,0x0,0x2,0xd,message]))

    def requestLightOnBoard(self,extID,callback):
        self.requestLight(extID,8,callback)

    def requestLight(self,extID,port,callback):
        self.__doCallback(extID,callback)
        self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x3,port]))

    def requestButtonOnBoard(self,extID,callback):
        self.__doCallback(extID,callback)
        self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x1f,0x7]))

    def requestIROnBoard(self,extID,callback):
        self.__doCallback(extID,callback)
        self.__writePackage(bytearray([0xff,0x55,0x3,extID,0x1,0xd]))

    def requestUltrasonicSensor(self,extID,port,callback):
        self.__doCallback(extID,callback)
        self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x1,port]))

    def requestLineFollower(self,extID,port,callback):
        self.__doCallback(extID,callback)
        self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x11,port]))

    def onParse(self, byte):
        position = 0
        value = 0   
        self.buffer+=[byte]
        bufferLength = len(self.buffer)
        if bufferLength >= 2:
            if (self.buffer[bufferLength-1]==0x55 and self.buffer[bufferLength-2]==0xff):
                self.isParseStart = True
                self.isParseStartIndex = bufferLength-2 
            if (self.buffer[bufferLength-1]==0xa and self.buffer[bufferLength-2]==0xd and self.isParseStart==True):         
                self.isParseStart = False
                position = self.isParseStartIndex+2
                extID = self.buffer[position]
                position+=1
                type = self.buffer[position]
                position+=1
                # 1 byte 2 float 3 short 4 len+string 5 double
                if type == 1:
                    value = self.buffer[position]
                if type == 2:
                    value = self.readFloat(position)
                    if(value<-255 or value>1023):
                        value = 0
                if type == 3:
                    value = self.readShort(position)
                if type == 4:
                    value = self.readString(position)
                if type == 5:
                    value = self.readDouble(position)
                if(type<=5):
                    self.responseValue(extID,value)
                self.buffer = []

    def readFloat(self, position):
        v = [self.buffer[position], self.buffer[position+1],self.buffer[position+2],self.buffer[position+3]]
        return struct.unpack('<f', struct.pack('4B', *v))[0]
    def readShort(self, position):
        v = [self.buffer[position], self.buffer[position+1]]
        return struct.unpack('<h', struct.pack('2B', *v))[0]
    def readString(self, position):
        l = self.buffer[position]
        position+=1
        s = ""
        for i in Range(l):
            s += self.buffer[position+i].charAt(0)
        return s
    def readDouble(self, position):
        v = [self.buffer[position], self.buffer[position+1],self.buffer[position+2],self.buffer[position+3]]
        return struct.unpack('<f', struct.pack('4B', *v))[0]

    def responseValue(self, extID, value):
        self.__selectors["callback_"+str(extID)](value)

    def __doCallback(self, extID, callback):
        self.__selectors["callback_"+str(extID)] = callback

    def float2bytes(self,fval):
        val = struct.pack("f",fval)
        return [ord(val[0]),ord(val[1]),ord(val[2]),ord(val[3])]

    def short2bytes(self,sval):
        val = struct.pack("h",sval)
        return [ord(val[0]),ord(val[1])]

test.py

this is the test file that i am working with

from lib.mBot import *

if __name__ == "__main__":
    bot = mBot()
    print ("bot \n\n")
    bot.startWithSerial("COM3")
    print ("start with serial\n\n")
    bot.startWithHID()
    print ("start with HID \n\n")

    print(f'--------------------\n')
    print (bot)
    print(f'--------------------\n')

    bot.doMove(50,50)

I believe your trouble is here:

class mHID():
    def __init__(self):
        print (self)

    def start(self):
        # ...
        self.dict = self.manager.dict()
        # ...

    def close(self):
        self.dict.device.close()

You should always define your instance attributes in __init__() , at least with an initial value of None , even if you plan to change them later.

Additionally, whenever you have a situation where " A must be called before B ", you should write the code to properly handle when B is called without A . In this case, what should close() do if start() was never called? For simplicity, I'm just having it do nothing, but you may consider raising an exception.

class mHID():
    def __init__(self):
        print (self)
        self.dct = None

    def start(self):
        # ...
        self.dct = self.manager.dict()
        # ...

    def close(self):
        if self.dct:
            self.dct.device.close()

You'll notice I also renamed self.dict to self.dct . Although the former name may technically be allowable because of the self. namespace, dict is actually a built-in class. Under various circumstances, you could wind up dealing with shadowing. In the very least, it's confusing to always have to remind oneself that "this isn't the built-in dict , but an instance variable instead.

(Possible aside: is there a particular reason why you don't want to call start() from the initializer?)

WARNING: This is not a simple case of "copy and paste the answer". I've illustrated a couple of design principles here that you should incorporate into the rest of your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM