Example #1
0
class TinkerforgeConnection(object):
    # Connection to the Brick Daemon on localhost and port 4223
    ipcon = None
    current_entries = dict()

    # noinspection PyUnusedLocal
    def cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier,
                     enumeration_type):

        if enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED:
            del self.current_entries[uid]

        else:
            if device_identifier == 13:
                self.current_entries.update({uid: "Master Brick"})
            elif device_identifier == 21:
                self.current_entries.update({uid: "Ambient Light Bricklet"})
            elif device_identifier == 229:
                self.current_entries.update({uid: "Distance US Bricklet"})
            elif device_identifier == 235:
                self.current_entries.update({uid: "RemoteSwitchBricklet"})
            else:
                self.current_entries.update(
                    {uid: "device_identifier = {0}".format(device_identifier)})

    def switch_socket(self, uid, address, unit, state):
        rs = BrickletRemoteSwitch(uid, self.ipcon)
        rs.switch_socket_b(address, unit, state)

    def dim_socket(self, uid, address, unit, value):
        rs = BrickletRemoteSwitch(uid, self.ipcon)
        rs.dim_socket_b(address, unit, value)

    def get_illuminance(self, uid):
        try:
            al = BrickletAmbientLight(uid, self.ipcon)
            return al.get_illuminance() / 10
        except Exception:
            log.warn(uid + " not connected")
            return -1

    def get_distance(self, uid):
        try:
            dus = BrickletDistanceUS(uid, self.ipcon)
            return dus.get_distance_value()
        except Exception:
            log.warn(uid + " not connected")
            return -1

    def __init__(self, ip_address):
        self.ipcon = IPConnection()
        self.ipcon.connect(ip_address, 4223)
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate)
        self.ipcon.enumerate()
Example #2
0
class volt_cur:
    def __init__(self):
        self.vc = None

        # Create IP Connection
        self.ipcon = IPConnection() 

        # Register IP Connection callbacks
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, 
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, 
                                     self.cb_connected)

        # Connect to brickd, will trigger cb_connected
        self.ipcon.connect(constants.ownIP, PORT) 
        #self.ipcon.enumerate()                 
       
    
    def cb_reached_vc(self):        
        voltage = self.vc.get_voltage()
        dicti = {}
        dicti['value'] = str(voltage)
        dicti['name'] = 'Voltage'
        mySocket.sendto(str(dicti),(constants.server1,constants.broadPort)) 
        mySocket.sendto(str(dicti),(constants.server1,constants.broadPort)) 
        current = self.vc.get_current()
        dicti = {}
        dicti['value'] = str(current)
        dicti['name'] = 'Current'
        mySocket.sendto(str(dicti),(constants.server1,constants.broadPort)) 
        mySocket.sendto(str(dicti),(constants.server1,constants.broadPort))         
        thread_cb_reached = Timer(60, self.cb_reached_vc, [])
        thread_cb_reached.start()        
       
    
    # Callback handles device connections and configures possibly lost 
    # configuration of lcd and temperature callbacks, backlight etc.
    def cb_enumerate(self, uid, connected_uid, position, hardware_version, 
                     firmware_version, device_identifier, enumeration_type):

        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            
            # Enumeration for V/C
            if device_identifier == BrickletVoltageCurrent.DEVICE_IDENTIFIER:
                self.vc = BrickletVoltageCurrent(uid, self.ipcon)
                self.cb_reached_vc()
        
    def cb_connected(self, connected_reason):
        # Enumerate devices again. If we reconnected, the Bricks/Bricklets
        # may have been offline and the configuration may be lost.
        # In this case we don't care for the reason of the connection
        self.ipcon.enumerate()    
Example #3
0
class volt_cur:
    def __init__(self):
        self.vc = None

        # Create IP Connection
        self.ipcon = IPConnection()

        # Register IP Connection callbacks
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        # Connect to brickd, will trigger cb_connected
        self.ipcon.connect(constants.ownIP, PORT)
        #self.ipcon.enumerate()

    def cb_reached_vc(self):
        voltage = self.vc.get_voltage()
        dicti = {}
        dicti['value'] = str(voltage)
        dicti['name'] = 'Voltage'
        mySocket.sendto(str(dicti), (constants.server1, constants.broadPort))
        mySocket.sendto(str(dicti), (constants.server1, constants.broadPort))
        current = self.vc.get_current()
        dicti = {}
        dicti['value'] = str(current)
        dicti['name'] = 'Current'
        mySocket.sendto(str(dicti), (constants.server1, constants.broadPort))
        mySocket.sendto(str(dicti), (constants.server1, constants.broadPort))
        thread_cb_reached = Timer(60, self.cb_reached_vc, [])
        thread_cb_reached.start()

    # Callback handles device connections and configures possibly lost
    # configuration of lcd and temperature callbacks, backlight etc.
    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):

        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:

            # Enumeration for V/C
            if device_identifier == BrickletVoltageCurrent.DEVICE_IDENTIFIER:
                self.vc = BrickletVoltageCurrent(uid, self.ipcon)
                self.cb_reached_vc()

    def cb_connected(self, connected_reason):
        # Enumerate devices again. If we reconnected, the Bricks/Bricklets
        # may have been offline and the configuration may be lost.
        # In this case we don't care for the reason of the connection
        self.ipcon.enumerate()
Example #4
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
Example #5
0
class dist_us:
    def __init__(self):
        self.dus = None

        # Create IP Connection
        self.ipcon = IPConnection() 

        # Register IP Connection callbacks
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, 
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, 
                                     self.cb_connected)

        # Connect to brickd, will trigger cb_connected
        self.ipcon.connect(constants.ownIP, PORT) 
        #self.ipcon.enumerate()                 
       
    
    def cb_distance(self, distance):        
        dicti = {}
        dicti['value'] = str(distance)
        dicti['name'] = str(self.dus.get_identity()[0]) + "_" + str(self.dus.get_identity()[5])
        mySocket.sendto(str(dicti),(constants.server1,constants.broadPort)) 
        mySocket.sendto(str(dicti),(constants.server1,constants.broadPort)) 
       
    
    # Callback handles device connections and configures possibly lost 
    # configuration of lcd and temperature callbacks, backlight etc.
    def cb_enumerate(self, uid, connected_uid, position, hardware_version, 
                     firmware_version, device_identifier, enumeration_type):

        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            
            # Enumeration for Distance US
            if device_identifier == BrickletDistanceUS.DEVICE_IDENTIFIER:
                self.dus = BrickletDistanceUS(uid, self.ipcon)
                self.dus.register_callback(self.dus.CALLBACK_DISTANCE, self.cb_distance)
                self.dus.set_distance_callback_period(10000)

        
    def cb_connected(self, connected_reason):
        # Enumerate devices again. If we reconnected, the Bricks/Bricklets
        # may have been offline and the configuration may be lost.
        # In this case we don't care for the reason of the connection
        self.ipcon.enumerate()          
Example #6
0
class dist_us:
    def __init__(self):
        self.dus = None

        # Create IP Connection
        self.ipcon = IPConnection()

        # Register IP Connection callbacks
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        # Connect to brickd, will trigger cb_connected
        self.ipcon.connect(constants.ownIP, PORT)
        #self.ipcon.enumerate()

    def cb_distance(self, distance):
        dicti = {}
        dicti['value'] = str(distance)
        dicti['name'] = str(self.dus.get_identity()[0]) + "_" + str(
            self.dus.get_identity()[5])
        mySocket.sendto(str(dicti), (constants.server1, constants.broadPort))
        mySocket.sendto(str(dicti), (constants.server1, constants.broadPort))

    # Callback handles device connections and configures possibly lost
    # configuration of lcd and temperature callbacks, backlight etc.
    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):

        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:

            # Enumeration for Distance US
            if device_identifier == BrickletDistanceUS.DEVICE_IDENTIFIER:
                self.dus = BrickletDistanceUS(uid, self.ipcon)
                self.dus.register_callback(self.dus.CALLBACK_DISTANCE,
                                           self.cb_distance)
                self.dus.set_distance_callback_period(10000)

    def cb_connected(self, connected_reason):
        # Enumerate devices again. If we reconnected, the Bricks/Bricklets
        # may have been offline and the configuration may be lost.
        # In this case we don't care for the reason of the connection
        self.ipcon.enumerate()
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 #8
0
def main():
    global uids
    global PORT

    if len(sys.argv) != 1:
        print("Usage: {}")
        sys.exit(0)

    result = {"start": now()}

    try:
        with socket.create_connection((PRINTER_HOST, PRINTER_PORT)):
            print("Label printer is online")
    except:
        if input("Failed to reach label printer. Continue anyway? [y/n]"
                 ) != "y":
            sys.exit(0)

    print("Checking ESP state")
    mac_address = check_if_esp_is_sane_and_get_mac()
    print("MAC Address is {}".format(mac_address))
    result["mac"] = mac_address

    set_voltage_fuses, set_block_3, passphrase, uid = get_espefuse_tasks()
    if set_voltage_fuses or set_block_3:
        print("Fuses are not set. Re-run stage 0!")

    esptool(["--after", "hard_reset", "chip_id"])

    result["uid"] = uid

    ssid = "warp-" + uid

    run(["systemctl", "restart", "NetworkManager.service"])

    print("Waiting for ESP wifi. Takes about one minute.")
    if not wait_for_wifi(ssid, 90):
        print("ESP wifi not found after 90 seconds")
        sys.exit(0)

    print("Testing ESP Wifi.")
    with wifi(ssid, passphrase):
        with urllib.request.urlopen(
                "http://10.0.0.1/hidden_proxy/enable") as f:
            f.read()
        ipcon = IPConnection()
        ipcon.connect("10.0.0.1", 4223)
        result["wifi_test_successful"] = True
        print("Connected. Testing bricklet ports")
        # Register Enumerate Callback
        ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, cb_enumerate)

        # Trigger Enumerate
        ipcon.enumerate()
        start = time.time()
        while time.time() - start < 5:
            if len(uids) == 6:
                break
            time.sleep(0.1)

        if len(uids) != 6:
            print("Expected 6 RGB LED 2.0 bricklets but found {}".format(
                len(uids)))
            sys.exit(0)

        uids = sorted(uids, key=lambda x: x[0])

        bricklets = [(uid[0], BrickletRGBLEDV2(uid[1], ipcon)) for uid in uids]
        error_count = 0
        for bricklet_port, rgb in bricklets:
            rgb.set_rgb_value(127, 127, 0)
            time.sleep(0.5)
            if rgb.get_rgb_value() == (127, 127, 0):
                rgb.set_rgb_value(0, 127, 0)
            else:
                print("Setting color failed on port {}.".format(bricklet_port))
                error_count += 1

        if error_count != 0:
            sys.exit(0)

        result["bricklet_port_test_successful"] = True

        stop_event = threading.Event()
        blink_thread = threading.Thread(target=blink_thread_fn,
                                        args=([x[1] for x in bricklets],
                                              stop_event))
        blink_thread.start()
        input("Bricklet ports seem to work. Press any key to continue")
        stop_event.set()
        blink_thread.join()
        ipcon.disconnect()

    led0 = input("Does LED 0 blink blue? [y/n]")
    while led0 != "y" and led0 != "n":
        led0 = input("Does LED 0 blink blue? [y/n]")
    result["led0_test_successful"] = led0 == "y"
    if led0 == "n":
        print("LED 0 does not work")
        sys.exit(0)

    led1 = input(
        "Press IO0 button (for max 3 seconds). Does LED 1 glow green? [y/n]")
    while led1 != "y" and led1 != "n":
        led1 = input(
            "Press IO0 Button (for max 3 seconds). Does LED 1 glow green? [y/n]"
        )
    result["led1_io0_test_successful"] = led1 == "y"
    if led1 == "n":
        print("LED 1 or IO0 button does not work")
        sys.exit(0)

    led0_stop = input(
        "Press EN button. Does LED 0 stop blinking for some seconds? [y/n]")
    while led0_stop != "y" and led0_stop != "n":
        led0_stop = input(
            "Press EN button. Does LED 0 stop blinking for some seconds? [y/n]"
        )
    result["enable_test_successful"] = led0_stop == "y"
    if led0_stop == "n":
        print("EN button does not work")
        sys.exit(0)

    result["tests_successful"] = True

    run(["python3", "print-esp32-label.py", ssid, passphrase, "-c", "3"])
    label_success = input(
        "Stick one label on the esp, put esp and the other two labels in the ESD bag. [y/n]"
    )
    while label_success != "y" and label_success != "n":
        label_success = input(
            "Stick one label on the esp, put esp and the other two labels in the ESD bag. [y/n]"
        )
    result["labels_printed"] = label_success == "y"
    result["end"] = now()

    with open(
            "{}_{}_report_stage_1.json".format(ssid,
                                               now().replace(":", "-")),
            "w") as f:
        json.dump(result, f, indent=4)
Example #9
0
class led_strips:
    HOST = "localhost"
    PORT = 4223

    UID_LED_STRIP_ONE = "jGy"
    UID_LED_STRIP_TWO = "jHE"

    MODE = 0
    MODE_HUE = 1
    MODE_SATURATION = 2
    MODE_VALUE = 3
    MODE_VELOCITY = 4
    MODE_COLOR_GRADIENT = 5
    MODE_COLOR_DOT = 6
    MODE_COLOR_FADING = 7
    MODE_COLOR_RANDOMLY = 8
    MODE_LEDS = 9
    MODE_OFF = 10

    MODE_STRIPS = 0
    MODE_LEFT_STRIP = 1
    MODE_RIGHT_STRIP = 2
    MODE_BOTH_STRIPS = 3

    POSITION_HUE = 1
    POSITION_SATURATION = 1
    POSITION_VALUE = 0.3
    POSITION_VELOCITY = 1

    R = [255]*16
    G = [0]*16
    B = [0]*16
    
    MAX_LEDS = 16
    ACTIVE_LEDS = 16

    ipcon = None
    led_strip_1 = None
    led_strip_2 = None
    multi_touch = None
    rotary_poti = None

    def __init__(self):
        # Create IP Connection
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(led_strips.HOST, led_strips.PORT)
                break
            except Error as e:
                log.error('Connection error: ' + str(e.description))
                time.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                time.sleep(1)

        # Register IP Connection callbacks
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate error: ' + str(e.description))
                time.sleep(1)

    # Callback handels device connections and configures possibly lost configuration
    def cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == LEDStrip.DEVICE_IDENTIFIER and uid == self.UID_LED_STRIP_ONE: #LED-Strip 1
                try:
                    self.led_strip_1 = LEDStrip(uid, self.ipcon)
                    log.info('LED-Strip 1 initialized.')
                except Error as e:
                    log.error('LED-Strip 1 init failed: ' + str(e.description))
                    self.led_strip_1 = None
            elif device_identifier == LEDStrip.DEVICE_IDENTIFIER and uid == self.UID_LED_STRIP_TWO: #LED-Strip 2
                try:
                    self.led_strip_2 = LEDStrip(uid, self.ipcon)
                    log.info('LED-Strip 2 initialized.')
                except Error as e:
                    log.error('LED-Strip 2 init failed: ' + str(e.description))
                    self.led_strip_2 = None
            elif device_identifier == MultiTouch.DEVICE_IDENTIFIER: # MulitTouch for changing colors etc.
                try:
                    self.multi_touch = MultiTouch(uid, self.ipcon)
                    self.multi_touch.register_callback(self.multi_touch.CALLBACK_TOUCH_STATE, self.cb_buttons)
                    self.multi_touch.set_electrode_config(0x0FFF)
                    self.multi_touch.recalibrate()
                    log.info('Set proximity off.')
                    log.info('Multi-Touch initialized.')
                except Error as e:
                    log.error('Multi-Touch init failed: ' + str(e.description))
                    self.multi_touch = None
            elif device_identifier == RotaryPoti.DEVICE_IDENTIFIER: # Rotary Poti for picking a color or changing the saturation
                try:
                    self.rotary_poti = RotaryPoti(uid, self.ipcon)
                    self.rotary_poti.register_callback(self.rotary_poti.CALLBACK_POSITION, self.cb_position)
                    self.rotary_poti.set_position_callback_period(50)
                    log.info('Rotary Poti initialized.')
                except Error as e:
                    log.error('Rotary Poti init failed: ' + str(e.description))
                    self.rotary_poti = None

    # Callback handels reconnection of IP Connection
    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto reconnect.')
            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate error:' + str(e.description))
                    time.sleep(1)

    # Check which mode is set: the left LED strip, the right LED strip or both LED strips
    def set_mode(self, mode, i, leds, r, b, g):
        if self.MODE_STRIPS == self.MODE_BOTH_STRIPS:
            self.led_strip_1.set_rgb_values(i, leds, r, b, g)
            self.led_strip_2.set_rgb_values(i, leds, r, b, g)
        elif self.MODE_STRIPS == self.MODE_LEFT_STRIP:
            self.led_strip_1.set_rgb_values(i, leds, r, b, g)
        elif self.MODE_STRIPS == self.MODE_RIGHT_STRIP:
            self.led_strip_2.set_rgb_values(i, leds, r, b, g)
    
    # Turn off the LED strips depending on the given mode
    def leds_off(self):
        r = [0]*self.MAX_LEDS
        g = [0]*self.MAX_LEDS
        b = [0]*self.MAX_LEDS
        self.set_mode(self.MODE_STRIPS, 0, self.MAX_LEDS, r, b, g)

    # Some simple color functions to turn the strips to red, green or blue
    def led_strips_red(self):
        r = [255]*self.MAX_LEDS
        g = [0]*self.MAX_LEDS
        b = [0]*self.MAX_LEDS
        self.set_mode(self.MODE_STRIPS, 0, self.MAX_LEDS, r, b, g)

    def led_strips_green(self):
        r = [0]*self.MAX_LEDS
        g = [255]*self.MAX_LEDS
        b = [0]*self.MAX_LEDS
        self.set_mode(self.MODE_STRIPS, 0, self.MAX_LEDS, r, b, g)

    def led_strips_blue(self):
        r = [0]*self.MAX_LEDS
        g = [0]*self.MAX_LEDS
        b = [255]*self.MAX_LEDS
        self.set_mode(self.MODE_STRIPS, 0, self.MAX_LEDS, r, b, g)

    # Match the hue (color) to the position by the rotary poti.
    def set_hue(self, position):
        # The position returned by the rotary poti (o to +300) must be mapped to 0°-360° in the HSV colorspace
        hue = ((position / 360) * 432)
        # Convert the HSV color (hue,saturation,value) to the RGB color
        # The function expects hue to be in the range 0-1 not 0-360
        r, g, b = colorsys.hsv_to_rgb(hue/360, self.POSITION_SATURATION, self.POSITION_VALUE)
        #print('Hue: {0:.1f}'.format(hue),'Saturation: {0:.2f}'.format(self.POSITION_SATURATION),'Value: {0:.2f}'.format(self.POSITION_VALUE))
        # Build the LED strip
        self.build_led_strip(r, g, b) 
        # Save the value in the variable
        self.POSITION_HUE = hue/360

    # Match the saturation to the position by the rotary poti.
    def set_saturation(self, position):
        # The position returned by the rotary poti must be mapped to 0-1 in the HSV colorspace
        saturation = (position / 300)
        # Convert the HSV color (hue,saturation,value) to the RGB color
        r, g, b = colorsys.hsv_to_rgb(self.POSITION_HUE, saturation, self.POSITION_VALUE) 
        #print('Hue: {0:.1f}'.format(self.POSITION_HUE*360),'Saturation: {0:.2f}'.format(saturation),'Value: {0:.2f}'.format(self.POSITION_VALUE))
        # Build the LED strip
        self.build_led_strip(r, g, b)
        # Save the value in the variable
        self.POSITION_SATURATION = saturation
    
    # Match the value to the position by the rotary poti.
    def set_value(self, position):
        # The position returned by the rotary poti must be mapped to 0-1 in the HSV colorspace
        value = (position / 300)
        # Convert the HSV color (hue,saturation,value) to the RGB color
        r, g, b = colorsys.hsv_to_rgb(self.POSITION_HUE, self.POSITION_SATURATION, value)
        #print('Hue: {0:.1f}'.format(self.POSITION_HUE*360),'Saturation: {0:.2f}'.format(self.POSITION_SATURATION),'Value: {0:.2f}'.format(value))
        # Build the LED strip
        self.build_led_strip(r, g, b)
        # Save the value in the variable
        self.POSITION_VALUE = value

    # NOT USED AT THE MOMENT
    # The veolcity for some functions can be adjusted by the rotary poti.
    def set_velocity(self, position):
        velocity = (position / 3)
        #print('Velocity: {0:0.1f}'.format(velocity))
        # Save the velocity in the variable
        self.POSITION_VELOCITY = velocity

    # Function to generate a rainbow gradient. Can be adjusted by the velocity.
    def set_color_gradient(self, position):
        # use all LEDs for the gradient
        active_leds = self.MAX_LEDS
        loop_counter = 0
        r = []
        g = []
        b = []
        for led in list(range(active_leds)):
            rv, gv, bv = colorsys.hsv_to_rgb(1.*led/active_leds, self.POSITION_SATURATION, self.POSITION_VALUE)
            r.append(int(rv*255))
            g.append(int(gv*255))
            b.append(int(bv*255))
        for leds in range(active_leds):
            #print("Loop counter: " + str(loop_counter))
            first_red = r.pop(0)
            r.append(first_red)
            first_green = g.pop(0)
            g.append(first_green)
            first_blue = b.pop(0)
            b.append(first_blue)
            #print('R: ' + str(r) + '\n','G: ' + str(g) + '\n','B: ' + str(b) + '\n')
            self.set_mode(self.MODE, 0, self.MAX_LEDS, r, b, g)
            loop_counter = loop_counter + 1            
            time.sleep(0.075)

    # Fade and change the color for the whole strip
    def set_color_gradient_fading(self):
        # Outer loop for changing the color
        for hue in range(0, 360, 30):
            hue = (hue / 360)
            #print("Hue: " + str(hue))
            # Inner loop for fading the actual color
            for value in range(1, 21):
                value = value / 20
                #print("Value: " + str(value))
                r, g, b = colorsys.hsv_to_rgb(hue, self.POSITION_SATURATION, value)
                self.build_led_strip(r, g, b)
                time.sleep(0.075)
            for value in reversed(range(1, 21)):
                value = value / 20
                #print("Value: " + str(value))
                r, g, b = colorsys.hsv_to_rgb(hue, self.POSITION_SATURATION, value)
                self.build_led_strip(r, g, b)
                time.sleep(0.075)
 
    # The LEDs are fading from 0.1 to 1.0 in the value space. The fading can be adjusted by the velocity.
    def set_color_fading(self, position):
        loop_counter = 0
        while loop_counter < 5:
            #print("Loop counter: " + str(loop_counter))
            for value in range(1, 21):
                value = value / 20
                #print("Value: " + str(value))
                r, g, b = colorsys.hsv_to_rgb(self.POSITION_HUE, self.POSITION_SATURATION, value)
                self.build_led_strip(r, g, b)
                time.sleep(0.075)
            for value in reversed(range(1, 21)):
                value = value / 20
                #print("Value: " + str(value))
                r, g, b = colorsys.hsv_to_rgb(self.POSITION_HUE, self.POSITION_SATURATION, value)
                self.build_led_strip(r, g, b)
                time.sleep(0.075)
                loop_counter = loop_counter + 1

    # Only one LED is active and moves from one end to the other end of the strip.
    def set_color_dot(self, position):
        # Build the initial array
        r = self.R[0]
        g = self.G[0]
        b = self.B[0]
        r = [r]
        g = [g]
        b = [b]
        r.extend([0]*15)
        g.extend([0]*15)
        b.extend([0]*15)
        #print('R: ' + str(r) + '\n','G: ' + str(g) + '\n','B: ' + str(b) + '\n')
        # Now get the dot moving
        i = 0
        while i < 15:
            dot_r = r[i]
            dot_g = g[i]
            dot_b = b[i]
            r[i] = 0
            g[i] = 0
            b[i] = 0
            r[i+1] = dot_r
            g[i+1] = dot_g
            b[i+1] = dot_b
            #print('R: ' + str(r) + '\n','G: ' + str(g) + '\n','B: ' + str(b) + '\n')
            i = i + 1
            self.set_mode(self.MODE, 0, self.MAX_LEDS, r, b, g)
            time.sleep(0.1)
        while i > 0:
            dot_r = r[i]
            dot_g = g[i]
            dot_b = b[i]
            r[i] = 0
            g[i] = 0
            b[i] = 0
            r[i-1] = dot_r
            g[i-1] = dot_g
            b[i-1] = dot_b
            #print('R: ' + str(r) + '\n','G: ' + str(g) + '\n','B: ' + str(b) + '\n')
            i = i - 1
            self.set_mode(self.MODE, 0, self.MAX_LEDS, r, b, g)
            time.sleep(0.1)

    # Build random color values and place them randomly on the strips.
    def set_color_randomly(self, position):
        active_leds = self.ACTIVE_LEDS
        """
        r = []
        g = []
        b = []
        # 1. Variant
        for led in list(range(active_leds)):
            rv = random.randrange(1, 256)
            gv = random.randrange(1, 256)
            bv = random.randrange(1, 256)
            r.append(rv)
            g.append(gv)
            b.append(bv)
        # 2. Variant
        for led in list(range(active_leds)):
            rv, gv, bv = colorsys.hsv_to_rgb(1.*led/active_leds, self.POSITION_SATURATION, self.POSITION_VALUE)
            r.append(int(rv*255))
            g.append(int(gv*255))
            b.append(int(bv*255))
        for leds in range(active_leds):
            random.shuffle(r)
            random.shuffle(g)
            random.shuffle(b)
            print('R: ' + str(r) + '\n','G: ' + str(g) + '\n','B: ' + str(b) + '\n')
            self.set_mode(self.MODE, 0, self.MAX_LEDS, r, b, g)
            time.sleep(0.075)
        """
        # 3. Variant
        for leds in range(active_leds):
            r = []
            g = []
            b = []
            range_leds = list(range(active_leds))
            random.shuffle(range_leds)
            #print("LEDs: " + str(range_leds))
            for led in range_leds:
                rv, gv, bv = colorsys.hsv_to_rgb(1.*led/active_leds, self.POSITION_SATURATION, self.POSITION_VALUE)
                r.append(int(rv*255))
                g.append(int(gv*255))
                b.append(int(bv*255))
            #print('R: ' + str(r) + '\n','G: ' + str(g) + '\n','B: ' + str(b) + '\n')
            self.set_mode(self.MODE, 0, self.MAX_LEDS, r, b, g)
            time.sleep(0.1)

    # Extend the LEDs from 1 LED to 16 LEDs per strip. Like the fading, but here the LEDs can be adjusted by the rotary poti.
    def set_leds(self, position):
        # The rotary poti can set the number of LEDs which should be used
        active_leds = (position / 300) * self.MAX_LEDS
        active_leds = int(math.ceil(active_leds))
        #print('Active LEDs: ' + str(active_leds))
        
        # Get the color values from the variables
        r = self.R[0]
        g = self.G[0]
        b = self.B[0]
        #print('R: ' + str(r),'G: ' + str(g),'B: ' + str(b))

        # Now build the list with the active leds
        r = [r]*active_leds
        g = [g]*active_leds
        b = [b]*active_leds
        #print('R: ' + str(r) + '\n','G: ' + str(g) + '\n','B: ' + str(b) + '\n')

        # Now add the remaining dark leds to the list
        dark_leds = 16 - active_leds
        #print('Dark LEDs: ' + str(dark_leds))
        r.extend([0]*dark_leds)
        g.extend([0]*dark_leds)
        b.extend([0]*dark_leds)          
        #print('R: ' + str(r) + '\n','G: ' + str(g) + '\n','B: ' + str(b) + '\n')

        # Now get it to the strips
        self.set_mode(self.MODE, 0, self.MAX_LEDS, r, b, g)           

        # Save the value in the variable
        self.ACTIVE_LEDS = active_leds

    # Helper function to generate the output for the LED strips
    def build_led_strip(self, r, g, b):
        r = int(r*255)
        g = int(g*255)
        b = int(b*255)
        #print('R: ' + str(r),'G: ' + str(g),'B: ' + str(b))

        # Get the actual number of LEDs which should be used
        active_leds = self.ACTIVE_LEDS
        r = [r]*active_leds
        g = [g]*active_leds
        b = [b]*active_leds
        
        # Now add the remaining dark leds to the list
        dark_leds = 16 - active_leds
        r.extend([0]*dark_leds)
        g.extend([0]*dark_leds)
        b.extend([0]*dark_leds)
        #print('R: ' + str(r) + '\n','G: ' + str(g) + '\n','B: ' + str(b) + '\n')
        
        # Now get it to the strips
        self.set_mode(self.MODE, 0, self.MAX_LEDS, r, b, g)
        # Save the values in the variables
        self.R = r
        self.G = g
        self.B = b

    # Callback function for position callback (parameter has range -150 to 150)
    def cb_position(self, position):
        # Print the position for debuging
        #print('Position: ' + str(position))
        # Always add +150 to the position value so that it will start on the left by 0 and to the right it will end by 300
        position = position + 150
        # Select in which MODE it is called
        if self.MODE == self.MODE_HUE:
            self.set_hue(position)
        elif self.MODE == self.MODE_SATURATION:
            self.set_saturation(position)
        elif self.MODE == self.MODE_VALUE:
            self.set_value(position)
        elif self.MODE == self.MODE_VELOCITY:
            self.set_velocity(position)
        elif self.MODE == self.MODE_COLOR_GRADIENT:
            self.set_color_gradient(position)
        elif self.MODE == self.MODE_COLOR_DOT:
            self.set_color_dot(position)
        elif self.MODE == self.MODE_COLOR_FADING:
            self.set_color_fading(position)
        elif self.MODE == self.MODE_COLOR_RANDOMLY:
            self.set_color_randomly(position)
        elif self.MODE == self.MODE_LEDS:
            self.set_leds(position)

    # Callback function for button callback
    def cb_buttons(self, button_state):
        for i in range(12):
            if button_state & (1 << i):
                if i == 0:
                    self.MODE_STRIPS = self.MODE_LEFT_STRIP
                elif i == 1:
                    self.MODE = self.MODE_HUE
                elif i == 2:
                    self.MODE = self.MODE_COLOR_GRADIENT
                elif i == 3:
                    self.MODE_STRIPS = self.MODE_BOTH_STRIPS
                elif i == 4:
                    self.MODE = self.MODE_SATURATION
                elif i == 5:
                    self.set_color_gradient_fading()
                elif i == 6:
                    self.MODE_STRIPS = self.MODE_RIGHT_STRIP
                elif i == 7:
                    self.MODE = self.MODE_VALUE
                elif i == 8:
                    self.MODE = self.MODE_COLOR_FADING
                elif i == 9:
                    #self.MODE = self.MODE_OFF
                    self.MODE = self.MODE_COLOR_RANDOMLY
                elif i == 10:
                    self.MODE = self.MODE_LEDS
                elif i == 11:
                    self.MODE = self.MODE_COLOR_DOT
