Пример #1
0
 def __init__(self):
     # a dictionary associating all physical attached Phidget channels
     # to their availablility state:
     #    True: available for attach to a software channel
     #    False: occupied and connected to a software channel
     # access to this dict is protected by the managersemaphore and
     # should happen only via the methods addChannel and deleteChannel
     self.attachedPhidgetChannels = {}
     self.managersemaphore = QSemaphore(1)
     self.manager = Manager()
     self.manager.setOnAttachHandler(self.attachHandler)
     self.manager.setOnDetachHandler(self.detachHandler)
     self.manager.open()
Пример #2
0
class PhidgetManager():

    def __init__(self):
        # a dictionary associating all physical attached Phidget channels
        # to their availablility state:
        #    True: available for attach to a software channel
        #    False: occupied and connected to a software channel
        # access to this dict is protected by the managersemaphore and
        # should happen only via the methods addChannel and deleteChannel
        self.attachedPhidgetChannels = {}
        self.managersemaphore = QSemaphore(1)
        self.manager = Manager()
        self.manager.setOnAttachHandler(self.attachHandler)
        self.manager.setOnDetachHandler(self.detachHandler)
        self.manager.open()
        
    def close(self):
        self.manager.close()
        self.attachedPhidgetChannels.clear()
        
    def attachHandler(self,_,attachedChannel):
        try:
            if attachedChannel.getParent().getDeviceClass() != DeviceClass.PHIDCLASS_HUB:
                # we do not add the hub itself
                self.addChannel(attachedChannel)
        except:
            pass
    
    def detachHandler(self,_,attachedChannel):
        try:
            self.deleteChannel(attachedChannel)
        except:
            pass
    
    def addChannel(self,channel):
        try:
            self.managersemaphore.acquire(1)
            state = True
            try:
                # reserve all channels with the same hubport on the same hub
                hub = channel.getHub()
                hubport = channel.getHubPort()
                hupportdevice = bool(channel.getIsHubPortDevice() == 0) # it is not a direct hubport channel
                for k, _ in self.attachedPhidgetChannels.items():
                    try:
                        khub = k.getHub()
                        khubport = k.getHubPort()
                        if khub == hub and khubport == hubport:
                            if hupportdevice:
                                if k.getIsHubPortDevice() != 0:
                                    self.attachedPhidgetChannels[k] = False
                                #else:
                                #  other is also a VINT device. Do nothing
                            else:
                                if k.getIsHubPortDevice() == 0:
                                    # there is a port registered with connected VINT device we deactivate this hubport channel
                                    state = False
                                #else:
                                #   do nothing
                    except:
                        pass
            except:
                pass
            self.attachedPhidgetChannels[channel] = state
        except Exception:
            pass
        finally:
            if self.managersemaphore.available() < 1:
                self.managersemaphore.release(1)

    def deleteChannel(self,channel):
        try:
            self.managersemaphore.acquire(1)
            # if channel is a VINT device, release all HUBport channels that were blocked by this VINT device
            try:
                hub = channel.getHub()
                hubport = channel.getHubPort()
                hupportdevice = bool(channel.getIsHubPortDevice() == 0) # it is not a direct hubport channel
                if hupportdevice:
                    for k, _ in self.attachedPhidgetChannels.items():
                        if k != channel:
                            try:
                                khub = k.getHub()
                                khubport = k.getHubPort()
                                if khub == hub and khubport == hubport:                                    
                                    self.attachedPhidgetChannels[k] = True
                            except:
                                pass
            except:
                pass
            self.attachedPhidgetChannels.pop(channel, None)
        except Exception:
            pass
        finally:
            if self.managersemaphore.available() < 1:
                self.managersemaphore.release(1)
                
    def getChannel(self,serial,port,channel,phidget_class_name,device_id,remote,remoteOnly):
        try:
            self.managersemaphore.acquire(1)
            if device_id in [DeviceID.PHIDID_HUB0000]:
                # we are looking for HUB ports
                hub = 1
            else:
                hub = 0
            for k, _ in self.attachedPhidgetChannels.items():
                if k.getIsHubPortDevice() or k.getDeviceClass() == DeviceClass.PHIDCLASS_VINT:
                    kport = k.getHubPort()
                else:
                    kport = None
                if k.getDeviceSerialNumber() == serial and (port is None or kport == port) and \
                    (hub or (k.getDeviceID() == device_id)) and \
                    ((remote and not remoteOnly) or (not remote and k.getIsLocal()) or (remote and remoteOnly and not k.getIsLocal())) and \
                    k.getChannelClassName() == phidget_class_name and \
                    k.getChannel() == channel:
                    return k
            return None
        except Exception:
            return None
        finally:
            if self.managersemaphore.available() < 1:
                self.managersemaphore.release(1)
                
    def reserveSerialPort(self,serial,port,channel,phidget_class_name,device_id,remote=False,remoteOnly=False):
        chnl = self.getChannel(serial,port,channel,phidget_class_name,device_id,remote,remoteOnly)
        self.reserveChannel(chnl)
        
    def releaseSerialPort(self,serial,port,channel,phidget_class_name,device_id,remote=False,remoteOnly=False):
        chnl = self.getChannel(serial,port,channel,phidget_class_name,device_id,remote,remoteOnly)
        self.releaseChannel(chnl)

    # should be called from the attach handler that binds this hardware channel to a software channel
    def reserveChannel(self,channel):
        try:
            self.managersemaphore.acquire(1)
            if channel is not None and channel in self.attachedPhidgetChannels:
                self.attachedPhidgetChannels[channel] = False
                if channel.getIsHubPortDevice():
                    hub = channel.getHub()
                    port = channel.getHubPort()
                    # reserve also all other channels with that hub/port combination
                    for k, _ in self.attachedPhidgetChannels.items():
                        try:
                            if k.getHub() == hub and k.getHubPort() == port:
                                self.attachedPhidgetChannels[k] = False
                        except:
                            pass
                #else:
                #  not a HUB port
        except Exception:
            pass
        finally:
            if self.managersemaphore.available() < 1:
                self.managersemaphore.release(1)

    # should be called from the detach handler that releases this hardware channel fron a software channel
    def releaseChannel(self,channel):
        try:
            self.managersemaphore.acquire(1)
            if channel is not None and channel in self.attachedPhidgetChannels:
                self.attachedPhidgetChannels[channel] = True
                if channel.getIsHubPortDevice():
                    hub = channel.getHub()
                    port = channel.getHubPort()
                    # enable also all other channels with that hub/port combination
                    for k, _ in self.attachedPhidgetChannels.items():
                        try:
                            if k.getHub() == hub and k.getHubPort() == port:
                                self.attachedPhidgetChannels[k] = True
                        except:
                            pass                
        except Exception:
            pass
        finally:
            if self.managersemaphore.available() < 1:
                self.managersemaphore.release(1)
                
