Example #1
0
 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
Example #4
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)
Example #5
0
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
Example #6
0
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)