class WeatherStation:
    HOST = "localhost"
    PORT = 4223

    ipcon = None
    lcd = None
    lcd_clear = False
    al = None
    hum = None
    baro = None

    def __init__(self):
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(WeatherStation.HOST, WeatherStation.PORT)
                break
            except Error as e:
                log.error('Connection Error: ' + str(e.description))
                timer.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                timer.sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate Error: ' + str(e.description))
                timer.sleep(1)  

    def start(self):
        t = 10
        extended_timer = 10      
        try:
            while True:
                if self.lcd:
                    self.write_date(0, 0)
                    self.write_time(1, 0)
                    t = t + 1
                    if t >= extended_timer:
                        if self.baro:
                            self.write_temperatur(2, 0)
                        if self.hum:
                            self.write_humidity(3, 0)
                        t = 0
                timer.sleep(1)
        except KeyboardInterrupt:    
            if weather_station.ipcon != None:
                weather_station.ipcon.disconnect()
            return

    def init_lcd(self, uid):
        try:
            self.lcd = LCD20x4(uid, self.ipcon)
            self.lcd.clear_display()
            self.lcd.backlight_on()
            log.info('LCD 20x4 initialized')
        except Error as e:
            log.error('LCD 20x4 init failed: ' + str(e.description))
            self.lcd = None
            
    def init_ambientlight(self, uid):
        try:
            self.al = AmbientLight(uid, self.ipcon)
            self.al.set_illuminance_callback_period(1000)
            self.al.register_callback(self.al.CALLBACK_ILLUMINANCE,
                                              self.cb_illuminance)
        except Error as e:
            log.error('Ambient Light init failed: ' + str(e.description))
            self.al = None
    
      
    def init_barometer(self, uid):
        try:
            self.baro = Barometer(uid, self.ipcon)
        except Error as e:
            log.error('Barometer init failed: ' + str(e.description))
            self.baro = None
    
    def init_humidity(self, uid):
        try:
            self.hum = Humidity(uid, self.ipcon)
        except Error as e:
            log.error('Humidity init failed: ' + str(e.description))
            self.hum = None
    
    def write_time(self, line, start_position):
        lt = localtime()
        hour, minute, second = lt[3:6]
        self.lcd.write_line(line, start_position, "Time:       %02i:%02i:%02i" % (hour, minute, second))

    def write_date(self, line, start_position):
        lt = localtime()
        year, month, day = lt[0:3]
        self.lcd.write_line(line, start_position, "Date:     %02i.%02i.%04i" % (day, month, year))

    def write_temperatur(self, line, start_position):
        try:
            temperature = self.baro.get_chip_temperature()
            text = 'Temp:       %5.2f \xDFC' % (temperature / 100.0)
            self.lcd.write_line(line, start_position, text)
        except Error as e:
            log.error('Could not get temperature: ' + str(e.description))
            return        
    
    def write_humidity(self, line, start_position):
        try:
            h = self.hum.get_humidity()
            text = 'Humidity:   %6.2f %%' % (h / 10.0)
            self.lcd.write_line(line, start_position, text)
        except Error as e:
            log.error('Could not get temperature: ' + str(e.description))
            return 

    def cb_illuminance(self, illuminance):
        if self.lcd is not None:
            i = illuminance / 10.0 
            if i < 0.5 and self.lcd.is_backlight_on():
                self.lcd.backlight_off()
            elif i >= 0.5 and not self.lcd.is_backlight_on():
                self.lcd.backlight_on()

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == LCD20x4.DEVICE_IDENTIFIER:
                self.init_lcd(uid)
            elif device_identifier == AmbientLight.DEVICE_IDENTIFIER:
                self.init_ambientlight(uid)
            elif device_identifier == Humidity.DEVICE_IDENTIFIER:
                self.init_humidity(uid)
            elif device_identifier == Barometer.DEVICE_IDENTIFIER:  
                self.init_barometer(uid)
         

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto Reconnect')
            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate Error: ' + str(e.description))
                    timer.sleep(1)
class WeatherStation:
    HOST = "localhost"
    PORT = 4223

    ipcon = None
    lcd = None
    al_v2 = None
    hum_v2 = None
    baro = None
    master = None

    def __init__(self):
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(WeatherStation.HOST, WeatherStation.PORT)
                break
            except Error as e:
                log.error('Connection Error: ' + str(e.description))
                time.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                time.sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate Error: ' + str(e.description))
                time.sleep(1)
                
    def cb_lcd_button_pressed(self, button):
        if self.lcd is not None:
            text = str(self.lcd.is_button_pressed(button))
            log.debug('Button pressed ' + text)
            log.debug('It was button ' + str(button))
            if button == 0:
                if self.lcd.is_backlight_on():
                    self.lcd.backlight_off()
                else:
                    self.lcd.backlight_on()

    def cb_illuminance_v2(self, illuminance):
        if self.lcd is not None:
            text = 'Illuminanz %6.2f lx' % (illuminance/100.0)
            self.lcd.write_line(0, 0, text)
            log.debug('Write to line 0: ' + text)

    def cb_humidity_v2(self, humidity):
        if self.lcd is not None:
            text = 'Luftfeuchte %5.2f %%' % (humidity/100.0)
            self.lcd.write_line(1, 0, text)
            log.debug('Write to line 1: ' + text)

            try:
                temperature = self.hum_v2.get_temperature()
            except Error as e:
                log.error('Could not get temperature: ' + str(e.description))
                return

            # \xDF == ° on LCD 20x4 charset
            text = 'Temperatur %6.2f \xDFC' % (temperature/100.0)
            self.lcd.write_line(3, 0, text)
            log.debug('Write to line 3: ' + text.replace('\xDF', '°'))


    def cb_air_pressure(self, air_pressure):
        if self.lcd is not None:
            text = 'Luftdruck %7.2f mb' % (air_pressure/1000.0)
            self.lcd.write_line(2, 0, text)
            log.debug('Write to line 2: ' + text)

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == BrickletLCD20x4.DEVICE_IDENTIFIER:
                try:
                    self.lcd = BrickletLCD20x4(uid, self.ipcon)
                    self.lcd.clear_display()
                    self.lcd.backlight_on()
                    self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_PRESSED,
                                               self.cb_lcd_button_pressed)
                    log.info('LCD 20x4 initialized')
                except Error as e:
                    log.error('LCD 20x4 init failed: ' + str(e.description))
                    self.lcd = None
            elif device_identifier == BrickletAmbientLightV2.DEVICE_IDENTIFIER:
                try:
                    self.al_v2 = BrickletAmbientLightV2(uid, self.ipcon)
                    self.al_v2.set_configuration(self.al_v2.ILLUMINANCE_RANGE_64000LUX,
                                                 self.al_v2.INTEGRATION_TIME_200MS)
                    self.al_v2.set_illuminance_callback_period(1000)
                    self.al_v2.register_callback(self.al_v2.CALLBACK_ILLUMINANCE,
                                                 self.cb_illuminance_v2)
                    log.info('Ambient Light 2.0 initialized')
                except Error as e:
                    log.error('Ambient Light 2.0 init failed: ' + str(e.description))
                    self.al_v2 = None
            elif device_identifier == BrickletHumidityV2.DEVICE_IDENTIFIER:
                try:
                    self.hum_v2 = BrickletHumidityV2(uid, self.ipcon)
                    self.hum_v2.set_humidity_callback_configuration(1000, True, 'x', 0, 0)
                    self.hum_v2.register_callback(self.hum_v2.CALLBACK_HUMIDITY,
                                                  self.cb_humidity_v2)
                    log.info('Humidity 2.0 initialized')
                except Error as e:
                    log.error('Humidity 2.0 init failed: ' + str(e.description))
                    self.hum_v2 = None
            elif device_identifier == BrickletBarometer.DEVICE_IDENTIFIER:
                try:
                    self.baro = BrickletBarometer(uid, self.ipcon)
                    self.baro.set_air_pressure_callback_period(1000)
                    self.baro.register_callback(self.baro.CALLBACK_AIR_PRESSURE,
                                                self.cb_air_pressure)
                    log.info('Barometer initialized')
                except Error as e:
                    log.error('Barometer init failed: ' + str(e.description))
                    self.baro = None
            elif device_identifier == BrickMaster.DEVICE_IDENTIFIER:
                try:
                    self.master = BrickMaster(uid, self.ipcon)
                    self.master.disable_status_led()
                    log.info('MasterBrick initialized')
                except Error as e:
                    log.error('MasterBrick init failed: ' + str(e.description))
                    self.baro = None

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto Reconnect')

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
Example #12
0
class tiFo:
    
    r = [0]*16
    g = [0]*16
    b = [0]*16
    
    def __init__(self):
        self.led = None
        self.io = []
        self.io16list = io16Dict()
        self.LEDs = []
        self.LEDList = LEDStrips()
        self.al = []
        self.drb = []
        self.master = []
        self.md = []
        self.si = []
        self.ptc = []
        self.co2 = []
        self.moist = None
        # Create IP Connection
        self.ipcon = IPConnection() 
        # Register IP Connection callbacks
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, 
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, 
                                     self.cb_connected)
        # Connect to brickd, will trigger cb_connected
        self.ipcon.connect(constants.ownIP, PORT) 
        self.unknown = []
        self.threadliste = []
        #self.ipcon.enumerate()        

    def thread_RSerror(self):
        for mastr in self.master:    
            print mastr.get_rs485_error_log()
        thread_rs_error = Timer(60, self.thread_RSerror, [])
        thread_rs_error.start()         

    def cb_ambLight(self, illuminance,device):
        thresUp = illuminance * 4/3
        thresDown = illuminance * 4 / 5
        if thresDown == 0:
            thresDown = 0
            thresUp = 3
        if thresUp > 9000:
            thresUp = 9000            
        #print illuminance, thresDown, thresUp
        device.set_illuminance_callback_threshold('o', thresDown, thresUp)
        dicti = {}
        name = tifo_config.inputs.get(str(device.get_identity()[1]) +"."+ str(device.get_identity()[0]))
        name = str(device.get_identity()[1]) +"."+ str(device.get_identity()[0])
        dicti['Value'] = str(illuminance)
        dicti['Name'] = 'TiFo.' + name
        #print dicti
        mySocket.sendto(str(dicti) ,(constants.server1,constants.broadPort))
        
    def thread_ambLight(self, device):
        illuminance = device.get_illuminance()
        dicti = {}
        name = tifo_config.inputs.get(str(device.get_identity()[1]) +"."+ str(device.get_identity()[0]))
        name = str(device.get_identity()[1]) +"."+ str(device.get_identity()[0])
        dicti['Value'] = str(illuminance)
        dicti['Name'] = 'TiFo.' + name
        #print dicti
        mySocket.sendto(str(dicti) ,(constants.server1,constants.broadPort))
        thread_cb_amb = Timer(60, self.thread_ambLight, [device])
        thread_cb_amb.start()        

    def thread_CO2(self, device):
        value = device.get_co2_concentration()
        dicti = {}
        name = tifo_config.inputs.get(str(device.get_identity()[1]) +"."+ str(device.get_identity()[0]))
        name = str(device.get_identity()[1]) +"."+ str(device.get_identity()[0])
        dicti['Value'] = str(value)
        dicti['Name'] = 'TiFo.' + name
        mySocket.sendto(str(dicti) ,(constants.server1,constants.broadPort))
        thread_co2_ = Timer(60, self.thread_CO2, [device])
        thread_co2_.start()

    def thread_pt(self, device):
        value = device.get_temperature()
        dicti = {}
        name = tifo_config.inputs.get(str(device.get_identity()[1]) +"."+ str(device.get_identity()[0]))
        name = str(device.get_identity()[1]) +"."+ str(device.get_identity()[0])
        dicti['Value'] = str(float(value)/100)
        dicti['Name'] = 'TiFo.' + name
        mySocket.sendto(str(dicti) ,(constants.server1,constants.broadPort))
        thread_pt_ = Timer(60, self.thread_pt, [device])
        thread_pt_.start()

    def cb_interrupt(self, port, interrupt_mask, value_mask, device, uid):
        #print('Interrupt on port: ' + port + str(bin(interrupt_mask)))
        #print('Value: ' + str(bin(value_mask)))
        namelist = []
        temp_uid = uid #str(device.get_identity()[1]) +"."+ str(device.get_identity()[0])
        bit_list = [(1 << bit) for bit in range(7, -1, -1)]
        for wert in bit_list:
            if interrupt_mask & wert > 0:
                name = tifo_config.IO16i.get(temp_uid).get(port + str(bin(wert)))
                name = temp_uid + "." + port + str(bin(wert))
                if name <> None:
                    namelist.append(name)
        if port == 'a':
            nc_mask = tifo_config.IO16.get(temp_uid)[7]
        else:
            nc_mask = tifo_config.IO16.get(temp_uid)[8]
        value = (value_mask&interrupt_mask)/interrupt_mask
        nc_pos = (nc_mask&interrupt_mask)/interrupt_mask
        dicti = {}
#        dicti['Name'] = name
#        dicti['temp_uid'] = temp_uid
#        dicti['name'] = port + str(bin(interrupt_mask))
        #print name, value
        self.io16list.setValues(device,value_mask,port)
        #print self.io16list.getTimeDiff(device,interrupt_mask, port)
        if value == nc_pos:        
            dicti['Value'] = self.io16list.getTimeDiff(device,interrupt_mask, port)
        else:
            dicti['Value'] = 0
            self.io16list.setTime(device,interrupt_mask, port)
        #print dicti
        for name in namelist:
            dicti['Name'] = 'TiFo.' + name
            mySocket.sendto(str(dicti) ,(constants.server1,constants.broadPort))       

    def cb_md(self, device, uid):
        dicti = {'Name':tifo_config.inputs.get(uid),'Value':1}
        dicti = {'Name':'TiFo.' + str(device.get_identity()[1]) +"."+ str(device.get_identity()[0]),'Value':1}
        mySocket.sendto(str(dicti) ,(constants.server1,constants.broadPort))
        
    def cb_md_end(self, device, uid):
        dicti = {'Name':tifo_config.inputs.get(uid),'Value':0}
        dicti = {'Name':'TiFo.' + str(device.get_identity()[1]) +"."+ str(device.get_identity()[0]),'Value':0}
        mySocket.sendto(str(dicti) ,(constants.server1,constants.broadPort))      

    def cb_si(self,value, device, uid):
        dicti = {'Name':tifo_config.inputs.get(uid),'Value':value}
        dicti = {'Name':'TiFo.' + str(device.get_identity()[1]) +"."+ str(device.get_identity()[0]),'Value':value}
        mySocket.sendto(str(dicti) ,(constants.server1,constants.broadPort)) 

    def set_io16_sub(self,cmd,io,value):
        port = cmd.get('Port') 
        if port  == 'A':
            flopmask = tifo_config.IO16.get(io.get('addr'))[4]
            if flopmask & cmd.get('Pin') > 0:
                if value == 1:
                    normpos = tifo_config.IO16.get(io.get('addr'))[7]
                    io.get('IO').set_port_monoflop('a', cmd.get('Pin'),((~normpos)&0b11111111),tifo_config.IO16.get(io.get('addr'))[6])
            else:
                if value == 1:
                    mask = io.get('valueA') | cmd.get('Pin')
                else:
                    mask = io.get('valueA') & (0b11111111 & ~ cmd.get('Pin'))
                self.io16list.setValues(io.get('IO'),mask,'a')
                io.get('IO').set_port('a',mask)
        else:
            flopmask = tifo_config.IO16.get(io.get('addr'))[5]
            if flopmask & cmd.get('Pin') > 0:
                if value == 1:
                    #working but gets overwritten but other commands
#                    normpos = tifo_config.IO16.get(io.get('addr'))[8]
#                    io.get('IO').set_port_monoflop('b', cmd.get('Pin'),((~normpos)&0b11111111),tifo_config.IO16.get(io.get('addr'))[6]) 
                    mask = io.get('IO').get_port('b') | cmd.get('Pin')
                    io.get('IO').set_port('b',mask)
                    time.sleep(float(tifo_config.IO16.get(io.get('addr'))[6])/1000)
                    mask = io.get('IO').get_port('b') & (0b11111111 & ~ cmd.get('Pin'))
                    io.get('IO').set_port('b',mask)   
            else:
                if value == 1:
                    mask = io.get('IO').get_port('b') | cmd.get('Pin')
                else:
                    mask = io.get('IO').get_port('b') & (0b11111111 & ~ cmd.get('Pin'))
                self.io16list.setValues(io.get('IO'),mask,'b')
                io.get('IO').set_port('b',mask)       

    def set_io16(self,device,value):
        #koennte noch auch .set_selected_values(port, selection_mask, value_mask) umgeschrieben werden
        #monoflop tut nicht
        cmd_lsts = tifo_config.IO16o.get(device)
        for cmd in cmd_lsts:
            if cmd.get('Value') == value:
                cmds = cmd.get('Commands')
                #print cmds
                if type(cmds) in (list,tuple):
                    for cmd in cmds:
                        #print cmd
                        if cmd.get('Value') == 0: #erst alle auf Null setzen
                            addr = cmd.get('UID') 
                            for io in self.io16list.liste:
                                if io.get('addr') == addr:
                                    self.set_io16_sub(cmd,io,cmd.get('Value'))
                    for cmd in cmds:                            
                        if cmd.get('Value') == 1: #erst alle auf Null setzen
                            addr = cmd.get('UID') 
                            for io in self.io16list.liste:
                                if io.get('addr') == addr:
                                    self.set_io16_sub(cmd,io,cmd.get('Value'))    
                else:
                    cmd = cmds
                    addr = cmd.get('UID') 
                    for io in self.io16list.liste:
                        if io.get('addr') == addr:
                            self.set_io16_sub(cmd,io,cmd.get('Value'))
        return True                           

    def _set_LED_zusammen(self,LED,start,ende,red,green,blue,transitiontime):
        laenge = (ende-start)                        
        o_r, o_g, o_b = LED.get('LED').get_rgb_values(start, 1)
        steps = abs(red-o_r) + abs(green-o_g) + abs(blue-o_b)
        wartezeit = float(transitiontime) / steps 
        while o_r <> red or o_g <> green or o_b <> blue:
            while (laenge) > 16:
                laenge = 16
                if (red-o_r) > 0:
                    o_r = o_r + 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit)
                elif (red-o_r) < 0:
                    o_r = o_r - 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit)
                if (green-o_g) > 0:
                    o_g = o_g + 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit)
                elif (green-o_g) < 0:
                    o_g = o_g - 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit) 
                if (blue-o_b) > 0:
                    o_b = o_b + 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit)
                elif (blue-o_b) < 0:
                    o_b = o_b - 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit)                                     
                start += laenge
                laenge = (ende-start)
            else:
                if (red-o_r) > 0:
                    o_r = o_r + 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit)
                elif (red-o_r) < 0:
                    o_r = o_r - 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit)
                if (green-o_g) > 0:
                    o_g = o_g + 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit)
                elif (green-o_g) < 0:
                    o_g = o_g - 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit) 
                if (blue-o_b) > 0:
                    o_b = o_b + 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit)
                elif (blue-o_b) < 0:
                    o_b = o_b - 1
                    LED.get('LED').set_rgb_values(start, laenge, o_r, o_g, o_b)
                    time.sleep(wartezeit)       
        
    def set_LED(self, **kwargs):
#        device, rot, gruen, blau, transitiontime, transition=ANSTEIGEND
        device = kwargs.get('Device')
#        range check kwargs
        try:
            for varia in ['red','green','blue']:
                if int(kwargs.get(varia)) > 255:
                    kwargs[varia] = 255
                if int(kwargs.get(varia)) < 0:
                    kwargs[varia] = 0            
            green = int(kwargs.get('red',0))
            blue = int(kwargs.get('green',0))
            red = int(kwargs.get('blue',0))
    
            transitiontime = kwargs.get('transitiontime')
            transition = kwargs.get('transition',ANSTEIGEND)
            proc = kwargs.get('percentage',None)
    
            red_1 = kwargs.get('blue_1','None')
            green_1 = kwargs.get('red_1','None')
            blue_1 = kwargs.get('green_1','None')
    
            red_2 = int(kwargs.get('blue_2',0))
            green_2 = int(kwargs.get('red_2',0))
            blue_2 = int(kwargs.get('green_2',0))        
        except:
            print(kwargs)
            return False
#        gradient
#        lauflicht          
        LEDDict = tifo_config.LEDsOut.get(device)
        uid = LEDDict.get('UID')
        start = LEDDict.get('Start')
        ende = LEDDict.get('Ende')
#        TODO vectorize
        delta_r = 0
        delta_g = 0
        delta_b = 0        
        if str(red_1) == 'None' and str(green_1) == 'None' and str(blue_1) == 'None':
            red = [int(red)]*16
            green = [int(green)]*16
            blue = [int(blue)]*16 
            gradient = False
        else:
            laenge = (ende-start)
            if not str(red_1) == 'None':
                delta_r = int(red_1) - int(red)
                delta_pr = float(delta_r) / laenge
            else:
                delta_pr = 0
            if not str(green_1) == 'None':
                delta_g = (int(green_1) -int(green))
                delta_pg = float(delta_g) / laenge
            else:
                delta_pg = 0                
            if not str(blue_1) == 'None':
                delta_b = (int(blue_1) - int(blue))    
                delta_pb = float(delta_b) / laenge 
            else:
                delta_pb = 0 
            gradient = True

        for LED in self.LEDList.liste:
            if LED.get('addr') == uid:
                laenge = (ende-start)
                if proc <> None and 0 <= proc <= 100:
                    laenge = int(float(proc)/100 * laenge)                  
                elif proc <> None and proc < 0:
                    laenge = 0  
                if (transitiontime == None or transitiontime <= 0) and not gradient:                  
                    while (laenge) > 16:
                        laenge = 16
#                         TODO check that command is executed
#                        while not (red, green, blue) == LED.get('LED').get_rgb_values(start, laenge):
                        LED.get('LED').set_rgb_values(start, laenge, red, green, blue)
                        start += laenge
                        laenge = (ende-start)
                    else:
                        LED.get('LED').set_rgb_values(start, laenge, red, green, blue)
                elif not (transitiontime == None or transitiontime <= 0):
#                    Ansteigend
                    if transition == ANSTEIGEND:
                        wartezeit = float(transitiontime) / (ende-start)
                        for birne in range(start,ende):
                            LED.get('LED').set_rgb_values(birne, 1, red, green, blue)  
                            time.sleep(wartezeit)
                    elif transition == ABSTEIGEND:
                        wartezeit = float(transitiontime) / (ende-start)
                        for birne in list(reversed(range(start,ende))):
                            LED.get('LED').set_rgb_values(birne, 1, red, green, blue)  
                            time.sleep(wartezeit)        
                    elif transition == ZUSAMMEN:
                        self._set_LED_zusammen(LED,start,ende,red,green,blue,transitiontime)  
                else:
                    for birne in range(start,(start+laenge)):
                        LED.get('LED').set_rgb_values(birne, 1, [int(red)]*16, [int(green)]*16, [int(blue)]*16)  
                        red += delta_pr
                        green += delta_pg
                        blue += delta_pb  
                    for birne in range((start+laenge),ende):
                        LED.get('LED').set_rgb_values(birne, 1, [int(red_2)]*16, [int(green_2)]*16, [int(blue_2)]*16)                          
#        TODO Transition, 4 types
#        von links nach rechts (ansteigend), von rechts nach links (absteigend)
#        alle zusammen, beides                

        return True
         
    def set_drb(self, device, value):
        uid_cmds = tifo_config.DualRelay.get(device) 
        uid = ''
        for cmd in uid_cmds:
            if (cmd.get('Value')) == float(value):
                uid = cmd.get('UID')
                state = cmd.get('state')
                relaynr = cmd.get('relay')
        for relay in self.drb:
            temp_uid = str(relay.get_identity()[1]) +"."+ str(relay.get_identity()[0])
            if temp_uid == uid:
                relay.set_selected_state(relaynr, state)
                return True
        return False
         
         
    def set_device(self, data_ev): 
#       TODO do threaded with stop criteria
        if tifo_config.outputs.get(data_ev.get('Device')) == 'IO16o':
            return self.set_io16(data_ev.get('Device'),data_ev.get('Value'))
        elif tifo_config.outputs.get(data_ev.get('Device')) == 'IO16o':
            return self.set_io16(data_ev.get('Device'),data_ev.get('Value'))
        elif tifo_config.outputs.get(data_ev.get('Device')) == 'LEDs':
            return self.set_LED(**data_ev) #data_ev.get('Device'),data_ev.get('red'),data_ev.get('green'),data_ev.get('blue'),data_ev.get('transitiontime'))      
        elif tifo_config.outputs.get(data_ev.get('Device')) == 'DualRelay':
            return self.set_drb(data_ev.get('Device'),data_ev.get('Value'))            
        else:
            return False

    def cb_enumerate(self, uid, connected_uid, position, hardware_version, 
                     firmware_version, device_identifier, enumeration_type):
        #global self.led
        found = False
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            # Enumeration for LED
            if device_identifier == LEDStrip.DEVICE_IDENTIFIER:
                self.LEDs.append(LEDStrip(uid, self.ipcon))
                temp_uid = str(self.LEDs[-1].get_identity()[1]) +"."+ str(self.LEDs[-1].get_identity()[0])
                self.LEDList.addLED(self.LEDs[-1],temp_uid)
                self.LEDs[-1].set_frame_duration(200)
                if tifo_config.LEDs.get(temp_uid) <> None:
                    self.LEDs[-1].set_chip_type(tifo_config.LEDs.get(temp_uid)[0])
                    self.LEDs[-1].set_frame_duration(tifo_config.LEDs.get(temp_uid)[1])
                    found  = True
                #self.led.register_callback(self.led.CALLBACK_FRAME_RENDERED, 
                #                lambda x: __cb_frame_rendered__(self.led, x))
                #self.led.set_rgb_values(0, self.NUM_LEDS, self.r, self.g, self.b)
                #self.led.set_rgb_values(15, self.NUM_LEDS, self.r, self.g, self.b)
                #self.led.set_rgb_values(30, self.NUM_LEDS, self.r, self.g, self.b)

            if device_identifier == IO16.DEVICE_IDENTIFIER:
                self.io.append(IO16(uid, self.ipcon))
                temp_uid = str(self.io[-1].get_identity()[1]) +"."+ str(self.io[-1].get_identity()[0])
                self.io16list.addIO(self.io[-1],temp_uid,16)
                self.io[-1].set_debounce_period(100)
                if tifo_config.IO16.get(temp_uid) <> None:
                    self.io[-1].set_port_interrupt('a', tifo_config.IO16.get(temp_uid)[0])
                    self.io[-1].set_port_interrupt('b', tifo_config.IO16.get(temp_uid)[1])
                    self.io[-1].set_port_configuration('a', tifo_config.IO16.get(temp_uid)[0],'i',True)
                    self.io[-1].set_port_configuration('b', tifo_config.IO16.get(temp_uid)[1],'i',True)                    
                    self.io[-1].set_port_configuration('a', tifo_config.IO16.get(temp_uid)[2],'o',False)
                    self.io[-1].set_port_configuration('b', tifo_config.IO16.get(temp_uid)[3],'o',False)
                    #self.io[-1].set_port_monoflop('a', tifo_config.IO16.get(temp_uid)[4],0,tifo_config.IO16.get(temp_uid)[6])
                    #self.io[-1].set_port_monoflop('b', tifo_config.IO16.get(temp_uid)[5],0,tifo_config.IO16.get(temp_uid)[6])
                    self.io[-1].register_callback(self.io[-1].CALLBACK_INTERRUPT, partial( self.cb_interrupt, device = self.io[-1], uid = temp_uid ))
                    found  = True
             
            if device_identifier == AmbientLight.DEVICE_IDENTIFIER:
                self.al.append(AmbientLight(uid, self.ipcon))
                self.al[-1].set_illuminance_callback_threshold('o', 0, 0)
                self.al[-1].set_debounce_period(10)
                #self.al.set_illuminance_callback_threshold('<', 30, 30)
                #self.al.set_analog_value_callback_period(10000)
                #self.al.set_illuminance_callback_period(10000)
                #self.al.register_callback(self.al.CALLBACK_ILLUMINANCE, self.cb_ambLight)
                #self.al.register_callback(self.al.CALLBACK_ILLUMINANCE_REACHED, self.cb_ambLight)
                args = self.al[-1]
                #self.al[-1].register_callback(self.al[-1].CALLBACK_ILLUMINANCE_REACHED, lambda event1, event2, event3, args=args: self.cb_ambLight(event1, event2, event3, args))
                
                self.al[-1].register_callback(self.al[-1].CALLBACK_ILLUMINANCE_REACHED, partial( self.cb_ambLight,  device=args))
                temp_uid = str(self.al[-1].get_identity()[1]) +"."+ str(self.al[-1].get_identity()[0])               
                found  = True  
                thread_cb_amb = Timer(60, self.thread_ambLight, [self.al[-1]])
                thread_cb_amb.start() 

            if device_identifier == BrickletCO2.DEVICE_IDENTIFIER:
                self.co2.append(BrickletCO2(uid, self.ipcon))
                temp_uid = str(self.co2[-1].get_identity()[1]) +"."+ str(self.co2[-1].get_identity()[0])
                found  = True  
                thread_co2_ = Timer(5, self.thread_CO2, [self.co2[-1]])
                thread_co2_.start()    
                self.threadliste.append(thread_co2_)

            if device_identifier == BrickletDualRelay.DEVICE_IDENTIFIER:
                self.drb.append(BrickletDualRelay(uid, self.ipcon))