#    def print_list(self,items):
#        for k,v in items:
#            print(v,k.getDeviceSerialNumber(),k.getDeviceClass(),k.getDeviceClassName(),k.getDeviceName(),k.getDeviceSKU(),k.getChannelClassName(),k.getDeviceID(),k.getIsHubPortDevice(),"port: ",k.getHubPort(),"ch: ", k.getChannel(), "local: ", k.getIsLocal())
#
#    def print_list2(self,items):
#        for k in items:
#            print(k.getDeviceSerialNumber(),k.getChannelClassName(),k.getDeviceID(),k.getIsHubPortDevice(),"port: ", k.getHubPort(),"ch: ",k.getChannel(), "local: ", k.getIsLocal())

    # returns the first matching Phidget channel and reserves it
    def getFirstMatchingPhidget(self,phidget_class_name,device_id,channel=None,remote=False,remoteOnly=False):
        try:
            self.managersemaphore.acquire(1)
            if device_id in [
                    DeviceID.PHIDID_HUB0000,
                    DeviceID.PHIDID_DIGITALINPUT_PORT,
                    DeviceID.PHIDID_DIGITALOUTPUT_PORT,
                    DeviceID.PHIDID_VOLTAGEINPUT_PORT,
                    DeviceID.PHIDID_VOLTAGERATIOINPUT_PORT]:
                # we are looking for HUB ports
                hub = 1
            else:
                hub = 0

#            self.print_list(self.attachedPhidgetChannels.items())

            # get list of all matching phidget channels
            matching_channels = [k for k, v in self.attachedPhidgetChannels.items() if v and \
                (hub or (k.getDeviceID() == device_id)) and \
                ((remote and not remoteOnly) or (not remote and k.getIsLocal()) or (remote and remoteOnly and not k.getIsLocal())) and \
                k.getChannelClassName() == phidget_class_name and \
                (channel is None or (not hub and channel == k.getChannel()) or (hub and k.getIsHubPortDevice() and k.getHubPort() == channel))]

#            self.print_list2(matching_channels)

            # sort by serial number (local first)
            matching_channels.sort(key=lambda x:x.getDeviceSerialNumber())
            # return smallest / first item
            if len(matching_channels) > 0:
                p = matching_channels[0]
                if p.getIsHubPortDevice() or p.getDeviceClass() == DeviceClass.PHIDCLASS_VINT:
                    port = p.getHubPort()
                else:
                    port = None
                return p.getDeviceSerialNumber(), port
            else:
                return None, None
        except Exception:
            return None, None
        finally:
            if self.managersemaphore.available() < 1:
                self.managersemaphore.release(1)