def run(self): global ipcon isexception = False try: ipcon = IPConnection() if ipcon.get_connection_state( ) != IPConnection.CONNECTION_STATE_CONNECTED: ipcon.connect("localhost", 4223) ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, cb_enumerate) ipcon.time_out = 0.5 ipcon.enumerate() time.sleep(0.3) except: logging.debug("Tinkerforge:failed connecting to IP Connection") pass
class MainWindow(QMainWindow, Ui_MainWindow): qtcb_ipcon_enumerate = pyqtSignal(str, str, 'char', type((0, )), type( (0, )), int, int) qtcb_ipcon_connected = pyqtSignal(int) qtcb_high_contrast_image = pyqtSignal(object) image_pixel_width = 1 crosshair_width = 1 def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setupUi(self) self.setWindowTitle( 'Tinkerforge CES Demo: Thermal Imaging Bricklet by FLIR') self.qtcb_ipcon_enumerate.connect(self.cb_ipcon_enumerate) self.qtcb_ipcon_connected.connect(self.cb_ipcon_connected) self.qtcb_high_contrast_image.connect(self.cb_high_contrast_image) self.image = QImage(QSize(80, 60), QImage.Format_RGB32) # Add Tinkerforge logo # Adapt this path self.label_logo.setPixmap( QPixmap('/home/pi/Desktop/demo/logo_klein.png')) # create and setup ipcon self.ipcon = IPConnection() self.ipcon.connect(HOST, PORT) self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.qtcb_ipcon_enumerate.emit) self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, self.qtcb_ipcon_connected.emit) self.ti = BrickletThermalImaging(UID_TI, self.ipcon) self.ti.register_callback(self.ti.CALLBACK_HIGH_CONTRAST_IMAGE, self.qtcb_high_contrast_image.emit) self.ti.set_image_transfer_config( self.ti.IMAGE_TRANSFER_CALLBACK_HIGH_CONTRAST_IMAGE) self.ti.set_spotmeter_config([35, 25, 45, 35]) #print(ti.get_spotmeter_config()) al = BrickletAmbientLightV2(UID_AL, self.ipcon) al.register_callback(al.CALLBACK_ILLUMINANCE, self.cb_illuminance) al.set_illuminance_callback_period(500) hu = BrickletHumidityV2(UID_HU, self.ipcon) hu.register_callback(hu.CALLBACK_HUMIDITY, self.cb_humidity) hu.set_humidity_callback_configuration(500, False, "x", 0, 0) bm = BrickletBarometer(UID_BM, self.ipcon) bm.register_callback(bm.CALLBACK_AIR_PRESSURE, self.cb_air_pressure) bm.set_air_pressure_callback_period(500) self.rgb_lookup = [] for x in range(256): x /= 255.0 r = int(round(255 * math.sqrt(x))) g = int(round(255 * pow(x, 3))) if math.sin(2 * math.pi * x) >= 0: b = int(round(255 * math.sin(2 * math.pi * x))) else: b = 0 self.rgb_lookup.append((r, g, b)) def paintEvent(event): painter = QPainter(self.label_image) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) w = self.label_image.size().width() h = self.label_image.size().height() painter.scale(w / 80.0, h / 60.0) painter.drawImage(0, 0, self.image) if 35 != None and 45 != None: pen = QPen() pen.setColor(Qt.white) pen.setWidth(0.2) painter.setPen(pen) from_x, from_y, to_x, to_y = [35, 25, 45, 35] from_x = from_x * self.image_pixel_width + 1 from_y = from_y * self.image_pixel_width + 1 to_x = to_x * self.image_pixel_width + 1 to_y = to_y * self.image_pixel_width + 1 cross_x = from_x + (to_x - from_x) / 2.0 cross_y = from_y + (to_y - from_y) / 2.0 if to_x - from_x > 5 or to_y - from_y > 5: lines = [ QLine(from_x, from_y, from_x + self.crosshair_width, from_y), QLine(from_x, from_y, from_x, from_y + self.crosshair_width), QLine(to_x, to_y, to_x, to_y - self.crosshair_width), QLine(to_x, to_y, to_x - self.crosshair_width, to_y), QLine(from_x, to_y, from_x, to_y - self.crosshair_width), QLine(from_x, to_y, from_x + self.crosshair_width, to_y), QLine(to_x, from_y, to_x, from_y + self.crosshair_width), QLine(to_x, from_y, to_x - self.crosshair_width, from_y) ] painter.drawLines(lines) lines = [ QLine(cross_x - self.crosshair_width, cross_y, cross_x + self.crosshair_width, cross_y), QLine(cross_x, cross_y - self.crosshair_width, cross_x, cross_y + self.crosshair_width) ] painter.drawLines(lines) self.update_spotmeter_roi_label() self.label_image.paintEvent = paintEvent def update_spotmeter_roi_label(self): from_x, from_y, to_x, to_y = self.ti.get_spotmeter_config() self.spotmeter_roi_label.setText( 'from <b>[{0}, {1}]</b> to <b>[{2}, {3}]</b>'.format( from_x, from_y, to_x, to_y)) def cb_ipcon_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): if self.ipcon.get_connection_state( ) != IPConnection.CONNECTION_STATE_CONNECTED: # ignore enumerate callbacks that arrived after the connection got closed return def cb_ipcon_connected(self, connect_reason): try: self.ipcon.enumerate() except: pass def cb_high_contrast_image(self, image): if image != None: self.new_image(image) print("New image") self.statistics(self.ti.get_statistics()) def statistics(self, data): self.valid_resolution = data.resolution spot_mean = self.kelvin_to_degstr(data.spotmeter_statistics[0]) spot_max = self.kelvin_to_degstr(data.spotmeter_statistics[1]) spot_min = self.kelvin_to_degstr(data.spotmeter_statistics[2]) spot_pix = str(data.spotmeter_statistics[3]) self.spotmeter_mean_label.setText(spot_mean) self.spotmeter_minimum_label.setText(spot_min) self.spotmeter_maximum_label.setText(spot_max) self.spotmeter_pixel_count_label.setText(spot_pix) #temp_fpa = self.kelvin_to_degstr(data.temperatures[0], 1) #temp_fpa_ffc = self.kelvin_to_degstr(data.temperatures[1], 1) #temp_housing = self.kelvin_to_degstr(data.temperatures[2], 1) #temp_housing_ffc = self.kelvin_to_degstr(data.temperatures[3], 1) #self.temp_fpa_label.setText(temp_fpa) #self.temp_fpa_ffc_label.setText(temp_fpa_ffc) #self.temp_housing_label.setText(temp_housing) #self.temp_housing_ffc_label.setText(temp_housing_ffc) #sheet_green = "QLabel { color: green; }" #sheet_orange = "QLabel { color: orange; }" #sheet_red = "QLabel { color: red; }" #if data.ffc_status == 0b00: # self.ffc_state_label.setStyleSheet(sheet_orange) # self.ffc_state_label.setText('Never Commanded') #elif data.ffc_status == 0b01: # self.ffc_state_label.setStyleSheet(sheet_orange) # self.ffc_state_label.setText('Imminent') #elif data.ffc_status == 0b10: # self.ffc_state_label.setStyleSheet(sheet_orange) # self.ffc_state_label.setText('In Progress') #elif data.ffc_status == 0b11: # self.ffc_state_label.setStyleSheet(sheet_green) # self.ffc_state_label.setText('Complete') #if data.temperature_warning[0]: # self.shutter_lockout_label.setStyleSheet(sheet_red) # self.shutter_lockout_label.setText('Yes') #else: # self.shutter_lockout_label.setStyleSheet(sheet_green) # self.shutter_lockout_label.setText('No') #if data.temperature_warning[1]: # self.overtemp_label.setStyleSheet(sheet_red) # self.overtemp_label.setText('Yes') #else: # self.overtemp_label.setStyleSheet(sheet_green) # self.overtemp_label.setText('No') def cb_humidity(self, humidity): #print("Humidity: " + str(humidity/100.0) + " %RH") self.label_humidity.setText(str(humidity / 100) + " %RH") def cb_illuminance(self, illuminance): #print("Illuminance: " + str(illuminance/100.0) + " Lux") self.label_brightness.setText(str(illuminance / 100) + " Lux") def cb_air_pressure(self, air_pressure): #print("Air Pressure: " + str(air_pressure/1000.0) + " mbar") self.label_airpressure.setText(str(air_pressure / 1000) + " mbar") def new_image(self, image): for i, value in enumerate(image): r, g, b = self.rgb_lookup[value] self.image.setPixel(QPoint(i % 80, i // 80), (r << 16) | (g << 8) | b) self.label_image.update() #self.label_image.setPixmap(QPixmap(self.image)) def kelvin_to_degstr(self, value, res=None): if res == None: res = self.valid_resolution if res == 0: return "{0:.2f}".format(value / 10.0 - 273.15) else: return "{0:.2f}".format(value / 100.0 - 273.15)
class ClimateSensors: def __init__(self, host, port): self.hum = None self.hum_value = 0.0 self.temp = None self.temp_value = 0.0 self.lcd = None self.port = port self.host = host self.conn = IPConnection() self.conn.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate) self.conn.register_callback(IPConnection.CALLBACK_CONNECTED, self.cb_connected) def update_display(self): if self.lcd is not None: self.lcd.write_line(1, 2, 'Temp: {:3.2f} C'.format(self.temp_value)) self.lcd.write_line(2, 2, 'RelHum: {:3.2f} %'.format(self.hum_value)) def connect(self): if self.conn.get_connection_state() == self.conn.CONNECTION_STATE_DISCONNECTED: self.conn.connect(self.host, self.port) self.conn.enumerate() def disconnect(self): if self.conn.get_connection_state() != self.conn.CONNECTION_STATE_DISCONNECTED: if self.lcd is not None: self.lcd.backlight_off() self.lcd.clear_display() self.conn.disconnect() def cb_connected(self, connected_reason): self.conn.enumerate() def cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): if enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED: # print("DISCONNECTED") return if device_identifier == Temperature.DEVICE_IDENTIFIER: self.temp = Temperature(uid, self.conn) self.temp.register_callback(self.temp.CALLBACK_TEMPERATURE, self.cb_temperature) self.update_temperature(self.temp.get_temperature()) self.temp.set_temperature_callback_period(UPDATE_PERIOD) if device_identifier == Humidity.DEVICE_IDENTIFIER: self.hum = Humidity(uid, self.conn) self.hum.register_callback(self.hum.CALLBACK_HUMIDITY, self.cb_humidity) self.update_humidity(self.hum.get_humidity()) self.hum.set_humidity_callback_period(UPDATE_PERIOD) if device_identifier == LCD20x4.DEVICE_IDENTIFIER: self.lcd = LCD20x4(uid, self.conn) self.lcd.backlight_on() def cb_temperature(self, temperature): self.update_temperature(temperature) self.update_display() def update_temperature(self, raw_temperature): self.temp_value = raw_temperature / 100.0 def cb_humidity(self, humidity): self.update_humidity(humidity) self.update_display() def update_humidity(self, raw_humidity): self.hum_value = raw_humidity / 10.0
class DeviceManager(object): """ Diese Klasse implementiert den Gerätemanager einer ORBIT-Anwendung. **Parameter** ``core`` Ein Verweis auf den Anwendungskern der ORBIT-Anwendung. Eine Instanz der Klasse :py:class:`Core`. **Beschreibung** Der Gerätemanager baut eine Verbindung zu einem TinkerForge-Server auf, ermittelt die angeschlossenen Bricks und Bricklets und stellt den Komponenten in den Jobs die jeweils geforderten Geräte zur Verfügung. Dabei behält der Gerätemanager die Kontrolle über den Gerätezugriff. Das bedeutet, dass der Gerätemanager die Autorität hat, einer Komponente ein Gerät zur Verügung zu stellen, aber auch wieder zu entziehen. Eine Komponente bekommt ein von ihm angefordertes Gerät i.d.R. dann zugewiesen, wenn die Komponente aktiv und das Gerät verfügbar ist. Wird die Verbindung zum TinkerForge-Server unterbrochen oder verliert der TinkerForge-Server die Verbindung zum Master-Brick (USB-Kabel herausgezogen), entzieht der Gerätemanager der Komponente automatisch das Gerät, so dass eine Komponente i.d.R. keine Verbindungsprobleme behandeln muss. Umgesetzt wird dieses Konzept mit Hilfe der Klassen :py:class:`SingleDeviceHandle` und :py:class:`MultiDeviceHandle`. """ def __init__(self, core): self._core = core self._connected = False self._devices = {} self._device_handles = [] self._device_callbacks = {} self._device_initializers = {} self._device_finalizers = {} # initialize IP connection self._conn = IPConnection() self._conn.set_auto_reconnect(True) self._conn.register_callback(IPConnection.CALLBACK_ENUMERATE, self._cb_enumerate) self._conn.register_callback(IPConnection.CALLBACK_CONNECTED, self._cb_connected) self._conn.register_callback(IPConnection.CALLBACK_DISCONNECTED, self._cb_disconnected) def trace(self, text): """ Schreibt eine Nachverfolgungsmeldung mit dem Ursprung ``DeviceManager`` auf die Konsole. """ if self._core.configuration.device_tracing: self._core._trace_function(text, 'DeviceManager') @property def devices(self): """ Ein Dictionary mit allen zur Zeit verfügbaren Geräten. Die UID des Geräts ist der Schlüssel und der Wert ist eine Instanz der TinkerForge-Geräte-Klasse (wie z.B. ``tinkerforge.bricklet_lcd_20x4.BrickletLCD20x4``). """ return self._devices def start(self): """ Startet den Gerätemanager und baut eine Verbindung zu einem TinkerForge-Server auf. Die Verbindungdaten für den Server werden der ORBIT-Konfiguration entnommen. Gibt ``True`` zurück, wenn die Verbindung aufgebaut werden konnte, sonst ``False``. Siehe auch: :py:meth:`stop` """ if self._conn.get_connection_state() == IPConnection.CONNECTION_STATE_DISCONNECTED: host = self._core.configuration.host port = self._core.configuration.port retry_time = self._core.configuration.connection_retry_time self.trace("connecting to %s:%d ..." % (host, port)) connected = False while not connected: try: self._conn.connect(host, port) connected = True except KeyboardInterrupt: connected = False break except: connected = False self.trace("... connection failed, waiting %d, retry ..." % retry_time) try: time.sleep(retry_time) except KeyboardInterrupt: break if connected: self.trace("... connected") return connected def stop(self): """ Trennt die Verbindung zum TinkerForge-Server und beendet den Gerätemanager. Vor dem Trennen der Verbindung wird die Zuordnung zwischen den Geräten und den Komponenten aufgehoben. Siehe auch: :py:meth:`start` """ self._finalize_and_unbind_devices() if self._conn.get_connection_state() != IPConnection.CONNECTION_STATE_DISCONNECTED: self.trace("disconnecting") self._conn.disconnect() def _cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): if enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE or \ enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED: # initialize device configuration and bindings self.trace("device present '%s' [%s]" % (device_name(device_identifier), uid)) if known_device(device_identifier): # bind device and notify components self._bind_device(device_identifier, uid) else: self.trace("could not create a device binding for device identifier " + device_identifier) if enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED: # recognize absence of device self.trace("device absent '%s' [%s]" % (device_name(device_identifier), uid)) # unbind device and notify components self._unbind_device(uid) def _cb_connected(self, reason): self._connected = True # recognize connection if reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT: self.trace("connection established (auto reconnect)") else: self.trace("connection established") # enumerate devices self._conn.enumerate() def _cb_disconnected(self, reason): self._connected = False # recognize lost connection if reason == IPConnection.DISCONNECT_REASON_ERROR: self.trace("connection lost (error)") elif reason == IPConnection.DISCONNECT_REASON_SHUTDOWN: self.trace("connection lost (shutdown)") else: self.trace("connection lost") def _bind_device(self, device_identifier, uid): self.trace("binding '%s' [%s]" % (device_name(device_identifier), uid)) # create binding instance device = device_instance(device_identifier, uid, self._conn) # add passive identity attribute identity = device.get_identity() device.identity = identity # initialize device self._initialize_device(device) # store reference to binding instance self.devices[uid] = device # register callbacks if uid in self._device_callbacks: callbacks = self._device_callbacks[uid] for event in callbacks: self.trace("binding dispatcher to '%s' [%s] (%s)" % (device_name(device_identifier), uid, event)) mcc = callbacks[event] device.register_callback(event, mcc) # notify device handles for device_handle in self._device_handles: device_handle.on_bind_device(device) def _unbind_device(self, uid): if uid in self._devices: device = self._devices[uid] self.trace("unbinding '%s' [%s]" % (device_name(device.identity[5]), uid)) # notify device handles for device_handle in self._device_handles: device_handle.on_unbind_device(device) # delete reference to binding interface del(self._devices[uid]) # delete reference to multicast callbacks if uid in self._device_callbacks: del(self._device_callbacks[uid]) else: self.trace("attempt to unbind not bound device [%s]" % uid) def _finalize_and_unbind_devices(self): for uid in list(self._devices.keys()): self._finalize_device(self._devices[uid]) self._unbind_device(uid) def add_device_initializer(self, device_identifier, initializer): """ Richtet eine Initialisierungsfunktion für einen Brick- oder Bricklet-Typ ein. **Parameter** ``device_identifier`` Die Geräte-ID der TinkerForge-API. Z.B. ``tinkerforge.bricklet_lcd_20x4.BrickletLCD20x4.DEVICE_IDENTIFIER`` ``initializer`` Eine Funktion, welche als Parameter eine Instanz der TinkerForge-Geräteklasse entgegennimmt. **Beschreibung** Sobald der Gerätemanager ein neues Gerät entdeckt, zu dem er bisher keine Verbindung aufgebaut hatte, ruft er alle Initialisierungsfunktionen für die entsprechende Geräte-ID auf. *Siehe auch:* :py:meth:`add_device_finalizer` """ if device_identifier not in self._device_initializers: self._device_initializers[device_identifier] = [] self._device_initializers[device_identifier].append(initializer) self.trace("added initializer for '%s'" % (device_name(device_identifier))) def _initialize_device(self, device): device_identifier = device.identity[5] if device_identifier in self._device_initializers: self.trace("initializing '%s' [%s]" % (device_name(device.identity[5]), device.identity[0])) for initializer in self._device_initializers[device_identifier]: try: initializer(device) except Error as err: if err.value != -8: # connection lost self.trace("Error during initialization of : %s" % err.description) except Exception as exc: self.trace("Exception caught during device initialization:\n%s" % exc) def add_device_finalizer(self, device_identifier, finalizer): """ Richtet eine Abschlussfunktion für einen Brick- oder Bricklet-Typ ein. **Parameter** ``device_identifier`` Die Geräte-ID der TinkerForge-API. Z.B. ``tinkerforge.bricklet_lcd_20x4.BrickletLCD20x4.DEVICE_IDENTIFIER`` ``finalizer`` Eine Funktion, welche als Parameter eine Instanz der TinkerForge-Geräteklasse entgegennimmt. **Beschreibung** Sobald der Gerätemanager die Verbindung zu einem Gerät selbstständig aufgibt (d.h. die Verbindung nicht durch eine Störung unterbrochen wurde), ruft er alle Abschlussfunktionen für die entsprechende Geräte-ID auf. *Siehe auch:* :py:meth:`add_device_initializer` """ if device_identifier not in self._device_finalizers: self._device_finalizers[device_identifier] = [] self._device_finalizers[device_identifier].append(finalizer) self.trace("added finalizer for '%s'" % device_name(device_identifier)) def _finalize_device(self, device): device_identifier = device.identity[5] if device_identifier in self._device_finalizers: self.trace("finalizing '%s' [%s]" % (device_name(device.identity[5]), device.identity[0])) for finalizer in self._device_finalizers[device_identifier]: try: finalizer(device) except Error as err: if err.value != -8: # connection lost self.trace("Error during device finalization: %s" % err.description) except Exception as exc: self.trace("Exception caught during device finalization:\n%s" % exc) def add_handle(self, device_handle): """ Richtet eine Geräteanforderung (Geräte-Handle) ein. Eine Geräteanforderung ist eine Instanz einer Sub-Klasse von :py:class:`DeviceHandle`. Das kann entweder eine Instanz von :py:class:`SingleDeviceHandle` oder von :py:class:`MultiDeviceHandle` sein. Das übergebene Geräte-Handle wird über alle neu entdeckten Geräte mit einem Aufruf von :py:meth:`DeviceHandle.on_bind_device` benachrichtigt. Je nach Konfiguration nimmt das Handle das neue Gerät an oder ignoriert es. Verliert der Gerätemanager die Verbindung zu einem Gerät, wird das Geräte-Handle ebenfalls mit einem Aufruf von :py:meth:`DeviceHandle.on_unbind_device` benachrichtigt. *Siehe auch:* :py:meth:`remove_handle` """ if device_handle in self._device_handles: return self._device_handles.append(device_handle) device_handle.on_add_handle(self) for device in self._devices.values(): device_handle.on_bind_device(device) def remove_handle(self, device_handle): """ Entfernt eine Geräteanforderung (Geräte-Handle). Eine Geräteanforderung ist eine Instanz einer Sub-Klasse von :py:class:`DeviceHandle`. Das kann entweder eine Instanz von :py:class:`SingleDeviceHandle` oder von :py:class:`MultiDeviceHandle` sein. *Siehe auch:* :py:meth:`add_handle` """ if device_handle not in self._device_handles: return for device in self._devices.values(): device_handle.on_unbind_device(device) device_handle.on_remove_handle() self._device_handles.remove(device_handle) def add_device_callback(self, uid, event, callback): """ Richtet eine Callback-Funktion für ein Ereignis eines Bricks oder eines Bricklets ein. **Parameter** ``uid`` Die UID des Gerätes für das ein Ereignis abgefangen werden soll. ``event`` Die ID für das abzufangene Ereignis. Z.B. ``tinkerforge.bricklet_lcd_20x4.BrickletLCD20x4.CALLBACK_BUTTON_PRESSED`` ``callback`` Eine Callback-Funktion die bei Auftreten des Ereignisses aufgerufen werden soll. **Beschreibung** Da jedes Ereignis andere Ereignisparameter besitzt, muss die richtige Signatur für die Callbackfunktion der TinkerForge-Dokumentation entnommen werden. Die Ereignisparameter werden in der API-Dokumentation für jeden Brick und jedes Bricklet im Abschnitt *Callbacks* beschrieben. .. note:: Der Gerätemanager stellt einen zentralen Mechanismus für die Registrierung von Callbacks für Geräteereignisse zur Verfügung, weil die TinkerForge-Geräteklassen nur ein Callback per Ereignis zulassen. Der Gerätemanager hingegen unterstützt beliebig viele Callbacks für ein Ereignis eines Gerätes. *Siehe auch:* :py:meth:`remove_device_callback` """ if uid not in self._device_callbacks: self._device_callbacks[uid] = {} callbacks = self._device_callbacks[uid] if event not in callbacks: self.trace("creating dispatcher for [%s] (%s)" % (uid, event)) mcc = MulticastCallback() callbacks[event] = mcc if uid in self._devices: device = self._devices[uid] self.trace("binding dispatcher to [%s] (%s)" % (uid, event)) device.register_callback(event, mcc) mcc = callbacks[event] self.trace("adding callback to dispatcher for [%s] (%s)" % (uid, event)) mcc.add_callback(callback) def remove_device_callback(self, uid, event, callback): """ Entfernt eine Callback-Funktion von einem Ereignis eines Bricks oder eines Bricklets. **Parameter** ``uid`` Die UID des Gerätes für das ein Callback aufgehoben werden soll. ``event`` Die ID für das Ereignis. Z.B. ``tinkerforge.bricklet_lcd_20x4.BrickletLCD20x4.CALLBACK_BUTTON_PRESSED`` ``callback`` Die registrierte Callback-Funktion die entfernt werde soll. **Beschreibung** Für die Aufhebung des Callbacks muss die gleiche Funktionsreferenz übergeben werden wie bei der Einrichtung des Callback. *Siehe auch:* :py:meth:`add_device_callback` """ if uid in self._device_callbacks: callbacks = self._device_callbacks[uid] if event in callbacks: mcc = callbacks[event] self.trace("removing callback from dispatcher for [%s] (%s)" % (uid, event)) mcc.remove_callback(callback)
class MainWindow(QMainWindow, Ui_MainWindow): qtcb_ipcon_enumerate = pyqtSignal(str, str, 'char', type((0, )), type( (0, )), int, int) qtcb_ipcon_connected = pyqtSignal(int) qtcb_frame_started = pyqtSignal() qtcb_frame = pyqtSignal(object, int) def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setupUi(self) self.setWindowTitle('DMX Test Tool by LauerSystems') # create and setup ipcon self.ipcon = IPConnection() self.ipcon.connect(HOST, PORT) self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.qtcb_ipcon_enumerate.emit) self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, self.qtcb_ipcon_connected.emit) self.dmx = BrickletDMX(UID_DMX, self.ipcon) self.label_image.setText("Started!") #Configs self.wait_for_first_read = True self.qtcb_frame_started.connect(self.cb_frame_started) self.qtcb_frame.connect(self.cb_frame) self.dmx.set_dmx_mode(BrickletDMX.DMX_MODE_MASTER) print("DMX Mode [0=Master; 1=Slave]: " + str(self.dmx.get_dmx_mode())) self.dmx.set_frame_duration(200) print("Frame Duration [ms]: " + str(self.dmx.get_frame_duration())) self.address_spinboxes = [] self.address_slider = [] print("Config Ende") for i in range(20): spinbox = QSpinBox() spinbox.setMinimum(0) spinbox.setMaximum(255) slider = QSlider(Qt.Horizontal) slider.setMinimum(0) slider.setMaximum(255) spinbox.valueChanged.connect(slider.setValue) slider.valueChanged.connect(spinbox.setValue) def get_frame_value_changed_func(i): return lambda x: self.frame_value_changed(i, x) slider.valueChanged.connect(get_frame_value_changed_func(i)) self.address_table.setCellWidget(i, 0, spinbox) self.address_table.setCellWidget(i, 1, slider) self.address_spinboxes.append(spinbox) self.address_slider.append(slider) print("Erzeuge Set: " + str(i)) self.address_table.horizontalHeader().setStretchLastSection(True) self.address_table.show() self.current_frame = [0] * 512 print(self.current_frame) self.dmx.register_callback(self.dmx.CALLBACK_FRAME_STARTED, self.qtcb_frame_started.emit) self.dmx.register_callback(self.dmx.CALLBACK_FRAME, self.qtcb_frame.emit) self.dmx.set_frame_callback_config(True, False, True, False) def frame_value_changed(self, line, value): self.current_frame[line] = value print("Value Changed") print(self.current_frame) self.dmx.write_frame(self.current_frame) #self.dmx_overview.draw_line(line, value, None, True) def mode_changed(self, index, update=True): if index == 0: for spinbox in self.address_spinboxes: spinbox.setReadOnly(False) for slider in self.address_slider: slider.setEnabled(True) self.frame_duration_label.setVisible(True) self.frame_duration_unit.setVisible(True) self.frame_duration_spinbox.setVisible(True) else: for spinbox in self.address_spinboxes: spinbox.setReadOnly(True) for slider in self.address_slider: slider.setEnabled(False) self.frame_duration_label.setVisible(False) self.frame_duration_unit.setVisible(False) self.frame_duration_spinbox.setVisible(False) if update: self.dmx.set_dmx_mode(index) def frame_duration_changed(self, value): self.dmx.set_frame_duration(value) def handle_new_frame(self, frame): for i, value in enumerate(frame): self.address_spinboxes[i].setValue(value) self.frame_value_changed(i, value) self.wait_for_first_read = False def cb_get_frame_duration(self, frame_duration): self.frame_duration_spinbox.blockSignals(True) self.frame_duration_spinbox.setValue(frame_duration) self.frame_duration_spinbox.blockSignals(False) def cb_get_dmx_mode(self, mode): self.mode_combobox.blockSignals(True) self.mode_combobox.setCurrentIndex(mode) self.mode_changed(mode, False) self.mode_combobox.blockSignals(False) if mode == self.dmx.DMX_MODE_MASTER: self.dmx.read_frame, None, self.cb_read_frame, self.increase_error_count def cb_read_frame(self, frame): self.handle_new_frame(frame.frame) def cb_frame_started(self): if not self.wait_for_first_read: self.dmx.write_frame, self.current_frame, None, self.increase_error_count def cb_frame(self, frame, frame_number): if frame == None: return self.handle_new_frame(frame) def cb_ipcon_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): if self.ipcon.get_connection_state( ) != IPConnection.CONNECTION_STATE_CONNECTED: # ignore enumerate callbacks that arrived after the connection got closed return def cb_ipcon_connected(self, connect_reason): try: self.ipcon.enumerate() except: pass
import numpy import math from PIL import Image, ImageOps from tinkerforge.ip_connection import IPConnection from tinkerforge.bricklet_thermal_imaging import BrickletThermalImaging #Tinkerforge Config HOST = "localhost" PORT = 4223 UID = "LcN" print("start Connection") ipcon = IPConnection() # Create IP connection ti = BrickletThermalImaging(UID, ipcon) # Create device object ipcon.connect(HOST, PORT) # Connect to brickd while ipcon.get_connection_state() == 2: print(".") print(ipcon.get_connection_state()) def get_thermal_image_color_palette(): palette = [] for x in range(256): x /= 255.0 palette.append(int(round(255 * math.sqrt(x)))) # RED palette.append(int(round(255 * pow(x, 3)))) # GREEN if math.sin(2 * math.pi * x) >= 0: palette.append(int(round(255 * math.sin(2 * math.pi * x)))) # BLUE else: palette.append(0)