#                
#            if device_identifier == Moisture.DEVICE_IDENTIFIER:
#                self.moist = Moisture(uid, self.ipcon)
#                self.moist.set_moisture_callback_period(10000)
#                self.moist.register_callback(self.moist.CALLBACK_MOISTURE, self.cb_moisture)
            
            if device_identifier == BrickletMotionDetector.DEVICE_IDENTIFIER:   
                self.md.append(BrickletMotionDetector(uid, self.ipcon))
                temp_uid = str(self.md[-1].get_identity()[1]) +"."+ str(self.md[-1].get_identity()[0])
                self.md[-1].register_callback(self.md[-1].CALLBACK_MOTION_DETECTED, partial( self.cb_md, device = self.md[-1], uid = temp_uid ))  
                self.md[-1].register_callback(self.md[-1].CALLBACK_DETECTION_CYCLE_ENDED, partial( self.cb_md_end, device = self.md[-1], uid = temp_uid ))
                found  = True                
            
            if device_identifier == BrickletSoundIntensity.DEVICE_IDENTIFIER:   
                self.si.append(BrickletSoundIntensity(uid, self.ipcon))
                temp_uid = str(self.si[-1].get_identity()[1]) +"."+ str(self.si[-1].get_identity()[0])
# TODO: remove all ifs
                found  = True             
                self.si[-1].set_debounce_period(1000)                
                self.si[-1].register_callback(self.si[-1].CALLBACK_INTENSITY_REACHED, partial( self.cb_si, device = self.si[-1], uid = temp_uid ))  
                self.si[-1].set_intensity_callback_threshold('>', 200, 0)                    
            
            if device_identifier == BrickletPTC.DEVICE_IDENTIFIER:
                self.ptc.append(BrickletPTC(uid, self.ipcon))
                temp_uid = str(self.ptc[-1].get_identity()[1]) +"."+ str(self.ptc[-1].get_identity()[0])
                found  = True  
                thread_pt_ = Timer(5, self.thread_pt, [self.ptc[-1]])
                thread_pt_.start()   
                self.threadliste.append(thread_pt_)
            
            if device_identifier == BrickMaster.DEVICE_IDENTIFIER:   
                self.master.append(BrickMaster(uid, self.ipcon))
                thread_rs_error = Timer(60, self.thread_RSerror, [])
                #thread_rs_error.start()       
                if tifo_config.inputs.get(uid) <> None:
                    found  = True                 
            
            if not found:
                print connected_uid, uid, device_identifier

        
    def cb_connected(self, connected_reason):
        # Enumerate devices again. If we reconnected, the Bricks/Bricklets
        # may have been offline and the configuration may be lost.
        # In this case we don't care for the reason of the connection
        self.ipcon.enumerate()     
Example #13
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-  
# this one creates an array of connected devices called dev
# and acts as enum in standalone mode 

from tinkerforge.ip_connection import IPConnection
from settings import HOST, PORT

dev = []
def cb_enumerate(uid, name, stack_id, is_new):
    
    if is_new:
        print("New device:")
        dev.append([name, uid, stack_id])
    else:
        print("Removed device:")
        for i in dev:
            if i[1] == uid:
                dev.remove(i)
    if __name__ == "__main__":
        print(" Name:     " + name)
        print(" UID:      " + uid)
        print(" Stack ID: " + str(stack_id))
        print("")
     
if __name__ == "__main__":
    ipcon = IPConnection(HOST, PORT) # Create IP connection to brickd
    ipcon.enumerate(cb_enumerate) # Enumerate Bricks and Bricklets

    raw_input('Press key to exit\n') # Use input() in Python 3
    ipcon.destroy()
Example #14
0
class RTCTimeToLinuxTime:
    def __init__(self):
        # Create IP connection
        self.ipcon = IPConnection()

        # Connect to brickd
        self.ipcon.connect(HOST, PORT)
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate)
        self.ipcon.enumerate()

        self.enum_sema = Semaphore(0)
        self.rtc_uid = None
        self.rtc_device_identifier = None
        self.rtc = None
        self.rtc_time = None
        self.timer = None

    # go trough the functions to update date and time
    def __enter__(self):
        if self.is_ntp_present():
            return -1, None
        if not self.get_rtc_uid():
            return -2, None
        if not self.get_rtc_time():
            return -3, None
        if self.are_times_equal():
            return 1, self.rtc_time
        if not self.set_linux_time():
            return -4, None

        return 0, self.rtc_time

    def __exit__(self, type, value, traceback):
        try:
            self.timer.cancel()
        except:
            pass

        try:
            self.ipcon.disconnect()
        except:
            pass

    def is_ntp_present(self):
        # FIXME: Find out if we have internet access and ntp is working, in
        #        that case we don't need to use the RTC time.
        return False

    def get_rtc_uid(self):
        try:
            # Release semaphore after 1 second (if no Real-Time Clock Bricklet is found)
            self.timer = Timer(1, self.enum_sema.release)
            self.timer.start()
            self.enum_sema.acquire()
        except:
            return False

        return True

    def get_rtc_time(self):
        if self.rtc_uid == None:
            return False

        try:
            # Create Real-Time Clock device object
            if self.rtc_device_identifier == BrickletRealTimeClock.DEVICE_IDENTIFIER:
                self.rtc = BrickletRealTimeClock(self.rtc_uid, self.ipcon)
                year, month, day, hour, minute, second, centisecond, _ = self.rtc.get_date_time()
            else:
                self.rtc = BrickletRealTimeClockV2(self.rtc_uid, self.ipcon)
                year, month, day, hour, minute, second, centisecond, _, _ = self.rtc.get_date_time()

            self.rtc_time = datetime.datetime(year, month, day, hour, minute, second, centisecond * 10000)
        except:
            return False

        return True

    def are_times_equal(self):
        # Are we more then 3 seconds off?
        if abs(int(self.rtc_time.strftime("%s")) - time.time()) > 3:
            return False

        return True

    def set_linux_time(self):
        if self.rtc_time == None:
            return False

        try:
            # Set date as root
            command = ['/usr/bin/sudo', '-S', '/bin/date', self.rtc_time.strftime('%m%d%H%M%Y.%S')]
            Popen(command, stdout=PIPE, stdin=PIPE).communicate(SUDO_PASSWORD)
        except:
            return False

        return True

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        # If more then one Real-Time Clock Bricklet is connected we will use the first one that we find
        if device_identifier in [BrickletRealTimeClock.DEVICE_IDENTIFIER,
                                 BrickletRealTimeClockV2.DEVICE_IDENTIFIER]:
            self.rtc_uid = uid
            self.rtc_device_identifier = device_identifier
            self.enum_sema.release()
Example #15
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
class PiTinkerforgeStack:
    #host = '192.168.178.36' #raspi
    #host = '127.0.0.1' #localhost
    host = 'brickd'
    port = 4223
    female = False
    io = None
    poti_left = None
    poti_volume = None
    master = None

    def __init__(self):
        syslog.openlog('insultr-tf', 0, syslog.LOG_LOCAL4)

        self.con = IPConnection()

        # Register IP Connection callbacks
        self.con.register_callback(IPConnection.CALLBACK_ENUMERATE, 
                                     self.cb_enumerate)
        self.con.register_callback(IPConnection.CALLBACK_CONNECTED, 
                                     self.cb_connected)
        
        self.insultr = Insultr()
        self.set_volume(50)
        self.log("---" + str(15^15))
        self.log("---" + str(15^14))

    def log(self, msg):
        syslog.syslog(msg)
        print msg

    def connect(self):
        self.log("Connecting to host " + self.host + " on port " + str(self.port))
        self.con.connect(self.host, self.port)
        self.con.enumerate()

    def disconnect(self):
        self.log("Disconnecting from host " + self.host)
        self.con.disconnect()

    # Callback handles device connections and configures possibly lost 
    # configuration of lcd and temperature callbacks, backlight etc.
    def cb_enumerate(self, uid, connected_uid, position, hardware_version, 
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            
            self.log("cb_enumerate() id {} - Found device: ident={}, position={}".format(uid, device_identifier, position))
            if device_identifier == IO4.DEVICE_IDENTIFIER:
                self.log("cb_enumerate() id {} - Creating IO4 device object".format(uid))
                self.io = IO4(uid, self.con) 
                self.io.set_debounce_period(1000)

                if position == 'a':
                    self.log("cb_enumerate() id {} - Configuring IO4 device object at position a (switches).".format(uid))
                    self.io.register_callback(self.io.CALLBACK_INTERRUPT, self.io_switch)
                    self.io.set_configuration(15, 'i', True)
                    # Enable interrupt on pin 0 and 1
                    self.io.set_interrupt(1 << 0)
                    self.io.set_interrupt(1 << 1)
                    self.set_ziel_geschlecht(self.io.get_value())
                else:
                    self.log("cb_enumerate() id {} - Configuring IO4 device object at position ? (lights, shutdown).".format(uid))
                    self.io.set_configuration((1 << 0) | (1 << 1), "o", True)

            elif device_identifier == RotaryPoti.DEVICE_IDENTIFIER:
                self.log("cb_enumerate() id {} - Creating RotaryPoti device object".format(uid))
                self.poti_volume = RotaryPoti(uid, self.con) 
                self.poti_volume.set_position_callback_period(100)
                self.poti_volume.register_callback(self.poti_volume.CALLBACK_POSITION, self.poti_volume_changed)
            elif device_identifier == Master.DEVICE_IDENTIFIER:
                self.log("cb_enumerate() id {} - Creating Master device object".format(uid))
                self.master = Master(uid, self.con)
            else: 
                self.log("cb_enumerate() id {} - Could not register unknown device bricklet".format(uid))

    # Callback handles reconnection of IP Connection
    def cb_connected(self, connected_reason):
        # Enumerate devices again. If we reconnected, the Bricks/Bricklets
        # may have been offline and the configuration may be lost.
        # In this case we don't care for the reason of the connection
        self.con.enumerate()    

    def motion_detected(self):
        self.log("CALLBACK!!")
        self.insult()

    def insult(self):
        self.insultr.speak_next_insult()

    def set_volume(self, volume_percent=50):
        set_volume_cmd = 'amixer sset Master {}%'.format(volume_percent)
        self.log("set_volume() Setting volume with command: " + set_volume_cmd)
        os.system(set_volume_cmd)

    def set_volume_from_poti(self):
        if self.poti_volume:
            position = self.poti_volume.get_position()
            self.poti_volume_changed(position)
        else:            
            self.set_volume(50)

    def poti_volume_changed(self, position=0):
        self.log("poti_volume_changed() poti was set to position {}".format(position))
        if position > 150:
            position = 150
        if position < -150:
            position = -150
        MIN_VOLUME = 25.0
        MAX_VOLUME = 90.0
        poti_percent = ((position + 150.0) / 300.0) # between 0.0 and 1.0
        volume_percent = MIN_VOLUME + ((MAX_VOLUME-MIN_VOLUME)*poti_percent)
        self.set_volume(volume_percent)

    def motion_cycle_ended(self):
        self.log("READY for motion detection!")

    def io_switch(self, interrupt_mask, value_mask):
        self.log("io_switch() IO4 triggered")
        self.log("io_switch() Interrupt by {} / {} ".format(str(bin(interrupt_mask)), interrupt_mask))
        self.log('io_switch() Value: ' + str(bin(value_mask)))
        
        try: 
            self.set_volume_from_poti()

            if interrupt_mask == 1:
                self.log("io_switch() Sex switched...")
                # button 1 switched
                self.set_ziel_geschlecht(value_mask)
            elif interrupt_mask == 2:
                self.log("io_switch() Insult button pressed...")
                button_up = value_mask&2
                self.log("io_switch() value_mask =" + str(button_up))
                if button_up == 2:
                    self.insult()
            else: 
                self.log("io_switch() Don't know what to do with interrupt_mask {}".format(interrupt_mask))
        except Error as e:
            self.log("io_switch() ERROR:{}".format(e))
            
        self.log("io_switch() end")

    def set_ziel_geschlecht(self, value_mask):
        is_on = value_mask^14
        if is_on:
            self.log("sex was set to MALE")
            self.female = False
            self.insultr.set_maennlich()
            self.io.set_configuration(1 << 0, "o", True)
            self.io.set_configuration(1 << 1, "o", False)
        else:
            self.log("sex was set to FEMALE")
            self.female = True
            self.insultr.set_weiblich()
            self.io.set_configuration(1 << 0, "o", False)
            self.io.set_configuration(1 << 1, "o", True)


    def register_callbacks(self):
        self.log("Registering callback to motion detector...")
        self.motion.register_callback(self.motion.CALLBACK_MOTION_DETECTED, self.motion_detected)
        self.motion.register_callback(self.motion.CALLBACK_DETECTION_CYCLE_ENDED, self.motion_cycle_ended)
        self.io.set_debounce_period(1000)
        self.io.register_callback(self.io.CALLBACK_INTERRUPT, self.io_switch)
        # Enable interrupt on pin 0
        self.io.set_interrupt((1 << 0) | (1 << 1))
        #self.io.set_interrupt(1 << 1)
        self.log("register done")
Example #17
0
class LushRoomsLighting():
    def __init__(self):
        print('Lushroom Lighting init!')
        self.PLAY_HUE = True
        self.PLAY_DMX = True
        self.TRANSITION_TIME = 5  # milliseconds
        self.hue_list = [[]]
        self.player = None
        self.scheduler = None
        self.dmx_interpolator = DmxInterpolator()

        # 'last_played' seems to be the last numbered lighting event
        # in the SRT file
        self.last_played = 0
        self.subs = ""

        # Hue
        self.bridge = None

        # DMX
        self.dmx = None
        self.tfIDs = []
        self.ipcon = IPConnection()
        self.deviceIDs = [i[0] for i in deviceIdentifiersList]

        if self.PLAY_DMX: self.initDMX()
        if self.PLAY_HUE: self.initHUE()

    def emptyDMXFrame(self):
        return zeros((512, ), dtype=int)

    # Tinkerforge sensors enumeration
    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        self.tfIDs.append([uid, device_identifier])

    ############################### LIGHTING FUNCTION METHODS

    def initDMX(self):
        # configure Tinkerforge DMX
        try:
            self.ipcon.connect(HOST, PORT)

            # Register Enumerate Callback
            self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                         self.cb_enumerate)

            # Trigger Enumerate
            self.ipcon.enumerate()

            # Likely wait for the tinkerforge brickd to finish doing its thing
            sleep(0.7)

            if DEBUG:
                print("Tinkerforge enumerated IDs", self.tfIDs)

            dmxcount = 0
            for tf in self.tfIDs:
                if len(
                        tf[0]
                ) <= 3:  # if the device UID is 3 characters it is a bricklet
                    if tf[1] in self.deviceIDs:
                        if VERBOSE:
                            print(tf[0], tf[1], self.getIdentifier(tf))
                    if tf[1] == 285:  # DMX Bricklet
                        if dmxcount == 0:
                            print(
                                "Registering %s as slave DMX device for playing DMX frames"
                                % tf[0])
                            self.dmx = BrickletDMX(tf[0], self.ipcon)
                            self.dmx.set_dmx_mode(self.dmx.DMX_MODE_MASTER)
                            self.dmx.set_frame_duration(DMX_FRAME_DURATION)
                        dmxcount += 1

            if dmxcount < 1:
                if LIGHTING_MSGS:
                    print("No DMX devices found.")
        except Exception as e:
            print(
                "Could not create connection to Tinkerforge DMX. DMX lighting is now disabled"
            )
            print("Why: ", e)
            self.PLAY_DMX = False

    def resetDMX(self):
        print("Directly resetting DMX...")
        if self.dmx:
            self.dmx.write_frame([
                int(0.65 * MAX_BRIGHTNESS),
                int(0.40 * MAX_BRIGHTNESS),
                int(0.40 * MAX_BRIGHTNESS),
                int(0.40 * MAX_BRIGHTNESS),
                int(0.40 * MAX_BRIGHTNESS),
                int(0.40 * MAX_BRIGHTNESS),
                int(0.40 * MAX_BRIGHTNESS),
                int(0.40 * MAX_BRIGHTNESS),
                int(0.40 * MAX_BRIGHTNESS), 0, 0, 0,
                int(0.40 * MAX_BRIGHTNESS)
            ])
        else:
            logging.error("Could not connect to DMX daemon to reset!")

    def initHUE(self):
        try:
            if self.PLAY_HUE:
                HUE_IP_ADDRESS = find_hue.hue_ip()

                if HUE_IP_ADDRESS == None:
                    print("HUE disabled in settings.json, HUE is now disabled")
                    self.PLAY_HUE = False
                    return

                self.bridge = Bridge(HUE_IP_ADDRESS,
                                     config_file_path="/media/usb/python_hue")
                # If the app is not registered and the button is not pressed, press the button and call connect() (this only needs to be run a single time)
                self.bridge.connect()
                # Get the bridge state (This returns the full dictionary that you can explore)
                self.bridge.get_api()
                self.resetHUE()
                lights = self.bridge.lights
                self.hue_list = self.hue_build_lookup_table(lights)

                if LIGHTING_MSGS:
                    # Get a dictionary with the light name as the key
                    light_names = self.bridge.get_light_objects('name')
                    print("Light names:", light_names)
                    print(self.hue_list)
        except Exception as e:
            print(
                "Could not create connection to Hue. Hue lighting is now disabled"
            )
            print("Error: ", e)
            self.PLAY_HUE = False

    def resetHUE(self):
        if self.PLAY_HUE:
            for l in self.bridge.lights:
                # print(dir(l))
                l.on = True
            # Print light names
            # Set brightness of each light to 100
            for l in self.bridge.lights:
                if LIGHTING_MSGS:
                    print(l.name)
                l.brightness = 50
                ##l.colormode = 'ct'
                #l.colortemp_k = 2700
                #l.saturation = 0
                bri = 50
                sat = 100
                hue = 0
                colortemp = 450
                cmd = {
                    'transitiontime': int(self.TRANSITION_TIME),
                    'on': True,
                    'bri': int(bri),
                    'sat': int(sat),
                    'hue': int(hue),
                    'ct': colortemp
                }
                self.bridge.set_light(l.light_id, cmd)

    ############################### LOW LEVEL LIGHT METHODS

    def getIdentifier(self, ID):
        deviceType = ""
        for t in range(len(self.deviceIDs)):
            if ID[1] == deviceIdentifiersList[t][0]:
                deviceType = deviceIdentifiersList[t][1]
        return (deviceType)

    # tick()
    # callback that runs at every tick of the apscheduler

    def tick(self):
        # Leaving the comments below in for Francesco, they could be part of
        # a mysterious but useful debug strategy
        # try:

        if True:
            # print(subs[0])
            t = perf_counter()

            # ts = str(timedelta(seconds=t)).replace('.',',')
            # tsd = str(timedelta(seconds=t+10*TICK_TIME)).replace('.',',')

            ts = SubRipTime(seconds=t)
            tsd = SubRipTime(seconds=t + (1 * TICK_TIME))
            # print(dir(player))

            try:
                pp = self.player.getPosition()
            except Exception as e:
                print(
                    "Could not get the current position of the player, shutting down lighting gracefully..."
                )
                logging.error(e)
                self.__del__()

            #ptms = player.get_time()/1000.0
            #pt = SubRipTime(seconds=(player.get_time()/1000.0))
            #ptd = SubRipTime(seconds=(player.get_time()/1000.0+1*TICK_TIME))

            pt = SubRipTime(seconds=pp)
            ptd = SubRipTime(seconds=(pp + 1 * TICK_TIME))

            if DEBUG:
                #print('Time: %s | %s | %s - %s | %s - %s | %s | %s' % (datetime.now(),t,ts,tsd,pt,ptd,pp,ptms))
                # print('Time: %s | %s | %s | %s | %s | %s | %s ' % (datetime.now(),t,ts,tsd,pp,pt,ptd))
                pass
            ## sub, i = self.find_subtitle(subs, ts, tsd)
            # sub, i = self.find_subtitle(self.subs, pt, ptd)
            sub, i = self.find_subtitle(self.subs,
                                        pt,
                                        ptd,
                                        lo=self.last_played)

            if DEBUG:
                print(i, "Found Subtitle for light event:", sub, i)

            ## hours, minutes, seconds, milliseconds = time_convert(sub.start)
            ## t = seconds + minutes*60 + hours*60*60 + milliseconds/1000.0

            if sub != "":  #and i > self.last_played:
                if LIGHTING_MSGS and DEBUG:
                    print(i, "Light event:", sub)
                # print("Trigger light event %s" % i)
                self.trigger_light(sub)
                self.last_played = i
                if DEBUG:
                    print('last_played: ', i)

            pod_mode = MENU_DMX_VAL != None

            if self.dmx_interpolator.isRunning() and pod_mode is False:
                if self.PLAY_DMX:
                    if self.dmx != None:
                        iFrame = self.dmx_interpolator.getInterpolatedFrame(pt)
                        self.dmx.write_frame(iFrame)

            # except Exception as e:
            #     print('ERROR: It is likely the connection to the audio player has been severed...')
            #     print('Why? --> ', e)
            #     print('Scheduler is about to end gracefully...')
            #     self.__del__()

        # except:
        #    pass

    def find_subtitle(self, subtitle, from_t, to_t, lo=0, backwards=False):
        i = lo

        if backwards and SEEK_EVENT_LOG:
            print("searching backwards!")

        if DEBUG and VERBOSE:
            pass
            # print("Starting from subtitle", lo, from_t, to_t, len(subtitle))

        # Find where we are
        subLen = len(subtitle)

        while (i < subLen):
            if (subtitle[i].start >= to_t and not backwards):
                break

            if backwards and (subtitle[i].start >= from_t):
                previous_i = max(0, i - 1)
                if SEEK_EVENT_LOG:
                    print("In subs, at:", previous_i, " found: ",
                          subtitle[previous_i].text)
                return subtitle[previous_i].text, previous_i

            # if (from_t >= subtitle[i].start) & (fro   m_t  <= subtitle[i].end):
            if (subtitle[i].start >= from_t) & (to_t >= subtitle[i].start):
                # print(subtitle[i].start, from_t, to_t)
                if not self.dmx_interpolator.isRunning():
                    self.dmx_interpolator.findNextEvent(i, subtitle)
                return subtitle[i].text, i
            i += 1

        return "", i

    def end_callback(self, event):
        if LIGHTING_MSGS:
            print('End of media stream (event %s)' % event.type)
        exit(0)

    def hue_build_lookup_table(self, lights):
        if DEBUG:
            print("hue lookup lights: ", lights)

        hue_l = [[]]
        i = 0
        for j in range(1 + len(lights) + 1):
            for l in lights:
                #print(dir(l))
                #lname = "lamp   "+l.name+"   "
                lname = str(l.name)
                #print(lname)
                #print("testing", str(j), lname.find(str(i)), len(hue), l.name.find(str(i)), l.light_id, l.name, l.bridge.ip, l.bridge.name, str(i+1))
                if lname.find(str(j)) >= 0:
                    #if str(i) in lname:
                    if LIGHTING_MSGS:
                        print(j, lname.find(str(j)), l.light_id, l.name,
                              l.bridge.ip, l.bridge.name)
                    if len(hue_l) <= j:
                        hue_l.append([l.light_id])
                    else:
                        hue_l[j].append(l.light_id)
            i += 1
        if DEBUG:
            print("hue_l: ", hue_l)
        return (hue_l)

    def trigger_light(self, subs):
        global MAX_BRIGHTNESS, DEBUG
        if DEBUG:
            print("perf_count: ", perf_counter(), subs)
        commands = str(subs).split(";")

        if DEBUG:
            print("Trigger light", self.hue_list)
        for command in commands:
            try:
                # if True:
                # print(command)
                if DEBUG:
                    print(command[0:len(command) - 1].split("("))
                scope, items = command[0:len(command) - 1].split("(")

                if DEBUG:
                    print("sc: ", scope, "it: ", items)

                if scope[0:3] == "HUE" and self.PLAY_HUE:
                    l = int(scope[3:])
                    #print(l)
                    if VERBOSE:
                        print(self.hue_list[l])
                    hue, sat, bri, TRANSITION_TIME = items.split(',')
                    # print(perf_counter(), l, items, hue, sat, bri, TRANSITION_TIME)
                    bri = int((float(bri) / 255.0) * int(MAX_BRIGHTNESS))
                    # print(bri)
                    cmd = {
                        'transitiontime': int(self.TRANSITION_TIME),
                        'on': True,
                        'bri': int(bri),
                        'sat': int(sat),
                        'hue': int(hue)
                    }
                    if LIGHTING_MSGS:
                        print("Trigger HUE", l, cmd)
                    if self.PLAY_HUE:
                        #lights = bridge.lights
                        #for light in lights:
                        #   print(light.name)
                        #   if light.name.find(str(l)):
                        #       light.brightness = bri
                        #       light.hue = hue
                        #lights[l].brightness = bri
                        #lights[l].saturation = sat
                        #lights[l].hue = hue

                        for hl in self.hue_list[l]:
                            self.bridge.set_light(hl, cmd)

                if scope[0:3] == "DMX":
                    l = int(scope[3:])

                    if items == "":
                        print(
                            "Empty DMX event found! Turning all DMX channels off..."
                        )
                        channels = self.emptyDMXFrame()
                    else:
                        # channels = int(int(MAX_BRIGHTNESS)/255.0*(array(items.split(",")).astype(int)))
                        channels = array(items.split(",")).astype(int)
                        # channels = array(map(lambda i: int(MAX_BRIGHTNESS)*i, channels))

                    if LIGHTING_MSGS:
                        print("Trigger DMX:", l, channels)

                    if self.PLAY_DMX:
                        if self.dmx != None:
                            self.dmx.write_frame(channels)
            except:
                pass
        if LIGHTING_MSGS and DEBUG:
            print(30 * '-')

    ############################### PLAYER FUNCTION METHODS

    def time_convert(self, t):
        block, milliseconds = str(t).split(",")
        hours, minutes, seconds = block.split(":")
        return (int(hours), int(minutes), int(seconds), int(milliseconds))

    def start(self, audioPlayer, subs):
        self.player = audioPlayer
        self.subs = subs
        self.dmx_interpolator.__init__()
        subs_length = len(self.subs)
        if subs is not None:
            if LIGHTING_MSGS:
                print("Lighting: Start!")
                print('AudioPlayer: ', self.player)
                print("Number of lighting events: ", subs_length)
            # Trigger the first lighting event before the scheduler event starts
            self.triggerPreviousEvent(0)
            self.last_played = 0

            if subs_length == 1:
                if LIGHTING_MSGS:
                    print(
                        "There's only 1 lighting event, so no need to start the scheduler and unleash hell..."
                    )
            elif subs_length > 1:
                # start lighting scheduler
                self.scheduler = BackgroundScheduler({
                    'apscheduler.executors.processpool': {
                        'type': 'processpool',
                        'max_workers': '10'
                    }
                })
                self.scheduler.add_job(self.tick,
                                       'interval',
                                       seconds=TICK_TIME,
                                       misfire_grace_time=None,
                                       max_instances=16,
                                       coalesce=True)
                # This could be the cause of the _very_ first event, after a cold boot, not triggering correctly:
                self.scheduler.start(paused=False)

            if LIGHTING_MSGS:
                print("-------------")
        else:
            print(
                'Subtitle track not found/empty subtitle track. Lighting is now disabled'
            )

    def playPause(self, status):

        print('Lighting PlayPause: ', status)
        if status == "Paused":
            self.scheduler.pause()
        elif status == "Playing":
            self.scheduler.resume()
        if LIGHTING_MSGS:
            print("-------------")

    def fadeDown(self, status):

        print("Lighting: fadeDown")
        # self.scheduler.shutdown()
        self.last_played = 0

        if status == "Paused":
            self.scheduler.pause()
        elif status == "Playing":
            self.scheduler.resume()
        if LIGHTING_MSGS:
            print("-------------")

    def exit(self):
        self.__del__()

    def triggerPreviousEvent(self, pos):
        if LIGHTING_MSGS:
            print("Finding last lighting command from pos: ", pos)

        pp = pos
        pt = SubRipTime(seconds=pp)
        ptd = SubRipTime(seconds=(pp + 1 * TICK_TIME))

        if VERBOSE and DEBUG:
            print("Finding last light event, starting from: ")
            print("pt: ", ptd)
            print("ptd: ", ptd)

        sub, i = self.find_subtitle(self.subs, pt, ptd, backwards=True)

        if LIGHTING_MSGS:
            print("Seeking, found sub:", sub, " at pos: ", i)

        if sub != "":  #and i > self.last_played:
            if LIGHTING_MSGS and DEBUG:
                print(i, "Found last lighting event!:", sub)
            # print("Trigger light event %s" % i)
            self.trigger_light(sub)
            self.last_played = i
            if DEBUG:
                print('last_played: ', i)

    def seek(self, pos):
        # This doesn't seem to work fully...
        # But may be solved by LUSHDigital/lrpi_player#116
        # Get the last DMX and HUE events after a seek
        # Then trigger that...
        self.dmx_interpolator.__init__()
        self.triggerPreviousEvent(pos)

    def __del__(self):
        try:
            print("ipcon: ", self.ipcon)
            if self.scheduler:
                logging.info("Shutting down scheduler...")
                self.scheduler.shutdown()

            logging.info("Disconnecting from tinkerforge...")
            self.ipcon.disconnect()
            self.dmx = None
            self.ipcon = None
        except Exception as e:
            print('Lighting destructor failed: ', e)
        if LIGHTING_MSGS:
            print("Lighting died!")
