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()
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()
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()
def run(self): global ipcon isexception = False try: ipcon = IPConnection() if ipcon.get_connection_state( ) != IPConnection.CONNECTION_STATE_CONNECTED: ipcon.connect("localhost", 4223) ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, cb_enumerate) ipcon.time_out = 0.5 ipcon.enumerate() time.sleep(0.3) except: logging.debug("Tinkerforge:failed connecting to IP Connection") pass
class 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 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
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)
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)
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()
#!/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()
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 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")
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)
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()
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()
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()
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()
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)
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)
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'
class DeviceManager(object): """ Diese Klasse implementiert den Gerätemanager einer ORBIT-Anwendung. **Parameter** ``core`` Ein Verweis auf den Anwendungskern der ORBIT-Anwendung. Eine Instanz der Klasse :py:class:`Core`. **Beschreibung** Der Gerätemanager baut eine Verbindung zu einem TinkerForge-Server auf, ermittelt die angeschlossenen Bricks und Bricklets und stellt den Komponenten in den Jobs die jeweils geforderten Geräte zur Verfügung. Dabei behält der Gerätemanager die Kontrolle über den Gerätezugriff. Das bedeutet, dass der Gerätemanager die Autorität hat, einer Komponente ein Gerät zur Verügung zu stellen, aber auch wieder zu entziehen. Eine Komponente bekommt ein von ihm angefordertes Gerät i.d.R. dann zugewiesen, wenn die Komponente aktiv und das Gerät verfügbar ist. Wird die Verbindung zum TinkerForge-Server unterbrochen oder verliert der TinkerForge-Server die Verbindung zum Master-Brick (USB-Kabel herausgezogen), entzieht der Gerätemanager der Komponente automatisch das Gerät, so dass eine Komponente i.d.R. keine Verbindungsprobleme behandeln muss. Umgesetzt wird dieses Konzept mit Hilfe der Klassen :py:class:`SingleDeviceHandle` und :py:class:`MultiDeviceHandle`. """ def __init__(self, core): self._core = core self._connected = False self._devices = {} self._device_handles = [] self._device_callbacks = {} self._device_initializers = {} self._device_finalizers = {} # initialize IP connection self._conn = IPConnection() self._conn.set_auto_reconnect(True) self._conn.register_callback(IPConnection.CALLBACK_ENUMERATE, self._cb_enumerate) self._conn.register_callback(IPConnection.CALLBACK_CONNECTED, self._cb_connected) self._conn.register_callback(IPConnection.CALLBACK_DISCONNECTED, self._cb_disconnected) def trace(self, text): """ Schreibt eine Nachverfolgungsmeldung mit dem Ursprung ``DeviceManager`` auf die Konsole. """ if self._core.configuration.device_tracing: self._core._trace_function(text, 'DeviceManager') @property def devices(self): """ Ein Dictionary mit allen zur Zeit verfügbaren Geräten. Die UID des Geräts ist der Schlüssel und der Wert ist eine Instanz der TinkerForge-Geräte-Klasse (wie z.B. ``tinkerforge.bricklet_lcd_20x4.BrickletLCD20x4``). """ return self._devices def start(self): """ Startet den Gerätemanager und baut eine Verbindung zu einem TinkerForge-Server auf. Die Verbindungdaten für den Server werden der ORBIT-Konfiguration entnommen. Gibt ``True`` zurück, wenn die Verbindung aufgebaut werden konnte, sonst ``False``. Siehe auch: :py:meth:`stop` """ if self._conn.get_connection_state() == IPConnection.CONNECTION_STATE_DISCONNECTED: host = self._core.configuration.host port = self._core.configuration.port retry_time = self._core.configuration.connection_retry_time self.trace("connecting to %s:%d ..." % (host, port)) connected = False while not connected: try: self._conn.connect(host, port) connected = True except KeyboardInterrupt: connected = False break except: connected = False self.trace("... connection failed, waiting %d, retry ..." % retry_time) try: time.sleep(retry_time) except KeyboardInterrupt: break if connected: self.trace("... connected") return connected def stop(self): """ Trennt die Verbindung zum TinkerForge-Server und beendet den Gerätemanager. Vor dem Trennen der Verbindung wird die Zuordnung zwischen den Geräten und den Komponenten aufgehoben. Siehe auch: :py:meth:`start` """ self._finalize_and_unbind_devices() if self._conn.get_connection_state() != IPConnection.CONNECTION_STATE_DISCONNECTED: self.trace("disconnecting") self._conn.disconnect() def _cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): if enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE or \ enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED: # initialize device configuration and bindings self.trace("device present '%s' [%s]" % (device_name(device_identifier), uid)) if known_device(device_identifier): # bind device and notify components self._bind_device(device_identifier, uid) else: self.trace("could not create a device binding for device identifier " + device_identifier) if enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED: # recognize absence of device self.trace("device absent '%s' [%s]" % (device_name(device_identifier), uid)) # unbind device and notify components self._unbind_device(uid) def _cb_connected(self, reason): self._connected = True # recognize connection if reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT: self.trace("connection established (auto reconnect)") else: self.trace("connection established") # enumerate devices self._conn.enumerate() def _cb_disconnected(self, reason): self._connected = False # recognize lost connection if reason == IPConnection.DISCONNECT_REASON_ERROR: self.trace("connection lost (error)") elif reason == IPConnection.DISCONNECT_REASON_SHUTDOWN: self.trace("connection lost (shutdown)") else: self.trace("connection lost") def _bind_device(self, device_identifier, uid): self.trace("binding '%s' [%s]" % (device_name(device_identifier), uid)) # create binding instance device = device_instance(device_identifier, uid, self._conn) # add passive identity attribute identity = device.get_identity() device.identity = identity # initialize device self._initialize_device(device) # store reference to binding instance self.devices[uid] = device # register callbacks if uid in self._device_callbacks: callbacks = self._device_callbacks[uid] for event in callbacks: self.trace("binding dispatcher to '%s' [%s] (%s)" % (device_name(device_identifier), uid, event)) mcc = callbacks[event] device.register_callback(event, mcc) # notify device handles for device_handle in self._device_handles: device_handle.on_bind_device(device) def _unbind_device(self, uid): if uid in self._devices: device = self._devices[uid] self.trace("unbinding '%s' [%s]" % (device_name(device.identity[5]), uid)) # notify device handles for device_handle in self._device_handles: device_handle.on_unbind_device(device) # delete reference to binding interface del(self._devices[uid]) # delete reference to multicast callbacks if uid in self._device_callbacks: del(self._device_callbacks[uid]) else: self.trace("attempt to unbind not bound device [%s]" % uid) def _finalize_and_unbind_devices(self): for uid in list(self._devices.keys()): self._finalize_device(self._devices[uid]) self._unbind_device(uid) def add_device_initializer(self, device_identifier, initializer): """ Richtet eine Initialisierungsfunktion für einen Brick- oder Bricklet-Typ ein. **Parameter** ``device_identifier`` Die Geräte-ID der TinkerForge-API. Z.B. ``tinkerforge.bricklet_lcd_20x4.BrickletLCD20x4.DEVICE_IDENTIFIER`` ``initializer`` Eine Funktion, welche als Parameter eine Instanz der TinkerForge-Geräteklasse entgegennimmt. **Beschreibung** Sobald der Gerätemanager ein neues Gerät entdeckt, zu dem er bisher keine Verbindung aufgebaut hatte, ruft er alle Initialisierungsfunktionen für die entsprechende Geräte-ID auf. *Siehe auch:* :py:meth:`add_device_finalizer` """ if device_identifier not in self._device_initializers: self._device_initializers[device_identifier] = [] self._device_initializers[device_identifier].append(initializer) self.trace("added initializer for '%s'" % (device_name(device_identifier))) def _initialize_device(self, device): device_identifier = device.identity[5] if device_identifier in self._device_initializers: self.trace("initializing '%s' [%s]" % (device_name(device.identity[5]), device.identity[0])) for initializer in self._device_initializers[device_identifier]: try: initializer(device) except Error as err: if err.value != -8: # connection lost self.trace("Error during initialization of : %s" % err.description) except Exception as exc: self.trace("Exception caught during device initialization:\n%s" % exc) def add_device_finalizer(self, device_identifier, finalizer): """ Richtet eine Abschlussfunktion für einen Brick- oder Bricklet-Typ ein. **Parameter** ``device_identifier`` Die Geräte-ID der TinkerForge-API. Z.B. ``tinkerforge.bricklet_lcd_20x4.BrickletLCD20x4.DEVICE_IDENTIFIER`` ``finalizer`` Eine Funktion, welche als Parameter eine Instanz der TinkerForge-Geräteklasse entgegennimmt. **Beschreibung** Sobald der Gerätemanager die Verbindung zu einem Gerät selbstständig aufgibt (d.h. die Verbindung nicht durch eine Störung unterbrochen wurde), ruft er alle Abschlussfunktionen für die entsprechende Geräte-ID auf. *Siehe auch:* :py:meth:`add_device_initializer` """ if device_identifier not in self._device_finalizers: self._device_finalizers[device_identifier] = [] self._device_finalizers[device_identifier].append(finalizer) self.trace("added finalizer for '%s'" % device_name(device_identifier)) def _finalize_device(self, device): device_identifier = device.identity[5] if device_identifier in self._device_finalizers: self.trace("finalizing '%s' [%s]" % (device_name(device.identity[5]), device.identity[0])) for finalizer in self._device_finalizers[device_identifier]: try: finalizer(device) except Error as err: if err.value != -8: # connection lost self.trace("Error during device finalization: %s" % err.description) except Exception as exc: self.trace("Exception caught during device finalization:\n%s" % exc) def add_handle(self, device_handle): """ Richtet eine Geräteanforderung (Geräte-Handle) ein. Eine Geräteanforderung ist eine Instanz einer Sub-Klasse von :py:class:`DeviceHandle`. Das kann entweder eine Instanz von :py:class:`SingleDeviceHandle` oder von :py:class:`MultiDeviceHandle` sein. Das übergebene Geräte-Handle wird über alle neu entdeckten Geräte mit einem Aufruf von :py:meth:`DeviceHandle.on_bind_device` benachrichtigt. Je nach Konfiguration nimmt das Handle das neue Gerät an oder ignoriert es. Verliert der Gerätemanager die Verbindung zu einem Gerät, wird das Geräte-Handle ebenfalls mit einem Aufruf von :py:meth:`DeviceHandle.on_unbind_device` benachrichtigt. *Siehe auch:* :py:meth:`remove_handle` """ if device_handle in self._device_handles: return self._device_handles.append(device_handle) device_handle.on_add_handle(self) for device in self._devices.values(): device_handle.on_bind_device(device) def remove_handle(self, device_handle): """ Entfernt eine Geräteanforderung (Geräte-Handle). Eine Geräteanforderung ist eine Instanz einer Sub-Klasse von :py:class:`DeviceHandle`. Das kann entweder eine Instanz von :py:class:`SingleDeviceHandle` oder von :py:class:`MultiDeviceHandle` sein. *Siehe auch:* :py:meth:`add_handle` """ if device_handle not in self._device_handles: return for device in self._devices.values(): device_handle.on_unbind_device(device) device_handle.on_remove_handle() self._device_handles.remove(device_handle) def add_device_callback(self, uid, event, callback): """ Richtet eine Callback-Funktion für ein Ereignis eines Bricks oder eines Bricklets ein. **Parameter** ``uid`` Die UID des Gerätes für das ein Ereignis abgefangen werden soll. ``event`` Die ID für das abzufangene Ereignis. Z.B. ``tinkerforge.bricklet_lcd_20x4.BrickletLCD20x4.CALLBACK_BUTTON_PRESSED`` ``callback`` Eine Callback-Funktion die bei Auftreten des Ereignisses aufgerufen werden soll. **Beschreibung** Da jedes Ereignis andere Ereignisparameter besitzt, muss die richtige Signatur für die Callbackfunktion der TinkerForge-Dokumentation entnommen werden. Die Ereignisparameter werden in der API-Dokumentation für jeden Brick und jedes Bricklet im Abschnitt *Callbacks* beschrieben. .. note:: Der Gerätemanager stellt einen zentralen Mechanismus für die Registrierung von Callbacks für Geräteereignisse zur Verfügung, weil die TinkerForge-Geräteklassen nur ein Callback per Ereignis zulassen. Der Gerätemanager hingegen unterstützt beliebig viele Callbacks für ein Ereignis eines Gerätes. *Siehe auch:* :py:meth:`remove_device_callback` """ if uid not in self._device_callbacks: self._device_callbacks[uid] = {} callbacks = self._device_callbacks[uid] if event not in callbacks: self.trace("creating dispatcher for [%s] (%s)" % (uid, event)) mcc = MulticastCallback() callbacks[event] = mcc if uid in self._devices: device = self._devices[uid] self.trace("binding dispatcher to [%s] (%s)" % (uid, event)) device.register_callback(event, mcc) mcc = callbacks[event] self.trace("adding callback to dispatcher for [%s] (%s)" % (uid, event)) mcc.add_callback(callback) def remove_device_callback(self, uid, event, callback): """ Entfernt eine Callback-Funktion von einem Ereignis eines Bricks oder eines Bricklets. **Parameter** ``uid`` Die UID des Gerätes für das ein Callback aufgehoben werden soll. ``event`` Die ID für das Ereignis. Z.B. ``tinkerforge.bricklet_lcd_20x4.BrickletLCD20x4.CALLBACK_BUTTON_PRESSED`` ``callback`` Die registrierte Callback-Funktion die entfernt werde soll. **Beschreibung** Für die Aufhebung des Callbacks muss die gleiche Funktionsreferenz übergeben werden wie bei der Einrichtung des Callback. *Siehe auch:* :py:meth:`add_device_callback` """ if uid in self._device_callbacks: callbacks = self._device_callbacks[uid] if event in callbacks: mcc = callbacks[event] self.trace("removing callback from dispatcher for [%s] (%s)" % (uid, event)) mcc.remove_callback(callback)
class 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
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)
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
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)
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)
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)
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()
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)
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
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]
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)
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)
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)
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)
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()
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
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()
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)
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)