class EVSEV2Tester:
    def __init__(self, log_func=None):
        if log_func:
            global log
            log = log_func

        self.ipcon = IPConnection()
        self.ipcon.connect(HOST, PORT)
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.enumerate()

        log("Trying to find EVSE Bricklet...")
        while UID_EVSE == None:
            time.sleep(0.1)
        log("Found EVSE Bricklet: {0}".format(UID_EVSE))

        self.evse = BrickletEVSEV2(UID_EVSE, self.ipcon)

        self.idai = BrickletIndustrialDualAnalogInV2(UID_IDAI, self.ipcon)
        self.idr = BrickletIndustrialDualRelay(UID_IDR, self.ipcon)
        #        self.idi4 = BrickletIndustrialDigitalIn4V2(UID_IDI4,   self.ipcon)
        self.iqr1 = BrickletIndustrialQuadRelayV2(UID_IQR1, self.ipcon)
        self.iqr2 = BrickletIndustrialQuadRelayV2(UID_IQR2, self.ipcon)
        self.iqr3 = BrickletIndustrialQuadRelayV2(UID_IQR3, self.ipcon)
        #        self.icou = BrickletIndustrialCounter(UID_ICOU,        self.ipcon)
        self.idai.set_sample_rate(self.idai.SAMPLE_RATE_61_SPS)

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        global UID_EVSE
        if device_identifier == BrickletEVSEV2.DEVICE_IDENTIFIER:
            UID_EVSE = uid

    # Live = True
    def set_contactor(self, contactor_input, contactor_output):
        if contactor_input:
            self.idr.set_selected_value(0, True)
            log('AC0 live')
        else:
            self.idr.set_selected_value(0, False)
            log('AC0 off')

        if contactor_output:
            self.idr.set_selected_value(1, True)
            log('AC1 live')
        else:
            self.idr.set_selected_value(1, False)
            log('AC1 off')

    def set_diode(self, enable):
        value = list(self.iqr1.get_value())
        value[0] = enable
        self.iqr1.set_value(value)
        if enable:
            log("Enable lock switch configuration diode")
        else:
            log("Disable lock switch configuration diode")

    def get_cp_pe_voltage(self):
        return self.idai.get_voltage(1)

    def set_cp_pe_resistor(self, r2700, r880, r240):
        value = list(self.iqr1.get_value())
        value[1] = r2700
        value[2] = r880
        value[3] = r240
        self.iqr1.set_value(value)

        l = []
        if r2700: l.append("2700 Ohm")
        if r880: l.append("880 Ohm")
        if r240: l.append("240 Ohm")

        log("Set CP/PE resistor: " + ', '.join(l))

    def set_pp_pe_resistor(self, r1500, r680, r220, r100):
        value = [r1500, r680, r220, r100]
        self.iqr2.set_value(value)

        l = []
        if r1500: l.append("1500 Ohm")
        if r680: l.append("680 Ohm")
        if r220: l.append("220 Ohm")
        if r100: l.append("110 Ohm")

        log("Set PP/PE resistor: " + ', '.join(l))

    def wait_for_contactor_gpio(self, active):
        if active:
            log("Waiting for contactor GPIO to become active...")
        else:
            log("Waiting for contactor GPIO to become inactive...")

        while True:
            state = self.evse.get_low_level_state()
            if state.gpio[9] == active:
                break
            time.sleep(0.01)

        log("Done")

    def wait_for_button_gpio(self, active):
        if active:
            log("Waiting for button GPIO to become active...")
        else:
            log("Waiting for button GPIO to become inactive...")

        while True:
            state = self.evse.get_low_level_state()
            if state.gpio[6] == active:
                break
            time.sleep(0.1)

        log("Done")

    def set_max_charging_current(self, current):
        self.evse.set_charging_slot(5, current, True, False)

    def shutdown_input_enable(self, enable):
        self.iqr3.set_selected_value(0, enable)

    def get_energy_meter_data(self):
        a = self.evse.get_energy_meter_values()
        b = self.evse.get_all_energy_meter_values()
        c = self.evse.get_hardware_configuration()
        d = self.evse.get_energy_meter_errors()
        return (a, b, c, d)

    def get_cp_pe_voltage(self):
        return self.idai.get_voltage(1)

    def get_pp_pe_voltage(self):
        return self.idai.get_voltage(0)

    def exit(self, value):
        self.iqr1.set_value([False] * 4)
        self.iqr2.set_value([False] * 4)
        self.iqr3.set_value([False] * 4)
        self.idr.set_value(False, False)
        sys.exit(value)
Example #19
0
def main():
    global tfIDs
    mqttc = mqtt.Client("")
    mqttc.username_pw_set(USERNAME, password=PASSWORD)
    mqttc.tls_set(ca_certs="{}/fakelerootx1.pem".format(os.getcwd()),
                  certfile=None,
                  keyfile=None,
                  cert_reqs=ssl.CERT_REQUIRED,
                  tls_version=ssl.PROTOCOL_TLS,
                  ciphers=None)
    mqttc.connect(MQTT_ADAPTER_IP,
                  MQTT_ADAPTER_PORT)  # mqtt.abc.re.je == 35.242.131.248:30883
    mqttc.loop_start()

    if TF_CONNECT:
        # Create connection and connect to brickd
        ipcon = IPConnection()

        TPS1_bricklet = BrickletTemperature(TPS1_UID, ipcon)
        HMS1_bricklet = BrickletHumidity(HMS1_UID, ipcon)
        LPS1_bricklet = BrickletAmbientLightV2(LPS1_UID, ipcon)

        ipcon.connect(TF_HOST, TF_PORT)

        # Register Enumerate Callback
        ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, cb_enumerate)

        # Trigger Enumerate
        ipcon.enumerate()

        time.sleep(2)

    if DEBUG:
        print(tfIDs)

    if PUBLISH:

        # Get current temperature
        TPS1 = TPS1_bricklet.get_temperature() / 100.0
        HMS1 = HMS1_bricklet.get_humidity() / 10.0
        LPS1 = LPS1_bricklet.get_illuminance() / 100.0

        today = dt.now().strftime("%Y-%m-%d %H:%M")
        today_0 = dt.now().strftime("%Y-%m-%d 00:00")
        t = dt.now().strftime("%H:%M")
        # dtt = dateutil.parser.parse(today)
        dtt = dt.utcnow()

        points_TPS1 = {}
        points_TPS1["temperature"] = {"present_value": TPS1}

        points_HMS1 = {}
        points_HMS1["humidity"] = {"present_value": HMS1}

        points_LPS1 = {}
        points_LPS1["illuminance"] = {"present_value": LPS1}

        udmi_payload_TPS1 = str(udmi.Pointset(dtt, points_TPS1))
        # print(udmi_payload_TPS1)
        udmi_payload_HMS1 = str(udmi.Pointset(dtt, points_HMS1))
        # print(udmi_payload_HMS1)
        udmi_payload_LPS1 = str(udmi.Pointset(dtt, points_LPS1))
        # print(udmi_payload_LPS1)

        payload_norm_TPS1 = json_normalize(
            json.loads(udmi_payload_TPS1)).to_json(
                orient='records').strip('[]')
        print(payload_norm_TPS1)
        payload_norm_HMS1 = json_normalize(
            json.loads(udmi_payload_HMS1)).to_json(
                orient='records').strip('[]')
        print(payload_norm_HMS1)
        payload_norm_LPS1 = json_normalize(
            json.loads(udmi_payload_LPS1)).to_json(
                orient='records').strip('[]')
        print(payload_norm_LPS1)

        # msg = json.dumps({"wind": wind, "humidity": humidity, "temperature": temperature})

        # infot = mqttc.publish("telemetry", udmi_payload, qos=1)
        # print("Sending {}".format(udmi_payload_TPS1))
        infot = mqttc.publish("telemetry/myapp.iot/{}".format("TPS-1"),
                              payload_norm_TPS1,
                              qos=1)
        # print("Sending {}".format(udmi_payload_HMS1))
        infot = mqttc.publish("telemetry/myapp.iot/{}".format("HMS-1"),
                              payload_norm_HMS1,
                              qos=1)
        # print("Sending {}".format(udmi_payload_LPS1))
        infot = mqttc.publish("telemetry/myapp.iot/{}".format("LPS-1"),
                              payload_norm_LPS1,
                              qos=1)

        infot.wait_for_publish()
Example #20
0
class ExampleRugged:
    HOST = "localhost"
    PORT = 4223

    def __init__(self):
        self.lcd = None
        self.temp = None

        # Create IP Connection
        self.ipcon = IPConnection() 

        # Register IP Connection callbacks
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, 
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, 
                                     self.cb_connected)

        # Connect to brickd, will trigger cb_connected
        self.ipcon.connect(ExampleRugged.HOST, ExampleRugged.PORT) 

        self.ipcon.enumerate()

    # Callback switches lcd backlight on/off based on lcd button 0
    def cb_button_pressed(self, button):
        if self.lcd:
            if button == 0:
                if self.lcd.is_backlight_on():
                    self.lcd.backlight_off()
                else:
                    self.lcd.backlight_on()

    # Callback updates temperature displayed on lcd
    def cb_temperature(self, temperature):
        if self.lcd:
            self.lcd.clear_display()
            s = 'Temperature: {0:.2f}{1:c}C'.format(temperature/100.0, 0xdf)
            self.lcd.write_line(0, 0, s)

    # Callback handles device connections and configures possibly lost 
    # configuration of lcd and temperature callbacks, backlight etc.
    def cb_enumerate(self, uid, connected_uid, position, hardware_version, 
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            
            # Enumeration is for LCD Bricklet
            if device_identifier == LCD20x4.DEVICE_IDENTIFIER:
                # Create lcd device object
                self.lcd = LCD20x4(uid, self.ipcon) 
                self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_PRESSED, 
                                           self.cb_button_pressed)
                self.lcd.clear_display()
                self.lcd.backlight_on()
            # Enumeration is for Temperature Bricklet
            if device_identifier == Temperature.DEVICE_IDENTIFIER:
                # Create temperature device object
                self.temp = Temperature(uid, self.ipcon) 
                self.temp.register_callback(self.temp.CALLBACK_TEMPERATURE, 
                                            self.cb_temperature)

                self.temp.set_temperature_callback_period(50)

    # Callback handles reconnection of IP Connection
    def cb_connected(self, connected_reason):
        # Enumerate devices again. If we reconnected, the Bricks/Bricklets
        # may have been offline and the configuration may be lost.
        # In this case we don't care for the reason of the connection
        self.ipcon.enumerate()
Example #21
0
def main():

    # host = "localhost"
    # port = 4223
    # segment_display_uid = "abc"         # uid of the sensor to display on the 7-segment display
    # segment_display_brightness = 2      # brightness of the 7-segment display (0-7)

    settings = read_config()
    parser = OptionParser()
    parser.add_option(
        "--host",
        dest="host",
        default=settings["host"],
        help="host/ipaddress of the tinkerforge device",
        metavar="ADDRESS",
    )
    parser.add_option(
        "--port",
        dest="port",
        default=settings["port"],
        type=int,
        help="port of the tinkerforge device",
        metavar="PORT",
    )
    parser.add_option(
        "--segment_display_uid",
        dest="uid",
        default=settings["segment_display_uid"],
        help="uid of the bricklet which will be displayed in the 7-segment display",
        metavar="UID",
    )
    parser.add_option(
        "--segment_display_brightness",
        type=int,
        dest="brightness",
        default=settings["segment_display_brightness"],
        help="brightness of the 7-segment display (0-7)",
    )

    options, _args = parser.parse_args()

    settings = {
        "host": options.host,
        "port": options.port,
        "segment_display_uid": options.uid,
        "segment_display_brightness": options.brightness,
    }

    try:
        from tinkerforge.ip_connection import IPConnection
    except ImportError:
        print("<<<tinkerforge:sep(44)>>>")
        print("master,0.0.0,tinkerforge api isn't installed")
        return 1

    conn = IPConnection()
    try:
        conn.connect(settings["host"], settings["port"])
    except socket.error as e:
        sys.stderr.write("%s\n" % e)
        return 1

    device_handlers = init_device_handlers()

    try:
        print("<<<tinkerforge:sep(44)>>>")

        def cb(
            uid,
            connected_uid,
            position,
            hardware_version,
            firmware_version,
            device_identifier,
            enumeration_type,
        ):
            enumerate_callback(
                conn,
                device_handlers,
                settings,
                uid,
                connected_uid,
                position,
                hardware_version,
                firmware_version,
                device_identifier,
                enumeration_type,
            )

        conn.register_callback(IPConnection.CALLBACK_ENUMERATE, cb)
        conn.enumerate()

        # bricklets respond asynchronously in callbacks and we have no way of knowing
        # what bricklets to expect
        time.sleep(0.1)

        if segment_display is not None:
            if segment_display_value is not None:
                display_on_segment(
                    conn, settings, "%d%s" % (segment_display_value, segment_display_unit)
                )
            else:
                display_on_segment(conn, settings, "")
    finally:
        conn.disconnect()
Example #22
0
        if str(uid) == '6R3jeY':
            print 'WLAN Controller connected...'
    else:
        print("UID:               " + uid)
        print("Enumeration Type:  " + str(enumeration_type))

        if enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED:
            print("")
            return

        print("Connected UID:     " + connected_uid)
        print("Position:          " + position)
        print("Hardware Version:  " + str(hardware_version))
        print("Firmware Version:  " + str(firmware_version))
        print("Device Identifier: " + str(device_identifier))
        print("")

if __name__ == "__main__":
    # Create connection and connect to brickd
    ipcon = IPConnection()
    ipcon.connect(HOST, PORT)

    # Register Enumerate Callback
    ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, cb_enumerate)

    # Trigger Enumerate
    ipcon.enumerate()

    raw_input("Press key to exit\n") # Use input() in Python 3
    ipcon.disconnect()
Example #23
0
class HiveDataCollector:
    def __init__(self):
        self.loadcell = None
        self.hygrometer = None
        self.barometer = None
        self.voltage = None
        self.ptc = None
        self.lastweight = None

        self.firstlowbat = True

        self.config = {}

        # Reading config
        with open(os.path.expanduser("~/digitalhive_sender.conf"),
                  'r') as stream:
            try:
                self.config = yaml.safe_load(stream)
            except yaml.YAMLError as exc:
                print("Konnte Konfiguration nicht laden.")
                sys.exit(1)

        # Create connection and connect to brickd
        self.ipcon = IPConnection()

        # Register Enumerate Callback
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.connect('localhost', 4223)

        # Trigger Enumerate
        self.ipcon.enumerate()
        time.sleep(5)  # So that the enumeration has a chance to be done.

        print("{} - Starting.".format(
            datetime.now().strftime('%Y-%m-%d %H:%M:%S')))

        try:
            while True:
                self.send()
                time.sleep(int(self.config['interval']) * 60)
        except Exception as e:
            self.ipcon.disconnect()
            print("{} - Stopping.".format(
                datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
            #print (str(e))

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        #print("UID:               " + uid)
        #print("Enumeration Type:  " + str(enumeration_type))

        if enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED:
            #print("")
            return

        #print("Connected UID:     " + connected_uid)
        #print("Position:          " + position)
        #print("Hardware Version:  " + str(hardware_version))
        #print("Firmware Version:  " + str(firmware_version))
        #print("Device Identifier: " + str(device_identifier))
        #print("")

        if device_identifier == BrickletLoadCellV2.DEVICE_IDENTIFIER:
            self.loadcell = BrickletLoadCellV2(uid, self.ipcon)

        if device_identifier == BrickletAirQuality.DEVICE_IDENTIFIER:
            airquality = BrickletAirQuality(uid, self.ipcon)
            self.hygrometer = airquality
            self.barometer = airquality

        if device_identifier == BrickletVoltageCurrentV2.DEVICE_IDENTIFIER:
            self.voltage = BrickletVoltageCurrentV2(uid, self.ipcon)

        if device_identifier == BrickletPTCV2.DEVICE_IDENTIFIER:
            self.ptc = BrickletPTCV2(uid, self.ipcon)
            if not self.ptc.is_sensor_connected():
                self.ptc = None
                return

            self.ptc.set_wire_mode(BrickletPTCV2.WIRE_MODE_4)

    def send(self):
        # The order is important, its the order it get's written into the file.
        data = collections.OrderedDict()
        data['timestamp'] = datetime.now().strftime('%Y-%m-%d %H:%M')
        data['weight'] = 0.0
        data['temp'] = '?'
        data['pressure-qfe'] = '?'
        data['pressure-qff'] = '?'
        data['humidity'] = '?'
        data['innertemp'] = '?'
        data['height'] = '?'
        data['bat'] = '?'
        data['weightchange'] = '?'

        # Weight Data
        if self.loadcell is not None:
            data['weight'] = self.loadcell.get_weight()
            data['weight'] = round(data['weight'] / 1000.00, 2)

            if self.lastweight is not None:
                data['weightchange'] = round(data['weight'] - self.lastweight,
                                             2)
            else:
                # The scale just started so the lastweight ist empty, we have to read it from the csv file.
                try:
                    with open('data.csv', 'r') as csvfile:
                        datareader = csv.DictReader(csvfile,
                                                    delimiter=',',
                                                    quotechar='"',
                                                    quoting=csv.QUOTE_MINIMAL,
                                                    lineterminator='\n')
                        for line in datareader:
                            if line['weight'] != '?':
                                self.lastweight = float(line['weight'])

                        data['weightchange'] = round(
                            data['weight'] - self.lastweight, 2)
                except:
                    # If that file doesn't exist yet, the change equals the weight.
                    data['weightchange'] = data['weight']

            self.lastweight = data['weight']

        # We need the tempreture first
        temp = '?'
        if self.hygrometer is not None:
            data['humidity'] = round(
                float(self.hygrometer.get_humidity() / 100.00), 1)
            temp = self.hygrometer.get_temperature(
            ) / 100.00  # Need the detailed value for qff value.
            data['temp'] = round((temp), 1)

        # Other values
        if self.barometer is not None:
            qfe = self.barometer.get_air_pressure() / 100.00
            data['pressure-qfe'] = int(round(qfe, 0))
            # In order to calculate the value as the weather forecast does, we need the current
            # temprature and the height of the location.
            #
            # Interesstingly enough, I don't think, one could set the later
            # value in the barometers you can buy. That's why they don't give a
            # read out, just a 'good weather, bad weather'. Theid either would
            # have to give the QFE value, which would differ quite a bit from the
            # weather forecast and therefore be consideres 'wrong' by the customers
            # or the customer would have to enter their location value.
            #
            # I planed on doing the calculation here. But that would basically fix
            # the value. If you move the sensor to a different location and forgot
            # to change the value, it would modify the data.csv. I'd rather not
            # do that. On the other hand: If you do move the scale, and change the
            # value afterwards, it would change all the old values. So we would
            # actually have to introduce a 'until' value for the height. Also,
            # we need the temperture to the the forecast value. This makes it
            # difficult to calculate in the Javascript / backend software.
            #
            # So, two values it is. The readout from the sensor, and a calculated
            # one. This way we have a simple value (qff) and the exact value if
            # we ever decide to recalculate it.
            #
            # We also send the HEIGHT value, so that we can use it for later
            # recalculation

            if self.config['height'] is not None and temp is not '?':
                qfe = float(data['pressure-qfe'])
                Tg = 0.0065
                H = self.config['height']
                Tfe = temp

                qff = qfe / (1 - Tg * H /
                             (273.15 + Tfe + Tg * H))**(0.034163 / Tg)
                data['pressure-qff'] = int(round(qff, 0))

        if self.ptc is not None:
            data['innertemp'] = round((self.ptc.get_temperature() / 100.00), 1)

        if self.config['height'] is not None:
            data['height'] = self.config['height']

        if self.voltage is not None:
            data['bat'] = round(float(self.voltage.get_voltage() / 1000.00), 2)

        if not os.path.exists('data.csv'):
            with open('data.csv', 'w') as csvfile:
                csvfile.write(
                    "timestamp,weight,temp,pressure-qfe,pressure-qff,humidity,innertemp,height,bat\n"
                )

        with open('data.csv', 'a') as csvfile:
            datawriter = csv.DictWriter(csvfile,
                                        data.keys(),
                                        delimiter=',',
                                        quotechar='"',
                                        quoting=csv.QUOTE_MINIMAL,
                                        lineterminator='\n')
            datawriter.writerow(data)

        try:
            r = requests.post(
                "{}/admin/newdata.php".format(self.config['dest_url']),
                data=data,
                auth=(self.config['dest_user'], self.config['dest_passt']),
                timeout=10)
        except:
            pass

        # Emergency Shutdown if voltage is to low
        if data['bat'] is not '?' and data['bat'] < self.config['shutdownvolt']:
            if self.firstlowbat == True:
                # We want to shutdown only if it happend the second time. Why?
                # Otherwise, if the battery runs out, and we attach the Raspberry pi to
                # a normal power supply - without the battery on - the battery read out
                # will show '0.0' as there is no current running. So it would more or
                # less immediately shutdown the raspberry pi again. Without a chance
                # to disable the battery monitor.
                self.firstlowbat = False
            else:
                subprocess.call('sudo shutdown -h now', shell=True)
Example #24
0
class ServerRoomMonitoring:
    HOST = "ServerMonitoring"
    PORT = 4223

    ipcon = None
    al = None
    al_v2 = None
    temp = None

    def __init__(self):
        self.xively = Xively()
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(ServerRoomMonitoring.HOST, ServerRoomMonitoring.PORT)
                break
            except Error as e:
                log.error('Connection Error: ' + str(e.description))
                time.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                time.sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate Error: ' + str(e.description))
                time.sleep(1)

    def cb_illuminance(self, illuminance):
        self.xively.put('AmbientLight', illuminance/10.0)
        log.info('Ambient Light ' + str(illuminance/10.0))

    def cb_illuminance_v2(self, illuminance):
        self.xively.put('AmbientLight', illuminance/100.0)
        log.info('Ambient Light ' + str(illuminance/100.0))

    def cb_temperature(self, temperature):
        self.xively.put('Temperature', temperature/100.0)
        log.info('Temperature ' + str(temperature/100.0))

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == AmbientLight.DEVICE_IDENTIFIER:
                try:
                    self.al = AmbientLight(uid, self.ipcon)
                    self.al.set_illuminance_callback_period(1000)
                    self.al.register_callback(self.al.CALLBACK_ILLUMINANCE,
                                              self.cb_illuminance)
                    log.info('Ambient Light initialized')
                except Error as e:
                    log.error('Ambient Light init failed: ' + str(e.description))
                    self.al = None
            elif device_identifier == AmbientLightV2.DEVICE_IDENTIFIER:
                try:
                    self.al_v2 = AmbientLightV2(uid, self.ipcon)
                    self.al_v2.set_illuminance_callback_period(1000)
                    self.al_v2.register_callback(self.al_v2.CALLBACK_ILLUMINANCE,
                                                 self.cb_illuminance_v2)
                    log.info('Ambient Light 2.0 initialized')
                except Error as e:
                    log.error('Ambient Light 2.0 init failed: ' + str(e.description))
                    self.al_v2 = None
            elif device_identifier == Temperature.DEVICE_IDENTIFIER:
                try:
                    self.temp = Temperature(uid, self.ipcon)
                    self.temp.set_temperature_callback_period(1000)
                    self.temp.register_callback(self.temp.CALLBACK_TEMPERATURE,
                                               self.cb_temperature)
                    log.info('Temperature initialized')
                except Error as e:
                    log.error('Temperature init failed: ' + str(e.description))
                    self.temp = None

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto Reconnect')

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
class TinkerforgeController:

    def __init__(self, host, port):
        print("hello - connecting to %s %s" % (host, port))
        # Create connection and connect to brickd
        self.ipcon = IPConnection()
        self.ipcon.connect(host, port)
        print("connected")
        self.devices = {}

        # Register Enumerate Callback
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, EnumerateCallback(self))

        # Trigger Enumerate
        self.ipcon.enumerate()

    def run(self):

        while True:
            try:
                time.sleep(1)
                self.next()
            except KeyboardInterrupt:
                self.stop()
                print("goodbye")
                break

    def next(self):
        print("tick")


    def __getattr__(self, name):
        if name in self.devices:
            return self.devices[name]
        else:
            return None


    def cb_enumerate(self,
                     uid,
                     connected_uid,
                     position,
                     hardware_version,
                     firmware_version,
                     device_identifier,
                     enumeration_type):


        device_class = device_factory.get_device_class(device_identifier)
        device = device_class(uid, self.ipcon)
        device_name = device_class.DEVICE_URL_PART

        counter = 2
        while device_name in self.devices:
            if device.uid == self.devices[device_name].uid:
                return
            device_name = "%s_%s" % (device_name, counter)
            counter += 1

        print("found %s" % device_name)
        self.devices[device_name] = device


        # print("UID:               " + uid)
        # print("Enumeration Type:  " + str(enumeration_type))
        #
        # if enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED:
        #     print("")
        #     return
        #
        # print("Connected UID:     " + connected_uid)
        # print("Position:          " + position)
        # print("Hardware Version:  " + str(hardware_version))
        # print("Firmware Version:  " + str(firmware_version))
        # print("Device Identifier: " + str(device_identifier))
        # print("")


    def stop(self):

        self.ipcon.disconnect()
        print("\ndisconnected")
class DoorbellNotifier:
    HOST = 'localhost'
    PORT = 4223
    ipcon = None
    idi4 = None

    def __init__(self):
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(DoorbellNotifier.HOST,
                                   DoorbellNotifier.PORT)
                break
            except Error as e:
                log.error('Connection Error: ' + str(e.description))
                time.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                time.sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate Error: ' + str(e.description))
                time.sleep(1)

    def cb_interrupt(self, changed, value):
        log.warn('Ring Ring Ring!')

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == IndustrialDigitalIn4V2.DEVICE_IDENTIFIER:
                try:
                    self.idi4 = IndustrialDigitalIn4V2(uid, self.ipcon)

                    self.idi4.set_all_value_callback_configuration(10000, True)
                    self.idi4.register_callback(
                        IndustrialDigitalIn4V2.CALLBACK_ALL_VALUE,
                        self.cb_interrupt)

                    log.info('Industrial Digital In 4 V2 initialized')
                except Error as e:
                    log.error('Industrial Digital In 4 V2 init failed: ' +
                              str(e.description))

                    self.idi4 = None

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto Reconnect')

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
Example #27
0
class master():
    """docstring for master"""
    def __init__(self):
        #super(master, self).__init__()
        print 'init...'
        self.PORT   = 4223
        self.MENU_running = False
        self.BOARD_running = False

        ### Connection for Menu
        self.MENU_HOST   = "192.168.0.150" # Manually Set IP of Controller Board   "127.0.0.1"#
        self.MENU_lcdUID = "gFt" # LCD Screen
        self.MENU_jskUID = "hAP" # Joystick
        ### END MENU CONNECTION

        ### Connection for Board
        self.BOARD_HOST   = "192.168.0.111"
        self.BOARD_mstUID = "62eUEf" # master brick
        self.BOARD_io1UID = "ghh"    # io16
        self.BOARD_lcdUID = "9ew"    # lcd screen 20x4
        self.BOARD_iqrUID = "eRN"    # industrial quad relay
        self.BOARD_iluUID = "i8U"    # Ambient Light
        #### END BOARD CONNECTION

        self.ipcon = IPConnection() # Create IP connection
        self.ipcon.connect('127.0.0.1', self.PORT)
        # Register Enumerate Callback
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate)

        # Trigger Enumerate
        self.ipcon.enumerate()        

        print 'ready?'
        #print self.start()
        return

    def help(self):
        return "\nCommands: \n" \
               "     - start\n" \
               "     - status\n" \
               "     - beep\n" \
               "     - light\n" \
               "     - startMenu\n" \
               "     - startBoard\n" \
               "     - stop\n"


    def start(self):
        if self.BOARD_running: print 'Board already running!'
        else: self.startBoard(); print 'Board Started!'

        if self.MENU_running: print 'Menu already running!'
        elif self.BOARD_running: self.startMenu(); print 'Menu Started!'
        return 'Started!'

    def toggleLight(self):
        if self.BOARD_running:
            print self.BB.status('light')
            return 'Light Toggled!'
        else: return 'Board is offline!'

    def toggleBeep(self):
        if self.BOARD_running:
            print self.BB.status('beep')
            return 'Beep Toggled!'
        else: return 'Board is offline!'


    def status(self):
        if self.BOARD_running:
            if self.BB.status('door'): doorState = 'Open'
            else: doorState = 'Closed'

            tempState = self.BB.status('temp')

            RunningString = 'Board: '+str(self.BOARD_running)+'\nMenu: '+str(self.MENU_running)
            StateString   = 'Door: ' + str(doorState) + '\nTemperature: ' + str(tempState) + '°C'

            return RunningString + '\n' + StateString
        return 'all offline'


    def startBoard(self):
        if self.BOARD_running: return 'Board already running!'

        if isOpen(self.BOARD_HOST, self.PORT):

            self.BOARD_running = True

            self.BOARD_ipcon = IPConnection() # Create IP connection

            self.mst = Master(self.BOARD_mstUID, self.BOARD_ipcon)   # Master Brick
            self.io1 = IO16(self.BOARD_io1UID, self.BOARD_ipcon)       # io16
            self.lcd1 = LCD20x4(self.BOARD_lcdUID, self.BOARD_ipcon)  # lcd20x4
            self.iqr = IndustrialQuadRelay(self.BOARD_iqrUID, self.BOARD_ipcon) # Create device object
            self.ilu = AmbientLight(self.BOARD_iqrUID, self.BOARD_ipcon) # Create device object

            self.BOARD_ipcon.connect(self.BOARD_HOST, self.PORT) # Connect to brickd

            # create Board instance 
            self.BB = B(self.mst, self.io1, self.lcd1, self.iqr, self.ilu, self.BOARD_ipcon)
        else:
            return 'Board is offline'
        return "Hello, Board successfully started!"

    def startMenu(self):
        if self.MENU_running: return 'Menu already running!'

        if isOpen(self.MENU_HOST, self.PORT) and self.BOARD_running:

            self.MENU_running = True

            # Connect to WLAN Controller
            self.MENU_ipcon = IPConnection() # Create IP connection

            self.lcd = LCD20x4(self.MENU_lcdUID, self.MENU_ipcon) # Create device object LCD
            self.jsk = Joystick(self.MENU_jskUID, self.MENU_ipcon) # Create device object JOYSTICK

            # Don't use device before ipcon is connected
            self.MENU_ipcon.connect(self.MENU_HOST, self.PORT) # Connect to brickd

            # create Menu instance with the nessesary Hardware # IPCON to close Tinker Connection
            self.MM = M(self.jsk, self.lcd, self.MENU_ipcon, self.BB)
        elif self.BOARD_running == False:
            print 'board offline..'
        else:
            return 'Menu is offline'

        return "Hello, Menu successfully started!"

    # Print incoming enumeration
    def cb_enumerate( self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type):

        if str(device_identifier) == '13': # Device = Master
            if str(uid) == '6R3jeY':
                print 'WLAN Controller connected...'
                self.MENU_HOST = '127.0.0.1'
                sleep(2)
                self.startMenu()
        else:
            print("UID:               " + uid)
            print("Enumeration Type:  " + str(enumeration_type))

            if enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED:
                print("")
                return

            print("Connected UID:     " + connected_uid)
            print("Position:          " + position)
            print("Hardware Version:  " + str(hardware_version))
            print("Firmware Version:  " + str(firmware_version))
            print("Device Identifier: " + str(device_identifier))
            print("")


    def stop(self):
        print 'stopping devices...'
        if self.MENU_running:
            self.MENU_running = False
            self.MM.quit()
        if self.BOARD_running:
            self.BOARD_running = False
            self.BB.quit()    # Stop Board
        #quit()
        return 'successfully stopped'
Example #28
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 #29
0
class TimeServer:
    GPS_UPDATE_PERIOD = 5000
    RTC_UPDATE_PERIOD = 1000

    def __init__(self, host, port):
        # Available devices that we use
        self.gps = None
        self.rtc = None
        self.oled = None
        self.buzzer = None

        # GPS information
        self.last_gps_time = None
        self.last_gps_position = None

        self.ipcon = IPConnection() 
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, 
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, 
                                     self.cb_connected)
        self.ipcon.connect(host, int(port))
        self.ipcon.enumerate()

    def cb_enumerate(self, uid, connected_uid, position, hardware_version, 
                 firmware_version, device_identifier, enumeration_type):
        
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            
            # Initialize GPS
            if device_identifier == BrickletGPSV2.DEVICE_IDENTIFIER:
                self.gps = BrickletGPSV2(uid, self.ipcon)

                self.gps.set_date_time_callback_period(TimeServer.GPS_UPDATE_PERIOD)
                self.gps.set_coordinates_callback_period(TimeServer.GPS_UPDATE_PERIOD)

                self.gps.register_callback(BrickletGPSV2.CALLBACK_DATE_TIME, self.cb_time_updated)
                self.gps.register_callback(BrickletGPSV2.CALLBACK_COORDINATES, self.cb_location_updated)

            # Initialize OLED display
            if device_identifier == BrickletOLED128x64.DEVICE_IDENTIFIER:
                self.oled = BrickletOLED128x64(uid, self.ipcon)
                self.oled.clear_display()

            # Initialize RTC
            if device_identifier == BrickletRealTimeClock.DEVICE_IDENTIFIER:
                self.rtc = BrickletRealTimeClock(uid, self.ipcon)

                self.rtc.register_callback(BrickletRealTimeClock.CALLBACK_DATE_TIME, self.cb_rtc_time_update)
                self.rtc.set_date_time_callback_period(TimeServer.RTC_UPDATE_PERIOD)

    def cb_connected(self, connected_reason):
        self.ipcon.enumerate()

    def cb_time_updated(self, d, t):
        fix, satelite_num = self.gps.get_status()
        if fix:
            year, d = d % 100, int(d/100)
            month, d = d % 100, int(d/100)
            day = d % 100

            millisecond, t= t % 1000, int(t/1000)
            second, t = t % 100, int(t/100)
            minute, t = t % 100, int(t/100)
            hour = t % 100

            self.last_gps_time = datetime(2000+year, month, day, hour, minute, second, microsecond=millisecond*1000, tzinfo=from_zone)
            self.update_rtc_time(self.last_gps_time)

            if self.oled:
                self.oled.write_line(3, 2, "GPS Time: %02d:%02d:%02d.%02d" % (self.last_gps_time.hour, self.last_gps_time.minute, self.last_gps_time.second, millisecond/10))
                self.oled.write_line(4, 2, "GPS Date: %02d.%02d.%d" % (self.last_gps_time.day, self.last_gps_time.month, self.last_gps_time.year))

    def cb_location_updated(self, latitude, ns, longitude, ew):
        fix, satelite_num = self.gps.get_status()
        if fix:
            self.last_gps_position=GpsLocation(latitude, ns, longitude, ew)
            if self.oled:
                self.oled.write_line(6, 1, "Location: %.2f %s %.2f %s" % (self.last_gps_position.latitude, ns, self.last_gps_position.longitude, ew))    

    def update_rtc_time(self, dt):
        if self.rtc:
            self.rtc.set_date_time(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond/10000, dt.weekday()+1)

    def cb_rtc_time_update(self, year, month, day, hour, minute, second, centisecond, weekday, timestamp):
        if self.oled:
            self.oled.write_line(0, 2, "RTC Time: %02d:%02d:%02d.%02d" % (hour, minute, second, centisecond))
            self.oled.write_line(1, 2, "RTC Date: %02d.%02d.%d" % (day, month, year))

    def get_current_time(self):
        if self.rtc:
            year, month, day, hour, minute, second, centisecond, weekday = self.rtc.get_date_time()
            dt = datetime(year, month, day, hour, minute, second, 0, tzinfo=from_zone)

            timestamp = (calendar.timegm(dt.timetuple()) * 1000 )+(centisecond*10)  # I'm not sure if this is the best way

            return timestamp
        else:
            return 0
Example #30
0
def main():
    global uids
    global PORT

    return

    if len(sys.argv) not in [2, 3, 4]:
        print("Usage: {} [[--reflash port] test_firmware] [--bootloader port]")
        sys.exit(0)

    if "--bootloader" in sys.argv:
        port_idx = sys.argv.index("--bootloader") + 1
        PORT = sys.argv[port_idx]
        # TODO: use argparse
        sys.argv = sys.argv[:port_idx - 1] + sys.argv[port_idx + 1:]
        output = esptool(['--port', PORT, '--after', 'no_reset', 'chip_id'])
        return

    reflash = "--reflash" in sys.argv

    if reflash:
        reflash = True
        port_idx = sys.argv.index("--reflash") + 1
        PORT = sys.argv[port_idx]
        # TODO: use argparse
        sys.argv = sys.argv[:port_idx - 1] + sys.argv[port_idx + 1:]

    if not os.path.exists(sys.argv[1]):
        print("Test firmware {} not found.".format(sys.argv[1]))

    result = {"start": now()}

    if reflash:
        set_voltage_fuses, set_block_3, passphrase, uid = get_espefuse_tasks()
        if set_voltage_fuses or set_block_3:
            print("This ESP was not provisioned yet!")
            sys.exit(-1)

        ssid = "warp-" + uid
        result["uid"] = uid
        result["test_firmware"] = sys.argv[1]
        flash_firmware(sys.argv[1])
        result["end"] = now()
        with open(
                "{}_{}_report_stage_1_reflash.json".format(
                    ssid,
                    now().replace(":", "-")), "w") as f:
            json.dump(result, f, indent=4)
        return

    try:
        with socket.create_connection((PRINTER_HOST, PRINTER_PORT)):
            print("Label printer is online")
    except:
        if input("Failed to reach label printer. Continue anyway? [y/n]"
                 ) != "y":
            sys.exit(0)

    print("Checking ESP state")
    mac_address = check_if_esp_is_sane_and_get_mac()
    print("MAC Address is {}".format(mac_address))
    result["mac"] = mac_address

    set_voltage_fuses, set_block_3, passphrase, uid = get_espefuse_tasks()
    result["set_voltage_fuses"] = set_voltage_fuses
    result["set_block_3"] = set_block_3

    handle_voltage_fuses(set_voltage_fuses)

    uid, passphrase = handle_block3_fuses(set_block_3, uid, passphrase)

    if set_voltage_fuses or set_block_3:
        print("Verifying eFuses")
        _set_voltage_fuses, _set_block_3, _passphrase, _uid = get_espefuse_tasks(
        )
        if _set_voltage_fuses:
            print("Failed to verify voltage eFuses! Are they burned in yet?")
            sys.exit(0)

        if _set_block_3:
            print("Failed to verify block 3 eFuses! Are they burned in yet?")
            sys.exit(0)

        if _passphrase != passphrase:
            print(
                "Failed to verify block 3 eFuses! Passphrase is not the expected value"
            )
            sys.exit(0)

        if _uid != uid:
            print(
                "Failed to verify block 3 eFuses! UID {} is not the expected value {}"
                .format(_uid, uid))
            sys.exit(0)

    result["uid"] = uid

    print("Erasing flash")
    erase_flash()

    print("Flashing test firmware")
    flash_firmware(sys.argv[1])
    result["test_firmware"] = sys.argv[1]

    ssid = "warp-" + uid

    run(["systemctl", "restart", "NetworkManager.service"])

    print("Waiting for ESP wifi. Takes about one minute.")
    if not wait_for_wifi(ssid, 90):
        print("ESP wifi not found after 90 seconds")
        sys.exit(0)

    print("Testing ESP Wifi.")
    with wifi(ssid, passphrase):
        ipcon = IPConnection()
        ipcon.connect("10.0.0.1", 4223)
        result["wifi_test_successful"] = True
        print("Connected. Testing bricklet ports")
        # Register Enumerate Callback
        ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, cb_enumerate)

        # Trigger Enumerate
        ipcon.enumerate()
        start = time.time()
        while time.time() - start < 5:
            if len(uids) == 6:
                break
            time.sleep(0.1)

        if len(uids) != 6:
            print("Expected 6 RGB LED 2.0 bricklets but found {}".format(
                len(uids)))
            sys.exit(0)

        uids = sorted(uids, key=lambda x: x[0])

        bricklets = [(uid[0], BrickletRGBLEDV2(uid[1], ipcon)) for uid in uids]
        error_count = 0
        for bricklet_port, rgb in bricklets:
            rgb.set_rgb_value(127, 127, 0)
            time.sleep(0.5)
            if rgb.get_rgb_value() == (127, 127, 0):
                rgb.set_rgb_value(0, 127, 0)
            else:
                print("Setting color failed on port {}.".format(bricklet_port))
                error_count += 1

        if error_count != 0:
            sys.exit(0)

        result["bricklet_port_test_successful"] = True

        stop_event = threading.Event()
        blink_thread = threading.Thread(target=blink_thread_fn,
                                        args=([x[1] for x in bricklets],
                                              stop_event))
        blink_thread.start()
        input("Bricklet ports seem to work. Press any key to continue")
        stop_event.set()
        blink_thread.join()
        ipcon.disconnect()

    led0 = input("Does LED 0 blink blue? [y/n]")
    while led0 != "y" and led0 != "n":
        led0 = input("Does LED 0 blink blue? [y/n]")
    result["led0_test_successful"] = led0 == "y"
    if led0 == "n":
        print("LED 0 does not work")
        sys.exit(0)

    led1 = input(
        "Press IO0 button (for max 3 seconds). Does LED 1 glow green? [y/n]")
    while led1 != "y" and led1 != "n":
        led1 = input(
            "Press IO0 Button (for max 3 seconds). Does LED 1 glow green? [y/n]"
        )
    result["led1_io0_test_successful"] = led1 == "y"
    if led1 == "n":
        print("LED 1 or IO0 button does not work")
        sys.exit(0)

    led0_stop = input(
        "Press EN button. Does LED 0 stop blinking for some seconds? [y/n]")
    while led0_stop != "y" and led0_stop != "n":
        led0_stop = input(
            "Press EN button. Does LED 0 stop blinking for some seconds? [y/n]"
        )
    result["enable_test_successful"] = led0_stop == "y"
    if led0_stop == "n":
        print("EN button does not work")
        sys.exit(0)

    result["tests_successful"] = True

    run(["python3", "print-esp32-label.py", ssid, passphrase, "-c", "3"])
    label_success = input(
        "Stick one label on the esp, put esp and the other two labels in the ESD bag. [y/n]"
    )
    while label_success != "y" and label_success != "n":
        label_success = input(
            "Stick one label on the esp, put esp and the other two labels in the ESD bag. [y/n]"
        )
    result["labels_printed"] = label_success == "y"
    result["end"] = now()

    with open(
            "{}_{}_report_stage_0+1.json".format(ssid,
                                                 now().replace(":", "-")),
            "w") as f:
        json.dump(result, f, indent=4)
class WeatherStation:
    HOST = "localhost"
    PORT = 4223

    ipcon = None
    lcd = None
    al = None
    hum = None
    baro = None

    def __init__(self):
        self.xively = Xively()
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(WeatherStation.HOST, WeatherStation.PORT)
                break
            except Error as e:
                log.error('Connection Error: ' + str(e.description))
                time.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                time.sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate Error: ' + str(e.description))
                time.sleep(1)

    def cb_illuminance(self, illuminance):
        if self.lcd is not None:
            text = 'Illuminanc %6.2f lx' % (illuminance/10.0)
            self.lcd.write_line(0, 0, text)
            self.xively.put('AmbientLight', illuminance/10.0)
            log.info('Write to line 0: ' + text)

    def cb_humidity(self, humidity):
        if self.lcd is not None:
            text = 'Humidity   %6.2f %%' % (humidity/10.0)
            self.lcd.write_line(1, 0, text)
            self.xively.put('Humidity', humidity/10.0)
            log.info('Write to line 1: ' + text)

    def cb_air_pressure(self, air_pressure):
        if self.lcd is not None:
            text = 'Air Press %7.2f mb' % (air_pressure/1000.0)
            self.lcd.write_line(2, 0, text)
            self.xively.put('AirPressure', air_pressure/1000.0)
            log.info('Write to line 2: ' + text)

            temperature = self.baro.get_chip_temperature()/100.0
            # \xDF == ° on LCD 20x4 charset
            text = 'Temperature %5.2f \xDFC' % temperature
            self.lcd.write_line(3, 0, text)
            self.xively.put('Temperature', temperature)
            log.info('Write to line 3: ' + text.replace('\xDF', '°'))

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == LCD20x4.DEVICE_IDENTIFIER:
                try:
                    self.lcd = LCD20x4(uid, self.ipcon)
                    self.lcd.clear_display()
                    self.lcd.backlight_on()
                    log.info('LCD20x4 initialized')
                except Error as e:
                    log.error('LCD20x4 init failed: ' + str(e.description))
                    self.lcd = None
            elif device_identifier == AmbientLight.DEVICE_IDENTIFIER:
                try:
                    self.al = AmbientLight(uid, self.ipcon)
                    self.al.set_illuminance_callback_period(1000)
                    self.al.register_callback(self.al.CALLBACK_ILLUMINANCE,
                                              self.cb_illuminance)
                    log.info('AmbientLight initialized')
                except Error as e:
                    log.error('AmbientLight init failed: ' + str(e.description))
                    self.al = None
            elif device_identifier == Humidity.DEVICE_IDENTIFIER:
                try:
                    self.hum = Humidity(uid, self.ipcon)
                    self.hum.set_humidity_callback_period(1000)
                    self.hum.register_callback(self.hum.CALLBACK_HUMIDITY,
                                               self.cb_humidity)
                    log.info('Humidity initialized')
                except Error as e:
                    log.error('Humidity init failed: ' + str(e.description))
                    self.hum = None
            elif device_identifier == Barometer.DEVICE_IDENTIFIER:
                try:
                    self.baro = Barometer(uid, self.ipcon)
                    self.baro.set_air_pressure_callback_period(1000)
                    self.baro.register_callback(self.baro.CALLBACK_AIR_PRESSURE,
                                                self.cb_air_pressure)
                    log.info('Barometer initialized')
                except Error as e:
                    log.error('Barometer init failed: ' + str(e.description))
                    self.baro = None

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto Reconnect')

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
Example #32
0
def write_bricklets_into_configfile():    
    #if path.isfile(PATH) and access(PATH, R_OK) and access(PATH, W_OK) == True:  # check if config file exists and is readable and writeable
    #if __name__ == "__main__":
            
        ipcon = IPConnection() 
            
        cfg = configparser.ConfigParser()
            
        cfg.read(cfg_filename) # open config file to read
            
        port = cfg.getint('Connection', 'Port') # get port entry from config file
           
        host = cfg.get('Connection', 'Host') # get host entry from config file
            
        sleeptime = cfg.getfloat('Connection', 'SleepTime')  # get the sleeptime from config file
            
        ipcon.connect(HOST, PORT) 
            
        ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, bricklet_callback)
            
        ipcon.enumerate()
            
        time.sleep(sleeptime)   # sleeptime until all bricklets have answered
            
    #----------------------------------put barometer entrys into config file  ----------------------------------------
                
        if cfg.has_section(barometer_brick["Bricklet_Name"]) == False:
            cfg.add_section(barometer_brick["Bricklet_Name"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Section Barometer erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(barometer_brick["Bricklet_Name"], 'Bricklet_UID') == False:    
            cfg.set(barometer_brick["Bricklet_Name"], 'Bricklet_UID', barometer_brick["Bricklet_UID"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag UID erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(barometer_brick["Bricklet_Name"], 'Bricklet_Position') == False:    
            cfg.set(barometer_brick["Bricklet_Name"], 'Bricklet_Position', barometer_brick["Bricklet_Position"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Position erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(barometer_brick["Bricklet_Name"], 'Bricklet_Firmware') == False:    
            cfg.set(barometer_brick["Bricklet_Name"], 'Bricklet_Firmware', str(barometer_brick["Bricklet_Firmware"]))
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Firmware erstellt')
            else:
                #print ('Eintrag existiert')"""
                
    #----------------------------------put gps entrys into config file ----------------------------------------
            
        if cfg.has_section(gps_brick["Bricklet_Name"]) == False:
            cfg.add_section(gps_brick["Bricklet_Name"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Section Barometer erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(gps_brick["Bricklet_Name"], 'Bricklet_UID') == False:    
            cfg.set(gps_brick["Bricklet_Name"], 'Bricklet_UID', gps_brick["Bricklet_UID"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag UID erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(gps_brick["Bricklet_Name"], 'Bricklet_Position') == False:    
            cfg.set(gps_brick["Bricklet_Name"], 'Bricklet_Position', gps_brick["Bricklet_Position"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Position erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(gps_brick["Bricklet_Name"], 'Bricklet_Firmware') == False:    
            cfg.set(gps_brick["Bricklet_Name"], 'Bricklet_Firmware', str(gps_brick["Bricklet_Firmware"]))
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Firmware erstellt')
            else:
                print ('Eintrag existiert')"""
                
    #----------------------------------put humidity entrys into config file ----------------------------------------
            
        if cfg.has_section(humidity_brick["Bricklet_Name"]) == False:
            cfg.add_section(humidity_brick["Bricklet_Name"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Section Barometer erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(humidity_brick["Bricklet_Name"], 'Bricklet_UID') == False:    
            cfg.set(humidity_brick["Bricklet_Name"], 'Bricklet_UID', humidity_brick["Bricklet_UID"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag UID erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(humidity_brick["Bricklet_Name"], 'Bricklet_Position') == False:    
            cfg.set(humidity_brick["Bricklet_Name"], 'Bricklet_Position', humidity_brick["Bricklet_Position"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Position erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(humidity_brick["Bricklet_Name"], 'Bricklet_Firmware') == False:    
            cfg.set(humidity_brick["Bricklet_Name"], 'Bricklet_Firmware', str(humidity_brick["Bricklet_Firmware"]))
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Firmware erstellt')
            else:
                print ('Eintrag existiert')"""
                
    #----------------------------------put illuminance entrys into config file ----------------------------------------
            
        if cfg.has_section(illuminance_brick["Bricklet_Name"]) == False:
            cfg.add_section(illuminance_brick["Bricklet_Name"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Section Barometer erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(illuminance_brick["Bricklet_Name"], 'Bricklet_UID') == False:    
            cfg.set(illuminance_brick["Bricklet_Name"], 'Bricklet_UID', illuminance_brick["Bricklet_UID"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag UID erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(illuminance_brick["Bricklet_Name"], 'Bricklet_Position') == False:    
            cfg.set(illuminance_brick["Bricklet_Name"], 'Bricklet_Position', illuminance_brick["Bricklet_Position"])
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Position erstellt')
            else:
                print ('Eintrag existiert')"""
            
        if cfg.has_option(illuminance_brick["Bricklet_Name"], 'Bricklet_Firmware') == False:    
            cfg.set(illuminance_brick["Bricklet_Name"], 'Bricklet_Firmware', str(illuminance_brick["Bricklet_Firmware"]))
            with open(cfg_filename, 'w') as configfile:
                cfg.write(configfile)
                """print ('Eintrag Firmware erstellt')
            else:
                print ('Eintrag existiert')"""
            
        ipcon.disconnect()   # disconnect connection between masterbrick and bricklet
Example #33
0
class WeatherStation:
    HOST = "localhost"
    PORT = 4223

    ipcon = None
    lcd = None
    al = None
    al_v2 = None
    hum = None
    hum_v2 = None
    baro = None

    def __init__(self):
        self.xively = Xively()
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(WeatherStation.HOST, WeatherStation.PORT)
                break
            except Error as e:
                log.error('Connection Error: ' + str(e.description))
                time.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                time.sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate Error: ' + str(e.description))
                time.sleep(1)

    def cb_illuminance(self, illuminance):
        if self.lcd is not None:
            text = 'Illuminanc %6.2f lx' % (illuminance / 10.0)
            self.lcd.write_line(0, 0, text)
            self.xively.put('AmbientLight', illuminance / 10.0)
            log.info('Write to line 0: ' + text)

    def cb_illuminance_v2(self, illuminance):
        if self.lcd is not None:
            text = 'Illumina %8.2f lx' % (illuminance / 100.0)
            self.lcd.write_line(0, 0, text)
            self.xively.put('AmbientLight', illuminance / 100.0)
            log.info('Write to line 0: ' + text)

    def cb_humidity(self, humidity):
        if self.lcd is not None:
            text = 'Humidity   %6.2f %%' % (humidity / 10.0)
            self.lcd.write_line(1, 0, text)
            self.xively.put('Humidity', humidity / 10.0)
            log.info('Write to line 1: ' + text)

    def cb_air_pressure(self, air_pressure):
        if self.lcd is not None:
            text = 'Air Press %7.2f mb' % (air_pressure / 1000.0)
            self.lcd.write_line(2, 0, text)
            self.xively.put('AirPressure', air_pressure / 1000.0)
            log.info('Write to line 2: ' + text)

            temperature = self.baro.get_chip_temperature() / 100.0
            # \xDF == ° on LCD 20x4 charset
            text = 'Temperature %5.2f \xDFC' % temperature
            self.lcd.write_line(3, 0, text)
            self.xively.put('Temperature', temperature)
            log.info('Write to line 3: ' + text.replace('\xDF', '°'))

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == LCD20x4.DEVICE_IDENTIFIER:
                try:
                    self.lcd = LCD20x4(uid, self.ipcon)
                    self.lcd.clear_display()
                    self.lcd.backlight_on()
                    log.info('LCD 20x4 initialized')
                except Error as e:
                    log.error('LCD 20x4 init failed: ' + str(e.description))
                    self.lcd = None
            elif device_identifier == BrickletAmbientLight.DEVICE_IDENTIFIER:
                try:
                    self.al = BrickletAmbientLight(uid, self.ipcon)
                    self.al.set_illuminance_callback_period(1000)
                    self.al.register_callback(self.al.CALLBACK_ILLUMINANCE,
                                              self.cb_illuminance)
                    log.info('Ambient Light initialized')
                except Error as e:
                    log.error('Ambient Light init failed: ' +
                              str(e.description))
                    self.al = None
            elif device_identifier == BrickletAmbientLightV2.DEVICE_IDENTIFIER:
                try:
                    self.al_v2 = BrickletAmbientLightV2(uid, self.ipcon)
                    self.al_v2.set_configuration(
                        self.al_v2.ILLUMINANCE_RANGE_64000LUX,
                        self.al_v2.INTEGRATION_TIME_200MS)
                    self.al_v2.set_illuminance_callback_period(1000)
                    self.al_v2.register_callback(
                        self.al_v2.CALLBACK_ILLUMINANCE,
                        self.cb_illuminance_v2)
                    log.info('Ambient Light 2.0 initialized')
                except Error as e:
                    log.error('Ambient Light 2.0 init failed: ' +
                              str(e.description))
                    self.al_v2 = None
            elif device_identifier == BrickletHumidity.DEVICE_IDENTIFIER:
                try:
                    self.hum = BrickletHumidity(uid, self.ipcon)
                    self.hum.set_humidity_callback_period(1000)
                    self.hum.register_callback(self.hum.CALLBACK_HUMIDITY,
                                               self.cb_humidity)
                    log.info('Humidity initialized')
                except Error as e:
                    log.error('Humidity init failed: ' + str(e.description))
                    self.hum = None
            elif device_identifier == BrickletHumidityV2.DEVICE_IDENTIFIER:
                try:
                    self.hum_v2 = BrickletHumidityV2(uid, self.ipcon)
                    self.hum_v2.set_humidity_callback_configuration(
                        1000, True, 'x', 0, 0)
                    self.hum_v2.register_callback(
                        self.hum_v2.CALLBACK_HUMIDITY, self.cb_humidity_v2)
                    log.info('Humidity 2.0 initialized')
                except Error as e:
                    log.error('Humidity 2.0 init failed: ' +
                              str(e.description))
                    self.hum_v2 = None
            elif device_identifier == BrickletBarometer.DEVICE_IDENTIFIER:
                try:
                    self.baro = BrickletBarometer(uid, self.ipcon)
                    self.baro.set_air_pressure_callback_period(1000)
                    self.baro.register_callback(
                        self.baro.CALLBACK_AIR_PRESSURE, self.cb_air_pressure)
                    log.info('Barometer initialized')
                except Error as e:
                    log.error('Barometer init failed: ' + str(e.description))
                    self.baro = None

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto Reconnect')

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
class SmokeDetector:
    HOST = 'localhost'
    PORT = 4223

    ipcon = None
    idi4 = None

    def __init__(self):
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(SmokeDetector.HOST, SmokeDetector.PORT)
                break
            except Error as e:
                log.error('Connection Error: ' + str(e.description))
                time.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                time.sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate Error: ' + str(e.description))
                time.sleep(1)

    def cb_interrupt(self, interrupt_mask, value_mask):
        if value_mask > 0:
            log.warn('Fire! Fire!')

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == IndustrialDigitalIn4.DEVICE_IDENTIFIER:
                try:
                    self.idi4 = IndustrialDigitalIn4(uid, self.ipcon)
                    self.idi4.set_debounce_period(10000)
                    self.idi4.set_interrupt(15)
                    self.idi4.register_callback(
                        IndustrialDigitalIn4.CALLBACK_INTERRUPT,
                        self.cb_interrupt)
                    log.info('Industrial Digital In 4 initialized')
                except Error as e:
                    log.error('Industrial Digital In 4 init failed: ' +
                              str(e.description))
                    self.idi4 = None

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto Reconnect')

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
Example #35
0
class Heater:

    # These are the bricklet objects which are populated
    # as the hardware responds to enumeration request.
    ipcon = None
    lcd = None
    thermocouple = None
    relay = None

    # PWM power for output. 0 - 100
    heater_power = 0

    # Current state of output. Boolean
    heater_active = False

    # Current active GUI tab index
    active_tab = 0

    # This is set to match graph width
    n_temp_points = 107
    temp_data = deque([0], n_temp_points)
    axis_min = 0
    axis_max = 0

    def __init__(self):
        LOGGER.info("Heater starting...")
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(HOST, PORT)
                break
            except TFConnectionError as error:
                LOGGER.error("Connection Error: " + str(error.description))
                sleep(1)
            except socket.error as error:
                LOGGER.error("Socket Error: " + str(error))
                sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                return
            except TFConnectionError as error:
                LOGGER.error("Enumerate Error: " + str(error.description))
                sleep(1)

    def _init_lcd(self, uid):
        try:
            self.lcd = BrickletLCD128x64(uid, self.ipcon)
            self.lcd.clear_display()
            self.lcd.remove_all_gui()
            LOGGER.info("LCD128x64 initialized")
        except TFConnectionError as error:
            LOGGER.error("LCD128x64 init failed: " + str(error.description))
            return

        self.lcd.set_gui_tab_selected_callback_configuration(
            GUI_READ_PERIOD, True)
        self.lcd.register_callback(BrickletLCD128x64.CALLBACK_GUI_TAB_SELECTED,
                                   self.cb_tab)
        self.lcd.set_gui_tab_configuration(
            self.lcd.CHANGE_TAB_ON_CLICK_AND_SWIPE, True)
        self.lcd.set_gui_tab_icon(0, CONTROL_ICON)
        self.lcd.set_gui_tab_icon(1, GRAPH_ICON)
        self.lcd.set_gui_tab_icon(2, SETTINGS_ICON)

        self.lcd.set_gui_button_pressed_callback_configuration(
            GUI_READ_PERIOD, True)
        self.lcd.register_callback(
            BrickletLCD128x64.CALLBACK_GUI_BUTTON_PRESSED, self.cb_button)

        # Set initial tab
        self.cb_tab(self.active_tab)

    def cb_tab(self, index):
        self.active_tab = index
        self.lcd.clear_display()
        if index == 0:
            self.write_temp()
            self.write_power()
            self.lcd.set_gui_button(0, 2, 22, 61, 14, "-1%")
            self.lcd.set_gui_button(1, 66, 22, 61, 14, "+1%")
            self.lcd.set_gui_button(2, 2, 38, 61, 14, "-10%")
            self.lcd.set_gui_button(3, 66, 38, 61, 14, "+10%")

        elif index == 1:
            self.lcd.set_gui_graph_configuration(
                0, BrickletLCD128x64.GRAPH_TYPE_LINE, 20, 0, 107, 52, "", "")
            self.update_graph()
            self.lcd.draw_text(0, 23, BrickletLCD128x64.FONT_6X8, True,
                               "\xDFC")
            self.update_axis()

        elif index == 2:
            self.lcd.draw_text(0, 0, BrickletLCD128x64.FONT_6X8, True, "BV21")
            self.lcd.set_gui_button(4, 0, 10, 80, 20, "Shut Down")

    def _cb_power_button(self, power):
        old_power = self.heater_power
        sticky_state_active = old_power == 100 or old_power == 0
        self.heater_power = power

        if power == 100:
            self.relay.set_state(True)
            self.heater_active = True
        elif power == 0:
            self.relay.set_state(False)
            self.heater_active = False
        elif 0 < power < 100 and sticky_state_active:
            # If we're coming out of a sticky state, kick of the
            # flop loop for PWM.
            self.relay.set_state(False)
            self.heater_active = False
            self.relay.set_monoflop(False, 0)

        self.write_power()

    def cb_button(self, index, value):
        if value is False:
            return
        if index == 0:
            self._cb_power_button(max(self.heater_power - 1, 0))
        elif index == 1:
            self._cb_power_button(min(self.heater_power + 1, 100))
        elif index == 2:
            self._cb_power_button(max(self.heater_power - 10, 0))
        elif index == 3:
            self._cb_power_button(min(self.heater_power + 10, 100))
        elif index == 4:
            self.close()
            self.shutdown_host()

    def _init_thermocouple(self, uid):
        try:
            self.thermocouple = BrickletThermocoupleV2(uid, self.ipcon)
            LOGGER.info("Thermocouple initialized")
        except TFConnectionError as error:
            LOGGER.error("Thermocouple init failed: " + str(error.description))
            return

        self.thermocouple.set_temperature_callback_configuration(
            THERMOCOUPLE_READ_PERIOD, False, "x", 0, 0)
        self.thermocouple.register_callback(
            BrickletThermocoupleV2.CALLBACK_TEMPERATURE, self.cb_thermocouple)

    def cb_thermocouple(self, value):
        celcius = int(value) / 100
        self.temp_data.append(celcius)
        self.write_temp()
        self.update_graph()

    def _init_relay(self, uid):
        try:
            self.relay = BrickletSolidStateRelayV2(uid, self.ipcon)
            LOGGER.info("Relay initialized")
        except TFConnectionError as error:
            LOGGER.error("Relay init failed: " + str(error.description))
            return

        self.relay.register_callback(
            BrickletSolidStateRelayV2.CALLBACK_MONOFLOP_DONE,
            self.cb_relay_flop)
        self.relay.set_state(False)

    def cb_relay_flop(self, _):
        on_time = round((self.heater_power / 100) * PWM_PERIOD)
        off_time = PWM_PERIOD - on_time

        if self.heater_power < 100:
            if self.heater_active:
                self.relay.set_monoflop(False, off_time)
                self.heater_active = False
            else:
                self.relay.set_monoflop(True, on_time)
                self.heater_active = True
        # If power is 0 or 100, we're not using the flop loop

    def write_temp(self):
        if self.lcd is None:
            return
        if self.active_tab != 0:
            return
        current_temp = self.temp_data[-1]
        temp_string = f"Temp: {current_temp:6.2f}\xDFC"
        self.lcd.draw_box(0, 0, 127, 10, True, BrickletLCD128x64.COLOR_WHITE)
        self.lcd.draw_text(0, 0, BrickletLCD128x64.FONT_6X8, True, temp_string)

    def write_power(self):
        if self.lcd is None:
            return
        if self.active_tab != 0:
            return
        self.lcd.draw_box(0, 11, 127, 20, True, BrickletLCD128x64.COLOR_WHITE)
        string = f"Power: {self.heater_power}%"
        self.lcd.draw_text(0, 11, BrickletLCD128x64.FONT_6X8, True, string)

    def update_axis(self):
        self.lcd.draw_box(0, 0, 20, 10, True, BrickletLCD128x64.COLOR_WHITE)
        self.lcd.draw_box(0, 45, 20, 55, True, BrickletLCD128x64.COLOR_WHITE)
        self.lcd.draw_text(0, 0, BrickletLCD128x64.FONT_6X8, True,
                           f"{self.axis_max:3.0f}")
        self.lcd.draw_text(0, 45, BrickletLCD128x64.FONT_6X8, True,
                           f"{self.axis_min:3.0f}")
        self.lcd.draw_text(0, 107, BrickletLCD128x64.FONT_6X8, True, f"")

    def update_graph(self):
        if self.lcd is None:
            return
        if self.active_tab != 1:
            return

        max_temp = round(max(self.temp_data))
        min_temp = round(min(self.temp_data))

        # Pad a little bit for looks
        max_temp *= 1.1
        min_temp *= 0.9

        diff = max_temp - min_temp
        if diff == 0:
            # This probably means we don't have any data yet
            return

        scaled_data = [((value - min_temp) / diff) * 255
                       for value in self.temp_data]

        # This gets rid of any randomness which apparently sometimes occurs when
        # the thermocouple bricklet is physically bumped.
        scaled_data = map(lambda value: max(min(value, 255), 0), scaled_data)

        if max_temp != self.axis_max or min_temp != self.axis_min:
            self.axis_max = max_temp
            self.axis_min = min_temp
            self.update_axis()

        self.lcd.set_gui_graph_data(0, scaled_data)

    def cb_enumerate(self, uid, _, __, ___, ____, device_identifier,
                     enumeration_type):
        if (enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or
                enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE):
            if device_identifier == BrickletLCD128x64.DEVICE_IDENTIFIER:
                self._init_lcd(uid)
            elif device_identifier == BrickletThermocoupleV2.DEVICE_IDENTIFIER:
                self._init_thermocouple(uid)
            elif device_identifier == BrickletSolidStateRelayV2.DEVICE_IDENTIFIER:
                self._init_relay(uid)

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            LOGGER.info("Auto Reconnect")

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except TFConnectionError as error:
                    LOGGER.error("Enumerate Error: " + str(error.description))
                    sleep(1)

    def close(self):
        if self.lcd:
            self.lcd.clear_display()
            self.lcd.remove_all_gui()
        if self.relay:
            self.relay.set_state(False)
        if self.ipcon is not None:
            self.ipcon.disconnect()
        LOGGER.info("Heater shut down")

    def shutdown_host(self):
        run("sudo shutdown now", shell=True)
Example #36
0
class Blinkenlights(QApplication):
    HOST = "localhost"
    PORT = 4223

    ipcon = None

    projects = []
    active_project = None

    error_msg = None

    def __init__(self, args):
        super(QApplication, self).__init__(args)

        self.error_msg = QErrorMessage()
        self.error_msg.setWindowTitle("Starter Kit: Blinkenlights Demo " + config.DEMO_VERSION)

        signal.signal(signal.SIGINT, self.exit_demo)
        signal.signal(signal.SIGTERM, self.exit_demo)

        self.make_gui()
        self.connect()

    def exit_demo(self, signl=None, frme=None):
        try:
            self.ipcon.disconnect()
            self.timer.stop()
            self.tabs.destroy()
        except:
            pass

        sys.exit()

    def make_gui(self):
        self.main = MainWindow(self)
        self.main.setWindowIcon(QIcon(os.path.join(ProgramPath.program_path(), "demo-icon.png")))

        self.tabs = QTabWidget()

        widget = QWidget()
        layout = QVBoxLayout()
        layout.addWidget(self.tabs)
        widget.setLayout(layout)

        self.main.setCentralWidget(widget)

        self.setup = SetupWidget(self.tabs, self)
        self.tetris = TetrisWidget(self.tabs, self)
        self.pong = PongWidget(self.tabs, self)
        self.fire = FireWidget(self.tabs, self)
        self.text = TextWidget(self.tabs, self)
        self.images = ImagesWidget(self.tabs, self)
        self.rainbow = RainbowWidget(self.tabs, self)

        self.projects.append(self.setup)
        self.projects.append(self.tetris)
        self.projects.append(self.pong)
        self.projects.append(self.fire)
        self.projects.append(self.text)
        self.projects.append(self.images)
        self.projects.append(self.rainbow)

        self.tabs.addTab(self.setup, "Setup")
        self.tabs.addTab(self.tetris, "Tetris")
        self.tabs.addTab(self.pong, "Pong")
        self.tabs.addTab(self.fire, "Fire")
        self.tabs.addTab(self.text, "Text")
        self.tabs.addTab(self.images, "Images")
        self.tabs.addTab(self.rainbow, "Rainbow")

        self.active_project = self.projects[0]

        self.tabs.currentChanged.connect(self.tab_changed_slot)

        self.main.setWindowTitle("Starter Kit: Blinkenlights Demo " + config.DEMO_VERSION)
        self.main.show()

    def connect(self):
        config.UID_LED_STRIP_BRICKLET = None
        self.setup.label_led_strip_found.setText('No')
        self.setup.label_led_strip_uid.setText('None')

        config.UID_MULTI_TOUCH_BRICKLET = None
        self.setup.label_multi_touch_found.setText('No')
        self.setup.label_multi_touch_uid.setText('None')

        config.UID_DUAL_BUTTON_BRICKLET = (None, None)
        self.setup.label_dual_button1_found.setText('No')
        self.setup.label_dual_button1_uid.setText('None')
        self.setup.label_dual_button2_found.setText('No')
        self.setup.label_dual_button2_uid.setText('None')

        config.UID_PIEZO_SPEAKER_BRICKLET = None
        self.setup.label_piezo_speaker_found.setText('No')
        self.setup.label_piezo_speaker_uid.setText('None')

        config.UID_SEGMENT_DISPLAY_4X7_BRICKLET = None
        self.setup.label_segment_display_found.setText('No')
        self.setup.label_segment_display_uid.setText('None')

        if self.ipcon != None:
            try:
                self.ipcon.disconnect()
            except:
                pass

        self.ipcon = IPConnection()

        host = self.setup.edit_host.text()
        port = self.setup.spinbox_port.value()
        try:
            self.ipcon.connect(host, port)
        except Error as e:
            self.error_msg.showMessage('Connection Error: ' + str(e.description) + "<br><br>Brickd installed and running?")
            return
        except socket.error as e:
            self.error_msg.showMessage('Socket error: ' + str(e) + "<br><br>Brickd installed and running?")
            return

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        # Wait for a second to give user visual feedback
        timer = QTimer(self)
        timer.setSingleShot(True)
        timer.timeout.connect(self.ipcon.enumerate)
        timer.start(250)

    def tab_changed_slot(self, tabIndex):
        self.active_project.stop()
        self.active_project = self.projects[tabIndex]
        self.active_project.start()

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == LEDStrip.DEVICE_IDENTIFIER:
                config.UID_LED_STRIP_BRICKLET = uid
                self.setup.label_led_strip_found.setText('Yes')
                self.setup.label_led_strip_uid.setText(uid)
            elif device_identifier == MultiTouch.DEVICE_IDENTIFIER:
                config.UID_MULTI_TOUCH_BRICKLET = uid
                self.setup.label_multi_touch_found.setText('Yes')
                self.setup.label_multi_touch_uid.setText(uid)
            elif device_identifier == DualButton.DEVICE_IDENTIFIER:
                if config.UID_DUAL_BUTTON_BRICKLET[0] == None:
                    config.UID_DUAL_BUTTON_BRICKLET = (uid, None)
                    self.setup.label_dual_button1_found.setText('Yes')
                    self.setup.label_dual_button1_uid.setText(uid)
                else:
                    config.UID_DUAL_BUTTON_BRICKLET = (config.UID_DUAL_BUTTON_BRICKLET[0], uid)
                    self.setup.label_dual_button2_found.setText('Yes')
                    self.setup.label_dual_button2_uid.setText(uid)
            elif device_identifier == PiezoSpeaker.DEVICE_IDENTIFIER:
                config.UID_PIEZO_SPEAKER_BRICKLET = uid
                self.setup.label_piezo_speaker_found.setText('Yes')
                self.setup.label_piezo_speaker_uid.setText(uid)
            elif device_identifier == SegmentDisplay4x7.DEVICE_IDENTIFIER:
                config.UID_SEGMENT_DISPLAY_4X7_BRICKLET = uid
                self.setup.label_segment_display_found.setText('Yes')
                self.setup.label_segment_display_uid.setText(uid)

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    self.error_msg.showMessage('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
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)
Example #38
0
class GPSTimeToLinuxTime:
    def __init__(self):
        # Create IP connection
        self.ipcon = IPConnection() 
        
        # Connect to brickd
        self.ipcon.connect(HOST, PORT)
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate)
        self.ipcon.enumerate()

        self.enum_sema = Semaphore(0)
        self.gps_uid = None
        self.gps_time = None
        self.timer = None

    # go trough the functions to update date and time
    def __enter__(self):
        if self.is_ntp_present():
            return -1, None
        if not self.get_gps_uid():
            return -2, None
        if not self.get_gps_time():
            return -3, None
        if self.are_times_equal():
            return 1, self.gps_time
        if self.is_time_crazy():
            return -4, None
        if not self.set_linux_time():
            return -5, None

        return 0, self.gps_time

    def __exit__(self, type, value, traceback):
        try:
            self.timer.cancel()
        except:
            pass

        try:
            self.ipcon.disconnect()
        except:
            pass

    def is_ntp_present(self):
        # FIXME: Find out if we have internet access and ntp is working, in
        #        that case we don't need to use the GPS time.
        return False

    def get_gps_uid(self):
        try:
            # Release semaphore after 1 second (if no GPS Bricklet is found)
            self.timer = Timer(1, self.enum_sema.release)
            self.timer.start()
            self.enum_sema.acquire()
        except:
            return False

        return True

    def get_gps_time(self):
        if self.gps_uid == None:
            return False

        try:
            # Create GPS device object
            self.gps = BrickletGPS(self.gps_uid, self.ipcon)
            date, time = self.gps.get_date_time()

            yy = date % 100
            yy += 2000
            date //= 100
            mm = date % 100
            date //= 100
            dd = date

            time //= 1000
            ss = time % 100
            time //= 100
            mins = time % 100
            time //= 100
            hh = time

            self.gps_time = datetime.datetime(yy, mm, dd, hh, mins, ss)
        except:
            return False

        return True

    def are_times_equal(self):
        # Are we more then 3 seconds off?
        if abs(int(self.gps_time.strftime("%s")) - time.time()) > 3:
            return False

        return True

    def is_time_crazy(self):
        try:
            return self.gps_time.year < 2014
        except:
            return True

    def set_linux_time(self):
        if self.gps_time == None:
            return False

        try:
            # Set date as root
            timestamp = (self.gps_time - datetime.datetime(1970, 1, 1)) / datetime.timedelta(seconds=1)
            command = ['/usr/bin/sudo', '-S']
            command.extend('/bin/date +%s -u -s @{0}'.format(timestamp).split(' '))
            Popen(command, stdout=PIPE, stdin=PIPE).communicate(SUDO_PASSWORD)
        except:
            return False

        return True

    def cb_enumerate(self, uid, connected_uid, position, hardware_version, 
                     firmware_version, device_identifier, enumeration_type):
        # If more then one GPS Bricklet is connected we will use the first one that we find
        if device_identifier == BrickletGPS.DEVICE_IDENTIFIER:
            self.gps_uid = uid
            self.enum_sema.release()
Example #39
0
class SmokeDetector:
    HOST = 'localhost'
    PORT = 4223

    ipcon = None
    idi4 = None

    def __init__(self):
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(SmokeDetector.HOST, SmokeDetector.PORT)
                break
            except Error as e:
                log.error('Connection Error: ' + str(e.description))
                time.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                time.sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate Error: ' + str(e.description))
                time.sleep(1)

    def cb_interrupt(self, interrupt_mask, value_mask):
        if value_mask > 0:
            log.warn('Fire! Fire!')

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == IndustrialDigitalIn4.DEVICE_IDENTIFIER:
                try:
                    self.idi4 = IndustrialDigitalIn4(uid, self.ipcon)
                    self.idi4.set_debounce_period(10000)
                    self.idi4.set_interrupt(15)
                    self.idi4.register_callback(IndustrialDigitalIn4.CALLBACK_INTERRUPT,
                                                self.cb_interrupt)
                    log.info('Industrial Digital In 4 initialized')
                except Error as e:
                    log.error('Industrial Digital In 4 init failed: ' + str(e.description))
                    self.idi4 = None

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto Reconnect')

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
Example #40
0
class Controller:
    identity = SHORT_IDENT

    ipcon = None
    current_module = None
    previous_module = None
    screen = None

    modules = {}
    ticklist = []
    publishers = []

    scheduler = sched.scheduler(time.time, time.sleep)

    def __init__(self):
        self.ipcon = IPConnection()
        self.ipcon.connect(HOST, PORT)

        for module in MODULES:
            self.add_module(module)

        if self.modules["MenuModule"]:
            for module in MENU_MODULES:
                self.add_module(module)
                self.modules["MenuModule"].add_menu_item(
                    self.modules[module[0]])

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.assign_bricklets)
        self.ipcon.enumerate()

    def add_module(self, module):
        self.modules[module[0]] = getattr(
            __import__("modules." + module[1], fromlist=[module[0]]),
            module[0])(self)
        if self.modules[module[0]].always_tick:
            self.ticklist.append(module[0])
        print("Loaded " + module[0])

    def tick(self):
        if self.current_module:
            self.current_module.tick()
        for module in self.ticklist:
            self.modules[module].tick()
        self.scheduler.enter(
            1,
            1,
            desk.tick,
            (),
        )

    def get_current_module(self):
        return self.current_module

    def change_module(self, module):
        if self.current_module:
            self.previous_module = self.current_module
        if module in self.modules:
            print("changing to " + module)
            self.current_module = self.modules[module]
        self.current_module.draw()

    def prev_module(self):
        if self.previous_module:
            self.change_module(self.previous_module.id)

    def navigate(self, direction):
        if direction not in ["forward", "back", "up", "down", "enter"]:
            return
        if self.current_module:
            self.current_module.navigate(direction)
        else:
            self.change_module("MenuModule")

    def assign_bricklets(self, uid, connected_uid, position, hardware_version,
                         firmware_version, device_identifier,
                         enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED:
            return
        for state in self.modules:
            self.modules[state].try_bricklet(uid, device_identifier, position)

    def publish(self, key, value):
        for callback in self.publishers:
            callback(self, key, value)
class readTFsensors:

    def __init__(self):
        self.tmpHW = None
        self.tmpFR = None
        self.tmpMain = None
        self.tmpHWval = 0
        self.tmpFRval = 0
        self.tmpMainval = 0

        # Create IP Connection
        self.ipcon = IPConnection() 

        # Register IP Connection callbacks
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, self.cb_connected)

        # Connect to brickd, will trigger cb_connected
        self.ipcon.connect( HOST, PORT ) 

        self.ipcon.enumerate()
        
        # wait until all values are being received
        Logger.debug('waiting for all sensors to send values ...')
        while self.tmpHWval==0 or self.tmpFRval==0 or self.tmpMainval==0:
            now = round( datetime.datetime.timestamp(datetime.datetime.now()) ) 
            Logger.debug( str(now) + ' (HW, FR, main) ' + str(self.tmpHWval)+', '+str(self.tmpFRval)+', '+str(self.tmpMainval) )
            time.sleep(15)               # wait 15 seconds
        Logger.debug( 'all sensors found: (HW, FR, main)' + str(self.tmpHWval)+', '+str(self.tmpFRval)+', '+str(self.tmpMainval) )    
        
        # loop to check if source code was changed, 
        # then exit the python program in order to get it restarted by the shell script
        while True:
            time.sleep(120)               # wait 2 minutes
            # check if script source code has changed
            newScrChgDate = os.path.getmtime(__file__)
            if ( scriptChangeDate != newScrChgDate ):
                Logger.info("Source code changed, (ending script). Old: "+str(scriptChangeDate) + ", New: " + str(newScrChgDate) )
                sys.exit(9)  # means 'reload and restart'
                
            # check if debugging is requested
            if os.path.isfile('debug_off'):
                Logger.setLevel(logging.INFO) 
                
            # check if debugging is requested
            if os.path.isfile('debug_on'):
                Logger.setLevel(logging.DEBUG) 
                
        
    # Callback updates temperature 
    # - for heatwater temperature
    def cb_tempHW(self, temperature):   
        self.tmpHWval = temperature/100.0
        writeSensFile("HW", self.tmpHWval, self.tmpHWval, self.tmpFRval, self.tmpMainval)
    # - for front room temperature
    def cb_tempFR( self, temperature):
        self.tmpFRval  = temperature/100.0
        writeSensFile("FR", self.tmpFRval, self.tmpHWval, self.tmpFRval, self.tmpMainval)
    # - for main room temperature
    def cb_tempMain(self, temperature):
        self.tmpMainval = temperature/100.0
        writeSensFile("Main", self.tmpMainval, self.tmpHWval, self.tmpFRval, self.tmpMainval)


    # Callback handles device connections and configures possibly lost 
    # configuration of lcd and temperature callbacks, backlight etc.
    def cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
                
            # Enumeration is for Temperature Bricklets
            if device_identifier == Temperature.DEVICE_IDENTIFIER:
                # Create individual temperature device objects for each sensor
                if uid==HW_ID:
                    self.tmpHW = Temperature(uid, self.ipcon) 
                    self.tmpHWval = self.tmpHW.get_temperature()/100.0    # read initial value
                    writeSensFile("HW", self.tmpHWval, self.tmpHWval, self.tmpFRval, self.tmpMainval)
                    self.tmpHW.register_callback( self.tmpHW.CALLBACK_TEMPERATURE, self.cb_tempHW )
                    self.tmpHW.set_temperature_callback_period(500)
                elif uid==FR_ID:
                    self.tmpFR = Temperature(uid, self.ipcon) 
                    self.tmpFRval = self.tmpFR.get_temperature()/100.0    # read initial value
                    writeSensFile("FR", self.tmpFRval, self.tmpHWval, self.tmpFRval, self.tmpMainval)
                    self.tmpFR.register_callback( self.tmpFR.CALLBACK_TEMPERATURE, self.cb_tempFR )
                    self.tmpFR.set_temperature_callback_period(500)
                elif uid==MAIN_ID:
                    self.tmpMain = Temperature(uid, self.ipcon) 
                    self.tmpMainval = self.tmpMain.get_temperature()/100.0    # read initial value
                    writeSensFile("Main", self.tmpMainval, self.tmpHWval, self.tmpFRval, self.tmpMainval)
                    self.tmpMain.register_callback( self.tmpMain.CALLBACK_TEMPERATURE, self.cb_tempMain )
                    self.tmpMain.set_temperature_callback_period(500)

    # Callback handles reconnection of IP Connection
    def cb_connected(self, connected_reason):
        # Enumerate devices again. If we reconnected, the Bricks/Bricklets
        # may have been offline and the configuration may be lost.
        # In this case we don't care for the reason of the connection
        self.ipcon.enumerate()
class LRF:
	HOST = "localhost"
	PORT = 4223
	PROG_PATH = "/home/pi/SICKRPi-Scanner/"
	#PROG_PATH = "/home/gus484/Programme/octomap_ibeo/"	
	TIMER_MS = 1.0

	def __init__(self):
		self.db = None
		self.is_scan = False
		self.led_l_blink = False
		self.led_r_blink = False
		self.run = True
		self.ipcon = None
		self.pro = None
		self.bat_lv = None

		try:
			# create ip connection
			self.ipcon = IPConnection()

			# register ip connection callbacks
			self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
							self.cb_enumerate)

			self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
							self.cb_connected)

			self.ipcon.connect(LRF.HOST, LRF.PORT)

			#self.ipcon.enumerate()
		except:
			self.run = False
			print "no connection to tinkerforge devices!"
			exit(0)

	def release(self):
		if self.ipcon != None:
			# turn off leds
			self.db.set_led_state(DualButton.LED_STATE_OFF,DualButton.LED_STATE_OFF)
			# disconnect			
			self.ipcon.disconnect()
			print "quit"
		self.run = False

	# thread: start laserscan
	def call_laser(self):
		# nicht blockierend
		self.pro = subprocess.Popen(LRF.PROG_PATH+"bin/main",  shell=False, preexec_fn=os.setsid) 

	# callback handles device connections and configures possibly lost 
	# configuration of lcd and temperature callbacks, backlight etc.
	def cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type):
		if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            
			# enumeration is for dual button bricklet
			if device_identifier == DualButton.DEVICE_IDENTIFIER:
				if self.db != None:
					return
				# create dual button device object
				self.db = DualButton(uid, self.ipcon) 
				# register button push callback to function cb_state_changed
				self.db.register_callback(self.db.CALLBACK_STATE_CHANGED, self.cb_state_changed)

				# set led state
				self.db.set_led_state(DualButton.LED_STATE_ON, DualButton.LED_STATE_OFF)

				Timer(LRF.TIMER_MS, self.led_blink).start()

	# callback handles reconnection of ip connection
	def cb_connected(self, connected_reason):
		self.ipcon.enumerate()

	# callback function for interrupts
	def cb_state_changed(self, button_l, button_r, led_l, led_r):
		# check for both interrupts
		if button_l == DualButton.BUTTON_STATE_PRESSED and button_r == DualButton.BUTTON_STATE_PRESSED:
			print "stop script"
			#if self.is_scan:
			execfile(LRF.PROG_PATH+"quit.py")
			time.sleep(0.5)
			try:
				print "terminate process"			
				#os.killpg(self.pro.pid, signal.SIGTERM)
				self.pro.terminate()
			except:
				print "..."
			self.run = False
		# check start interrupt
		elif button_l == DualButton.BUTTON_STATE_PRESSED:
			if self.is_scan == False:
				print "start scan"
				self.led_l_blink = False
				self.db.set_selected_led_state(DualButton.LED_RIGHT,DualButton.LED_STATE_ON)
				self.is_scan = True
				# start laser thread
				start_new_thread(self.call_laser,())
		# check stop interrupt
		elif button_r == DualButton.BUTTON_STATE_PRESSED:
			if self.is_scan:
				print "stop scan"
				self.led_l_blink =  False
				self.db.set_selected_led_state(DualButton.LED_RIGHT,DualButton.LED_STATE_OFF)	
				execfile(LRF.PROG_PATH+"quit.py")
				self.is_scan = False

	def led_blink(self):
		if self.db != None and self.run == True:
			# get led state
			ls = self.db.get_led_state()

			if self.led_l_blink:				
				if ls[0] == DualButton.LED_STATE_ON:
					l = DualButton.LED_STATE_OFF
				else:
					l = DualButton.LED_STATE_ON				
				# set led state
				self.db.set_selected_led_state(DualButton.LED_LEFT,l)
			if self.led_r_blink:
				if ls[1] == DualButton.LED_STATE_ON:
					l = DualButton.LED_STATE_OFF
				else:
					l = DualButton.LED_STATE_ON
				# set led state
				self.db.set_selected_led_state(DualButton.LED_RIGHT,l)
		if self.run == True:
			Timer(LRF.TIMER_MS, self.led_blink).start()
			
	def check_battery_level(self):
		try:
			#open serial dev
			s = serial.Serial()
			s.port = "/dev/ttyAMA0"
			s.baudrate = 38400
			s.timeout = 0.15
			
			s.open()

			if not s.isOpen():
				return
				
			s.write("@EPR"+'\r\n')
			#s.write("@USB"+'\r\n')

			if s.readable():
				msg = s.read(1000)
				msg = msg.split(":")
				msg = msg[1].split("V")
				self.bat_lv = float(msg[0])
				print "Voltage:" + str(self.bat_lv)
				
				s.close()
		except:
			self.bat_lv = None
Example #43
0
    subs = srtopen(srtFilename)

    print("Number of events", len(subs))

    # s = scheduler(time, sleep)

    # global ipcon

    ipcon.connect(HOST, PORT)

    # Register Enumerate Callback
    ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, cb_enumerate)

    # Trigger Enumerate
    ipcon.enumerate()

    sleep(2)

    if verbose:
        print(tfIDs)

    dmxcount = 0
    dmx = None
    for tf in tfIDs:
        # try:
        if True:
            # print(len(tf[0]))

            if len(
                    tf[0]
Example #44
0
class TF(object):
    def __init__(self, host, port, secret, timeout, verbose):
        self.host = host
        self.port = port
        self.secret = secret
        self.timeout = timeout
        self.verbose = verbose
        self.device_type = None
        self.ptc = None
        self.temp = None
        self.al = None
        self.hum = None
        self.dist = None
        self.motion = None

        self.type_ptc = "ptc"
        self.type_temperature = "temperature"
        self.type_ambient_light = "ambient_light"
        self.type_humidity = "humidity"
        self.type_distance = "distance"
        self.type_motion = "motion"

        self.ipcon = IPConnection()
        self.ipcon.set_timeout(self.timeout)

    def connect(self, device_type, run_enumeration):
        self.device_type = device_type

        self.ipcon.connect(self.host, self.port)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate)

        if self.verbose:
            print("Connected to host '%s' on port %s." % (self.host, self.port))

        if self.secret:
            try:
                self.ipcon.authenticate(self.secret)
                if self.verbose:
                    print("DEBUG: Authentication succeeded.")
            except IPConnectionError:
                output("Cannot authenticate", 3)

        if run_enumeration is True:
            self.ipcon.enumerate()
            if self.verbose:
                print("Enumerate request sent.")

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED:
            return

        # Note: The order is important, detect PTC before Humidity
        #
        # https://www.tinkerforge.com/en/doc/Software/Bricklets/PTCV2_Bricklet_Python.html
        if device_identifier == BrickletPTCV2.DEVICE_IDENTIFIER:
            self.ptc = BrickletPTCV2(uid, self.ipcon)
            self.device_type = self.type_ptc

        # https://www.tinkerforge.com/en/doc/Software/Bricklets/Temperature_Bricklet_Python.html
        if device_identifier == Temperature.DEVICE_IDENTIFIER:
            self.temp = Temperature(uid, self.ipcon)
            self.device_type = self.type_temperature

        # https://www.tinkerforge.com/en/doc/Software/Bricklets/AmbientLightV2_Bricklet_Python.html
        if device_identifier == BrickletAmbientLightV2.DEVICE_IDENTIFIER:
            self.al = BrickletAmbientLightV2(uid, self.ipcon)
            self.device_type = self.type_ambient_light

        # https://www.tinkerforge.com/en/doc/Software/Bricklets/HumidityV2_Bricklet_Python.html
        if device_identifier == BrickletHumidityV2.DEVICE_IDENTIFIER:
            self.hum = BrickletHumidityV2(uid, self.ipcon)
            self.device_type = self.type_humidity

        # https://www.tinkerforge.com/en/doc/Software/Bricklets/DistanceIRV2_Bricklet_Python.html
        if device_identifier == BrickletDistanceIRV2.DEVICE_IDENTIFIER:
            self.dist = BrickletDistanceIRV2(uid, self.ipcon)
            self.device_type = self.type_distance

        # https://www.tinkerforge.com/de/doc/Software/Bricklets/MotionDetectorV2_Bricklet_Python.html
        if device_identifier == BrickletMotionDetectorV2.DEVICE_IDENTIFIER:
            self.dist = BrickletMotionDetectorV2(uid, self.ipcon)
            self.device_type = self.type_motion

        if self.verbose:
            print("UID:               " + uid)
            print("Enumeration Type:  " + str(enumeration_type))
            print("Connected UID:     " + connected_uid)
            print("Position:          " + position)
            print("Hardware Version:  " + str(hardware_version))
            print("Firmware Version:  " + str(firmware_version))
            print("Device Identifier: " + str(device_identifier))
            print("Device Type:       " + str(self.device_type))
            print("")

    @staticmethod
    def parse_threshold(t):
        # ranges
        if ":" in t:
            return t.split(":")
        else:
            return [t]

    def eval_threshold_generic(self, val, threshold):
        t_arr = self.parse_threshold(threshold)

        # if we only have one value, treat this as 0..value range
        if len(t_arr) == 1:
            if self.verbose:
                print("Evaluating thresholds, single %s on value %s" % (" ".join(t_arr), val))

            if val > (float(t_arr[0])):
                return True
        else:
            if self.verbose:
                print("Evaluating thresholds, rangle %s on value %s" % (":".join(t_arr), val))

            if val < float(t_arr[0]) or val > float(t_arr[1]):
                return True

        return False

    def eval_thresholds(self, val, warning, critical):
        status = 0

        if warning:
            if self.eval_threshold_generic(val, warning):
                status = 1

        if critical:
            if self.eval_threshold_generic(val, critical):
                status = 2

        return status

    def check(self, uid, warning, critical):
        # PTC
        # https://www.tinkerforge.com/en/doc/Software/Bricklets/PTCV2_Bricklet_Python.html
        if self.device_type == self.type_ptc:
            ticks = 0
            if uid:
                self.ptc = BrickletPTCV2(uid, self.ipcon)
            else:
                # TODO: refactor
                while not self.ptc:
                    time.sleep(0.1)
                    ticks = ticks + 1
                    if ticks > self.timeout * 10:
                        output("Timeout %s s reached while detecting bricklet. "
                               "Please use -u to specify the device UID." % self.timeout, 3)

            ptc_value = self.ptc.get_temperature() / 100.0

            status = self.eval_thresholds(ptc_value, warning, critical)

            perfdata = {
                "temperature": ptc_value
            }

            output("Temperature is %s degrees celcius" % ptc_value, status, [], perfdata)

        # Temperature
        # https://www.tinkerforge.com/en/doc/Software/Bricklets/Temperature_Bricklet_Python.html
        if self.device_type == self.type_temperature:
            ticks = 0
            if uid:
                self.temp = Temperature(uid, self.ipcon)
            else:
                # TODO: refactor
                while not self.temp:
                    time.sleep(0.1)
                    ticks = ticks + 1
                    if ticks > self.timeout * 10:
                        output("Timeout %s s reached while detecting bricklet. "
                               "Please use -u to specify the device UID." % self.timeout, 3)

            temp_value = self.temp.get_temperature() / 100.0

            status = self.eval_thresholds(temp_value, warning, critical)

            perfdata = {
                "temperature": temp_value
            }

            output("Temperature is %s degrees celcius" % temp_value, status, [], perfdata)

        # Ambient Light
        # https://www.tinkerforge.com/en/doc/Software/Bricklets/AmbientLightV2_Bricklet_Python.html
        if self.device_type == self.type_ambient_light:
            ticks = 0
            if uid:
                self.al = BrickletAmbientLightV2(uid, self.ipcon)
            else:
                # TODO: refactor
                while not self.al:
                    time.sleep(0.1)
                    ticks = ticks + 1
                    if ticks > self.timeout * 10:
                        output("Timeout %s s reached while detecting bricklet. "
                               "Please use -u to specify the device UID." % self.timeout, 3)

            al_value = self.al.get_illuminance() / 100.0

            status = self.eval_thresholds(al_value, warning, critical)

            perfdata = {
                "illuminance": al_value
            }

            output("Illuminance is %s lx" % al_value, status, [], perfdata)

        # Humidity
        # https://www.tinkerforge.com/en/doc/Software/Bricklets/HumidityV2_Bricklet_Python.html
        if self.device_type == self.type_humidity:
            ticks = 0
            if uid:
                self.hum = BrickletHumidityV2(uid, self.ipcon)
            else:
                # TODO: refactor
                while not self.hum:
                    time.sleep(0.1)
                    ticks = ticks + 1
                    if ticks > self.timeout * 10:
                        output("Timeout %s s reached while detecting bricklet. "
                               "Please use -u to specify the device UID." % self.timeout, 3)

            hum_value = self.hum.get_humidity() / 100.0
            hum_temp_value = self.hum.get_temperature() / 100.0

            status = self.eval_thresholds(hum_value, warning, critical)

            perfdata = {
                "humidity": hum_value,
                "temperature": hum_temp_value
            }

            output("Humidity is %s %%HR (Temperature is %s degrees celcius)" % (hum_value, hum_temp_value),
                   status, [], perfdata)

        # Distance
        # https://www.tinkerforge.com/en/doc/Software/Bricklets/DistanceIRV2_Bricklet_Python.html
        if self.device_type == self.type_distance:
            ticks = 0
            if uid:
                self.dist = BrickletDistanceIRV2(uid, self.ipcon)
            else:
                # TODO: refactor
                while not self.dist:
                    time.sleep(0.1)
                    ticks = ticks + 1
                    if ticks > self.timeout * 10:
                        output("Timeout %s s reached while detecting bricklet. "
                               "Please use -u to specify the device UID." % self.timeout, 3)

            dist_value = self.dist.get_distance() / 10.0

            status = self.eval_thresholds(dist_value, warning, critical)

            perfdata = {
                "distance": dist_value,
            }

            output("Distance is %s cm" % dist_value, status, [], perfdata)

        # Motion
        # https://www.tinkerforge.com/de/doc/Software/Bricklets/MotionDetectorV2_Bricklet_Python.html
        if self.device_type == self.type_motion:
            ticks = 0
            if uid:
                self.motion = BrickletMotionDetectorV2(uid, self.ipcon)
            else:
                # TODO: refactor
                while not self.motion:
                    time.sleep(0.1)
                    ticks = ticks + 1
                    if ticks > self.timeout * 10:
                        output("Timeout %s s reached while detecting bricklet. "
                               "Please use -u to specify the device UID." % self.timeout, 3)

            motion_value = self.motion.get_motion_detected()

            perfdata = {
                    "motion": motion_value
            }
            
            if motion_value:
                output("Motion detected!", motion_value, [], perfdata)
            else:
                output("No motion detected", motion_value, [], perfdata)
Example #45
0
class RTCTimeToLinuxTime:
    def __init__(self):
        # Create IP connection
        self.ipcon = IPConnection()

        # Connect to brickd
        self.ipcon.connect(HOST, PORT)
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.enumerate()

        self.enum_sema = Semaphore(0)
        self.rtc_uid = None
        self.rtc_device_identifier = None
        self.rtc = None
        self.rtc_time = None
        self.timer = None

    # go trough the functions to update date and time
    def __enter__(self):
        if self.is_ntp_present():
            return -1, None
        if not self.get_rtc_uid():
            return -2, None
        if not self.get_rtc_time():
            return -3, None
        if self.are_times_equal():
            return 1, self.rtc_time
        if not self.set_linux_time():
            return -4, None

        return 0, self.rtc_time

    def __exit__(self, type, value, traceback):
        try:
            self.timer.cancel()
        except:
            pass

        try:
            self.ipcon.disconnect()
        except:
            pass

    def is_ntp_present(self):
        # FIXME: Find out if we have internet access and ntp is working, in
        #        that case we don't need to use the RTC time.
        return False

    def get_rtc_uid(self):
        try:
            # Release semaphore after 1 second (if no Real-Time Clock Bricklet is found)
            self.timer = Timer(1, self.enum_sema.release)
            self.timer.start()
            self.enum_sema.acquire()
        except:
            return False

        return True

    def get_rtc_time(self):
        if self.rtc_uid == None:
            return False

        try:
            # Create Real-Time Clock device object
            if self.rtc_device_identifier == BrickletRealTimeClock.DEVICE_IDENTIFIER:
                self.rtc = BrickletRealTimeClock(self.rtc_uid, self.ipcon)
                year, month, day, hour, minute, second, centisecond, _ = self.rtc.get_date_time(
                )
            else:
                self.rtc = BrickletRealTimeClockV2(self.rtc_uid, self.ipcon)
                year, month, day, hour, minute, second, centisecond, _, _ = self.rtc.get_date_time(
                )

            self.rtc_time = datetime.datetime(year, month, day, hour, minute,
                                              second, centisecond * 10000)
        except:
            return False

        return True

    def are_times_equal(self):
        # Are we more then 3 seconds off?
        if abs(int(self.rtc_time.strftime("%s")) - time.time()) > 3:
            return False

        return True

    def set_linux_time(self):
        if self.rtc_time == None:
            return False

        try:
            # Set date as root
            command = [
                '/usr/bin/sudo', '-S', '/bin/date',
                self.rtc_time.strftime('%m%d%H%M%Y.%S')
            ]
            Popen(command, stdout=PIPE, stdin=PIPE).communicate(SUDO_PASSWORD)
        except:
            return False

        return True

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        # If more then one Real-Time Clock Bricklet is connected we will use the first one that we find
        if device_identifier in [
                BrickletRealTimeClock.DEVICE_IDENTIFIER,
                BrickletRealTimeClockV2.DEVICE_IDENTIFIER
        ]:
            self.rtc_uid = uid
            self.rtc_device_identifier = device_identifier
            self.enum_sema.release()
class DoorbellNotifier:
    HOST = 'localhost'
    PORT = 4223
    ipcon = None
    idi4 = None

    def __init__(self):
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(DoorbellNotifier.HOST, DoorbellNotifier.PORT)
                break
            except Error as e:
                log.error('Connection Error: ' + str(e.description))
                time.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                time.sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate Error: ' + str(e.description))
                time.sleep(1)

    def cb_interrupt(self, changed, value):
        log.warn('Ring Ring Ring!')

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
                if device_identifier == IndustrialDigitalIn4V2.DEVICE_IDENTIFIER:
                    try:
                        self.idi4 = IndustrialDigitalIn4V2(uid, self.ipcon)

                        self.idi4.set_all_value_callback_configuration(10000, True)
                        self.idi4.register_callback(IndustrialDigitalIn4V2.CALLBACK_ALL_VALUE,
                                                    self.cb_interrupt)

                        log.info('Industrial Digital In 4 V2 initialized')
                    except Error as e:
                        log.error('Industrial Digital In 4 V2 init failed: ' + str(e.description))

                        self.idi4 = None

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto Reconnect')

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
Example #47
0
class WeatherStation:
    HOST = "localhost"
    PORT = 4223

    ipcon = None
    lcd = None
    air_quality = None

    def __init__(self):
        self.ipcon = IPConnection()  # Create IP connection

        # Connect to brickd (retry if not possible)
        while True:
            try:
                self.ipcon.connect(WeatherStation.HOST, WeatherStation.PORT)
                break
            except Error as e:
                log.error('Connection Error: ' + str(e.description))
                time.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                time.sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        # Enumerate Bricks and Bricklets (retry if not possible)
        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate Error: ' + str(e.description))
                time.sleep(1)

    def cb_all_values(self, iaq_index, iaq_index_accuracy, temperature,
                      humidity, air_pressure):
        if self.lcd is not None:
            self.lcd.write_line(2, 0, 'IAQ:      {0:6}'.format(iaq_index))
            # 0xF8 == ° on LCD 128x64 charset
            self.lcd.write_line(
                3, 0, 'Temp:     {0:6.2f} {1}C'.format(temperature / 100.0,
                                                       chr(0xF8)))
            self.lcd.write_line(
                4, 0, 'Humidity: {0:6.2f} %RH'.format(humidity / 100.0))
            self.lcd.write_line(
                5, 0, 'Air Pres: {0:6.1f} mbar'.format(air_pressure / 100.0))

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == BrickletLCD128x64.DEVICE_IDENTIFIER:
                try:
                    # Initialize newly enumerated LCD128x64 Bricklet
                    self.lcd = BrickletLCD128x64(uid, self.ipcon)
                    self.lcd.clear_display()
                    self.lcd.write_line(0, 0, "   Weather Station")
                    log.info('LCD 128x64 initialized')
                except Error as e:
                    log.error('LCD 128x64 init failed: ' + str(e.description))
                    self.lcd = None
            elif device_identifier == BrickletAirQuality.DEVICE_IDENTIFIER:
                try:
                    # Initialize newly enumaratedy Air Quality Bricklet and configure callbacks
                    self.air_quality = BrickletAirQuality(uid, self.ipcon)
                    self.air_quality.set_all_values_callback_configuration(
                        1000, False)
                    self.air_quality.register_callback(
                        self.air_quality.CALLBACK_ALL_VALUES,
                        self.cb_all_values)
                    log.info('Air Quality initialized')
                except Error as e:
                    log.error('Air Quality init failed: ' + str(e.description))
                    self.air_quality = None

    def cb_connected(self, connected_reason):
        # Eumerate again after auto-reconnect
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto Reconnect')

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
Example #48
0
class tf_UI_App(App):

    # def cb_illuminance(illuminance):
    #     print("Illuminance: " + str(illuminance/100.0) + " Lux")

    def cb_sensors(self, dt):
        # print("Illuminance: "+str(al.get_illuminance()/100))
        i = 0
        for sensor in self.sensors:
            if debug:
                # print("Sensor: "+str(dir(sensor)))
                print("Sensor type: " + str(sensor.DEVICE_IDENTIFIER))
                print(self.buttons[i].text[0:3], sensor.DEVICE_DISPLAY_NAME,
                      sensor.get_identity().uid)
            if self.buttons[i].text[0:3] == sensor.get_identity().uid:
                quantity = getattr(
                    sensor, deviceIdentifiersDict[sensor.DEVICE_IDENTIFIER]
                    ["value_func"])() + 1
                v = eval(deviceIdentifiersDict[sensor.DEVICE_IDENTIFIER]
                         ["correction"] % quantity)
                unit = deviceIdentifiersDict[sensor.DEVICE_IDENTIFIER]["unit"]
                if debug:
                    # print(quantity, deviceIdentifiersDict[sensor.DEVICE_IDENTIFIER]["correction"] % quantity)
                    print(self.buttons[i].text[0:3], sensor.DEVICE_IDENTIFIER,
                          sensor.DEVICE_DISPLAY_NAME,
                          deviceIdentifiersDict[sensor.DEVICE_IDENTIFIER], v,
                          unit)
                if verbose:
                    print(self.buttons[i].text[0:3], sensor.DEVICE_IDENTIFIER,
                          sensor.DEVICE_DISPLAY_NAME, v, unit)
                self.buttons[i].text = sensor.get_identity(
                ).uid + "\n" + sensor.DEVICE_DISPLAY_NAME + "\n" + str(
                    v) + " " + unit
                #print(dir(self.buttons[i]))
                # if sensor.DEVICE_IDENTIFIER == 259:
                #     self.buttons[i].text = sensor.get_identity().uid+"\n"+sensor.DEVICE_DISPLAY_NAME+"\n"+str(sensor.get_illuminance()/100.0)+" lux"
                # if sensor.DEVICE_IDENTIFIER == 216:
                #     self.buttons[i].text = sensor.get_identity().uid+"\n"+sensor.DEVICE_DISPLAY_NAME+"\n"+str(sensor.get_temperature()/100.0)+" ºC"
                # if sensor.DEVICE_IDENTIFIER == 27:
                #     self.buttons[i].text = sensor.get_identity().uid+"\n"+sensor.DEVICE_DISPLAY_NAME+"\n"+str(sensor.get_humidity()/10.0)+" %RH"

                # Get timestamp
                ts = time.time()
                #print(time.time(), prev_time)
                datestr = datetime.datetime.fromtimestamp(ts).strftime(
                    '%Y-%m-%d %H:%M:%S')

                # Send value to InfluxDB at instantaneous interval
                if send_to_influx:
                    SENSORNAME = SHORT_IDENT + "_" + self.buttons[i].text[
                        0:3] + "_" + deviceIdentifiersDict[
                            sensor.DEVICE_IDENTIFIER]["brick_tag"]
                    json_body = [{
                        "measurement": SENSORNAME,
                        "tags": {
                            "sensor": SENSORNAME,
                        },
                        "time": datestr,
                        "fields": {
                            "value": v,
                        }
                    }]
                    if verbose:
                        print(json_body)
                    self.influx_client.write_points(json_body)
            i += 1

    def build(self):
        self.title = 'Tinkerforge Sensors'
        # self.layout = BoxLayout(padding=10)
        self.layout = GridLayout(cols=columns_number, padding=10, spacing=10)
        self.sensors = []
        self.buttons = []
        self.ipcon = None
        self.influx_client = None

        if tfConnect:
            # Create connection and connect to brickd
            self.ipcon = IPConnection()
            self.ipcon.connect(HOST, PORT)

            # Register Enumerate Callback
            self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                         cb_enumerate)

            # Trigger Enumerate
            self.ipcon.enumerate()

            sleep(2)
            #raw_input("Press key to exit\n") # Use input() in Python 3

        if debug:
            print(tfIDs)

        # Connect to InfluxDB server
        if send_to_influx:
            print("Connecting to InfluxDB server %s" % INFLUX_AUTH["host"])
            # self.influx_client = InfluxDBClient(INFLUXserver, INFLUXport, INFLUXdbuser, INFLUXdbuser_password, INFLUXdbname)
            try:
                self.influx_client = InfluxDBClient(
                    host=INFLUX_AUTH["host"],
                    port=INFLUX_AUTH["port"],
                    username=INFLUX_AUTH["user"],
                    password=INFLUX_AUTH["pass"],
                    database=INFLUX_AUTH["db"],
                    ssl=INFLUX_AUTH["ssl"],
                    timeout=1,
                    retries=5,
                )
            except Exception as e:
                print("Error connecting to InfluxDB:")
                print(e)

        for tf in tfIDs:
            # try:
            if True:
                # print(len(tf[0]))
                if len(
                        tf[0]
                ) <= 3:  # if the device UID is 3 characters it is a bricklet
                    #self.addButton(label=getIdentifier(tf))
                    if tf[1] in deviceIDs:
                        bricklet = deviceIdentifiersDict[tf[1]]["class"](
                            tf[0], self.ipcon)
                        self.sensors.append(bricklet)
                        quantity = getattr(
                            bricklet,
                            deviceIdentifiersDict[tf[1]]["value_func"])() + 1
                        v = eval(deviceIdentifiersDict[tf[1]]["correction"] %
                                 quantity)
                        unit = deviceIdentifiersDict[tf[1]]["unit"]
                        if debug:
                            print(
                                quantity,
                                deviceIdentifiersDict[tf[1]]["correction"] %
                                quantity)
                            print(tf[0], getIdentifier(tf),
                                  deviceIdentifiersDict[tf[1]], v, unit)
                        kv_button = Button(text=tf[0] + "\n" +
                                           getIdentifier(tf) + "\n" + str(v) +
                                           " " + unit,
                                           font_size=50)
                        self.buttons.append(kv_button)
                        self.layout.add_widget(kv_button)
                    # if tf[1] == 259:
                    #     al = BrickletAmbientLightV2(tf[0], ipcon)
                    #     print(al.get_identity())
                    #     # al.register_callback(al.CALLBACK_ILLUMINANCE, cb_illuminance)
                    #     #al.set_illuminance_callback_period(1000)
                    #     self.sensors.append(al)
                    #     kv_button = Button(text=tf[0]+"\n"+getIdentifier(tf)+"\n"+str(al.get_illuminance()/100.0)+" lux",font_size=50)
                    #     self.buttons.append(kv_button)
                    #     self.layout.add_widget(kv_button)
                    # if tf[1] == 216:
                    #     al = BrickletTemperature(tf[0], ipcon)
                    #     print(al.get_identity())
                    #     # al.register_callback(al.CALLBACK_ILLUMINANCE, cb_illuminance)
                    #     #al.set_illuminance_callback_period(1000)
                    #     self.sensors.append(al)
                    #     kv_button = Button(text=tf[0]+"\n"+getIdentifier(tf)+"\n"+str(al.get_temperature()/100.0)+" ºC",font_size=50)
                    #     self.buttons.append(kv_button)
                    #     self.layout.add_widget(kv_button)
                    # if tf[1] == 27:
                    #     al = BrickletHumidity(tf[0], ipcon)
                    #     print(al.get_identity())
                    #     # al.register_callback(al.CALLBACK_ILLUMINANCE, cb_illuminance)
                    #     #al.set_illuminance_callback_period(1000)
                    #     self.sensors.append(al)
                    #     kv_button = Button(text=tf[0]+"\n"+getIdentifier(tf)+"\n"+str(al.get_humidity()/10.0)+" %RH",font_size=50)
                    #     self.buttons.append(kv_button)
                    #     self.layout.add_widget(kv_button)

            # except:
            #     pass
        Clock.schedule_interval(self.cb_sensors, reading_interval)

        imgs = getImages(imgPath)
        # print(imgs)
        for img in imgs:
            fn = join(imgPath, img)
            im = CoreImage(fn)
            # print(dir(im))]
            # print(im.size)
            kv_button = Button(background_normal=fn)
            # print(dir(kv_button))
            kv_button.texture_size = [100, 100]  #im.size
            # print(kv_button.texture_size)
            self.layout.add_widget(kv_button)

        return (self.layout)
Example #49
0
class GPSTimeToLinuxTime:
    def __init__(self):
        # Create IP connection
        self.ipcon = IPConnection()

        # Connect to brickd
        self.ipcon.connect(HOST, PORT)
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.enumerate()

        self.enumerate_handshake = Semaphore(0)
        self.gps_uid = None
        self.gps_class = None
        self.gps_has_fix_function = None
        self.gps_datetime = None
        self.gps_has_fix = None
        self.timer = None

    # go trough the functions to update date and time
    def __enter__(self):
        if self.is_ntp_present():
            return -1, None

        if not self.get_gps_uid():
            return -2, None

        if not self.get_gps_time():
            return -3, None

        if not self.gps_has_fix:
            return 2, None

        if self.are_times_equal():
            return 1, self.gps_time

        if not self.set_linux_time():
            return -5, None

        return 0, self.gps_datetime

    def __exit__(self, type, value, traceback):
        try:
            self.timer.cancel()
        except:
            pass

        try:
            self.ipcon.disconnect()
        except:
            pass

    def is_ntp_present(self):
        # FIXME: Find out if we have internet access and ntp is working, in
        #        that case we don't need to use the GPS time.
        return False

    def get_gps_uid(self):
        try:
            # Release semaphore after 1 second (if no GPS Bricklet is found)
            self.timer = Timer(1, self.enumerate_handshake.release)
            self.timer.start()
            self.enumerate_handshake.acquire()
        except:
            return False

        return True

    def get_gps_time(self):
        if self.gps_uid == None:
            return False

        try:
            self.gps = BrickletGPSV2(self.gps_uid, self.ipcon)
            self.gps_has_fix = self.gps_has_fix_function(self.gps)

            if not self.gps_has_fix:
                return True

            gps_date, gps_time = self.gps.get_date_time()

            gps_year = 2000 + (gps_date % 100)
            gps_date //= 100
            gps_month = gps_date % 100
            gps_date //= 100
            gps_day = gps_date

            gps_microsecond = 1000 * (gps_time % 1000)
            gps_time //= 1000
            gps_second = gps_time % 100
            gps_time //= 100
            gps_minute = gps_time % 100
            gps_time //= 100
            gps_hour = gps_time

            self.gps_datetime = datetime(gps_year,
                                         gps_month,
                                         gps_day,
                                         gps_hour,
                                         gps_minute,
                                         gps_second,
                                         gps_microsecond,
                                         tzinfo=timezone.utc)
        except:
            return False

        return True

    def are_times_equal(self):
        return False
        # Are we more than 1 seconds off?
        return abs((self.gps_datetime - self.local_datetime) /
                   timedelta(seconds=1)) < 1

    def set_linux_time(self):
        if self.gps_datetime == None:
            return False

        try:
            # Set date as root
            timestamp = int(
                (self.gps_datetime - datetime(1970, 1, 1, tzinfo=timezone.utc))
                / timedelta(seconds=1) * 1000000000)
            command = [
                '/usr/bin/sudo', '-S', '-p', '', '/bin/date', '+%s.%N', '-u',
                '-s', '@{0}.{1:09}'.format(timestamp // 1000000000,
                                           timestamp % 1000000000)
            ]
            subprocess.Popen(command,
                             stdout=subprocess.PIPE,
                             stdin=subprocess.PIPE).communicate(SUDO_PASSWORD)
        except:
            return False

        return True

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        # If more then one GPS Bricklet is connected we will use the first one that we find
        if device_identifier == BrickletGPS.DEVICE_IDENTIFIER:
            self.gps_uid = uid
            self.gps_class = BrickletGPS
            self.gps_has_fix_function = lambda gps: gps.get_status(
            ).fix != gps.FIX_NO_FIX
            self.enumerate_handshake.release()
        elif device_identifier == BrickletGPSV2.DEVICE_IDENTIFIER:
            self.gps_uid = uid
            self.gps_class = BrickletGPSV2
            self.gps_has_fix_function = lambda gps: gps.get_status().has_fix
            self.enumerate_handshake.release()
Example #50
0
class Controller:

    HOST = 'localhost'
    PORT = 4223

    def __init__(self, waitForConn=True):
        self.ipcon = IPConnection()
        self.cache = [[], []]

        self.connect()
        if waitForConn:
            if not self.connected:
                print(_C.BOLD + _C.YEL + 'Please connect the CPS Commander' +
                      _C.ENDC)
                while not self.connected:
                    self.connect()
        if self.connected:
            print(_C.BOLD + _C.CYAN + 'CPS Commander connected' + _C.ENDC)
            self.gpio = digital.Digital(self)
            self.serial = rs485.RS485(self)
            self.analog = analog.Analog(self)
            self.gpio.update()
            self.state = self.gpio.state
        else:
            print(_C.BOLD + _C.RED + 'CPS Commander not connected' + _C.ENDC)

    def cb_read_1(self, signal):
        signal = parseReturn1(signal)
        self.cache[0].append(signal)

    def cb_read_2(self, signal):
        # print('reading:', signal)
        signal = parseReturn2(signal)
        self.cache[1].append(signal)

    def wipeCache(self, which=2):
        self.cache[which - 1] = []

    def reset(self):
        self.disconnect()
        self.connect()

    def connect(self):
        self.ipcon.connect(self.HOST, self.PORT)
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.callback)
        self.connected = False
        self.ipcon.enumerate()
        time.sleep(.1)
        if self.connected:
            self.io = BrickletIO16(self.IO16_ID, self.ipcon)
            self.vc = BrickletVoltageCurrent(self.VC_ID, self.ipcon)
            self.rs1 = BrickletRS485(self.RS485_1_ID, self.ipcon)
            self.rs2 = BrickletRS485(self.RS485_2_ID, self.ipcon)
            self.rs485 = [self.rs1, self.rs2]
            self.callbackFn = [self.cb_read_1, self.cb_read_2]
            for i, rs in enumerate(self.rs485):
                rs.set_rs485_configuration(1250000, rs.PARITY_NONE,
                                           rs.STOPBITS_1, rs.WORDLENGTH_8,
                                           rs.DUPLEX_HALF)
                rs.register_callback(rs.CALLBACK_READ, self.callbackFn[i])
                rs.enable_read_callback()
            return True
        else:
            self.ipcon.disconnect()
            return False

    def disconnect(self):
        self.ipcon.disconnect()

    def callback(self, uid, connected_uid, position, hardware_version,
                 firmware_version, device_identifier, enumeration_type):

        if position == 0:
            self.MASTER_ID = uid
        elif position == 'c':
            self.IO16_ID = uid
        elif position == 'b':
            self.RS485_2_ID = uid
        elif position == 'd':
            self.RS485_1_ID = uid
        elif position == 'a':
            self.VC_ID = uid

        self.connected = True

    def getVC(self):
        vc = self.analog.getVC()
        return vc

    def stateDigital(self, verbose=False):
        self.gpio.update()
        if verbose:
            self.gpio.status()
        return self.gpio.state

    def listenAdr(self, verbose=False):
        # Open Address channel
        self.gpio.listenAddr(verbose=verbose)
        return

    def enableSingle(self, i, verbose=False):
        self.gpio.enable(i, verbose=verbose)
        check = self.gpio.getPassthrough(i, verbose=verbose)
        return check

    def disableSingle(self, i, verbose=False):
        self.gpio.disable(i, verbose=verbose)
        check = self.gpio.getPassthrough(i, verbose=verbose)
        return (not check)

    def enable(self, verbose=False):
        e1 = self.enableSingle(1, verbose=verbose)
        e2 = self.enableSingle(2, verbose=verbose)
        check = e1 and e2
        return check

    def disable(self, verbose=False):
        d1 = self.disableSingle(1, verbose=verbose)
        d2 = self.disableSingle(2, verbose=verbose)
        check = d1 and d2
        return check

    def closeAdr(self, verbose=False):
        self.gpio.closeAddr(verbose=verbose)
        return

    def setAddr(self, adr, verbose=False):
        """
        Go through the complete addressing procedure of the power supply

        The on-state is querried immediately after the address is set to
        check for a response (if it's on or off is irrelevant) and consequently

        Parameters
        ----------
        adr: int
            address in the range 0-255
        verbose: bool, optional
            print all rs485 signals human readable

        Returns
        -------
        adr: int or None
            returns the address if successfull, otherwise None
        """
        if verbose:
            print(_C.BOLD + _C.CYAN + '---- Setting addr ----' + _C.ENDC)
            print(_C.LIME + 'Address: ' + str(hex(adr)) + _C.ENDC)

        # Setting Addr and closing channel
        self.serial.write2(adr=0x00,
                           cmd=0x05,
                           data=adr,
                           length=1,
                           verbose=verbose)
        # self.gpio.closeAddr(verbose=verbose)
        if verbose:
            print(_C.BOLD + _C.CYAN + '----------------------' + _C.ENDC)
        return True

    def resetAddr(self, verbose=False):
        """
        Reset the address of a power supply.
        If multiple supplies are connected this will reset all of them.

        Parameters
        ----------
        verbose: bool, optional
            print all rs485 signals human readable
        """
        self.serial.write2(adr=0x00,
                           cmd=0x06,
                           data=0x1234,
                           length=2,
                           verbose=verbose)
        return True
Example #51
0
def main():

    # host = "localhost"
    # port = 4223
    # segment_display_uid = "abc"         # uid of the sensor to display on the 7-segment display
    # segment_display_brightness = 2      # brightness of the 7-segment display (0-7)

    settings = read_config(os.environ)
    parser = OptionParser()
    parser.add_option("--host",
                      dest="host",
                      default=settings['host'],
                      help="host/ipaddress of the tinkerforge device",
                      metavar="ADDRESS")
    parser.add_option("--port",
                      dest="port",
                      default=settings['port'],
                      type=int,
                      help="port of the tinkerforge device",
                      metavar="PORT")
    parser.add_option(
        "--segment_display_uid",
        dest="uid",
        default=settings['segment_display_uid'],
        help=
        "uid of the bricklet which will be displayed in the 7-segment display",
        metavar="UID")
    parser.add_option("--segment_display_brightness",
                      type=int,
                      dest="brightness",
                      default=settings['segment_display_brightness'],
                      help="brightness of the 7-segment display (0-7)")
    parser.add_option(
        "--install",
        action="store_true",
        help="install tinkerforge python api to same directory as the plugin")

    options = parser.parse_args()[0]

    settings = {
        'host': options.host,
        'port': options.port,
        'segment_display_uid': options.uid,
        'segment_display_brightness': options.brightness
    }

    if options.install:
        return install()

    try:
        from tinkerforge.ip_connection import IPConnection  # type: ignore[import]
    except ImportError:
        sys.stdout.write("<<<tinkerforge:sep(44)>>>\n")
        sys.stdout.write("master,0.0.0,tinkerforge api isn't installed\n")
        return 1

    conn = IPConnection()
    conn.connect(settings['host'], settings['port'])

    device_handlers = init_device_handlers()

    try:
        sys.stdout.write("<<<tinkerforge:sep(44)>>>\n")

        cb = lambda uid, connected_uid, position, hardware_version, firmware_version, \
                    device_identifier, enumeration_type: \
            enumerate_callback(conn, device_handlers, settings, \
                               uid, connected_uid, position, \
                               hardware_version, firmware_version, \
                               device_identifier, enumeration_type)

        conn.register_callback(IPConnection.CALLBACK_ENUMERATE, cb)
        conn.enumerate()

        # bricklets respond asynchronously in callbacks and we have no way of knowing
        # what bricklets to expect
        time.sleep(0.1)

        if segment_display is not None:
            if segment_display_value is not None:
                display_on_segment(
                    conn, settings,
                    "%d%s" % (segment_display_value, segment_display_unit))
            else:
                display_on_segment(conn, settings, "")
    finally:
        conn.disconnect()
Example #52
0
class Heater:

    # These are the bricklet objects which are populated
    # as the hardware responds to enumeration request.
    ipcon = None
    lcd = None
    thermocouple = None
    relay = None
    pid = None

    # Current PID setpoint
    setpoint = 0

    # PWM power for output. 0 - 100
    heater_power = 0

    # Current state of output. Boolean
    heater_active = False

    # Current state of thermocouple.
    # False if bricklet reports an error state.
    thermocouple_active = True

    # Current active GUI tab index
    active_tab = 0

    # Number of readings to keep in state. This is set to match graph width
    n_temp_points = 107

    starting_temp = 20
    initial_temp_data = [starting_temp] * N_SMOOTHING_POINTS
    temp_data = deque(initial_temp_data, n_temp_points)

    # Min and max for graph Y axis. Updated automatically with data
    axis_min = starting_temp - 10
    axis_max = starting_temp + 10

    # Set true to read tuning parameters every iteration
    tuning_mode = False

    # Set true to log data to a file
    logging_mode = False

    # Current target tunings
    tunings = {
        "p": 0,
        "i": 0,
        "d": 0,
        "bias": 0,
        "proportional_on_measurement": False
    }

    def __init__(self):
        LOGGER.info("Heater starting...")

        self._init_pid()

        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(HOST, PORT)
                break
            except TFConnectionError as error:
                LOGGER.error("Connection Error: " + str(error.description))
                sleep(1)
            except socket.error as error:
                LOGGER.error("Socket Error: " + str(error))
                sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        if self.logging_mode:
            logfile_path = f"{datetime.now().timestamp():0f}_heated_data.csv"
            self.data_logger = getLogger("data-logger")
            self.data_logger.setLevel(INFO)
            self.data_logger.addHandler(FileHandler(logfile_path))
            self.data_logger.addHandler(STDOUT_HANDLER)
            self.data_logger.info(
                f"Timestamp, Temp (°C), Setpoint (°C), Power (%), Kp, Ki, Kd, Cp, Ci, Cd"
            )

        while True:
            try:
                self.ipcon.enumerate()
                return
            except TFConnectionError as error:
                LOGGER.error("Enumerate Error: " + str(error.description))
                sleep(1)

    def _init_pid(self):
        self.pid = PID(setpoint=self.setpoint, output_limits=(0, 100))
        self._read_pid_tunings_from_file()
        self._set_pid_tuning(self.tunings)

    def _read_pid_tunings_from_file(self):
        if not path.exists(PID_TUNING_FILE_PATH):
            LOGGER.info(
                f"{PID_TUNING_FILE_PATH} does not exist. Using default tunings."
            )
            return

        with open(PID_TUNING_FILE_PATH, "r") as f:
            self.tunings = json.load(f)

    def _set_pid_tuning(self, tuning_dict):
        tunings = (tuning_dict.get(parameter, 0)
                   for parameter in ("p", "i", "d"))
        self.pid.tunings = tunings
        self.pid.proportional_on_measurement = tuning_dict.get(
            "proportional_on_measurement", False)
        self.pid.bias = tuning_dict.get("bias", 0)

    def _init_lcd(self, uid):
        try:
            self.lcd = BrickletLCD128x64(uid, self.ipcon)
            self.lcd.clear_display()
            self.lcd.remove_all_gui()
            LOGGER.info("LCD128x64 initialized")
        except TFConnectionError as error:
            LOGGER.error("LCD128x64 init failed: " + str(error.description))
            return

        self.lcd.set_gui_tab_selected_callback_configuration(
            GUI_READ_PERIOD, True)
        self.lcd.register_callback(BrickletLCD128x64.CALLBACK_GUI_TAB_SELECTED,
                                   self.cb_tab)
        self.lcd.set_gui_tab_configuration(
            self.lcd.CHANGE_TAB_ON_CLICK_AND_SWIPE, True)
        self.lcd.set_gui_tab_icon(0, CONTROL_ICON)
        self.lcd.set_gui_tab_icon(1, GRAPH_ICON)
        self.lcd.set_gui_tab_icon(2, SETTINGS_ICON)

        self.lcd.set_gui_button_pressed_callback_configuration(
            GUI_READ_PERIOD, True)
        self.lcd.register_callback(
            BrickletLCD128x64.CALLBACK_GUI_BUTTON_PRESSED, self.cb_button)

        # Set initial tab
        self.cb_tab(self.active_tab)

    def cb_tab(self, index):
        self.active_tab = index
        self.lcd.clear_display()
        if index == 0:
            self.write_temp()
            self.write_setpoint()
            self.write_power()
            self.lcd.set_gui_button(0, 2, 18, 61, 11, "-1\xDFC")
            self.lcd.set_gui_button(1, 66, 18, 61, 11, "+1\xDFC")
            self.lcd.set_gui_button(2, 2, 30, 61, 11, "-10\xDFC")
            self.lcd.set_gui_button(3, 66, 30, 61, 11, "+10\xDFC")
            self.lcd.set_gui_button(4, 2, 42, 61, 11, "-100\xDFC")
            self.lcd.set_gui_button(5, 66, 42, 61, 11, "+100\xDFC")

        elif index == 1:
            self.lcd.set_gui_graph_configuration(
                0, BrickletLCD128x64.GRAPH_TYPE_LINE, 20, 0, 107, 52, "", "")
            self.update_graph()
            self.lcd.draw_text(0, 23, BrickletLCD128x64.FONT_6X8, True,
                               "\xDFC")
            self.update_axis()

        elif index == 2:
            self.lcd.draw_text(0, 0, BrickletLCD128x64.FONT_6X8, True, "BV21")
            self.lcd.set_gui_button(6, 0, 10, 80, 20, "Shut Down")

    def _cb_set_button(self, setpoint):
        self.setpoint = setpoint
        self.pid.setpoint = setpoint
        self.write_setpoint()

    def cb_button(self, index, value):
        if value is False:
            return
        if index == 0:
            self._cb_set_button(max(self.setpoint - 1, 0))
        elif index == 1:
            self._cb_set_button(min(self.setpoint + 1, 1500))
        elif index == 2:
            self._cb_set_button(max(self.setpoint - 10, 0))
        elif index == 3:
            self._cb_set_button(min(self.setpoint + 10, 1500))
        elif index == 4:
            self._cb_set_button(max(self.setpoint - 100, 0))
        elif index == 5:
            self._cb_set_button(min(self.setpoint + 100, 1500))
        elif index == 6:
            self.close()
            self.shutdown_host()

    def _init_thermocouple(self, uid):
        try:
            self.thermocouple = BrickletThermocoupleV2(uid, self.ipcon)
            LOGGER.info("Thermocouple initialized")
        except TFConnectionError as error:
            LOGGER.error("Thermocouple init failed: " + str(error.description))
            return

        self.thermocouple.set_configuration(
            BrickletThermocoupleV2.AVERAGING_16,
            BrickletThermocoupleV2.TYPE_K,
            BrickletThermocoupleV2.FILTER_OPTION_60HZ,
        )
        self.thermocouple.set_temperature_callback_configuration(
            THERMOCOUPLE_READ_PERIOD, False, "x", 0, 0)
        self.thermocouple.register_callback(
            BrickletThermocoupleV2.CALLBACK_ERROR_STATE,
            self.cb_thermocouple_error)
        self.thermocouple.register_callback(
            BrickletThermocoupleV2.CALLBACK_TEMPERATURE,
            self.cb_thermocouple_reading)

    def cb_thermocouple_error(self, over_under, open_circuit):
        if any((over_under, open_circuit)):
            self.thermocouple_active = False
        else:
            self.thermocouple_active = True

        LOGGER.info(
            f"Thermocouple reports: "
            f"over/under voltage {over_under}, open-circuit {open_circuit}")

    def get_pid_value(self):
        current_temp = (
            sum(last_n_values(N_SMOOTHING_POINTS, self.temp_data)) /
            N_SMOOTHING_POINTS)

        if self.tuning_mode:
            self._read_pid_tunings_from_file()
            self._set_pid_tuning(self.tunings)

        return self.pid(current_temp)

    def cb_thermocouple_reading(self, value):
        if self.thermocouple_active:
            current_temp = value / 100
            self.temp_data.append(current_temp)
            power = self.get_pid_value()
        else:
            power = 0
            LOGGER.info("Thermocouple in error state. Output deactivated.")

        old_power = self.heater_power
        sticky_state_active = old_power == 100 or old_power == 0
        self.heater_power = power

        if power == 100:
            self.relay.set_state(True)
            self.heater_active = True
        elif power == 0:
            self.relay.set_state(False)
            self.heater_active = False
        elif 0 < power < 100 and sticky_state_active:
            # If we're coming out of a sticky state, kick of the
            # flop loop for PWM.
            self.relay.set_state(False)
            self.heater_active = False
            self.relay.set_monoflop(False, 0)

        self.write_temp()
        self.write_power()
        self.update_graph()

        if self.logging_mode:
            self.log_line()

    def log_line(self):
        timestamp = datetime.now().strftime(DATETIME_FMT)
        current_temp = self.temp_data[-1]
        kp, ki, kd = self.pid.tunings
        cp, ci, cd = self.pid.components
        log_line = ", ".join(
            str(value) for value in (
                timestamp,
                current_temp,
                self.setpoint,
                self.heater_power,
                kp,
                ki,
                kd,
                cp,
                ci,
                cd,
            ))
        self.data_logger.info(log_line)

    def _init_relay(self, uid):
        try:
            self.relay = BrickletSolidStateRelayV2(uid, self.ipcon)
            LOGGER.info("Relay initialized")
        except TFConnectionError as error:
            LOGGER.error("Relay init failed: " + str(error.description))
            return

        self.relay.register_callback(
            BrickletSolidStateRelayV2.CALLBACK_MONOFLOP_DONE,
            self.cb_relay_flop)
        self.relay.set_state(False)

    def cb_relay_flop(self, _):
        on_time = round((self.heater_power / 100) * PWM_PERIOD)
        off_time = PWM_PERIOD - on_time

        if self.heater_power < 100:
            if self.heater_active:
                self.relay.set_monoflop(False, off_time)
                self.heater_active = False
            else:
                self.relay.set_monoflop(True, on_time)
                self.heater_active = True
        # If power is 0 or 100, we're not using the flop loop

    def write_temp(self):
        if self.lcd is None:
            return
        if self.active_tab != 0:
            return
        current_temp = self.temp_data[-1]
        temp_string = (f"T: {current_temp:2.0f}\xDFC"
                       if self.thermocouple_active else "T: ERR!")
        self.lcd.draw_box(0, 0, 59, 10, True, BrickletLCD128x64.COLOR_WHITE)
        self.lcd.draw_text(0, 0, BrickletLCD128x64.FONT_6X8, True, temp_string)

    def write_power(self):
        if self.lcd is None:
            return
        if self.active_tab != 0:
            return
        self.lcd.draw_box(0, 10, 127, 19, True, BrickletLCD128x64.COLOR_WHITE)
        string = f"Power: {self.heater_power:3.1f}%"
        self.lcd.draw_text(0, 10, BrickletLCD128x64.FONT_6X8, True, string)

    def write_setpoint(self):
        if self.lcd is None:
            return
        if self.active_tab != 0:
            return

        set_string = f"S: {self.setpoint}\xDFC"
        self.lcd.draw_box(60, 0, 127, 10, True, BrickletLCD128x64.COLOR_WHITE)
        self.lcd.draw_text(60, 0, BrickletLCD128x64.FONT_6X8, True, set_string)

    def update_axis(self):
        self.lcd.draw_box(0, 0, 20, 10, True, BrickletLCD128x64.COLOR_WHITE)
        self.lcd.draw_box(0, 45, 20, 55, True, BrickletLCD128x64.COLOR_WHITE)
        self.lcd.draw_text(0, 0, BrickletLCD128x64.FONT_6X8, True,
                           f"{self.axis_max:3.0f}")
        self.lcd.draw_text(0, 45, BrickletLCD128x64.FONT_6X8, True,
                           f"{self.axis_min:3.0f}")
        self.lcd.draw_text(0, 107, BrickletLCD128x64.FONT_6X8, True, f"")

    def update_graph(self):
        if self.lcd is None:
            return
        if self.active_tab != 1:
            return

        max_temp = max(self.temp_data)
        min_temp = min(self.temp_data)

        # Pad a little bit for looks
        max_temp *= 1.1
        min_temp *= 0.9

        diff = max_temp - min_temp
        if diff == 0:
            # This probably means we don't have any data yet
            return

        scaled_data = [((value - min_temp) / diff) * 255
                       for value in self.temp_data]

        # This gets rid of any randomness which apparently sometimes occurs when
        # the thermocouple bricklet is physically bumped.
        scaled_data = map(lambda value: max(min(value, 255), 0), scaled_data)

        if max_temp != self.axis_max or min_temp != self.axis_min:
            self.axis_max = max_temp
            self.axis_min = min_temp
            self.update_axis()

        self.lcd.set_gui_graph_data(0, scaled_data)

    def cb_enumerate(self, uid, _, __, ___, ____, device_identifier,
                     enumeration_type):
        if (enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or
                enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE):
            if device_identifier == BrickletLCD128x64.DEVICE_IDENTIFIER:
                self._init_lcd(uid)
            elif device_identifier == BrickletThermocoupleV2.DEVICE_IDENTIFIER:
                self._init_thermocouple(uid)
            elif device_identifier == BrickletSolidStateRelayV2.DEVICE_IDENTIFIER:
                self._init_relay(uid)

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            LOGGER.info("Auto Reconnect")

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except TFConnectionError as error:
                    LOGGER.error("Enumerate Error: " + str(error.description))
                    sleep(1)

    def close(self):
        if self.lcd:
            self.lcd.clear_display()
            self.lcd.remove_all_gui()
        if self.relay:
            self.relay.set_state(False)
        if self.ipcon is not None:
            self.ipcon.disconnect()
        LOGGER.info("Heater shut down")

    def shutdown_host(self):
        run("sudo shutdown now", shell=True)
Example #53
0
class WeatherStation(QApplication):
    HOST = "localhost"
    PORT = 4223

    ipcon = None
    lcd = None
    al = None
    hum = None
    baro = None

    projects = []
    active_project = None

    error_msg = None

    def __init__(self, args):
        super(QApplication, self).__init__(args)

        self.error_msg = QErrorMessage()
        self.ipcon = IPConnection()

        signal.signal(signal.SIGINT, self.exit_demo)
        signal.signal(signal.SIGTERM, self.exit_demo)

        timer = QTimer(self)
        timer.setSingleShot(True)
        timer.timeout.connect(self.connect)
        timer.start(1)

    def exit_demo(self, signl=None, frme=None):
        try:
            self.ipcon.disconnect()
            self.timer.stop()
            self.tabs.destroy()
        except:
            pass

        sys.exit()

    def open_gui(self):
        self.main = MainWindow(self)
        self.main.setFixedSize(730, 430)
        self.main.setWindowIcon(QIcon(os.path.join(ProgramPath.program_path(), "demo-icon.png")))
        
        self.tabs = QTabWidget()
        
        widget = QWidget()
        layout = QVBoxLayout()
        layout.addWidget(self.tabs)
        widget.setLayout(layout)

        self.main.setCentralWidget(widget)
        
        self.projects.append(ProjectEnvDisplay(self.tabs, self))
        self.projects.append(ProjectStatistics(self.tabs, self))
        self.projects.append(ProjectXively(self.tabs, self))

        self.tabs.addTab(self.projects[0], "Display Environment Measurements")
        self.tabs.addTab(self.projects[1], "Show Statistics with Button Control")
        self.tabs.addTab(self.projects[2], "Connect to Xively")

        self.active_project = self.projects[0]

        self.tabs.currentChanged.connect(self.tabChangedSlot)

        self.main.setWindowTitle("Starter Kit: Weather Station Demo " + config.DEMO_VERSION)
        self.main.show()

    def connect(self):
        try:
            self.ipcon.connect(WeatherStation.HOST, WeatherStation.PORT)
        except Error as e:
            self.error_msg.showMessage('Connection Error: ' + str(e.description) + "\nBrickd installed and running?")
            return
        except socket.error as e:
            self.error_msg.showMessage('Socket error: ' + str(e) + "\nBrickd installed and running?")
            return

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        try:
            self.ipcon.enumerate()
        except Error as e:
            self.error_msg.showMessage('Enumerate Error: ' + str(e.description))
            return

        self.open_gui()

    def tabChangedSlot(self, tabIndex):

        if self.lcd is not None:
            self.lcd.clear_display()

        self.active_project = self.projects[tabIndex]

    def cb_illuminance(self, illuminance):
        for p in self.projects:
            p.update_illuminance(illuminance)

    def cb_humidity(self, humidity):
        for p in self.projects:
            p.update_humidity(humidity)

    def cb_air_pressure(self, air_pressure):
        for p in self.projects:
            p.update_air_pressure(air_pressure)

        try:
            temperature = self.baro.get_chip_temperature()
        except Error as e:
            print('Could not get temperature: ' + str(e.description))
            return

        for p in self.projects:
            p.update_temperature(temperature)

    def configure_custom_chars(self):
        c = [[0x00 for x in range(8)] for y in range(8)]
	
        c[0] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff]
        c[1] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff]
        c[2] = [0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff]
        c[3] = [0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]
        c[4] = [0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff]
        c[5] = [0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
        c[6] = [0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
        c[7] = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]

        for i in range(len(c)):
            self.lcd.set_custom_character(i, c[i]);

    def cb_button_pressed(self, button):
        for p in self.projects:
            p.button_pressed(button)

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == LCD20x4.DEVICE_IDENTIFIER:
                try:
                    self.lcd = LCD20x4(uid, self.ipcon)
                    self.lcd.clear_display()
                    self.lcd.backlight_on()
                    self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_PRESSED, self.cb_button_pressed)
                    self.configure_custom_chars()

                except Error as e:
                    self.error_msg.showMessage('LCD 20x4 init failed: ' + str(e.description))
                    self.lcd = None
            elif device_identifier == AmbientLight.DEVICE_IDENTIFIER:
                try:
                    self.al = AmbientLight(uid, self.ipcon)
                    self.al.set_illuminance_callback_period(1000)
                    self.al.register_callback(self.al.CALLBACK_ILLUMINANCE,
                                              self.cb_illuminance)
                except Error as e:
                    self.error_msg.showMessage('Ambient Light init failed: ' + str(e.description))
                    self.al = None
            elif device_identifier == Humidity.DEVICE_IDENTIFIER:
                try:
                    self.hum = Humidity(uid, self.ipcon)
                    self.hum.set_humidity_callback_period(1000)
                    self.hum.register_callback(self.hum.CALLBACK_HUMIDITY,
                                               self.cb_humidity)
                except Error as e:
                    self.error_msg.showMessage('Humidity init failed: ' + str(e.description))
                    self.hum = None
            elif device_identifier == Barometer.DEVICE_IDENTIFIER:
                try:
                    self.baro = Barometer(uid, self.ipcon)
                    self.baro.set_air_pressure_callback_period(1000)
                    self.baro.register_callback(self.baro.CALLBACK_AIR_PRESSURE,
                                                self.cb_air_pressure)
                except Error as e:
                    self.error_msg.showMessage('Barometer init failed: ' + str(e.description))
                    self.baro = None

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    self.error_msg.showMessage('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
class Proxy(object):
    def __init__(self, brickd_host, brickd_port, broker_host, broker_port, update_interval):
        self.brickd_host = brickd_host
        self.brickd_port = brickd_port
        self.broker_host = broker_host
        self.broker_port = broker_port
        self.update_interval = update_interval

        self.ipcon = IPConnection()
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, self.ipcon_cb_connected)
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.ipcon_cb_enumerate)

        self.client = mqtt.Client()
        self.client.on_connect = self.mqtt_on_connect
        self.client.on_disconnect = self.mqtt_on_disconnect
        self.client.on_message = self.mqtt_on_message

        self.device_proxies = {}
        self.device_proxy_classes = {}

        for subclass in DeviceProxy.__subclasses__():
            self.device_proxy_classes[subclass.DEVICE_CLASS.DEVICE_IDENTIFIER] = subclass

    def connect(self):
        self.client.connect(self.broker_host, self.broker_port)
        self.client.loop_start()

        while True:
            try:
                time.sleep(ENUMERATE_INTERVAL)
                self.ipcon.enumerate()
            except KeyboardInterrupt:
                self.client.disconnect()
                break
            except:
                pass

        self.client.loop_stop()

    def publish_as_json(self, topic, payload, *args, **kwargs):
        self.client.publish(GLOBAL_TOPIC_PREFIX + topic,
                            json.dumps(payload, separators=(',',':')),
                            *args, **kwargs)

    def publish_enumerate(self, changed_uid, connected):
        device_proxy = self.device_proxies[changed_uid]
        topic_prefix = device_proxy.TOPIC_PREFIX

        if connected:
            topic = 'enumerate/connected/' + topic_prefix
        else:
            topic = 'enumerate/disconnected/' + topic_prefix

        self.publish_as_json(topic, device_proxy.get_enumerate_entry())

        enumerate_entries = []

        for uid, device_proxy in self.device_proxies.items():
            if not connected and uid == changed_uid or device_proxy.TOPIC_PREFIX != topic_prefix:
                continue

            enumerate_entries.append(device_proxy.get_enumerate_entry())

        self.publish_as_json('enumerate/available/' + topic_prefix, enumerate_entries, retain=True)

    def ipcon_cb_connected(self, connect_reason):
        self.ipcon.enumerate()

    def ipcon_cb_enumerate(self, uid, connected_uid, position, hardware_version,
                           firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED:
            if uid in self.device_proxies:
                self.publish_enumerate(uid, False)
                self.device_proxies[uid].destroy()
                del self.device_proxies[uid]
        elif device_identifier in self.device_proxy_classes and uid not in self.device_proxies:
            self.device_proxies[uid] = self.device_proxy_classes[device_identifier](uid, connected_uid, position, hardware_version,
                                                                                    firmware_version, self.ipcon, self.client,
                                                                                    self.update_interval)
            self.publish_enumerate(uid, True)

    def mqtt_on_connect(self, client, user_data, flags, result_code):
        if result_code == 0:
            self.ipcon.connect(self.brickd_host, self.brickd_port)

    def mqtt_on_disconnect(self, client, user_data, result_code):
        self.ipcon.disconnect()

        for uid in self.device_proxies:
            self.device_proxies[uid].destroy()

        self.device_proxies = {}

    def mqtt_on_message(self, client, user_data, message):
        logging.debug('Received message for topic ' + message.topic)

        topic = message.topic[len(GLOBAL_TOPIC_PREFIX):]

        if topic.startswith('brick/') or topic.startswith('bricklet/'):
            topic_prefix1, topic_prefix2, uid, topic_suffix = topic.split('/', 3)
            topic_prefix = topic_prefix1 + '/' + topic_prefix2

            if uid in self.device_proxies and topic_prefix == self.device_proxies[uid].TOPIC_PREFIX:
                payload = message.payload.strip()

                if len(payload) > 0:
                    try:
                        payload = json.loads(message.payload.decode('UTF-8'))
                    except:
                        logging.warn('Received message with invalid payload for topic ' + message.topic) # FIXME
                        return
                else:
                    payload = {}

                self.device_proxies[uid].handle_message(topic_suffix, payload)
                return

        logging.debug('Unknown topic ' + message.topic)