diff --git a/all.py b/all.py new file mode 100644 index 0000000..cf72bf7 --- /dev/null +++ b/all.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#rev2 :*barometer added (b1:#6) [not physically added!!!] +# *lcd disabled +# *exception-logging [dont forget to add empty .xml!] +#rev3 :*generic callbacks (15.01.2013-??) +# *lcd removed +#rev4 *V2.0 +# *barometer +# +# +#TODO: +# *sensorNames=array()... +# *sensorUIDs=array()? +# +# +# + +#HOST = "localhost" +HOST = "192.168.2.30" +PORT = 4223 +UID1 = "7B5" +name1="temp1"#not used +UID2 = "8js" +name2="temp2"#not used +UID3 = "7RY" +name3="humi1" +UID4="8Fw" +name4="ambi1" +UID5="8DJ" +name5="ambi2" +UID6="bB7" +name6="baro1" + +tempSensors=2 + +from tinkerforge.ip_connection import IPConnection +from tinkerforge.bricklet_temperature import Temperature +from tinkerforge.bricklet_humidity import Humidity +from tinkerforge.bricklet_ambient_light import AmbientLight +from tinkerforge.bricklet_barometer import Barometer + +import time +import string +import os.path +import os +import sys,traceback +import array +cbtimetemp=30000 +cbtimehumi=30000 +cbtimeambi=60000 +cbtimebaro=30000 + +tempmaxdiff=200 # 200== 2.0 C + +logs='logs' +locks='locks' +records='records' + +lockname=locks+"/all.lock" +log=open(logs+"/all.log",'a') + +def preptime(): + now=time.localtime() + day=now.tm_mday + month=now.tm_mon + year=str(now.tm_year) + if(day<10): + day="0"+str(day) + else: + day=str(day) + if(month<10): + month="0"+str(month) + else: + month=str(month) + return month+"."+day+"."+year + +def temp_rise(old,new,sensor): + if(old==20000): + return True + if((old-new)>tempmaxdiff or (new-old)>tempmaxdiff): + log.write('error checking '+sensor+';prev('+str(old)+');cur('+str(new)+'); ... @'+time.ctime()+"\n") + log.flush() + return False + else: + return True +########################################## +# common function to write value to file # +########################################## +def write_value(value,name): + valuename=records+"/"+name+"_"+preptime() + valuelog=open(valuename,'a') + valuelog.write(str(value) + ';' + str(int(time.time())) +"\n") + valuelog.close() +#end# + +prev_temps=[20000,20000] + +######################################### +# generic callback for temp# # +######################################### +def callback_temperature(value,sensor): + if(sensor>=tempSensors): + return + global prev_temps + name="temp"+str(sensor+1) + if(temp_rise(prev_temps[sensor],value,name)): + write_value(value,name) + prev_temps[sensor]=value +#end# + +########################################## +# callbacks for temp1+2 # +########################################## +def cb_temperature1(value): + callback_temperature(value,0) + print(name1+': ' + str(value/100.0) + ' °C,' + str(time.ctime())) +# +def cb_temperature2(value): + callback_temperature(value,1) + print(name2+': ' + str(value/100.0) + ' °C,' + str(time.ctime())) +#end# + +########################################### +# callback for humidity1 # +########################################### +def cb_humidity3(rh): + write_value(rh,name3) + print(name3 +': '+ str(rh/10.0) + ' %RH,' + str(time.ctime())) +#end# + +########################################### +# callback for ambi-light1+2 # +########################################### +def cb_illuminance4(illuminance): + write_value(illuminance,name4) + print(name4 +': '+ str(illuminance/10.0) + ' Lux,' + str(time.ctime())) +# +def cb_illuminance5(illuminance): + write_value(illuminance,name5) + print(name5 +': '+ str(illuminance/10.0) + ' Lux,' + str(time.ctime())) +#end# + +########################################### +# callback for barometer1 # +########################################### +def cb_pressure6(pressure): + write_value(pressure,name6) + print(name6+": "+str(pressure/1000)+ "mbar"+str(time.ctime())) +#end# + +########################################### +# exception logging # +########################################### +def printException(inst): + global log + import xml.etree.ElementTree as ET + tree=ET.parse('logs/exceptions.xml') + root=tree.getroot() + new=ET.Element('exception',{'class':str(type(inst)).split("'")[1],'date':str(time.ctime()),'time':str(int(time.time())),'type':str(inst)}) + new.text=traceback.format_exc() + root.append(new) + tree.write('logs/exceptions.xml') + + log.write('an Exception happen during connection @'+time.ctime()+"\n") + print('an Exception happen during connection @'+time.ctime()+"\n") + log.flush() +#end# + +if not os.path.exists(lockname): + if __name__ == "__main__": + lock=open(lockname,'w') + lock.write(str(time.time())) + lock.close() + # + try: + ipcon = IPConnection() + t1 = Temperature(UID1, ipcon) + t2 = Temperature(UID2, ipcon) + h3 = Humidity(UID3, ipcon) + al4 = AmbientLight(UID4, ipcon) + al5 = AmbientLight(UID5, ipcon) + b6 = Barometer(UID6, ipcon) + + + ipcon.connect(HOST, PORT) + except Exception as inst: + printException(inst) + else: + cb_temperature1(t1.get_temperature()) + cb_temperature2(t2.get_temperature()) + cb_humidity3(h3.get_humidity()) + cb_illuminance4(al4.get_illuminance()) + cb_illuminance5(al5.get_illuminance()) + cb_pressure6(b6.get_air_pressure()) + + t1.set_temperature_callback_period(cbtimetemp) + t2.set_temperature_callback_period(cbtimetemp) + h3.set_humidity_callback_period(cbtimehumi) + al4.set_illuminance_callback_period(cbtimeambi) + al5.set_illuminance_callback_period(cbtimeambi) + b6.set_air_pressure_callback_period(cbtimebaro) + + log.write('start logging "all" ... @'+time.ctime()+"\n") + log.flush() + + t1.register_callback(t1.CALLBACK_TEMPERATURE, cb_temperature1) + t2.register_callback(t2.CALLBACK_TEMPERATURE, cb_temperature2) + h3.register_callback(h3.CALLBACK_HUMIDITY, cb_humidity3) + al4.register_callback(al4.CALLBACK_ILLUMINANCE, cb_illuminance4) + al5.register_callback(al5.CALLBACK_ILLUMINANCE, cb_illuminance5) + b6.register_callback(b6.CALLBACK_AIR_PRESSURE,cb_pressure6) + + raw_input('Press key to exit\n') + ipcon.disconnect() + + log.write('stop logging... @'+time.ctime()+"\n") + + os.remove(lockname) +else: + print('lock file active!!') + log.write('lock collision: lock "all" active @ '+time.ctime()+"\n") + + diff --git a/ftp.sh b/ftp.sh new file mode 100644 index 0000000..72005ef --- /dev/null +++ b/ftp.sh @@ -0,0 +1,21 @@ +#!/bin/bash +cd /home/XXX/temp/python +cp records/humi* ftp/ +cp records/ambi* ftp/ +cp records/temp* ftp/ +cp records/baro* ftp/ +cd ftp +sshpass -p 'XXXXXXXXXX' sftp -oBatchMode=no -b - XXXX@YYYYY.ZZZ <>logs/ftp.log +date>>logs/ftp.log +echo "finished\n\n">>logs/ftp.log +python move.py diff --git a/logs/all.log b/logs/all.log new file mode 100644 index 0000000..e69de29 diff --git a/logs/exceptions.xml b/logs/exceptions.xml new file mode 100644 index 0000000..5b1e45e --- /dev/null +++ b/logs/exceptions.xml @@ -0,0 +1 @@ + diff --git a/move.py b/move.py new file mode 100644 index 0000000..3fab4ac --- /dev/null +++ b/move.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import time +import os + +checkfile='locks/records_moved' + +def prevday(then,now): + #ist "then" gestern (oder noch älter)? + return ((then.tm_ydaymove" + mv $f ../arch + fi +done +cd .. diff --git a/tinkerforge/__init__.py b/tinkerforge/__init__.py new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/tinkerforge/__init__.py @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tinkerforge/__init__.pyc b/tinkerforge/__init__.pyc new file mode 100644 index 0000000..3eb151b Binary files /dev/null and b/tinkerforge/__init__.pyc differ diff --git a/tinkerforge/brick_dc.py b/tinkerforge/brick_dc.py new file mode 100644 index 0000000..045dc06 --- /dev/null +++ b/tinkerforge/brick_dc.py @@ -0,0 +1,366 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetProtocol1BrickletName = namedtuple('Protocol1BrickletName', ['protocol_version', 'firmware_version', 'name']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickDC(Device): + """ + Device for controlling DC motors + """ + + DEVICE_IDENTIFIER = 11 + + CALLBACK_UNDER_VOLTAGE = 21 + CALLBACK_EMERGENCY_SHUTDOWN = 22 + CALLBACK_VELOCITY_REACHED = 23 + CALLBACK_CURRENT_VELOCITY = 24 + + FUNCTION_SET_VELOCITY = 1 + FUNCTION_GET_VELOCITY = 2 + FUNCTION_GET_CURRENT_VELOCITY = 3 + FUNCTION_SET_ACCELERATION = 4 + FUNCTION_GET_ACCELERATION = 5 + FUNCTION_SET_PWM_FREQUENCY = 6 + FUNCTION_GET_PWM_FREQUENCY = 7 + FUNCTION_FULL_BRAKE = 8 + FUNCTION_GET_STACK_INPUT_VOLTAGE = 9 + FUNCTION_GET_EXTERNAL_INPUT_VOLTAGE = 10 + FUNCTION_GET_CURRENT_CONSUMPTION = 11 + FUNCTION_ENABLE = 12 + FUNCTION_DISABLE = 13 + FUNCTION_IS_ENABLED = 14 + FUNCTION_SET_MINIMUM_VOLTAGE = 15 + FUNCTION_GET_MINIMUM_VOLTAGE = 16 + FUNCTION_SET_DRIVE_MODE = 17 + FUNCTION_GET_DRIVE_MODE = 18 + FUNCTION_SET_CURRENT_VELOCITY_PERIOD = 19 + FUNCTION_GET_CURRENT_VELOCITY_PERIOD = 20 + FUNCTION_GET_PROTOCOL1_BRICKLET_NAME = 241 + FUNCTION_GET_CHIP_TEMPERATURE = 242 + FUNCTION_RESET = 243 + FUNCTION_GET_IDENTITY = 255 + + DRIVE_MODE_DRIVE_BRAKE = 0 + DRIVE_MODE_DRIVE_COAST = 1 + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickDC.FUNCTION_SET_VELOCITY] = BrickDC.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickDC.FUNCTION_GET_VELOCITY] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_GET_CURRENT_VELOCITY] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_SET_ACCELERATION] = BrickDC.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickDC.FUNCTION_GET_ACCELERATION] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_SET_PWM_FREQUENCY] = BrickDC.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickDC.FUNCTION_GET_PWM_FREQUENCY] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_FULL_BRAKE] = BrickDC.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickDC.FUNCTION_GET_STACK_INPUT_VOLTAGE] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_GET_EXTERNAL_INPUT_VOLTAGE] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_GET_CURRENT_CONSUMPTION] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_ENABLE] = BrickDC.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickDC.FUNCTION_DISABLE] = BrickDC.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickDC.FUNCTION_IS_ENABLED] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_SET_MINIMUM_VOLTAGE] = BrickDC.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickDC.FUNCTION_GET_MINIMUM_VOLTAGE] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_SET_DRIVE_MODE] = BrickDC.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickDC.FUNCTION_GET_DRIVE_MODE] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_SET_CURRENT_VELOCITY_PERIOD] = BrickDC.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickDC.FUNCTION_GET_CURRENT_VELOCITY_PERIOD] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.CALLBACK_UNDER_VOLTAGE] = BrickDC.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickDC.CALLBACK_EMERGENCY_SHUTDOWN] = BrickDC.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickDC.CALLBACK_VELOCITY_REACHED] = BrickDC.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickDC.CALLBACK_CURRENT_VELOCITY] = BrickDC.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickDC.FUNCTION_GET_PROTOCOL1_BRICKLET_NAME] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_GET_CHIP_TEMPERATURE] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickDC.FUNCTION_RESET] = BrickDC.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickDC.FUNCTION_GET_IDENTITY] = BrickDC.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickDC.CALLBACK_UNDER_VOLTAGE] = 'H' + self.callback_formats[BrickDC.CALLBACK_EMERGENCY_SHUTDOWN] = '' + self.callback_formats[BrickDC.CALLBACK_VELOCITY_REACHED] = 'h' + self.callback_formats[BrickDC.CALLBACK_CURRENT_VELOCITY] = 'h' + + def set_velocity(self, velocity): + """ + Sets the velocity of the motor. Whereas -32767 is full speed backward, + 0 is stop and 32767 is full speed forward. Depending on the + acceleration (see :func:`SetAcceleration`), the motor is not immediately + brought to the velocity but smoothly accelerated. + + The velocity describes the duty cycle of the PWM with which the motor is + controlled, e.g. a velocity of 3277 sets a PWM with a 10% duty cycle. + You can not only control the duty cycle of the PWM but also the frequency, + see :func:`SetPWMFrequency`. + + The default velocity is 0. + """ + self.ipcon.send_request(self, BrickDC.FUNCTION_SET_VELOCITY, (velocity,), 'h', '') + + def get_velocity(self): + """ + Returns the velocity as set by :func:`SetVelocity`. + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_GET_VELOCITY, (), '', 'h') + + def get_current_velocity(self): + """ + Returns the *current* velocity of the motor. This value is different + from :func:`GetVelocity` whenever the motor is currently accelerating + to a goal set by :func:`SetVelocity`. + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_GET_CURRENT_VELOCITY, (), '', 'h') + + def set_acceleration(self, acceleration): + """ + Sets the acceleration of the motor. It is given in *velocity/s*. An + acceleration of 10000 means, that every second the velocity is increased + by 10000 (or about 30% duty cycle). + + For example: If the current velocity is 0 and you want to accelerate to a + velocity of 16000 (about 50% duty cycle) in 10 seconds, you should set + an acceleration of 1600. + + If acceleration is set to 0, there is no speed ramping, i.e. a new velocity + is immediately given to the motor. + + The default acceleration is 10000. + """ + self.ipcon.send_request(self, BrickDC.FUNCTION_SET_ACCELERATION, (acceleration,), 'H', '') + + def get_acceleration(self): + """ + Returns the acceleration as set by :func:`SetAcceleration`. + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_GET_ACCELERATION, (), '', 'H') + + def set_pwm_frequency(self, frequency): + """ + Sets the frequency (in Hz) of the PWM with which the motor is driven. + The possible range of the frequency is 1-20000Hz. Often a high frequency + is less noisy and the motor runs smoother. However, with a low frequency + there are less switches and therefore fewer switching losses. Also with + most motors lower frequencies enable higher torque. + + If you have no idea what all this means, just ignore this function and use + the default frequency, it will very likely work fine. + + The default frequency is 15 kHz. + """ + self.ipcon.send_request(self, BrickDC.FUNCTION_SET_PWM_FREQUENCY, (frequency,), 'H', '') + + def get_pwm_frequency(self): + """ + Returns the PWM frequency (in Hz) as set by :func:`SetPWMFrequency`. + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_GET_PWM_FREQUENCY, (), '', 'H') + + def full_brake(self): + """ + Executes an active full brake. + + .. warning:: + This function is for emergency purposes, + where an immediate brake is necessary. Depending on the current velocity and + the strength of the motor, a full brake can be quite violent. + + Call :func:`SetVelocity` with 0 if you just want to stop the motor. + """ + self.ipcon.send_request(self, BrickDC.FUNCTION_FULL_BRAKE, (), '', '') + + def get_stack_input_voltage(self): + """ + Returns the stack input voltage in mV. The stack input voltage is the + voltage that is supplied via the stack, i.e. it is given by a + Step-Down or Step-Up Power Supply. + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_GET_STACK_INPUT_VOLTAGE, (), '', 'H') + + def get_external_input_voltage(self): + """ + Returns the external input voltage in mV. The external input voltage is + given via the black power input connector on the DC Brick. + + If there is an external input voltage and a stack input voltage, the motor + will be driven by the external input voltage. If there is only a stack + voltage present, the motor will be driven by this voltage. + + .. warning:: + This means, if you have a high stack voltage and a low external voltage, + the motor will be driven with the low external voltage. If you then remove + the external connection, it will immediately be driven by the high + stack voltage. + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_GET_EXTERNAL_INPUT_VOLTAGE, (), '', 'H') + + def get_current_consumption(self): + """ + Returns the current consumption of the motor in mA. + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_GET_CURRENT_CONSUMPTION, (), '', 'H') + + def enable(self): + """ + Enables the driver chip. The driver parameters can be configured (velocity, + acceleration, etc) before it is enabled. + """ + self.ipcon.send_request(self, BrickDC.FUNCTION_ENABLE, (), '', '') + + def disable(self): + """ + Disables the driver chip. The configurations are kept (velocity, + acceleration, etc) but the motor is not driven until it is enabled again. + """ + self.ipcon.send_request(self, BrickDC.FUNCTION_DISABLE, (), '', '') + + def is_enabled(self): + """ + Returns *true* if the driver chip is enabled, *false* otherwise. + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_IS_ENABLED, (), '', '?') + + def set_minimum_voltage(self, voltage): + """ + Sets the minimum voltage in mV, below which the :func:`UnderVoltage` callback + is triggered. The minimum possible value that works with the DC Brick is 5V. + You can use this function to detect the discharge of a battery that is used + to drive the motor. If you have a fixed power supply, you likely do not need + this functionality. + + The default value is 5V. + """ + self.ipcon.send_request(self, BrickDC.FUNCTION_SET_MINIMUM_VOLTAGE, (voltage,), 'H', '') + + def get_minimum_voltage(self): + """ + Returns the minimum voltage as set by :func:`SetMinimumVoltage` + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_GET_MINIMUM_VOLTAGE, (), '', 'H') + + def set_drive_mode(self, mode): + """ + Sets the drive mode. Possible modes are: + + * 0 = Drive/Brake + * 1 = Drive/Coast + + These modes are different kinds of motor controls. + + In Drive/Brake mode, the motor is always either driving or braking. There + is no freewheeling. Advantages are: A more linear correlation between + PWM and velocity, more exact accelerations and the possibility to drive + with slower velocities. + + In Drive/Coast mode, the motor is always either driving or freewheeling. + Advantages are: Less current consumption and less demands on the motor and + driver chip. + + The default value is 0 = Drive/Brake. + """ + self.ipcon.send_request(self, BrickDC.FUNCTION_SET_DRIVE_MODE, (mode,), 'B', '') + + def get_drive_mode(self): + """ + Returns the drive mode, as set by :func:`SetDriveMode`. + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_GET_DRIVE_MODE, (), '', 'B') + + def set_current_velocity_period(self, period): + """ + Sets a period in ms with which the :func:`CurrentVelocity` callback is triggered. + A period of 0 turns the callback off. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickDC.FUNCTION_SET_CURRENT_VELOCITY_PERIOD, (period,), 'H', '') + + def get_current_velocity_period(self): + """ + Returns the period as set by :func:`SetCurrentVelocityPeriod`. + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_GET_CURRENT_VELOCITY_PERIOD, (), '', 'H') + + def get_protocol1_bricklet_name(self, port): + """ + Returns the firmware and protocol version and the name of the Bricklet for a given port. + + This functions sole purpose is to allow automatic flashing of v1.x.y Bricklet plugins. + + .. versionadded:: 2.0.0~(Firmware) + """ + return GetProtocol1BrickletName(*self.ipcon.send_request(self, BrickDC.FUNCTION_GET_PROTOCOL1_BRICKLET_NAME, (port,), 'c', 'B 3B 40s')) + + def get_chip_temperature(self): + """ + Returns the temperature in °C/10 as measured inside the microcontroller. The + value returned is not the ambient temperature! + + The temperature is only proportional to the real temperature and it has an + accuracy of +-15%. Practically it is only useful as an indicator for + temperature changes. + + .. versionadded:: 1.1.3~(Firmware) + """ + return self.ipcon.send_request(self, BrickDC.FUNCTION_GET_CHIP_TEMPERATURE, (), '', 'h') + + def reset(self): + """ + Calling this function will reset the Brick. Calling this function + on a Brick inside of a stack will reset the whole stack. + + After a reset you have to create new device objects, + calling functions on the existing ones will result in + undefined behavior! + + .. versionadded:: 1.1.3~(Firmware) + """ + self.ipcon.send_request(self, BrickDC.FUNCTION_RESET, (), '', '') + + def get_identity(self): + """ + Returns the UID, the UID where the Brick is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be '0'-'8' (stack position). + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Firmware) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickDC.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +DC = BrickDC # for backward compatibility diff --git a/tinkerforge/brick_imu.py b/tinkerforge/brick_imu.py new file mode 100644 index 0000000..d1996a0 --- /dev/null +++ b/tinkerforge/brick_imu.py @@ -0,0 +1,507 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetAcceleration = namedtuple('Acceleration', ['x', 'y', 'z']) +GetMagneticField = namedtuple('MagneticField', ['x', 'y', 'z']) +GetAngularVelocity = namedtuple('AngularVelocity', ['x', 'y', 'z']) +GetAllData = namedtuple('AllData', ['acc_x', 'acc_y', 'acc_z', 'mag_x', 'mag_y', 'mag_z', 'ang_x', 'ang_y', 'ang_z', 'temperature']) +GetOrientation = namedtuple('Orientation', ['roll', 'pitch', 'yaw']) +GetQuaternion = namedtuple('Quaternion', ['x', 'y', 'z', 'w']) +GetProtocol1BrickletName = namedtuple('Protocol1BrickletName', ['protocol_version', 'firmware_version', 'name']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickIMU(Device): + """ + Device for sensing acceleration, magnetic field and angular velocity + """ + + DEVICE_IDENTIFIER = 16 + + CALLBACK_ACCELERATION = 31 + CALLBACK_MAGNETIC_FIELD = 32 + CALLBACK_ANGULAR_VELOCITY = 33 + CALLBACK_ALL_DATA = 34 + CALLBACK_ORIENTATION = 35 + CALLBACK_QUATERNION = 36 + + FUNCTION_GET_ACCELERATION = 1 + FUNCTION_GET_MAGNETIC_FIELD = 2 + FUNCTION_GET_ANGULAR_VELOCITY = 3 + FUNCTION_GET_ALL_DATA = 4 + FUNCTION_GET_ORIENTATION = 5 + FUNCTION_GET_QUATERNION = 6 + FUNCTION_GET_IMU_TEMPERATURE = 7 + FUNCTION_LEDS_ON = 8 + FUNCTION_LEDS_OFF = 9 + FUNCTION_ARE_LEDS_ON = 10 + FUNCTION_SET_ACCELERATION_RANGE = 11 + FUNCTION_GET_ACCELERATION_RANGE = 12 + FUNCTION_SET_MAGNETOMETER_RANGE = 13 + FUNCTION_GET_MAGNETOMETER_RANGE = 14 + FUNCTION_SET_CONVERGENCE_SPEED = 15 + FUNCTION_GET_CONVERGENCE_SPEED = 16 + FUNCTION_SET_CALIBRATION = 17 + FUNCTION_GET_CALIBRATION = 18 + FUNCTION_SET_ACCELERATION_PERIOD = 19 + FUNCTION_GET_ACCELERATION_PERIOD = 20 + FUNCTION_SET_MAGNETIC_FIELD_PERIOD = 21 + FUNCTION_GET_MAGNETIC_FIELD_PERIOD = 22 + FUNCTION_SET_ANGULAR_VELOCITY_PERIOD = 23 + FUNCTION_GET_ANGULAR_VELOCITY_PERIOD = 24 + FUNCTION_SET_ALL_DATA_PERIOD = 25 + FUNCTION_GET_ALL_DATA_PERIOD = 26 + FUNCTION_SET_ORIENTATION_PERIOD = 27 + FUNCTION_GET_ORIENTATION_PERIOD = 28 + FUNCTION_SET_QUATERNION_PERIOD = 29 + FUNCTION_GET_QUATERNION_PERIOD = 30 + FUNCTION_GET_PROTOCOL1_BRICKLET_NAME = 241 + FUNCTION_GET_CHIP_TEMPERATURE = 242 + FUNCTION_RESET = 243 + FUNCTION_GET_IDENTITY = 255 + + CALIBRATION_TYPE_ACCELEROMETER_GAIN = 0 + CALIBRATION_TYPE_ACCELEROMETER_BIAS = 1 + CALIBRATION_TYPE_MAGNETOMETER_GAIN = 2 + CALIBRATION_TYPE_MAGNETOMETER_BIAS = 3 + CALIBRATION_TYPE_GYROSCOPE_GAIN = 4 + CALIBRATION_TYPE_GYROSCOPE_BIAS = 5 + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickIMU.FUNCTION_GET_ACCELERATION] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_MAGNETIC_FIELD] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_ANGULAR_VELOCITY] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_ALL_DATA] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_ORIENTATION] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_QUATERNION] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_IMU_TEMPERATURE] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_LEDS_ON] = BrickIMU.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickIMU.FUNCTION_LEDS_OFF] = BrickIMU.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickIMU.FUNCTION_ARE_LEDS_ON] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_SET_ACCELERATION_RANGE] = BrickIMU.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickIMU.FUNCTION_GET_ACCELERATION_RANGE] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_SET_MAGNETOMETER_RANGE] = BrickIMU.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickIMU.FUNCTION_GET_MAGNETOMETER_RANGE] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_SET_CONVERGENCE_SPEED] = BrickIMU.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickIMU.FUNCTION_GET_CONVERGENCE_SPEED] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_SET_CALIBRATION] = BrickIMU.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickIMU.FUNCTION_GET_CALIBRATION] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_SET_ACCELERATION_PERIOD] = BrickIMU.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_ACCELERATION_PERIOD] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_SET_MAGNETIC_FIELD_PERIOD] = BrickIMU.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_MAGNETIC_FIELD_PERIOD] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_SET_ANGULAR_VELOCITY_PERIOD] = BrickIMU.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_ANGULAR_VELOCITY_PERIOD] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_SET_ALL_DATA_PERIOD] = BrickIMU.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_ALL_DATA_PERIOD] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_SET_ORIENTATION_PERIOD] = BrickIMU.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_ORIENTATION_PERIOD] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_SET_QUATERNION_PERIOD] = BrickIMU.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_QUATERNION_PERIOD] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.CALLBACK_ACCELERATION] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickIMU.CALLBACK_MAGNETIC_FIELD] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickIMU.CALLBACK_ANGULAR_VELOCITY] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickIMU.CALLBACK_ALL_DATA] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickIMU.CALLBACK_ORIENTATION] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickIMU.CALLBACK_QUATERNION] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickIMU.FUNCTION_GET_PROTOCOL1_BRICKLET_NAME] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_GET_CHIP_TEMPERATURE] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickIMU.FUNCTION_RESET] = BrickIMU.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickIMU.FUNCTION_GET_IDENTITY] = BrickIMU.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickIMU.CALLBACK_ACCELERATION] = 'h h h' + self.callback_formats[BrickIMU.CALLBACK_MAGNETIC_FIELD] = 'h h h' + self.callback_formats[BrickIMU.CALLBACK_ANGULAR_VELOCITY] = 'h h h' + self.callback_formats[BrickIMU.CALLBACK_ALL_DATA] = 'h h h h h h h h h h' + self.callback_formats[BrickIMU.CALLBACK_ORIENTATION] = 'h h h' + self.callback_formats[BrickIMU.CALLBACK_QUATERNION] = 'f f f f' + + def get_acceleration(self): + """ + Returns the calibrated acceleration from the accelerometer for the + x, y and z axis in mG (G/1000, 1G = 9.80605m/s²). + + If you want to get the acceleration periodically, it is recommended + to use the callback :func:`Acceleration` and set the period with + :func:`SetAccelerationPeriod`. + """ + return GetAcceleration(*self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_ACCELERATION, (), '', 'h h h')) + + def get_magnetic_field(self): + """ + Returns the calibrated magnetic field from the magnetometer for the + x, y and z axis in mG (Milligauss or Nanotesla). + + If you want to get the magnetic field periodically, it is recommended + to use the callback :func:`MagneticField` and set the period with + :func:`SetMagneticFieldPeriod`. + """ + return GetMagneticField(*self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_MAGNETIC_FIELD, (), '', 'h h h')) + + def get_angular_velocity(self): + """ + Returns the calibrated angular velocity from the gyroscope for the + x, y and z axis in °/17.5s (you have to divide by 17.5 to + get the value in °/s). + + If you want to get the angular velocity periodically, it is recommended + to use the callback :func:`AngularVelocity` and set the period with + :func:`SetAngularVelocityPeriod`. + """ + return GetAngularVelocity(*self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_ANGULAR_VELOCITY, (), '', 'h h h')) + + def get_all_data(self): + """ + Returns the data from :func:`GetAcceleration`, :func:`GetMagneticField` + and :func:`GetAngularVelocity` as well as the temperature of the IMU Brick. + + The temperature is given in °C/100. + + If you want to get the data periodically, it is recommended + to use the callback :func:`AllData` and set the period with + :func:`SetAllDataPeriod`. + """ + return GetAllData(*self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_ALL_DATA, (), '', 'h h h h h h h h h h')) + + def get_orientation(self): + """ + Returns the current orientation (roll, pitch, yaw) of the IMU Brick as Euler + angles in one-hundredth degree. Note that Euler angles always experience a + `gimbal lock `__. + + We recommend that you use quaternions instead. + + The order to sequence in which the orientation values should be applied is + roll, yaw, pitch. + + If you want to get the orientation periodically, it is recommended + to use the callback :func:`Orientation` and set the period with + :func:`SetOrientationPeriod`. + """ + return GetOrientation(*self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_ORIENTATION, (), '', 'h h h')) + + def get_quaternion(self): + """ + Returns the current orientation (x, y, z, w) of the IMU as + `quaternions `__. + + You can go from quaternions to Euler angles with the following formula:: + + roll = atan2(2*y*w - 2*x*z, 1 - 2*y*y - 2*z*z) + pitch = atan2(2*x*w - 2*y*z, 1 - 2*x*x - 2*z*z) + yaw = asin(2*x*y + 2*z*w) + + This process is not reversible, because of the + `gimbal lock `__. + + Converting the quaternions to an OpenGL transformation matrix is + possible with the following formula:: + + matrix = [[1 - 2*(y*y + z*z), 2*(x*y - w*z), 2*(x*z + w*y), 0], + [ 2*(x*y + w*z), 1 - 2*(x*x + z*z), 2*(y*z - w*x), 0], + [ 2*(x*z - w*y), 2*(y*z + w*x), 1 - 2*(x*x + y*y), 0], + [ 0, 0, 0, 1]] + + If you want to get the quaternions periodically, it is recommended + to use the callback :func:`Quaternion` and set the period with + :func:`SetQuaternionPeriod`. + """ + return GetQuaternion(*self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_QUATERNION, (), '', 'f f f f')) + + def get_imu_temperature(self): + """ + Returns the temperature of the IMU Brick. The temperature is given in + °C/100. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_IMU_TEMPERATURE, (), '', 'h') + + def leds_on(self): + """ + Turns the orientation and direction LEDs of the IMU Brick on. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_LEDS_ON, (), '', '') + + def leds_off(self): + """ + Turns the orientation and direction LEDs of the IMU Brick off. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_LEDS_OFF, (), '', '') + + def are_leds_on(self): + """ + Returns *true* if the orientation and direction LEDs of the IMU Brick + are on, *false* otherwise. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_ARE_LEDS_ON, (), '', '?') + + def set_acceleration_range(self, range): + """ + Not implemented yet. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_SET_ACCELERATION_RANGE, (range,), 'B', '') + + def get_acceleration_range(self): + """ + Not implemented yet. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_ACCELERATION_RANGE, (), '', 'B') + + def set_magnetometer_range(self, range): + """ + Not implemented yet. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_SET_MAGNETOMETER_RANGE, (range,), 'B', '') + + def get_magnetometer_range(self): + """ + Not implemented yet. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_MAGNETOMETER_RANGE, (), '', 'B') + + def set_convergence_speed(self, speed): + """ + Sets the convergence speed of the IMU Brick in °/s. The convergence speed + determines how the different sensor measurements are fused. + + If the orientation of the IMU Brick is off by 10° and the convergence speed is + set to 20°/s, it will take 0.5s until the orientation is corrected. However, + if the correct orientation is reached and the convergence speed is too high, + the orientation will fluctuate with the fluctuations of the accelerometer and + the magnetometer. + + If you set the convergence speed to 0, practically only the gyroscope is used + to calculate the orientation. This gives very smooth movements, but errors of the + gyroscope will not be corrected. If you set the convergence speed to something + above 500, practically only the magnetometer and the accelerometer are used to + calculate the orientation. In this case the movements are abrupt and the values + will fluctuate, but there won't be any errors that accumulate over time. + + In an application with high angular velocities, we recommend a high convergence + speed, so the errors of the gyroscope can be corrected fast. In applications with + only slow movements we recommend a low convergence speed. You can change the + convergence speed on the fly. So it is possible (and recommended) to increase + the convergence speed before an abrupt movement and decrease it afterwards + again. + + You might want to play around with the convergence speed in the Brick Viewer to + get a feeling for a good value for your application. + + The default value is 30. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_SET_CONVERGENCE_SPEED, (speed,), 'H', '') + + def get_convergence_speed(self): + """ + Returns the convergence speed as set by :func:`SetConvergenceSpeed`. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_CONVERGENCE_SPEED, (), '', 'H') + + def set_calibration(self, typ, data): + """ + There are several different types that can be calibrated: + + .. csv-table:: + :header: "Type", "Description", "Values" + :widths: 10, 40, 100 + + "0", "Accelerometer Gain", "[mul x, mul y, mul z, div x, div y, div z, 0, 0, 0, 0]" + "1", "Accelerometer Bias", "[bias x, bias y, bias z, 0, 0, 0, 0, 0, 0, 0]" + "2", "Magnetometer Gain", "[mul x, mul y, mul z, div x, div y, div z, 0, 0, 0, 0]" + "3", "Magnetometer Bias", "[bias x, bias y, bias z, 0, 0, 0, 0, 0, 0, 0]" + "4", "Gyroscope Gain", "[mul x, mul y, mul z, div x, div y, div z, 0, 0, 0, 0]" + "5", "Gyroscope Bias", "[bias xl, bias yl, bias zl, temp l, bias xh, bias yh, bias zh, temp h, 0, 0]" + + The calibration via gain and bias is done with the following formula:: + + new_value = (bias + orig_value) * gain_mul / gain_div + + If you really want to write your own calibration software, please keep + in mind that you first have to undo the old calibration (set bias to 0 and + gain to 1/1) and that you have to average over several thousand values + to obtain a usable result in the end. + + The gyroscope bias is highly dependent on the temperature, so you have to + calibrate the bias two times with different temperatures. The values xl, yl, zl + and temp l are the bias for x, y, z and the corresponding temperature for a + low temperature. The values xh, yh, zh and temp h are the same for a high + temperatures. The temperature difference should be at least 5°C. If you have + a temperature where the IMU Brick is mostly used, you should use this + temperature for one of the sampling points. + + .. note:: + We highly recommend that you use the Brick Viewer to calibrate your + IMU Brick. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_SET_CALIBRATION, (typ, data), 'B 10h', '') + + def get_calibration(self, typ): + """ + Returns the calibration for a given type as set by :func:`SetCalibration`. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_CALIBRATION, (typ,), 'B', '10h') + + def set_acceleration_period(self, period): + """ + Sets the period in ms with which the :func:`Acceleration` callback is triggered + periodically. A value of 0 turns the callback off. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_SET_ACCELERATION_PERIOD, (period,), 'I', '') + + def get_acceleration_period(self): + """ + Returns the period as set by :func:`SetAccelerationPeriod`. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_ACCELERATION_PERIOD, (), '', 'I') + + def set_magnetic_field_period(self, period): + """ + Sets the period in ms with which the :func:`MagneticField` callback is triggered + periodically. A value of 0 turns the callback off. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_SET_MAGNETIC_FIELD_PERIOD, (period,), 'I', '') + + def get_magnetic_field_period(self): + """ + Returns the period as set by :func:`SetMagneticFieldPeriod`. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_MAGNETIC_FIELD_PERIOD, (), '', 'I') + + def set_angular_velocity_period(self, period): + """ + Sets the period in ms with which the :func:`AngularVelocity` callback is triggered + periodically. A value of 0 turns the callback off. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_SET_ANGULAR_VELOCITY_PERIOD, (period,), 'I', '') + + def get_angular_velocity_period(self): + """ + Returns the period as set by :func:`SetAngularVelocityPeriod`. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_ANGULAR_VELOCITY_PERIOD, (), '', 'I') + + def set_all_data_period(self, period): + """ + Sets the period in ms with which the :func:`AllData` callback is triggered + periodically. A value of 0 turns the callback off. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_SET_ALL_DATA_PERIOD, (period,), 'I', '') + + def get_all_data_period(self): + """ + Returns the period as set by :func:`SetAllDataPeriod`. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_ALL_DATA_PERIOD, (), '', 'I') + + def set_orientation_period(self, period): + """ + Sets the period in ms with which the :func:`Orientation` callback is triggered + periodically. A value of 0 turns the callback off. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_SET_ORIENTATION_PERIOD, (period,), 'I', '') + + def get_orientation_period(self): + """ + Returns the period as set by :func:`SetOrientationPeriod`. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_ORIENTATION_PERIOD, (), '', 'I') + + def set_quaternion_period(self, period): + """ + Sets the period in ms with which the :func:`Quaternion` callback is triggered + periodically. A value of 0 turns the callback off. + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_SET_QUATERNION_PERIOD, (period,), 'I', '') + + def get_quaternion_period(self): + """ + Returns the period as set by :func:`SetQuaternionPeriod`. + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_QUATERNION_PERIOD, (), '', 'I') + + def get_protocol1_bricklet_name(self, port): + """ + Returns the firmware and protocol version and the name of the Bricklet for a given port. + + This functions sole purpose is to allow automatic flashing of v1.x.y Bricklet plugins. + + .. versionadded:: 2.0.0~(Firmware) + """ + return GetProtocol1BrickletName(*self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_PROTOCOL1_BRICKLET_NAME, (port,), 'c', 'B 3B 40s')) + + def get_chip_temperature(self): + """ + Returns the temperature in °C/10 as measured inside the microcontroller. The + value returned is not the ambient temperature! + + The temperature is only proportional to the real temperature and it has an + accuracy of +-15%. Practically it is only useful as an indicator for + temperature changes. + + .. versionadded:: 1.0.7~(Firmware) + """ + return self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_CHIP_TEMPERATURE, (), '', 'h') + + def reset(self): + """ + Calling this function will reset the Brick. Calling this function + on a Brick inside of a stack will reset the whole stack. + + After a reset you have to create new device objects, + calling functions on the existing ones will result in + undefined behavior! + + .. versionadded:: 1.0.7~(Firmware) + """ + self.ipcon.send_request(self, BrickIMU.FUNCTION_RESET, (), '', '') + + def get_identity(self): + """ + Returns the UID, the UID where the Brick is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be '0'-'8' (stack position). + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Firmware) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickIMU.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +IMU = BrickIMU # for backward compatibility diff --git a/tinkerforge/brick_master.py b/tinkerforge/brick_master.py new file mode 100644 index 0000000..a1c05d0 --- /dev/null +++ b/tinkerforge/brick_master.py @@ -0,0 +1,1080 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetChibiErrorLog = namedtuple('ChibiErrorLog', ['underrun', 'crc_error', 'no_ack', 'overflow']) +GetRS485Configuration = namedtuple('RS485Configuration', ['speed', 'parity', 'stopbits']) +GetWifiConfiguration = namedtuple('WifiConfiguration', ['ssid', 'connection', 'ip', 'subnet_mask', 'gateway', 'port']) +GetWifiEncryption = namedtuple('WifiEncryption', ['encryption', 'key', 'key_index', 'eap_options', 'ca_certificate_length', 'client_certificate_length', 'private_key_length']) +GetWifiStatus = namedtuple('WifiStatus', ['mac_address', 'bssid', 'channel', 'rssi', 'ip', 'subnet_mask', 'gateway', 'rx_count', 'tx_count', 'state']) +GetWifiCertificate = namedtuple('WifiCertificate', ['data', 'data_length']) +GetWifiBufferInfo = namedtuple('WifiBufferInfo', ['overflow', 'low_watermark', 'used']) +GetStackCurrentCallbackThreshold = namedtuple('StackCurrentCallbackThreshold', ['option', 'min', 'max']) +GetStackVoltageCallbackThreshold = namedtuple('StackVoltageCallbackThreshold', ['option', 'min', 'max']) +GetUSBVoltageCallbackThreshold = namedtuple('USBVoltageCallbackThreshold', ['option', 'min', 'max']) +GetProtocol1BrickletName = namedtuple('Protocol1BrickletName', ['protocol_version', 'firmware_version', 'name']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickMaster(Device): + """ + Device for controlling Stacks and four Bricklets + """ + + DEVICE_IDENTIFIER = 13 + + CALLBACK_STACK_CURRENT = 59 + CALLBACK_STACK_VOLTAGE = 60 + CALLBACK_USB_VOLTAGE = 61 + CALLBACK_STACK_CURRENT_REACHED = 62 + CALLBACK_STACK_VOLTAGE_REACHED = 63 + CALLBACK_USB_VOLTAGE_REACHED = 64 + + FUNCTION_GET_STACK_VOLTAGE = 1 + FUNCTION_GET_STACK_CURRENT = 2 + FUNCTION_SET_EXTENSION_TYPE = 3 + FUNCTION_GET_EXTENSION_TYPE = 4 + FUNCTION_IS_CHIBI_PRESENT = 5 + FUNCTION_SET_CHIBI_ADDRESS = 6 + FUNCTION_GET_CHIBI_ADDRESS = 7 + FUNCTION_SET_CHIBI_MASTER_ADDRESS = 8 + FUNCTION_GET_CHIBI_MASTER_ADDRESS = 9 + FUNCTION_SET_CHIBI_SLAVE_ADDRESS = 10 + FUNCTION_GET_CHIBI_SLAVE_ADDRESS = 11 + FUNCTION_GET_CHIBI_SIGNAL_STRENGTH = 12 + FUNCTION_GET_CHIBI_ERROR_LOG = 13 + FUNCTION_SET_CHIBI_FREQUENCY = 14 + FUNCTION_GET_CHIBI_FREQUENCY = 15 + FUNCTION_SET_CHIBI_CHANNEL = 16 + FUNCTION_GET_CHIBI_CHANNEL = 17 + FUNCTION_IS_RS485_PRESENT = 18 + FUNCTION_SET_RS485_ADDRESS = 19 + FUNCTION_GET_RS485_ADDRESS = 20 + FUNCTION_SET_RS485_SLAVE_ADDRESS = 21 + FUNCTION_GET_RS485_SLAVE_ADDRESS = 22 + FUNCTION_GET_RS485_ERROR_LOG = 23 + FUNCTION_SET_RS485_CONFIGURATION = 24 + FUNCTION_GET_RS485_CONFIGURATION = 25 + FUNCTION_IS_WIFI_PRESENT = 26 + FUNCTION_SET_WIFI_CONFIGURATION = 27 + FUNCTION_GET_WIFI_CONFIGURATION = 28 + FUNCTION_SET_WIFI_ENCRYPTION = 29 + FUNCTION_GET_WIFI_ENCRYPTION = 30 + FUNCTION_GET_WIFI_STATUS = 31 + FUNCTION_REFRESH_WIFI_STATUS = 32 + FUNCTION_SET_WIFI_CERTIFICATE = 33 + FUNCTION_GET_WIFI_CERTIFICATE = 34 + FUNCTION_SET_WIFI_POWER_MODE = 35 + FUNCTION_GET_WIFI_POWER_MODE = 36 + FUNCTION_GET_WIFI_BUFFER_INFO = 37 + FUNCTION_SET_WIFI_REGULATORY_DOMAIN = 38 + FUNCTION_GET_WIFI_REGULATORY_DOMAIN = 39 + FUNCTION_GET_USB_VOLTAGE = 40 + FUNCTION_SET_LONG_WIFI_KEY = 41 + FUNCTION_GET_LONG_WIFI_KEY = 42 + FUNCTION_SET_WIFI_HOSTNAME = 43 + FUNCTION_GET_WIFI_HOSTNAME = 44 + FUNCTION_SET_STACK_CURRENT_CALLBACK_PERIOD = 45 + FUNCTION_GET_STACK_CURRENT_CALLBACK_PERIOD = 46 + FUNCTION_SET_STACK_VOLTAGE_CALLBACK_PERIOD = 47 + FUNCTION_GET_STACK_VOLTAGE_CALLBACK_PERIOD = 48 + FUNCTION_SET_USB_VOLTAGE_CALLBACK_PERIOD = 49 + FUNCTION_GET_USB_VOLTAGE_CALLBACK_PERIOD = 50 + FUNCTION_SET_STACK_CURRENT_CALLBACK_THRESHOLD = 51 + FUNCTION_GET_STACK_CURRENT_CALLBACK_THRESHOLD = 52 + FUNCTION_SET_STACK_VOLTAGE_CALLBACK_THRESHOLD = 53 + FUNCTION_GET_STACK_VOLTAGE_CALLBACK_THRESHOLD = 54 + FUNCTION_SET_USB_VOLTAGE_CALLBACK_THRESHOLD = 55 + FUNCTION_GET_USB_VOLTAGE_CALLBACK_THRESHOLD = 56 + FUNCTION_SET_DEBOUNCE_PERIOD = 57 + FUNCTION_GET_DEBOUNCE_PERIOD = 58 + FUNCTION_GET_PROTOCOL1_BRICKLET_NAME = 241 + FUNCTION_GET_CHIP_TEMPERATURE = 242 + FUNCTION_RESET = 243 + FUNCTION_GET_IDENTITY = 255 + + EXTENSION_TYPE_CHIBI = 1 + EXTENSION_TYPE_RS485 = 2 + EXTENSION_TYPE_WIFI = 3 + EXTENSION_TYPE_ETHERNET = 4 + CHIBI_FREQUENCY_OQPSK_868_MHZ = 0 + CHIBI_FREQUENCY_OQPSK_915_MHZ = 1 + CHIBI_FREQUENCY_OQPSK_780_MHZ = 2 + CHIBI_FREQUENCY_BPSK40_915_MHZ = 3 + RS485_PARITY_NONE = 'n' + RS485_PARITY_EVEN = 'e' + RS485_PARITY_ODD = 'o' + WIFI_CONNECTION_DHCP = 0 + WIFI_CONNECTION_STATIC_IP = 1 + WIFI_CONNECTION_ACCESS_POINT_DHCP = 2 + WIFI_CONNECTION_ACCESS_POINT_STATIC_IP = 3 + WIFI_CONNECTION_AD_HOC_DHCP = 4 + WIFI_CONNECTION_AD_HOC_STATIC_IP = 5 + WIFI_ENCRYPTION_WPA_WPA2 = 0 + WIFI_ENCRYPTION_WPA_ENTERPRISE = 1 + WIFI_ENCRYPTION_WEP = 2 + WIFI_ENCRYPTION_NO_ENCRYPTION = 3 + WIFI_EAP_OPTION_OUTER_AUTH_EAP_FAST = 0 + WIFI_EAP_OPTION_OUTER_AUTH_EAP_TLS = 1 + WIFI_EAP_OPTION_OUTER_AUTH_EAP_TTLS = 2 + WIFI_EAP_OPTION_OUTER_AUTH_EAP_PEAP = 3 + WIFI_EAP_OPTION_INNER_AUTH_EAP_MSCHAP = 0 + WIFI_EAP_OPTION_INNER_AUTH_EAP_GTC = 4 + WIFI_EAP_OPTION_CERT_TYPE_CA_CERT = 0 + WIFI_EAP_OPTION_CERT_TYPE_CLIENT_CERT = 8 + WIFI_EAP_OPTION_CERT_TYPE_PRIVATE_KEY = 16 + WIFI_STATE_DISASSOCIATED = 0 + WIFI_STATE_ASSOCIATED = 1 + WIFI_STATE_ASSOCIATING = 2 + WIFI_STATE_ERROR = 3 + WIFI_STATE_NOT_INITIALIZED_YET = 255 + WIFI_POWER_MODE_FULL_SPEED = 0 + WIFI_POWER_MODE_LOW_POWER = 1 + WIFI_DOMAIN_CHANNEL_1TO11 = 0 + WIFI_DOMAIN_CHANNEL_1TO13 = 1 + WIFI_DOMAIN_CHANNEL_1TO14 = 2 + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 1) + + self.response_expected[BrickMaster.FUNCTION_GET_STACK_VOLTAGE] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_STACK_CURRENT] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_EXTENSION_TYPE] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_EXTENSION_TYPE] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_IS_CHIBI_PRESENT] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_CHIBI_ADDRESS] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_CHIBI_ADDRESS] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_CHIBI_MASTER_ADDRESS] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_CHIBI_MASTER_ADDRESS] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_CHIBI_SLAVE_ADDRESS] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_CHIBI_SLAVE_ADDRESS] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_CHIBI_SIGNAL_STRENGTH] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_CHIBI_ERROR_LOG] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_CHIBI_FREQUENCY] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_CHIBI_FREQUENCY] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_CHIBI_CHANNEL] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_CHIBI_CHANNEL] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_IS_RS485_PRESENT] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_RS485_ADDRESS] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_RS485_ADDRESS] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_RS485_SLAVE_ADDRESS] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_RS485_SLAVE_ADDRESS] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_RS485_ERROR_LOG] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_RS485_CONFIGURATION] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_RS485_CONFIGURATION] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_IS_WIFI_PRESENT] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_WIFI_CONFIGURATION] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_WIFI_CONFIGURATION] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_WIFI_ENCRYPTION] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_WIFI_ENCRYPTION] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_WIFI_STATUS] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_REFRESH_WIFI_STATUS] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_SET_WIFI_CERTIFICATE] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_WIFI_CERTIFICATE] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_WIFI_POWER_MODE] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_WIFI_POWER_MODE] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_WIFI_BUFFER_INFO] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_WIFI_REGULATORY_DOMAIN] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_WIFI_REGULATORY_DOMAIN] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_USB_VOLTAGE] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_LONG_WIFI_KEY] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_LONG_WIFI_KEY] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_WIFI_HOSTNAME] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_WIFI_HOSTNAME] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_STACK_CURRENT_CALLBACK_PERIOD] = BrickMaster.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_STACK_CURRENT_CALLBACK_PERIOD] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_STACK_VOLTAGE_CALLBACK_PERIOD] = BrickMaster.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_STACK_VOLTAGE_CALLBACK_PERIOD] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_USB_VOLTAGE_CALLBACK_PERIOD] = BrickMaster.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_USB_VOLTAGE_CALLBACK_PERIOD] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_STACK_CURRENT_CALLBACK_THRESHOLD] = BrickMaster.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_STACK_CURRENT_CALLBACK_THRESHOLD] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_STACK_VOLTAGE_CALLBACK_THRESHOLD] = BrickMaster.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_STACK_VOLTAGE_CALLBACK_THRESHOLD] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_USB_VOLTAGE_CALLBACK_THRESHOLD] = BrickMaster.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_USB_VOLTAGE_CALLBACK_THRESHOLD] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickMaster.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.CALLBACK_STACK_CURRENT] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickMaster.CALLBACK_STACK_VOLTAGE] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickMaster.CALLBACK_USB_VOLTAGE] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickMaster.CALLBACK_STACK_CURRENT_REACHED] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickMaster.CALLBACK_STACK_VOLTAGE_REACHED] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickMaster.CALLBACK_USB_VOLTAGE_REACHED] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_PROTOCOL1_BRICKLET_NAME] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_GET_CHIP_TEMPERATURE] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickMaster.FUNCTION_RESET] = BrickMaster.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickMaster.FUNCTION_GET_IDENTITY] = BrickMaster.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickMaster.CALLBACK_STACK_CURRENT] = 'H' + self.callback_formats[BrickMaster.CALLBACK_STACK_VOLTAGE] = 'H' + self.callback_formats[BrickMaster.CALLBACK_USB_VOLTAGE] = 'H' + self.callback_formats[BrickMaster.CALLBACK_STACK_CURRENT_REACHED] = 'H' + self.callback_formats[BrickMaster.CALLBACK_STACK_VOLTAGE_REACHED] = 'H' + self.callback_formats[BrickMaster.CALLBACK_USB_VOLTAGE_REACHED] = 'H' + + def get_stack_voltage(self): + """ + Returns the stack voltage in mV. The stack voltage is the + voltage that is supplied via the stack, i.e. it is given by a + Step-Down or Step-Up Power Supply. + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_STACK_VOLTAGE, (), '', 'H') + + def get_stack_current(self): + """ + Returns the stack current in mA. The stack current is the + current that is drawn via the stack, i.e. it is given by a + Step-Down or Step-Up Power Supply. + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_STACK_CURRENT, (), '', 'H') + + def set_extension_type(self, extension, exttype): + """ + Writes the extension type to the EEPROM of a specified extension. + The extension is either 0 or 1 (0 is the on the bottom, 1 is the on on top, + if only one extension is present use 0). + + Possible extension types: + + .. csv-table:: + :header: "Type", "Description" + :widths: 10, 100 + + "1", "Chibi" + "2", "RS485" + "3", "WIFI" + "4", "Ethernet" + + The extension type is already set when bought and it can be set with the + Brick Viewer, it is unlikely that you need this function. + + The value will be saved in the EEPROM of the Chibi Extension, it does not + have to be set on every startup. + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_EXTENSION_TYPE, (extension, exttype), 'B I', '') + + def get_extension_type(self, extension): + """ + Returns the extension type for a given extension as set by + :func:`SetExtensionType`. + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_EXTENSION_TYPE, (extension,), 'B', 'I') + + def is_chibi_present(self): + """ + Returns *true* if a Chibi Extension is available to be used by the Master. + + .. versionadded:: 1.1.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_IS_CHIBI_PRESENT, (), '', '?') + + def set_chibi_address(self, address): + """ + Sets the address (1-255) belonging to the Chibi Extension. + + It is possible to set the address with the Brick Viewer and it will be + saved in the EEPROM of the Chibi Extension, it does not + have to be set on every startup. + + .. versionadded:: 1.1.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_CHIBI_ADDRESS, (address,), 'B', '') + + def get_chibi_address(self): + """ + Returns the address as set by :func:`SetChibiAddress`. + + .. versionadded:: 1.1.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_CHIBI_ADDRESS, (), '', 'B') + + def set_chibi_master_address(self, address): + """ + Sets the address (1-255) of the Chibi Master. This address is used if the + Chibi Extension is used as slave (i.e. it does not have a USB connection). + + It is possible to set the address with the Brick Viewer and it will be + saved in the EEPROM of the Chibi Extension, it does not + have to be set on every startup. + + .. versionadded:: 1.1.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_CHIBI_MASTER_ADDRESS, (address,), 'B', '') + + def get_chibi_master_address(self): + """ + Returns the address as set by :func:`SetChibiMasterAddress`. + + .. versionadded:: 1.1.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_CHIBI_MASTER_ADDRESS, (), '', 'B') + + def set_chibi_slave_address(self, num, address): + """ + Sets up to 254 slave addresses. Valid addresses are in range 1-255. 0 has a + special meaning and is used as list terminator. + The address numeration (via num parameter) has to be used + ascending from 0. For example: If you use the Chibi Extension in Master mode + (i.e. the stack has an USB connection) and you want to talk to three other + Chibi stacks with the slave addresses 17, 23, and 42, you should call with + "(0, 17), (1, 23), (2, 42) and (3, 0)". The last call with "(3, 0)" indicates + that the RS485 slave address list contains 3 addresses in this case. + + It is possible to set the addresses with the Brick Viewer and it will be + saved in the EEPROM of the Chibi Extension, they don't + have to be set on every startup. + + .. versionadded:: 1.1.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_CHIBI_SLAVE_ADDRESS, (num, address), 'B B', '') + + def get_chibi_slave_address(self, num): + """ + Returns the slave address for a given num as set by + :func:`SetChibiSlaveAddress`. + + .. versionadded:: 1.1.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_CHIBI_SLAVE_ADDRESS, (num,), 'B', 'B') + + def get_chibi_signal_strength(self): + """ + Returns the signal strength in dBm. The signal strength updates every time a + packet is received. + + .. versionadded:: 1.1.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_CHIBI_SIGNAL_STRENGTH, (), '', 'B') + + def get_chibi_error_log(self): + """ + Returns underrun, CRC error, no ACK and overflow error counts of the Chibi + communication. If these errors start rising, it is likely that either the + distance between two Chibi stacks is becoming too big or there are + interferences. + + .. versionadded:: 1.1.0~(Firmware) + """ + return GetChibiErrorLog(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_CHIBI_ERROR_LOG, (), '', 'H H H H')) + + def set_chibi_frequency(self, frequency): + """ + Sets the Chibi frequency range for the Chibi Extension. Possible values are: + + .. csv-table:: + :header: "Type", "Description" + :widths: 10, 100 + + "0", "OQPSK 868MHz (Europe)" + "1", "OQPSK 915MHz (US)" + "2", "OQPSK 780MHz (China)" + "3", "BPSK40 915MHz" + + It is possible to set the frequency with the Brick Viewer and it will be + saved in the EEPROM of the Chibi Extension, it does not + have to be set on every startup. + + .. versionadded:: 1.1.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_CHIBI_FREQUENCY, (frequency,), 'B', '') + + def get_chibi_frequency(self): + """ + Returns the frequency value as set by :func:`SetChibiFrequency`. + + .. versionadded:: 1.1.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_CHIBI_FREQUENCY, (), '', 'B') + + def set_chibi_channel(self, channel): + """ + Sets the channel used by the Chibi Extension. Possible channels are + different for different frequencies: + + .. csv-table:: + :header: "Frequency", "Possible Channels" + :widths: 40, 60 + + "OQPSK 868Mhz (Europe)", "0" + "OQPSK 915Mhz (US)", "1, 2, 3, 4, 5, 6, 7, 8, 9, 10" + "OQPSK 780Mhz (China)", "0, 1, 2, 3" + "BPSK40 915Mhz", "1, 2, 3, 4, 5, 6, 7, 8, 9, 10" + + It is possible to set the channel with the Brick Viewer and it will be + saved in the EEPROM of the Chibi Extension, it does not + have to be set on every startup. + + .. versionadded:: 1.1.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_CHIBI_CHANNEL, (channel,), 'B', '') + + def get_chibi_channel(self): + """ + Returns the channel as set by :func:`SetChibiChannel`. + + .. versionadded:: 1.1.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_CHIBI_CHANNEL, (), '', 'B') + + def is_rs485_present(self): + """ + Returns *true* if a RS485 Extension is available to be used by the Master. + + .. versionadded:: 1.2.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_IS_RS485_PRESENT, (), '', '?') + + def set_rs485_address(self, address): + """ + Sets the address (0-255) belonging to the RS485 Extension. + + Set to 0 if the RS485 Extension should be the RS485 Master (i.e. + connected to a PC via USB). + + It is possible to set the address with the Brick Viewer and it will be + saved in the EEPROM of the RS485 Extension, it does not + have to be set on every startup. + + .. versionadded:: 1.2.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_RS485_ADDRESS, (address,), 'B', '') + + def get_rs485_address(self): + """ + Returns the address as set by :func:`SetRS485Address`. + + .. versionadded:: 1.2.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_RS485_ADDRESS, (), '', 'B') + + def set_rs485_slave_address(self, num, address): + """ + Sets up to 255 slave addresses. Valid addresses are in range 1-255. 0 has a + special meaning and is used as list terminator. + The address numeration (via num parameter) has to be used + ascending from 0. For example: If you use the RS485 Extension in Master mode + (i.e. the stack has an USB connection) and you want to talk to three other + RS485 stacks with the IDs 17, 23, and 42, you should call with "(0, 17), + (1, 23), (2, 42) and (3, 0)". The last call with "(3, 0)" indicates that the + RS485 slave address list contains 3 addresses in this case. + + It is possible to set the addresses with the Brick Viewer and it will be + saved in the EEPROM of the RS485 Extension, they don't + have to be set on every startup. + + .. versionadded:: 1.2.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_RS485_SLAVE_ADDRESS, (num, address), 'B B', '') + + def get_rs485_slave_address(self, num): + """ + Returns the slave address for a given num as set by + :func:`SetRS485SlaveAddress`. + + .. versionadded:: 1.2.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_RS485_SLAVE_ADDRESS, (num,), 'B', 'B') + + def get_rs485_error_log(self): + """ + Returns CRC error counts of the RS485 communication. + If this counter starts rising, it is likely that the distance + between the RS485 nodes is too big or there is some kind of + interference. + + .. versionadded:: 1.2.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_RS485_ERROR_LOG, (), '', 'H') + + def set_rs485_configuration(self, speed, parity, stopbits): + """ + Sets the configuration of the RS485 Extension. Speed is given in baud. The + Master Brick will try to match the given baud rate as exactly as possible. + The maximum recommended baud rate is 2000000 (2Mbit/s). + Possible values for parity are 'n' (none), 'e' (even) and 'o' (odd). + Possible values for stop bits are 1 and 2. + + If your RS485 is unstable (lost messages etc.), the first thing you should + try is to decrease the speed. On very large bus (e.g. 1km), you probably + should use a value in the range of 100000 (100kbit/s). + + The values are stored in the EEPROM and only applied on startup. That means + you have to restart the Master Brick after configuration. + + .. versionadded:: 1.2.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_RS485_CONFIGURATION, (speed, parity, stopbits), 'I c B', '') + + def get_rs485_configuration(self): + """ + Returns the configuration as set by :func:`SetRS485Configuration`. + + .. versionadded:: 1.2.0~(Firmware) + """ + return GetRS485Configuration(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_RS485_CONFIGURATION, (), '', 'I c B')) + + def is_wifi_present(self): + """ + Returns *true* if a WIFI Extension is available to be used by the Master. + + .. versionadded:: 1.2.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_IS_WIFI_PRESENT, (), '', '?') + + def set_wifi_configuration(self, ssid, connection, ip, subnet_mask, gateway, port): + """ + Sets the configuration of the WIFI Extension. The *ssid* can have a max length + of 32 characters. Possible values for *connection* are: + + .. csv-table:: + :header: "Value", "Description" + :widths: 10, 90 + + "0", "DHCP" + "1", "Static IP" + "2", "Access Point: DHCP" + "3", "Access Point: Static IP" + "4", "Ad Hoc: DHCP" + "5", "Ad Hoc: Static IP" + + If you set *connection* to one of the static IP options then you have to supply + *ip*, *subnet_mask* and *gateway* as an array of size 4 (first element of the + array is the least significant byte of the address). If *connection* is set to + one of the DHCP options then *ip*, *subnet_mask* and *gateway* are ignored, you + can set them to 0. + + The last parameter is the port that your program will connect to. The + default port, that is used by brickd, is 4223. + + The values are stored in the EEPROM and only applied on startup. That means + you have to restart the Master Brick after configuration. + + It is recommended to use the Brick Viewer to set the WIFI configuration. + + .. versionadded:: 1.3.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_WIFI_CONFIGURATION, (ssid, connection, ip, subnet_mask, gateway, port), '32s B 4B 4B 4B H', '') + + def get_wifi_configuration(self): + """ + Returns the configuration as set by :func:`SetWifiConfiguration`. + + .. versionadded:: 1.3.0~(Firmware) + """ + return GetWifiConfiguration(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_WIFI_CONFIGURATION, (), '', '32s B 4B 4B 4B H')) + + def set_wifi_encryption(self, encryption, key, key_index, eap_options, ca_certificate_length, client_certificate_length, private_key_length): + """ + Sets the encryption of the WIFI Extension. The first parameter is the + type of the encryption. Possible values are: + + .. csv-table:: + :header: "Value", "Description" + :widths: 10, 90 + + "0", "WPA/WPA2" + "1", "WPA Enterprise (EAP-FAST, EAP-TLS, EAP-TTLS, PEAP)" + "2", "WEP" + "3", "No Encryption" + + The key has a max length of 50 characters and is used if encryption + is set to 0 or 2 (WPA/WPA2 or WEP). Otherwise the value is ignored. + + For WPA/WPA2 the key has to be at least 8 characters long. If you want to set + a key with more than 50 characters, see :func:`SetLongWifiKey`. + + For WEP the key has to be either 10 or 26 hexdecimal digits long. It is + possible to set the WEP key index (1-4). If you don't know your key index, + it is likely 1. + + If you choose WPA Enterprise as encryption, you have to set eap options and + the length of the certificates (for other encryption types these paramters + are ignored). The certificate length are given in byte and the certificates + themself can be set with :func:`SetWifiCertificate`. Eap options consist of + the outer authentication (bits 1-2), inner authentication (bit 3) and + certificate type (bits 4-5): + + .. csv-table:: + :header: "Option", "Bits", "Description" + :widths: 10, 10, 80 + + "outer auth", "1-2", "0=EAP-FAST, 1=EAP-TLS, 2=EAP-TTLS, 3=EAP-PEAP" + "inner auth", "3", "0=EAP-MSCHAP, 1=EAP-GTC" + "cert type", "4-5", "0=CA Certificate, 1=Client Certificate, 2=Private Key" + + Example for EAP-TTLS + EAP-GTC + Private Key: option = 2 | (1 << 2) | (2 << 3). + + The values are stored in the EEPROM and only applied on startup. That means + you have to restart the Master Brick after configuration. + + It is recommended to use the Brick Viewer to set the WIFI encryption. + + .. versionadded:: 1.3.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_WIFI_ENCRYPTION, (encryption, key, key_index, eap_options, ca_certificate_length, client_certificate_length, private_key_length), 'B 50s B B H H H', '') + + def get_wifi_encryption(self): + """ + Returns the encryption as set by :func:`SetWifiEncryption`. + + .. versionadded:: 1.3.0~(Firmware) + """ + return GetWifiEncryption(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_WIFI_ENCRYPTION, (), '', 'B 50s B B H H H')) + + def get_wifi_status(self): + """ + Returns the status of the WIFI Extension. The state is updated automatically, + all of the other parameters are updated on startup and every time + :func:`RefreshWifiStatus` is called. + + Possible states are: + + .. csv-table:: + :header: "State", "Description" + :widths: 10, 90 + + "0", "Disassociated" + "1", "Associated" + "2", "Associating" + "3", "Error" + "255", "Not initialized yet" + + .. versionadded:: 1.3.0~(Firmware) + """ + return GetWifiStatus(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_WIFI_STATUS, (), '', '6B 6B B h 4B 4B 4B I I B')) + + def refresh_wifi_status(self): + """ + Refreshes the WIFI status (see :func:`GetWifiStatus`). To read the status + of the WIFI module, the Master Brick has to change from data mode to + command mode and back. This transaction and the readout itself is + unfortunately time consuming. This means, that it might take some ms + until the stack with attached WIFI Extensions reacts again after this + function is called. + + .. versionadded:: 1.3.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_REFRESH_WIFI_STATUS, (), '', '') + + def set_wifi_certificate(self, index, data, data_length): + """ + This function is used to set the certificate as well as password and username + for WPA Enterprise. To set the username use index 0xFFFF, + to set the password use index 0xFFFE. The max length of username and + password is 32. + + The certificate is written in chunks of size 32 and the index is used as + the index of the chunk. The data length should nearly always be 32. Only + the last chunk can have a length that is not equal to 32. + + The starting index of the CA Certificate is 0, of the Client Certificate + 10000 and for the Private Key 20000. Maximum sizes are 1312, 1312 and + 4320 byte respectively. + + The values are stored in the EEPROM and only applied on startup. That means + you have to restart the Master Brick after uploading the certificate. + + It is recommended to use the Brick Viewer to set the certificate, username + and password. + + .. versionadded:: 1.3.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_WIFI_CERTIFICATE, (index, data, data_length), 'H 32B B', '') + + def get_wifi_certificate(self, index): + """ + Returns the certificate for a given index as set by :func:`SetWifiCertificate`. + + .. versionadded:: 1.3.0~(Firmware) + """ + return GetWifiCertificate(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_WIFI_CERTIFICATE, (index,), 'H', '32B B')) + + def set_wifi_power_mode(self, mode): + """ + Sets the power mode of the WIFI Extension. Possible modes are: + + .. csv-table:: + :header: "Mode", "Description" + :widths: 10, 90 + + "0", "Full Speed (high power consumption, high throughput)" + "1", "Low Power (low power consumption, low throughput)" + + The default value is 0 (Full Speed). + + .. versionadded:: 1.3.0~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_WIFI_POWER_MODE, (mode,), 'B', '') + + def get_wifi_power_mode(self): + """ + Returns the power mode as set by :func:`SetWifiPowerMode`. + + .. versionadded:: 1.3.0~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_WIFI_POWER_MODE, (), '', 'B') + + def get_wifi_buffer_info(self): + """ + Returns informations about the WIFI receive buffer. The WIFI + receive buffer has a max size of 1500 byte and if data is transfered + too fast, it might overflow. + + The return values are the number of overflows, the low watermark + (i.e. the smallest number of bytes that were free in the buffer) and + the bytes that are currently used. + + You should always try to keep the buffer empty, otherwise you will + have a permanent latency. A good rule of thumb is, that you can transfer + 1000 messages per second without problems. + + Try to not send more then 50 messages at a time without any kind of + break between them. + + .. versionadded:: 1.3.2~(Firmware) + """ + return GetWifiBufferInfo(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_WIFI_BUFFER_INFO, (), '', 'I H H')) + + def set_wifi_regulatory_domain(self, domain): + """ + Sets the regulatory domain of the WIFI Extension. Possible domains are: + + .. csv-table:: + :header: "Domain", "Description" + :widths: 10, 90 + + "0", "FCC: Channel 1-11 (N/S America, Australia, New Zealand)" + "1", "ETSI: Channel 1-13 (Europe, Middle East, Africa)" + "2", "TELEC: Channel 1-14 (Japan)" + + The default value is 1 (ETSI). + + .. versionadded:: 1.3.4~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_WIFI_REGULATORY_DOMAIN, (domain,), 'B', '') + + def get_wifi_regulatory_domain(self): + """ + Returns the regulatory domain as set by :func:`SetWifiRegulatoryDomain`. + + .. versionadded:: 1.3.4~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_WIFI_REGULATORY_DOMAIN, (), '', 'B') + + def get_usb_voltage(self): + """ + Returns the USB voltage in mV. + + .. versionadded:: 1.3.5~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_USB_VOLTAGE, (), '', 'H') + + def set_long_wifi_key(self, key): + """ + Sets a long WIFI key (up to 63 chars, at least 8 chars) for WPA encryption. + This key will be used + if the key in :func:`SetWifiEncryption` is set to "-". In the old protocol, + a payload of size 63 was not possible, so the maximum key length was 50 chars. + + With the new protocol this is possible, since we didn't want to break API, + this function was added additionally. + + .. versionadded:: 2.0.2~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_LONG_WIFI_KEY, (key,), '64s', '') + + def get_long_wifi_key(self): + """ + Returns the encryption key as set by :func:`SetLongWifiKey`. + + .. versionadded:: 2.0.2~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_LONG_WIFI_KEY, (), '', '64s') + + def set_wifi_hostname(self, hostname): + """ + Sets the hostname of the WIFI Extension. The hostname will be displayed + by access points as the hostname in the DHCP clients table. + + .. versionadded:: 2.0.5~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_WIFI_HOSTNAME, (hostname,), '16s', '') + + def get_wifi_hostname(self): + """ + Returns the hostname as set by :func:`GetWifiHostname`. + + .. versionadded:: 2.0.5~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_WIFI_HOSTNAME, (), '', '16s') + + def set_stack_current_callback_period(self, period): + """ + Sets the period in ms with which the :func:`StackCurrent` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`StackCurrent` is only triggered if the current has changed since the + last triggering. + + The default value is 0. + + .. versionadded:: 2.0.5~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_STACK_CURRENT_CALLBACK_PERIOD, (period,), 'I', '') + + def get_stack_current_callback_period(self): + """ + Returns the period as set by :func:`SetCurrentCallbackPeriod`. + + .. versionadded:: 2.0.5~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_STACK_CURRENT_CALLBACK_PERIOD, (), '', 'I') + + def set_stack_voltage_callback_period(self, period): + """ + Sets the period in ms with which the :func:`StackVoltage` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`StackVoltage` is only triggered if the voltage has changed since the + last triggering. + + The default value is 0. + + .. versionadded:: 2.0.5~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_STACK_VOLTAGE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_stack_voltage_callback_period(self): + """ + Returns the period as set by :func:`SetStackVoltageCallbackPeriod`. + + .. versionadded:: 2.0.5~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_STACK_VOLTAGE_CALLBACK_PERIOD, (), '', 'I') + + def set_usb_voltage_callback_period(self, period): + """ + Sets the period in ms with which the :func:`USBVoltage` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`USBVoltage` is only triggered if the voltage has changed since the + last triggering. + + The default value is 0. + + .. versionadded:: 2.0.5~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_USB_VOLTAGE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_usb_voltage_callback_period(self): + """ + Returns the period as set by :func:`SetUSBVoltageCallbackPeriod`. + + .. versionadded:: 2.0.5~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_USB_VOLTAGE_CALLBACK_PERIOD, (), '', 'I') + + def set_stack_current_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`StackCurrentReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the current is *outside* the min and max values" + "'i'", "Callback is triggered when the current is *inside* the min and max values" + "'<'", "Callback is triggered when the current is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the current is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + + .. versionadded:: 2.0.5~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_STACK_CURRENT_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_stack_current_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetStackCurrentCallbackThreshold`. + + .. versionadded:: 2.0.5~(Firmware) + """ + return GetStackCurrentCallbackThreshold(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_STACK_CURRENT_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_stack_voltage_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`StackStackVoltageReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the voltage is *outside* the min and max values" + "'i'", "Callback is triggered when the voltage is *inside* the min and max values" + "'<'", "Callback is triggered when the voltage is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the voltage is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + + .. versionadded:: 2.0.5~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_STACK_VOLTAGE_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_stack_voltage_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetStackVoltageCallbackThreshold`. + + .. versionadded:: 2.0.5~(Firmware) + """ + return GetStackVoltageCallbackThreshold(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_STACK_VOLTAGE_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_usb_voltage_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`USBVoltageReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the voltage is *outside* the min and max values" + "'i'", "Callback is triggered when the voltage is *inside* the min and max values" + "'<'", "Callback is triggered when the voltage is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the voltage is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + + .. versionadded:: 2.0.5~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_USB_VOLTAGE_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_usb_voltage_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetUSBVoltageCallbackThreshold`. + + .. versionadded:: 2.0.5~(Firmware) + """ + return GetUSBVoltageCallbackThreshold(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_USB_VOLTAGE_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`StackCurrentReached`, :func:`StackVoltageReached`, :func:`USBVoltageReached` + + are triggered, if the thresholds + + :func:`SetStackCurrentCallbackThreshold`, :func:`SetStackVoltageCallbackThreshold`, :func:`SetUSBVoltageCallbackThreshold` + + keep being reached. + + The default value is 100. + + .. versionadded:: 2.0.5~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + + .. versionadded:: 2.0.5~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_protocol1_bricklet_name(self, port): + """ + Returns the firmware and protocol version and the name of the Bricklet for a given port. + + This functions sole purpose is to allow automatic flashing of v1.x.y Bricklet plugins. + + .. versionadded:: 2.0.0~(Firmware) + """ + return GetProtocol1BrickletName(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_PROTOCOL1_BRICKLET_NAME, (port,), 'c', 'B 3B 40s')) + + def get_chip_temperature(self): + """ + Returns the temperature in °C/10 as measured inside the microcontroller. The + value returned is not the ambient temperature! + + The temperature is only proportional to the real temperature and it has an + accuracy of +-15%. Practically it is only useful as an indicator for + temperature changes. + + .. versionadded:: 1.2.1~(Firmware) + """ + return self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_CHIP_TEMPERATURE, (), '', 'h') + + def reset(self): + """ + Calling this function will reset the Brick. Calling this function + on a Brick inside of a stack will reset the whole stack. + + After a reset you have to create new device objects, + calling functions on the existing ones will result in + undefined behavior! + + .. versionadded:: 1.2.1~(Firmware) + """ + self.ipcon.send_request(self, BrickMaster.FUNCTION_RESET, (), '', '') + + def get_identity(self): + """ + Returns the UID, the UID where the Brick is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be '0'-'8' (stack position). + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Firmware) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickMaster.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +Master = BrickMaster # for backward compatibility diff --git a/tinkerforge/brick_servo.py b/tinkerforge/brick_servo.py new file mode 100644 index 0000000..eec6268 --- /dev/null +++ b/tinkerforge/brick_servo.py @@ -0,0 +1,438 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetPulseWidth = namedtuple('PulseWidth', ['min', 'max']) +GetDegree = namedtuple('Degree', ['min', 'max']) +GetProtocol1BrickletName = namedtuple('Protocol1BrickletName', ['protocol_version', 'firmware_version', 'name']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickServo(Device): + """ + Device for controlling up to seven servos + """ + + DEVICE_IDENTIFIER = 14 + + CALLBACK_UNDER_VOLTAGE = 26 + CALLBACK_POSITION_REACHED = 27 + CALLBACK_VELOCITY_REACHED = 28 + + FUNCTION_ENABLE = 1 + FUNCTION_DISABLE = 2 + FUNCTION_IS_ENABLED = 3 + FUNCTION_SET_POSITION = 4 + FUNCTION_GET_POSITION = 5 + FUNCTION_GET_CURRENT_POSITION = 6 + FUNCTION_SET_VELOCITY = 7 + FUNCTION_GET_VELOCITY = 8 + FUNCTION_GET_CURRENT_VELOCITY = 9 + FUNCTION_SET_ACCELERATION = 10 + FUNCTION_GET_ACCELERATION = 11 + FUNCTION_SET_OUTPUT_VOLTAGE = 12 + FUNCTION_GET_OUTPUT_VOLTAGE = 13 + FUNCTION_SET_PULSE_WIDTH = 14 + FUNCTION_GET_PULSE_WIDTH = 15 + FUNCTION_SET_DEGREE = 16 + FUNCTION_GET_DEGREE = 17 + FUNCTION_SET_PERIOD = 18 + FUNCTION_GET_PERIOD = 19 + FUNCTION_GET_SERVO_CURRENT = 20 + FUNCTION_GET_OVERALL_CURRENT = 21 + FUNCTION_GET_STACK_INPUT_VOLTAGE = 22 + FUNCTION_GET_EXTERNAL_INPUT_VOLTAGE = 23 + FUNCTION_SET_MINIMUM_VOLTAGE = 24 + FUNCTION_GET_MINIMUM_VOLTAGE = 25 + FUNCTION_GET_PROTOCOL1_BRICKLET_NAME = 241 + FUNCTION_GET_CHIP_TEMPERATURE = 242 + FUNCTION_RESET = 243 + FUNCTION_GET_IDENTITY = 255 + + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickServo.FUNCTION_ENABLE] = BrickServo.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickServo.FUNCTION_DISABLE] = BrickServo.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickServo.FUNCTION_IS_ENABLED] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_SET_POSITION] = BrickServo.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickServo.FUNCTION_GET_POSITION] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_GET_CURRENT_POSITION] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_SET_VELOCITY] = BrickServo.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickServo.FUNCTION_GET_VELOCITY] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_GET_CURRENT_VELOCITY] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_SET_ACCELERATION] = BrickServo.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickServo.FUNCTION_GET_ACCELERATION] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_SET_OUTPUT_VOLTAGE] = BrickServo.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickServo.FUNCTION_GET_OUTPUT_VOLTAGE] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_SET_PULSE_WIDTH] = BrickServo.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickServo.FUNCTION_GET_PULSE_WIDTH] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_SET_DEGREE] = BrickServo.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickServo.FUNCTION_GET_DEGREE] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_SET_PERIOD] = BrickServo.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickServo.FUNCTION_GET_PERIOD] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_GET_SERVO_CURRENT] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_GET_OVERALL_CURRENT] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_GET_STACK_INPUT_VOLTAGE] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_GET_EXTERNAL_INPUT_VOLTAGE] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_SET_MINIMUM_VOLTAGE] = BrickServo.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickServo.FUNCTION_GET_MINIMUM_VOLTAGE] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.CALLBACK_UNDER_VOLTAGE] = BrickServo.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickServo.CALLBACK_POSITION_REACHED] = BrickServo.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickServo.CALLBACK_VELOCITY_REACHED] = BrickServo.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickServo.FUNCTION_GET_PROTOCOL1_BRICKLET_NAME] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_GET_CHIP_TEMPERATURE] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickServo.FUNCTION_RESET] = BrickServo.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickServo.FUNCTION_GET_IDENTITY] = BrickServo.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickServo.CALLBACK_UNDER_VOLTAGE] = 'H' + self.callback_formats[BrickServo.CALLBACK_POSITION_REACHED] = 'B h' + self.callback_formats[BrickServo.CALLBACK_VELOCITY_REACHED] = 'B h' + + def enable(self, servo_num): + """ + Enables a servo (0 to 6). If a servo is enabled, the configured position, + velocity, acceleration, etc. are applied immediately. + """ + self.ipcon.send_request(self, BrickServo.FUNCTION_ENABLE, (servo_num,), 'B', '') + + def disable(self, servo_num): + """ + Disables a servo (0 to 6). Disabled servos are not driven at all, i.e. a + disabled servo will not hold its position if a load is applied. + """ + self.ipcon.send_request(self, BrickServo.FUNCTION_DISABLE, (servo_num,), 'B', '') + + def is_enabled(self, servo_num): + """ + Returns *true* if the specified servo is enabled, *false* otherwise. + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_IS_ENABLED, (servo_num,), 'B', '?') + + def set_position(self, servo_num, position): + """ + Sets the position in °/100 for the specified servo. + + The default range of the position is -9000 to 9000, but it can be specified + according to your servo with :func:`SetDegree`. + + If you want to control a linear servo or RC brushless motor controller or + similar with the Servo Brick, you can also define lengths or speeds with + :func:`SetDegree`. + """ + self.ipcon.send_request(self, BrickServo.FUNCTION_SET_POSITION, (servo_num, position), 'B h', '') + + def get_position(self, servo_num): + """ + Returns the position of the specified servo as set by :func:`SetPosition`. + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_POSITION, (servo_num,), 'B', 'h') + + def get_current_position(self, servo_num): + """ + Returns the *current* position of the specified servo. This may not be the + value of :func:`SetPosition` if the servo is currently approaching a + position goal. + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_CURRENT_POSITION, (servo_num,), 'B', 'h') + + def set_velocity(self, servo_num, velocity): + """ + Sets the maximum velocity of the specified servo in °/100s. The velocity + is accelerated according to the value set by :func:`SetAcceleration`. + + The minimum velocity is 0 (no movement) and the maximum velocity is 65535. + With a value of 65535 the position will be set immediately (no velocity). + + The default value is 65535. + """ + self.ipcon.send_request(self, BrickServo.FUNCTION_SET_VELOCITY, (servo_num, velocity), 'B H', '') + + def get_velocity(self, servo_num): + """ + Returns the velocity of the specified servo as set by :func:`SetVelocity`. + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_VELOCITY, (servo_num,), 'B', 'H') + + def get_current_velocity(self, servo_num): + """ + Returns the *current* velocity of the specified servo. This may not be the + value of :func:`SetVelocity` if the servo is currently approaching a + velocity goal. + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_CURRENT_VELOCITY, (servo_num,), 'B', 'H') + + def set_acceleration(self, servo_num, acceleration): + """ + Sets the acceleration of the specified servo in °/100s². + + The minimum acceleration is 1 and the maximum acceleration is 65535. + With a value of 65535 the velocity will be set immediately (no acceleration). + + The default value is 65535. + """ + self.ipcon.send_request(self, BrickServo.FUNCTION_SET_ACCELERATION, (servo_num, acceleration), 'B H', '') + + def get_acceleration(self, servo_num): + """ + Returns the acceleration for the specified servo as set by + :func:`SetAcceleration`. + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_ACCELERATION, (servo_num,), 'B', 'H') + + def set_output_voltage(self, voltage): + """ + Sets the output voltages with which the servos are driven in mV. + The minimum output voltage is 5000mV and the maximum output voltage is + 9000mV. + + .. note:: + We recommend that you set this value to the maximum voltage that is + specified for your servo, most servos achieve their maximum force only + with high voltages. + + The default value is 5000. + """ + self.ipcon.send_request(self, BrickServo.FUNCTION_SET_OUTPUT_VOLTAGE, (voltage,), 'H', '') + + def get_output_voltage(self): + """ + Returns the output voltage as specified by :func:`SetOutputVoltage`. + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_OUTPUT_VOLTAGE, (), '', 'H') + + def set_pulse_width(self, servo_num, min, max): + """ + Sets the minimum and maximum pulse width of the specified servo in µs. + + Usually, servos are controlled with a + `PWM `__, whereby the + length of the pulse controls the position of the servo. Every servo has + different minimum and maximum pulse widths, these can be specified with + this function. + + If you have a datasheet for your servo that specifies the minimum and + maximum pulse width, you should set the values accordingly. If your servo + comes without any datasheet you have to find the values via trial and error. + + Both values have a range from 1 to 65535 (unsigned 16-bit integer). The + minimum must be smaller than the maximum. + + The default values are 1000µs (1ms) and 2000µs (2ms) for minimum and + maximum pulse width. + """ + self.ipcon.send_request(self, BrickServo.FUNCTION_SET_PULSE_WIDTH, (servo_num, min, max), 'B H H', '') + + def get_pulse_width(self, servo_num): + """ + Returns the minimum and maximum pulse width for the specified servo as set by + :func:`SetPulseWidth`. + """ + return GetPulseWidth(*self.ipcon.send_request(self, BrickServo.FUNCTION_GET_PULSE_WIDTH, (servo_num,), 'B', 'H H')) + + def set_degree(self, servo_num, min, max): + """ + Sets the minimum and maximum degree for the specified servo (by default + given as °/100). + + This only specifies the abstract values between which the minimum and maximum + pulse width is scaled. For example: If you specify a pulse width of 1000µs + to 2000µs and a degree range of -90° to 90°, a call of :func:`SetPosition` + with 0 will result in a pulse width of 1500µs + (-90° = 1000µs, 90° = 2000µs, etc.). + + Possible usage: + + * The datasheet of your servo specifies a range of 200° with the middle position + at 110°. In this case you can set the minimum to -9000 and the maximum to 11000. + * You measure a range of 220° on your servo and you don't have or need a middle + position. In this case you can set the minimum to 0 and the maximum to 22000. + * You have a linear servo with a drive length of 20cm, In this case you could + set the minimum to 0 and the maximum to 20000. Now you can set the Position + with :func:`SetPosition` with a resolution of cm/100. Also the velocity will + have a resolution of cm/100s and the acceleration will have a resolution of + cm/100s². + * You don't care about units and just want the highest possible resolution. In + this case you should set the minimum to -32767 and the maximum to 32767. + * You have a brushless motor with a maximum speed of 10000 rpm and want to + control it with a RC brushless motor controller. In this case you can set the + minimum to 0 and the maximum to 10000. :func:`SetPosition` now controls the rpm. + + Both values have a possible range from -32767 to 32767 + (signed 16-bit integer). The minimum must be smaller than the maximum. + + The default values are -9000 and 9000 for the minimum and maximum degree. + """ + self.ipcon.send_request(self, BrickServo.FUNCTION_SET_DEGREE, (servo_num, min, max), 'B h h', '') + + def get_degree(self, servo_num): + """ + Returns the minimum and maximum degree for the specified servo as set by + :func:`SetDegree`. + """ + return GetDegree(*self.ipcon.send_request(self, BrickServo.FUNCTION_GET_DEGREE, (servo_num,), 'B', 'h h')) + + def set_period(self, servo_num, period): + """ + Sets the period of the specified servo in µs. + + Usually, servos are controlled with a + `PWM `__. Different + servos expect PWMs with different periods. Most servos run well with a + period of about 20ms. + + If your servo comes with a datasheet that specifies a period, you should + set it accordingly. If you don't have a datasheet and you have no idea + what the correct period is, the default value (19.5ms) will most likely + work fine. + + The minimum possible period is 2000µs and the maximum is 65535µs. + + The default value is 19.5ms (19500µs). + """ + self.ipcon.send_request(self, BrickServo.FUNCTION_SET_PERIOD, (servo_num, period), 'B H', '') + + def get_period(self, servo_num): + """ + Returns the period for the specified servo as set by :func:`SetPeriod`. + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_PERIOD, (servo_num,), 'B', 'H') + + def get_servo_current(self, servo_num): + """ + Returns the current consumption of the specified servo in mA. + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_SERVO_CURRENT, (servo_num,), 'B', 'H') + + def get_overall_current(self): + """ + Returns the current consumption of all servos together in mA. + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_OVERALL_CURRENT, (), '', 'H') + + def get_stack_input_voltage(self): + """ + Returns the stack input voltage in mV. The stack input voltage is the + voltage that is supplied via the stack, i.e. it is given by a + Step-Down or Step-Up Power Supply. + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_STACK_INPUT_VOLTAGE, (), '', 'H') + + def get_external_input_voltage(self): + """ + Returns the external input voltage in mV. The external input voltage is + given via the black power input connector on the Servo Brick. + + If there is an external input voltage and a stack input voltage, the motors + will be driven by the external input voltage. If there is only a stack + voltage present, the motors will be driven by this voltage. + + .. warning:: + This means, if you have a high stack voltage and a low external voltage, + the motors will be driven with the low external voltage. If you then remove + the external connection, it will immediately be driven by the high + stack voltage + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_EXTERNAL_INPUT_VOLTAGE, (), '', 'H') + + def set_minimum_voltage(self, voltage): + """ + Sets the minimum voltage in mV, below which the :func:`UnderVoltage` callback + is triggered. The minimum possible value that works with the Servo Brick is 5V. + You can use this function to detect the discharge of a battery that is used + to drive the stepper motor. If you have a fixed power supply, you likely do + not need this functionality. + + The default value is 5V (5000mV). + """ + self.ipcon.send_request(self, BrickServo.FUNCTION_SET_MINIMUM_VOLTAGE, (voltage,), 'H', '') + + def get_minimum_voltage(self): + """ + Returns the minimum voltage as set by :func:`SetMinimumVoltage` + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_MINIMUM_VOLTAGE, (), '', 'H') + + def get_protocol1_bricklet_name(self, port): + """ + Returns the firmware and protocol version and the name of the Bricklet for a given port. + + This functions sole purpose is to allow automatic flashing of v1.x.y Bricklet plugins. + + .. versionadded:: 2.0.0~(Firmware) + """ + return GetProtocol1BrickletName(*self.ipcon.send_request(self, BrickServo.FUNCTION_GET_PROTOCOL1_BRICKLET_NAME, (port,), 'c', 'B 3B 40s')) + + def get_chip_temperature(self): + """ + Returns the temperature in °C/10 as measured inside the microcontroller. The + value returned is not the ambient temperature! + + The temperature is only proportional to the real temperature and it has an + accuracy of +-15%. Practically it is only useful as an indicator for + temperature changes. + + .. versionadded:: 1.1.3~(Firmware) + """ + return self.ipcon.send_request(self, BrickServo.FUNCTION_GET_CHIP_TEMPERATURE, (), '', 'h') + + def reset(self): + """ + Calling this function will reset the Brick. Calling this function + on a Brick inside of a stack will reset the whole stack. + + After a reset you have to create new device objects, + calling functions on the existing ones will result in + undefined behavior! + + .. versionadded:: 1.1.3~(Firmware) + """ + self.ipcon.send_request(self, BrickServo.FUNCTION_RESET, (), '', '') + + def get_identity(self): + """ + Returns the UID, the UID where the Brick is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be '0'-'8' (stack position). + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Firmware) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickServo.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +Servo = BrickServo # for backward compatibility diff --git a/tinkerforge/brick_stepper.py b/tinkerforge/brick_stepper.py new file mode 100644 index 0000000..4596887 --- /dev/null +++ b/tinkerforge/brick_stepper.py @@ -0,0 +1,585 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetSpeedRamping = namedtuple('SpeedRamping', ['acceleration', 'deacceleration']) +GetAllData = namedtuple('AllData', ['current_velocity', 'current_position', 'remaining_steps', 'stack_voltage', 'external_voltage', 'current_consumption']) +GetProtocol1BrickletName = namedtuple('Protocol1BrickletName', ['protocol_version', 'firmware_version', 'name']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickStepper(Device): + """ + Device for controlling stepper motors + """ + + DEVICE_IDENTIFIER = 15 + + CALLBACK_UNDER_VOLTAGE = 31 + CALLBACK_POSITION_REACHED = 32 + CALLBACK_ALL_DATA = 40 + CALLBACK_NEW_STATE = 41 + + FUNCTION_SET_MAX_VELOCITY = 1 + FUNCTION_GET_MAX_VELOCITY = 2 + FUNCTION_GET_CURRENT_VELOCITY = 3 + FUNCTION_SET_SPEED_RAMPING = 4 + FUNCTION_GET_SPEED_RAMPING = 5 + FUNCTION_FULL_BRAKE = 6 + FUNCTION_SET_CURRENT_POSITION = 7 + FUNCTION_GET_CURRENT_POSITION = 8 + FUNCTION_SET_TARGET_POSITION = 9 + FUNCTION_GET_TARGET_POSITION = 10 + FUNCTION_SET_STEPS = 11 + FUNCTION_GET_STEPS = 12 + FUNCTION_GET_REMAINING_STEPS = 13 + FUNCTION_SET_STEP_MODE = 14 + FUNCTION_GET_STEP_MODE = 15 + FUNCTION_DRIVE_FORWARD = 16 + FUNCTION_DRIVE_BACKWARD = 17 + FUNCTION_STOP = 18 + FUNCTION_GET_STACK_INPUT_VOLTAGE = 19 + FUNCTION_GET_EXTERNAL_INPUT_VOLTAGE = 20 + FUNCTION_GET_CURRENT_CONSUMPTION = 21 + FUNCTION_SET_MOTOR_CURRENT = 22 + FUNCTION_GET_MOTOR_CURRENT = 23 + FUNCTION_ENABLE = 24 + FUNCTION_DISABLE = 25 + FUNCTION_IS_ENABLED = 26 + FUNCTION_SET_DECAY = 27 + FUNCTION_GET_DECAY = 28 + FUNCTION_SET_MINIMUM_VOLTAGE = 29 + FUNCTION_GET_MINIMUM_VOLTAGE = 30 + FUNCTION_SET_SYNC_RECT = 33 + FUNCTION_IS_SYNC_RECT = 34 + FUNCTION_SET_TIME_BASE = 35 + FUNCTION_GET_TIME_BASE = 36 + FUNCTION_GET_ALL_DATA = 37 + FUNCTION_SET_ALL_DATA_PERIOD = 38 + FUNCTION_GET_ALL_DATA_PERIOD = 39 + FUNCTION_GET_PROTOCOL1_BRICKLET_NAME = 241 + FUNCTION_GET_CHIP_TEMPERATURE = 242 + FUNCTION_RESET = 243 + FUNCTION_GET_IDENTITY = 255 + + STEP_MODE_FULL_STEP = 1 + STEP_MODE_HALF_STEP = 2 + STEP_MODE_QUARTER_STEP = 4 + STEP_MODE_EIGHTH_STEP = 8 + STATE_STOP = 1 + STATE_ACCELERATION = 2 + STATE_RUN = 3 + STATE_DEACCELERATION = 4 + STATE_DIRECTION_CHANGE_TO_FORWARD = 5 + STATE_DIRECTION_CHANGE_TO_BACKWARD = 6 + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickStepper.FUNCTION_SET_MAX_VELOCITY] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_MAX_VELOCITY] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_GET_CURRENT_VELOCITY] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_SET_SPEED_RAMPING] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_SPEED_RAMPING] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_FULL_BRAKE] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_SET_CURRENT_POSITION] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_CURRENT_POSITION] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_SET_TARGET_POSITION] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_TARGET_POSITION] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_SET_STEPS] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_STEPS] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_GET_REMAINING_STEPS] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_SET_STEP_MODE] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_STEP_MODE] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_DRIVE_FORWARD] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_DRIVE_BACKWARD] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_STOP] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_STACK_INPUT_VOLTAGE] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_GET_EXTERNAL_INPUT_VOLTAGE] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_GET_CURRENT_CONSUMPTION] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_SET_MOTOR_CURRENT] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_MOTOR_CURRENT] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_ENABLE] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_DISABLE] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_IS_ENABLED] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_SET_DECAY] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_DECAY] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_SET_MINIMUM_VOLTAGE] = BrickStepper.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickStepper.FUNCTION_GET_MINIMUM_VOLTAGE] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.CALLBACK_UNDER_VOLTAGE] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickStepper.CALLBACK_POSITION_REACHED] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickStepper.FUNCTION_SET_SYNC_RECT] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_IS_SYNC_RECT] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_SET_TIME_BASE] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_TIME_BASE] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_GET_ALL_DATA] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_SET_ALL_DATA_PERIOD] = BrickStepper.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickStepper.FUNCTION_GET_ALL_DATA_PERIOD] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.CALLBACK_ALL_DATA] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickStepper.CALLBACK_NEW_STATE] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_PROTOCOL1_BRICKLET_NAME] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_GET_CHIP_TEMPERATURE] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickStepper.FUNCTION_RESET] = BrickStepper.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickStepper.FUNCTION_GET_IDENTITY] = BrickStepper.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickStepper.CALLBACK_UNDER_VOLTAGE] = 'H' + self.callback_formats[BrickStepper.CALLBACK_POSITION_REACHED] = 'i' + self.callback_formats[BrickStepper.CALLBACK_ALL_DATA] = 'H i i H H H' + self.callback_formats[BrickStepper.CALLBACK_NEW_STATE] = 'B B' + + def set_max_velocity(self, velocity): + """ + Sets the maximum velocity of the stepper motor in steps per second. + This function does *not* start the motor, it merely sets the maximum + velocity the stepper motor is accelerated to. To get the motor running use + either :func:`SetTargetPosition`, :func:`SetSteps`, :func:`DriveForward` or + :func:`DriveBackward`. + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_MAX_VELOCITY, (velocity,), 'H', '') + + def get_max_velocity(self): + """ + Returns the velocity as set by :func:`SetMaxVelocity`. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_MAX_VELOCITY, (), '', 'H') + + def get_current_velocity(self): + """ + Returns the *current* velocity of the stepper motor in steps per second. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_CURRENT_VELOCITY, (), '', 'H') + + def set_speed_ramping(self, acceleration, deacceleration): + """ + Sets the acceleration and deacceleration of the stepper motor. The values + are given in *steps/s²*. An acceleration of 1000 means, that + every second the velocity is increased by 1000 *steps/s*. + + For example: If the current velocity is 0 and you want to accelerate to a + velocity of 8000 *steps/s* in 10 seconds, you should set an acceleration + of 800 *steps/s²*. + + An acceleration/deacceleration of 0 means instantaneous + acceleration/deacceleration (not recommended) + + The default value is 1000 for both + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_SPEED_RAMPING, (acceleration, deacceleration), 'H H', '') + + def get_speed_ramping(self): + """ + Returns the acceleration and deacceleration as set by + :func:`SetSpeedRamping`. + """ + return GetSpeedRamping(*self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_SPEED_RAMPING, (), '', 'H H')) + + def full_brake(self): + """ + Executes an active full brake. + + .. warning:: + This function is for emergency purposes, + where an immediate brake is necessary. Depending on the current velocity and + the strength of the motor, a full brake can be quite violent. + + Call :func:`Stop` if you just want to stop the motor. + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_FULL_BRAKE, (), '', '') + + def set_current_position(self, position): + """ + Sets the current steps of the internal step counter. This can be used to + set the current position to 0 when some kind of starting position + is reached (e.g. when a CNC machine reaches a corner). + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_CURRENT_POSITION, (position,), 'i', '') + + def get_current_position(self): + """ + Returns the current position of the stepper motor in steps. On startup + the position is 0. The steps are counted with all possible driving + functions (:func:`SetTargetPosition`, :func:`SetSteps`, :func:`DriveForward` or + :func:`DriveBackward`). It also is possible to reset the steps to 0 or + set them to any other desired value with :func:`SetCurrentPosition`. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_CURRENT_POSITION, (), '', 'i') + + def set_target_position(self, position): + """ + Sets the target position of the stepper motor in steps. For example, + if the current position of the motor is 500 and :func:`SetTargetPosition` is + called with 1000, the stepper motor will drive 500 steps forward. It will + use the velocity, acceleration and deacceleration as set by + :func:`SetMaxVelocity` and :func:`SetSpeedRamping`. + + A call of :func:`SetTargetPosition` with the parameter *x* is equivalent to + a call of :func:`SetSteps` with the parameter + (*x* - :func:`GetCurrentPosition`). + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_TARGET_POSITION, (position,), 'i', '') + + def get_target_position(self): + """ + Returns the last target position as set by :func:`SetTargetPosition`. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_TARGET_POSITION, (), '', 'i') + + def set_steps(self, steps): + """ + Sets the number of steps the stepper motor should run. Positive values + will drive the motor forward and negative values backward. + The velocity, acceleration and deacceleration as set by + :func:`SetMaxVelocity` and :func:`SetSpeedRamping` will be used. + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_STEPS, (steps,), 'i', '') + + def get_steps(self): + """ + Returns the last steps as set by :func:`SetSteps`. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_STEPS, (), '', 'i') + + def get_remaining_steps(self): + """ + Returns the remaining steps of the last call of :func:`SetSteps`. + For example, if :func:`SetSteps` is called with 2000 and + :func:`GetRemainingSteps` is called after the motor has run for 500 steps, + it will return 1500. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_REMAINING_STEPS, (), '', 'i') + + def set_step_mode(self, mode): + """ + Sets the step mode of the stepper motor. Possible values are: + + * Full Step = 1 + * Half Step = 2 + * Quarter Step = 4 + * Eighth Step = 8 + + A higher value will increase the resolution and + decrease the torque of the stepper motor. + + The default value is 8 (Eighth Step). + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_STEP_MODE, (mode,), 'B', '') + + def get_step_mode(self): + """ + Returns the step mode as set by :func:`SetStepMode`. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_STEP_MODE, (), '', 'B') + + def drive_forward(self): + """ + Drives the stepper motor forward until :func:`DriveBackward` or + :func:`Stop` is called. The velocity, acceleration and deacceleration as + set by :func:`SetMaxVelocity` and :func:`SetSpeedRamping` will be used. + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_DRIVE_FORWARD, (), '', '') + + def drive_backward(self): + """ + Drives the stepper motor backward until :func:`DriveForward` or + :func:`Stop` is triggered. The velocity, acceleration and deacceleration as + set by :func:`SetMaxVelocity` and :func:`SetSpeedRamping` will be used. + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_DRIVE_BACKWARD, (), '', '') + + def stop(self): + """ + Stops the stepper motor with the deacceleration as set by + :func:`SetSpeedRamping`. + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_STOP, (), '', '') + + def get_stack_input_voltage(self): + """ + Returns the stack input voltage in mV. The stack input voltage is the + voltage that is supplied via the stack, i.e. it is given by a + Step-Down or Step-Up Power Supply. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_STACK_INPUT_VOLTAGE, (), '', 'H') + + def get_external_input_voltage(self): + """ + Returns the external input voltage in mV. The external input voltage is + given via the black power input connector on the Stepper Brick. + + If there is an external input voltage and a stack input voltage, the motor + will be driven by the external input voltage. If there is only a stack + voltage present, the motor will be driven by this voltage. + + .. warning:: + This means, if you have a high stack voltage and a low external voltage, + the motor will be driven with the low external voltage. If you then remove + the external connection, it will immediately be driven by the high + stack voltage + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_EXTERNAL_INPUT_VOLTAGE, (), '', 'H') + + def get_current_consumption(self): + """ + Returns the current consumption of the motor in mA. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_CURRENT_CONSUMPTION, (), '', 'H') + + def set_motor_current(self, current): + """ + Sets the current in mA with which the motor will be driven. + The minimum value is 100mA, the maximum value 2291mA and the + default value is 800mA. + + .. warning:: + Do not set this value above the specifications of your stepper motor. + Otherwise it may damage your motor. + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_MOTOR_CURRENT, (current,), 'H', '') + + def get_motor_current(self): + """ + Returns the current as set by :func:`SetMotorCurrent`. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_MOTOR_CURRENT, (), '', 'H') + + def enable(self): + """ + Enables the driver chip. The driver parameters can be configured (maximum velocity, + acceleration, etc) before it is enabled. + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_ENABLE, (), '', '') + + def disable(self): + """ + Disables the driver chip. The configurations are kept (maximum velocity, + acceleration, etc) but the motor is not driven until it is enabled again. + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_DISABLE, (), '', '') + + def is_enabled(self): + """ + Returns *true* if the driver chip is enabled, *false* otherwise. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_IS_ENABLED, (), '', '?') + + def set_decay(self, decay): + """ + Sets the decay mode of the stepper motor. The possible value range is + between 0 and 65535. A value of 0 sets the fast decay mode, a value of + 65535 sets the slow decay mode and a value in between sets the mixed + decay mode. + + Changing the decay mode is only possible if synchronous rectification + is enabled (see :func:`SetSyncRect`). + + For a good explanation of the different decay modes see + `this `__ blog post by Avayan. + + A good decay mode is unfortunately different for every motor. The best + way to work out a good decay mode for your stepper motor, if you can't + measure the current with an oscilloscope, is to listen to the sound of + the motor. If the value is too low, you often hear a high pitched + sound and if it is too high you can often hear a humming sound. + + Generally, fast decay mode (small value) will be noisier but also + allow higher motor speeds. + + The default value is 10000. + + .. note:: + There is unfortunately no formula to calculate a perfect decay + mode for a given stepper motor. If you have problems with loud noises + or the maximum motor speed is too slow, you should try to tinker with + the decay value + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_DECAY, (decay,), 'H', '') + + def get_decay(self): + """ + Returns the decay mode as set by :func:`SetDecay`. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_DECAY, (), '', 'H') + + def set_minimum_voltage(self, voltage): + """ + Sets the minimum voltage in mV, below which the :func:`UnderVoltage` callback + is triggered. The minimum possible value that works with the Stepper Brick is 8V. + You can use this function to detect the discharge of a battery that is used + to drive the stepper motor. If you have a fixed power supply, you likely do + not need this functionality. + + The default value is 8V. + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_MINIMUM_VOLTAGE, (voltage,), 'H', '') + + def get_minimum_voltage(self): + """ + Returns the minimum voltage as set by :func:`SetMinimumVoltage`. + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_MINIMUM_VOLTAGE, (), '', 'H') + + def set_sync_rect(self, sync_rect): + """ + Turns synchronous rectification on or off (*true* or *false*). + + With synchronous rectification on, the decay can be changed + (see :func:`SetDecay`). Without synchronous rectification fast + decay is used. + + For an explanation of synchronous rectification see + `here `__. + + .. warning:: + If you want to use high speeds (> 10000 steps/s) for a large + stepper motor with a large inductivity we strongly + suggest that you disable synchronous rectification. Otherwise the + Brick may not be able to cope with the load and overheat. + + The default value is *false*. + + .. versionadded:: 1.1.4~(Firmware) + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_SYNC_RECT, (sync_rect,), '?', '') + + def is_sync_rect(self): + """ + Returns *true* if synchronous rectification is enabled, *false* otherwise. + + .. versionadded:: 1.1.4~(Firmware) + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_IS_SYNC_RECT, (), '', '?') + + def set_time_base(self, time_base): + """ + Sets the time base of the velocity and the acceleration of the stepper brick + (in seconds). + + For example, if you want to make one step every 1.5 seconds, you can set + the time base to 15 and the velocity to 10. Now the velocity is + 10steps/15s = 1steps/1.5s. + + The default value is 1. + + .. versionadded:: 1.1.6~(Firmware) + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_TIME_BASE, (time_base,), 'I', '') + + def get_time_base(self): + """ + Returns the time base as set by :func:`SetTimeBase`. + + .. versionadded:: 1.1.6~(Firmware) + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_TIME_BASE, (), '', 'I') + + def get_all_data(self): + """ + Returns the following parameters: The current velocity, + the current position, the remaining steps, the stack voltage, the external + voltage and the current consumption of the stepper motor. + + There is also a callback for this function, see :func:`AllData`. + + .. versionadded:: 1.1.6~(Firmware) + """ + return GetAllData(*self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_ALL_DATA, (), '', 'H i i H H H')) + + def set_all_data_period(self, period): + """ + Sets the period in ms with which the :func:`AllData` callback is triggered + periodically. A value of 0 turns the callback off. + + .. versionadded:: 1.1.6~(Firmware) + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_SET_ALL_DATA_PERIOD, (period,), 'I', '') + + def get_all_data_period(self): + """ + Returns the period as set by :func:`SetAllDataPeriod`. + + .. versionadded:: 1.1.6~(Firmware) + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_ALL_DATA_PERIOD, (), '', 'I') + + def get_protocol1_bricklet_name(self, port): + """ + Returns the firmware and protocol version and the name of the Bricklet for a given port. + + This functions sole purpose is to allow automatic flashing of v1.x.y Bricklet plugins. + + .. versionadded:: 2.0.0~(Firmware) + """ + return GetProtocol1BrickletName(*self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_PROTOCOL1_BRICKLET_NAME, (port,), 'c', 'B 3B 40s')) + + def get_chip_temperature(self): + """ + Returns the temperature in °C/10 as measured inside the microcontroller. The + value returned is not the ambient temperature! + + The temperature is only proportional to the real temperature and it has an + accuracy of +-15%. Practically it is only useful as an indicator for + temperature changes. + + .. versionadded:: 1.1.4~(Firmware) + """ + return self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_CHIP_TEMPERATURE, (), '', 'h') + + def reset(self): + """ + Calling this function will reset the Brick. Calling this function + on a Brick inside of a stack will reset the whole stack. + + After a reset you have to create new device objects, + calling functions on the existing ones will result in + undefined behavior! + + .. versionadded:: 1.1.4~(Firmware) + """ + self.ipcon.send_request(self, BrickStepper.FUNCTION_RESET, (), '', '') + + def get_identity(self): + """ + Returns the UID, the UID where the Brick is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be '0'-'8' (stack position). + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Firmware) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickStepper.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +Stepper = BrickStepper # for backward compatibility diff --git a/tinkerforge/bricklet_ambient_light.py b/tinkerforge/bricklet_ambient_light.py new file mode 100644 index 0000000..bda612b --- /dev/null +++ b/tinkerforge/bricklet_ambient_light.py @@ -0,0 +1,256 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetIlluminanceCallbackThreshold = namedtuple('IlluminanceCallbackThreshold', ['option', 'min', 'max']) +GetAnalogValueCallbackThreshold = namedtuple('AnalogValueCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletAmbientLight(Device): + """ + Device for sensing Ambient Light + """ + + DEVICE_IDENTIFIER = 21 + + CALLBACK_ILLUMINANCE = 13 + CALLBACK_ANALOG_VALUE = 14 + CALLBACK_ILLUMINANCE_REACHED = 15 + CALLBACK_ANALOG_VALUE_REACHED = 16 + + FUNCTION_GET_ILLUMINANCE = 1 + FUNCTION_GET_ANALOG_VALUE = 2 + FUNCTION_SET_ILLUMINANCE_CALLBACK_PERIOD = 3 + FUNCTION_GET_ILLUMINANCE_CALLBACK_PERIOD = 4 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD = 5 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD = 6 + FUNCTION_SET_ILLUMINANCE_CALLBACK_THRESHOLD = 7 + FUNCTION_GET_ILLUMINANCE_CALLBACK_THRESHOLD = 8 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_DEBOUNCE_PERIOD = 11 + FUNCTION_GET_DEBOUNCE_PERIOD = 12 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletAmbientLight.FUNCTION_GET_ILLUMINANCE] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAmbientLight.FUNCTION_GET_ANALOG_VALUE] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAmbientLight.FUNCTION_SET_ILLUMINANCE_CALLBACK_PERIOD] = BrickletAmbientLight.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletAmbientLight.FUNCTION_GET_ILLUMINANCE_CALLBACK_PERIOD] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAmbientLight.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletAmbientLight.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletAmbientLight.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAmbientLight.FUNCTION_SET_ILLUMINANCE_CALLBACK_THRESHOLD] = BrickletAmbientLight.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletAmbientLight.FUNCTION_GET_ILLUMINANCE_CALLBACK_THRESHOLD] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAmbientLight.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletAmbientLight.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletAmbientLight.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAmbientLight.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletAmbientLight.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletAmbientLight.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAmbientLight.CALLBACK_ILLUMINANCE] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletAmbientLight.CALLBACK_ANALOG_VALUE] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletAmbientLight.CALLBACK_ILLUMINANCE_REACHED] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletAmbientLight.CALLBACK_ANALOG_VALUE_REACHED] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletAmbientLight.FUNCTION_GET_IDENTITY] = BrickletAmbientLight.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletAmbientLight.CALLBACK_ILLUMINANCE] = 'H' + self.callback_formats[BrickletAmbientLight.CALLBACK_ANALOG_VALUE] = 'H' + self.callback_formats[BrickletAmbientLight.CALLBACK_ILLUMINANCE_REACHED] = 'H' + self.callback_formats[BrickletAmbientLight.CALLBACK_ANALOG_VALUE_REACHED] = 'H' + + def get_illuminance(self): + """ + Returns the illuminance of the ambient light sensor. The value + has a range of 0 to 9000 and is given in Lux/10, i.e. a value + of 4500 means that an illuminance of 450 Lux is measured. + + If you want to get the illuminance periodically, it is recommended to use the + callback :func:`Illuminance` and set the period with + :func:`SetIlluminanceCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_GET_ILLUMINANCE, (), '', 'H') + + def get_analog_value(self): + """ + Returns the value as read by a 12-bit analog-to-digital converter. + The value is between 0 and 4095. + + .. note:: + The value returned by :func:`GetIlluminance` is averaged over several samples + to yield less noise, while :func:`GetAnalogValue` gives back raw + unfiltered analog values. The only reason to use :func:`GetAnalogValue` is, + if you need the full resolution of the analog-to-digital converter. + + Also, the analog-to-digital converter covers three different ranges that are + set dynamically depending on the light intensity. It is impossible to + distinguish between these ranges with the analog value. + + If you want the analog value periodically, it is recommended to use the + callback :func:`AnalogValue` and set the period with + :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_GET_ANALOG_VALUE, (), '', 'H') + + def set_illuminance_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Illuminance` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Illuminance` is only triggered if the illuminance has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_SET_ILLUMINANCE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_illuminance_callback_period(self): + """ + Returns the period as set by :func:`SetIlluminanceCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_GET_ILLUMINANCE_CALLBACK_PERIOD, (), '', 'I') + + def set_analog_value_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AnalogValue` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AnalogValue` is only triggered if the analog value has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_analog_value_callback_period(self): + """ + Returns the period as set by :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD, (), '', 'I') + + def set_illuminance_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`IlluminanceReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the illuminance is *outside* the min and max values" + "'i'", "Callback is triggered when the illuminance is *inside* the min and max values" + "'<'", "Callback is triggered when the illuminance is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the illuminance is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_SET_ILLUMINANCE_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_illuminance_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetIlluminanceCallbackThreshold`. + """ + return GetIlluminanceCallbackThreshold(*self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_GET_ILLUMINANCE_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_analog_value_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AnalogValueReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the analog value is *outside* the min and max values" + "'i'", "Callback is triggered when the analog value is *inside* the min and max values" + "'<'", "Callback is triggered when the analog value is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the analog value is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_analog_value_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAnalogValueCallbackThreshold`. + """ + return GetAnalogValueCallbackThreshold(*self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`IlluminanceReached`, :func:`AnalogValueReached` + + are triggered, if the thresholds + + :func:`SetIlluminanceCallbackThreshold`, :func:`SetAnalogValueCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletAmbientLight.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +AmbientLight = BrickletAmbientLight # for backward compatibility diff --git a/tinkerforge/bricklet_ambient_light.pyc b/tinkerforge/bricklet_ambient_light.pyc new file mode 100644 index 0000000..bf98661 Binary files /dev/null and b/tinkerforge/bricklet_ambient_light.pyc differ diff --git a/tinkerforge/bricklet_analog_in.py b/tinkerforge/bricklet_analog_in.py new file mode 100644 index 0000000..394857a --- /dev/null +++ b/tinkerforge/bricklet_analog_in.py @@ -0,0 +1,252 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetVoltageCallbackThreshold = namedtuple('VoltageCallbackThreshold', ['option', 'min', 'max']) +GetAnalogValueCallbackThreshold = namedtuple('AnalogValueCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletAnalogIn(Device): + """ + Device for sensing Voltages between 0 and 45V + """ + + DEVICE_IDENTIFIER = 219 + + CALLBACK_VOLTAGE = 13 + CALLBACK_ANALOG_VALUE = 14 + CALLBACK_VOLTAGE_REACHED = 15 + CALLBACK_ANALOG_VALUE_REACHED = 16 + + FUNCTION_GET_VOLTAGE = 1 + FUNCTION_GET_ANALOG_VALUE = 2 + FUNCTION_SET_VOLTAGE_CALLBACK_PERIOD = 3 + FUNCTION_GET_VOLTAGE_CALLBACK_PERIOD = 4 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD = 5 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD = 6 + FUNCTION_SET_VOLTAGE_CALLBACK_THRESHOLD = 7 + FUNCTION_GET_VOLTAGE_CALLBACK_THRESHOLD = 8 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_DEBOUNCE_PERIOD = 11 + FUNCTION_GET_DEBOUNCE_PERIOD = 12 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletAnalogIn.FUNCTION_GET_VOLTAGE] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAnalogIn.FUNCTION_GET_ANALOG_VALUE] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAnalogIn.FUNCTION_SET_VOLTAGE_CALLBACK_PERIOD] = BrickletAnalogIn.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletAnalogIn.FUNCTION_GET_VOLTAGE_CALLBACK_PERIOD] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAnalogIn.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletAnalogIn.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletAnalogIn.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAnalogIn.FUNCTION_SET_VOLTAGE_CALLBACK_THRESHOLD] = BrickletAnalogIn.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletAnalogIn.FUNCTION_GET_VOLTAGE_CALLBACK_THRESHOLD] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAnalogIn.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletAnalogIn.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletAnalogIn.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAnalogIn.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletAnalogIn.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletAnalogIn.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAnalogIn.CALLBACK_VOLTAGE] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletAnalogIn.CALLBACK_ANALOG_VALUE] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletAnalogIn.CALLBACK_VOLTAGE_REACHED] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletAnalogIn.CALLBACK_ANALOG_VALUE_REACHED] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletAnalogIn.FUNCTION_GET_IDENTITY] = BrickletAnalogIn.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletAnalogIn.CALLBACK_VOLTAGE] = 'H' + self.callback_formats[BrickletAnalogIn.CALLBACK_ANALOG_VALUE] = 'H' + self.callback_formats[BrickletAnalogIn.CALLBACK_VOLTAGE_REACHED] = 'H' + self.callback_formats[BrickletAnalogIn.CALLBACK_ANALOG_VALUE_REACHED] = 'H' + + def get_voltage(self): + """ + Returns the voltage of the sensor. The value is in mV and + between 0V and 45V. The resolution between 0 and 6V is about 2mV. + Between 6 and 45V the resolution is about 10mV. + + If you want to get the voltage periodically, it is recommended to use the + callback :func:`Voltage` and set the period with + :func:`SetVoltageCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_GET_VOLTAGE, (), '', 'H') + + def get_analog_value(self): + """ + Returns the value as read by a 12-bit analog-to-digital converter. + The value is between 0 and 4095. + + .. note:: + The value returned by :func:`GetVoltage` is averaged over several samples + to yield less noise, while :func:`GetAnalogValue` gives back raw + unfiltered analog values. The only reason to use :func:`GetAnalogValue` is, + if you need the full resolution of the analog-to-digital converter. + + If you want the analog value periodically, it is recommended to use the + callback :func:`AnalogValue` and set the period with + :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_GET_ANALOG_VALUE, (), '', 'H') + + def set_voltage_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Voltage` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Voltage` is only triggered if the voltage has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_SET_VOLTAGE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_voltage_callback_period(self): + """ + Returns the period as set by :func:`SetVoltageCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_GET_VOLTAGE_CALLBACK_PERIOD, (), '', 'I') + + def set_analog_value_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AnalogValue` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AnalogValue` is only triggered if the analog value has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_analog_value_callback_period(self): + """ + Returns the period as set by :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD, (), '', 'I') + + def set_voltage_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`VoltageReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the voltage is *outside* the min and max values" + "'i'", "Callback is triggered when the voltage is *inside* the min and max values" + "'<'", "Callback is triggered when the voltage is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the voltage is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_SET_VOLTAGE_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_voltage_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetVoltageCallbackThreshold`. + """ + return GetVoltageCallbackThreshold(*self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_GET_VOLTAGE_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_analog_value_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AnalogValueReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the analog value is *outside* the min and max values" + "'i'", "Callback is triggered when the analog value is *inside* the min and max values" + "'<'", "Callback is triggered when the analog value is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the analog value is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_analog_value_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAnalogValueCallbackThreshold`. + """ + return GetAnalogValueCallbackThreshold(*self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`VoltageReached`, :func:`AnalogValueReached` + + are triggered, if the thresholds + + :func:`SetVoltageCallbackThreshold`, :func:`SetAnalogValueCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletAnalogIn.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +AnalogIn = BrickletAnalogIn # for backward compatibility diff --git a/tinkerforge/bricklet_analog_out.py b/tinkerforge/bricklet_analog_out.py new file mode 100644 index 0000000..b51e80e --- /dev/null +++ b/tinkerforge/bricklet_analog_out.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletAnalogOut(Device): + """ + Device for output of voltage between 0 and 5V + """ + + DEVICE_IDENTIFIER = 220 + + + FUNCTION_SET_VOLTAGE = 1 + FUNCTION_GET_VOLTAGE = 2 + FUNCTION_SET_MODE = 3 + FUNCTION_GET_MODE = 4 + FUNCTION_GET_IDENTITY = 255 + + MODE_ANALOG_VALUE = 0 + MODE_1K_TO_GROUND = 1 + MODE_100K_TO_GROUND = 2 + MODE_500K_TO_GROUND = 3 + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletAnalogOut.FUNCTION_SET_VOLTAGE] = BrickletAnalogOut.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletAnalogOut.FUNCTION_GET_VOLTAGE] = BrickletAnalogOut.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAnalogOut.FUNCTION_SET_MODE] = BrickletAnalogOut.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletAnalogOut.FUNCTION_GET_MODE] = BrickletAnalogOut.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletAnalogOut.FUNCTION_GET_IDENTITY] = BrickletAnalogOut.RESPONSE_EXPECTED_ALWAYS_TRUE + + + def set_voltage(self, voltage): + """ + Sets the voltage in mV. The possible range is 0V to 5V (0-5000). + Calling this function will set the mode to 0 (see :func:`SetMode`). + + The default value is 0 (with mode 1). + """ + self.ipcon.send_request(self, BrickletAnalogOut.FUNCTION_SET_VOLTAGE, (voltage,), 'H', '') + + def get_voltage(self): + """ + Returns the voltage as set by :func:`SetVoltage`. + """ + return self.ipcon.send_request(self, BrickletAnalogOut.FUNCTION_GET_VOLTAGE, (), '', 'H') + + def set_mode(self, mode): + """ + Sets the mode of the analog value. Possible modes: + + * 0: Normal Mode (Analog value as set by :func:`SetVoltage` is applied) + * 1: 1k Ohm resistor to ground + * 2: 100k Ohm resistor to ground + * 3: 500k Ohm resistor to ground + + Setting the mode to 0 will result in an output voltage of 0. You can jump + to a higher output voltage directly by calling :func:`SetVoltage`. + + The default mode is 1. + """ + self.ipcon.send_request(self, BrickletAnalogOut.FUNCTION_SET_MODE, (mode,), 'B', '') + + def get_mode(self): + """ + Returns the mode as set by :func:`SetMode`. + """ + return self.ipcon.send_request(self, BrickletAnalogOut.FUNCTION_GET_MODE, (), '', 'B') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletAnalogOut.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + +AnalogOut = BrickletAnalogOut # for backward compatibility diff --git a/tinkerforge/bricklet_barometer.py b/tinkerforge/bricklet_barometer.py new file mode 100644 index 0000000..db363b0 --- /dev/null +++ b/tinkerforge/bricklet_barometer.py @@ -0,0 +1,291 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetAirPressureCallbackThreshold = namedtuple('AirPressureCallbackThreshold', ['option', 'min', 'max']) +GetAltitudeCallbackThreshold = namedtuple('AltitudeCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletBarometer(Device): + """ + Device for sensing air pressure and altitude changes + """ + + DEVICE_IDENTIFIER = 221 + + CALLBACK_AIR_PRESSURE = 15 + CALLBACK_ALTITUDE = 16 + CALLBACK_AIR_PRESSURE_REACHED = 17 + CALLBACK_ALTITUDE_REACHED = 18 + + FUNCTION_GET_AIR_PRESSURE = 1 + FUNCTION_GET_ALTITUDE = 2 + FUNCTION_SET_AIR_PRESSURE_CALLBACK_PERIOD = 3 + FUNCTION_GET_AIR_PRESSURE_CALLBACK_PERIOD = 4 + FUNCTION_SET_ALTITUDE_CALLBACK_PERIOD = 5 + FUNCTION_GET_ALTITUDE_CALLBACK_PERIOD = 6 + FUNCTION_SET_AIR_PRESSURE_CALLBACK_THRESHOLD = 7 + FUNCTION_GET_AIR_PRESSURE_CALLBACK_THRESHOLD = 8 + FUNCTION_SET_ALTITUDE_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_ALTITUDE_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_DEBOUNCE_PERIOD = 11 + FUNCTION_GET_DEBOUNCE_PERIOD = 12 + FUNCTION_SET_REFERENCE_AIR_PRESSURE = 13 + FUNCTION_GET_CHIP_TEMPERATURE = 14 + FUNCTION_GET_REFERENCE_AIR_PRESSURE = 19 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletBarometer.FUNCTION_GET_AIR_PRESSURE] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletBarometer.FUNCTION_GET_ALTITUDE] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletBarometer.FUNCTION_SET_AIR_PRESSURE_CALLBACK_PERIOD] = BrickletBarometer.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletBarometer.FUNCTION_GET_AIR_PRESSURE_CALLBACK_PERIOD] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletBarometer.FUNCTION_SET_ALTITUDE_CALLBACK_PERIOD] = BrickletBarometer.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletBarometer.FUNCTION_GET_ALTITUDE_CALLBACK_PERIOD] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletBarometer.FUNCTION_SET_AIR_PRESSURE_CALLBACK_THRESHOLD] = BrickletBarometer.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletBarometer.FUNCTION_GET_AIR_PRESSURE_CALLBACK_THRESHOLD] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletBarometer.FUNCTION_SET_ALTITUDE_CALLBACK_THRESHOLD] = BrickletBarometer.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletBarometer.FUNCTION_GET_ALTITUDE_CALLBACK_THRESHOLD] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletBarometer.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletBarometer.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletBarometer.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletBarometer.FUNCTION_SET_REFERENCE_AIR_PRESSURE] = BrickletBarometer.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletBarometer.FUNCTION_GET_CHIP_TEMPERATURE] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletBarometer.CALLBACK_AIR_PRESSURE] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletBarometer.CALLBACK_ALTITUDE] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletBarometer.CALLBACK_AIR_PRESSURE_REACHED] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletBarometer.CALLBACK_ALTITUDE_REACHED] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletBarometer.FUNCTION_GET_REFERENCE_AIR_PRESSURE] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletBarometer.FUNCTION_GET_IDENTITY] = BrickletBarometer.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletBarometer.CALLBACK_AIR_PRESSURE] = 'i' + self.callback_formats[BrickletBarometer.CALLBACK_ALTITUDE] = 'i' + self.callback_formats[BrickletBarometer.CALLBACK_AIR_PRESSURE_REACHED] = 'i' + self.callback_formats[BrickletBarometer.CALLBACK_ALTITUDE_REACHED] = 'i' + + def get_air_pressure(self): + """ + Returns the air pressure of the air pressure sensor. The value + has a range of 10000 to 1200000 and is given in mbar/1000, i.e. a value + of 1001092 means that an air pressure of 1001.092 mbar is measured. + + If you want to get the air pressure periodically, it is recommended to use the + callback :func:`AirPressure` and set the period with + :func:`SetAirPressureCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletBarometer.FUNCTION_GET_AIR_PRESSURE, (), '', 'i') + + def get_altitude(self): + """ + Returns the relative altitude of the air pressure sensor. The value is given in + cm and is caluclated based on the difference between the current air pressure + and the reference air pressure that can be set with :func:`SetReferenceAirPressure`. + + If you want to get the altitude periodically, it is recommended to use the + callback :func:`Altitude` and set the period with + :func:`SetAltitudeCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletBarometer.FUNCTION_GET_ALTITUDE, (), '', 'i') + + def set_air_pressure_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AirPressure` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AirPressure` is only triggered if the air pressure has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletBarometer.FUNCTION_SET_AIR_PRESSURE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_air_pressure_callback_period(self): + """ + Returns the period as set by :func:`SetAirPressureCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletBarometer.FUNCTION_GET_AIR_PRESSURE_CALLBACK_PERIOD, (), '', 'I') + + def set_altitude_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Altitude` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Altitude` is only triggered if the altitude has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletBarometer.FUNCTION_SET_ALTITUDE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_altitude_callback_period(self): + """ + Returns the period as set by :func:`SetAltitudeCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletBarometer.FUNCTION_GET_ALTITUDE_CALLBACK_PERIOD, (), '', 'I') + + def set_air_pressure_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AirPressureReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the air pressure is *outside* the min and max values" + "'i'", "Callback is triggered when the air pressure is *inside* the min and max values" + "'<'", "Callback is triggered when the air pressure is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the air pressure is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletBarometer.FUNCTION_SET_AIR_PRESSURE_CALLBACK_THRESHOLD, (option, min, max), 'c i i', '') + + def get_air_pressure_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAirPressureCallbackThreshold`. + """ + return GetAirPressureCallbackThreshold(*self.ipcon.send_request(self, BrickletBarometer.FUNCTION_GET_AIR_PRESSURE_CALLBACK_THRESHOLD, (), '', 'c i i')) + + def set_altitude_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AltitudeReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the altitude is *outside* the min and max values" + "'i'", "Callback is triggered when the altitude is *inside* the min and max values" + "'<'", "Callback is triggered when the altitude is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the altitude is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletBarometer.FUNCTION_SET_ALTITUDE_CALLBACK_THRESHOLD, (option, min, max), 'c i i', '') + + def get_altitude_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAltitudeCallbackThreshold`. + """ + return GetAltitudeCallbackThreshold(*self.ipcon.send_request(self, BrickletBarometer.FUNCTION_GET_ALTITUDE_CALLBACK_THRESHOLD, (), '', 'c i i')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`AirPressureReached`, :func:`AltitudeReached` + + are triggered, if the thresholds + + :func:`SetAirPressureCallbackThreshold`, :func:`SetAltitudeCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletBarometer.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletBarometer.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def set_reference_air_pressure(self, air_pressure): + """ + Sets the reference air pressure in mbar/1000 for the altitude calculation. + Setting the reference to the current air pressure results in a calculated + altitude of 0cm. Passing 0 is a shortcut for passing the current air pressure as + reference. + + Well known reference values are the Q codes + `QNH `__ and + `QFE `__ + used in aviation. + + The default value is 1013.25mbar. + + .. versionadded:: 1.1.0~(Plugin) + """ + self.ipcon.send_request(self, BrickletBarometer.FUNCTION_SET_REFERENCE_AIR_PRESSURE, (air_pressure,), 'i', '') + + def get_chip_temperature(self): + """ + Returns the temperature of the air pressure sensor. The value + has a range of -4000 to 8500 and is given in °C/100, i.e. a value + of 2007 means that a temperature of 20.07 °C is measured. + + This temperature is used internally for temperature compensation of the air + pressure measurement. It is not as accurate as the temperature measured by the + :ref:`temperature_bricklet` or the :ref:`temperature_ir_bricklet`. + """ + return self.ipcon.send_request(self, BrickletBarometer.FUNCTION_GET_CHIP_TEMPERATURE, (), '', 'h') + + def get_reference_air_pressure(self): + """ + Returns the reference air pressure as set by :func:`SetReferenceAirPressure`. + + .. versionadded:: 1.1.0~(Plugin) + """ + return self.ipcon.send_request(self, BrickletBarometer.FUNCTION_GET_REFERENCE_AIR_PRESSURE, (), '', 'i') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletBarometer.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +Barometer = BrickletBarometer # for backward compatibility diff --git a/tinkerforge/bricklet_barometer.pyc b/tinkerforge/bricklet_barometer.pyc new file mode 100644 index 0000000..401a483 Binary files /dev/null and b/tinkerforge/bricklet_barometer.pyc differ diff --git a/tinkerforge/bricklet_current12.py b/tinkerforge/bricklet_current12.py new file mode 100644 index 0000000..e624196 --- /dev/null +++ b/tinkerforge/bricklet_current12.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetCurrentCallbackThreshold = namedtuple('CurrentCallbackThreshold', ['option', 'min', 'max']) +GetAnalogValueCallbackThreshold = namedtuple('AnalogValueCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletCurrent12(Device): + """ + Device for sensing current of up to 12.5A + """ + + DEVICE_IDENTIFIER = 23 + + CALLBACK_CURRENT = 15 + CALLBACK_ANALOG_VALUE = 16 + CALLBACK_CURRENT_REACHED = 17 + CALLBACK_ANALOG_VALUE_REACHED = 18 + CALLBACK_OVER_CURRENT = 19 + + FUNCTION_GET_CURRENT = 1 + FUNCTION_CALIBRATE = 2 + FUNCTION_IS_OVER_CURRENT = 3 + FUNCTION_GET_ANALOG_VALUE = 4 + FUNCTION_SET_CURRENT_CALLBACK_PERIOD = 5 + FUNCTION_GET_CURRENT_CALLBACK_PERIOD = 6 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD = 7 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD = 8 + FUNCTION_SET_CURRENT_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_CURRENT_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD = 11 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD = 12 + FUNCTION_SET_DEBOUNCE_PERIOD = 13 + FUNCTION_GET_DEBOUNCE_PERIOD = 14 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletCurrent12.FUNCTION_GET_CURRENT] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_CALIBRATE] = BrickletCurrent12.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletCurrent12.FUNCTION_IS_OVER_CURRENT] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_GET_ANALOG_VALUE] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_SET_CURRENT_CALLBACK_PERIOD] = BrickletCurrent12.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_GET_CURRENT_CALLBACK_PERIOD] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletCurrent12.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_SET_CURRENT_CALLBACK_THRESHOLD] = BrickletCurrent12.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_GET_CURRENT_CALLBACK_THRESHOLD] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletCurrent12.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletCurrent12.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletCurrent12.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent12.CALLBACK_CURRENT] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletCurrent12.CALLBACK_ANALOG_VALUE] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletCurrent12.CALLBACK_CURRENT_REACHED] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletCurrent12.CALLBACK_ANALOG_VALUE_REACHED] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletCurrent12.CALLBACK_OVER_CURRENT] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletCurrent12.FUNCTION_GET_IDENTITY] = BrickletCurrent12.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletCurrent12.CALLBACK_CURRENT] = 'h' + self.callback_formats[BrickletCurrent12.CALLBACK_ANALOG_VALUE] = 'H' + self.callback_formats[BrickletCurrent12.CALLBACK_CURRENT_REACHED] = 'h' + self.callback_formats[BrickletCurrent12.CALLBACK_ANALOG_VALUE_REACHED] = 'H' + self.callback_formats[BrickletCurrent12.CALLBACK_OVER_CURRENT] = '' + + def get_current(self): + """ + Returns the current of the sensor. The value is in mA + and between -12500mA and 12500mA. + + If you want to get the current periodically, it is recommended to use the + callback :func:`Current` and set the period with + :func:`SetCurrentCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_GET_CURRENT, (), '', 'h') + + def calibrate(self): + """ + Calibrates the 0 value of the sensor. You have to call this function + when there is no current present. + + The zero point of the current sensor + is depending on the exact properties of the analog-to-digital converter, + the length of the Bricklet cable and the temperature. Thus, if you change + the Brick or the environment in which the Bricklet is used, you might + have to recalibrate. + + The resulting calibration will be saved on the EEPROM of the Current + Bricklet. + """ + self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_CALIBRATE, (), '', '') + + def is_over_current(self): + """ + Returns *true* if more than 12.5A were measured. + + .. note:: + To reset this value you have to power cycle the Bricklet. + """ + return self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_IS_OVER_CURRENT, (), '', '?') + + def get_analog_value(self): + """ + Returns the value as read by a 12-bit analog-to-digital converter. + The value is between 0 and 4095. + + .. note:: + The value returned by :func:`GetCurrent` is averaged over several samples + to yield less noise, while :func:`GetAnalogValue` gives back raw + unfiltered analog values. The only reason to use :func:`GetAnalogValue` is, + if you need the full resolution of the analog-to-digital converter. + + If you want the analog value periodically, it is recommended to use the + callback :func:`AnalogValue` and set the period with + :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_GET_ANALOG_VALUE, (), '', 'H') + + def set_current_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Current` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Current` is only triggered if the current has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_SET_CURRENT_CALLBACK_PERIOD, (period,), 'I', '') + + def get_current_callback_period(self): + """ + Returns the period as set by :func:`SetCurrentCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_GET_CURRENT_CALLBACK_PERIOD, (), '', 'I') + + def set_analog_value_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AnalogValue` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AnalogValue` is only triggered if the analog value has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_analog_value_callback_period(self): + """ + Returns the period as set by :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD, (), '', 'I') + + def set_current_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`CurrentReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the current is *outside* the min and max values" + "'i'", "Callback is triggered when the current is *inside* the min and max values" + "'<'", "Callback is triggered when the current is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the current is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_SET_CURRENT_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_current_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetCurrentCallbackThreshold`. + """ + return GetCurrentCallbackThreshold(*self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_GET_CURRENT_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_analog_value_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AnalogValueReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the analog value is *outside* the min and max values" + "'i'", "Callback is triggered when the analog value is *inside* the min and max values" + "'<'", "Callback is triggered when the analog value is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the analog value is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_analog_value_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAnalogValueCallbackThreshold`. + """ + return GetAnalogValueCallbackThreshold(*self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`CurrentReached`, :func:`AnalogValueReached` + + are triggered, if the thresholds + + :func:`SetCurrentCallbackThreshold`, :func:`SetAnalogValueCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletCurrent12.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +Current12 = BrickletCurrent12 # for backward compatibility diff --git a/tinkerforge/bricklet_current25.py b/tinkerforge/bricklet_current25.py new file mode 100644 index 0000000..ba0766a --- /dev/null +++ b/tinkerforge/bricklet_current25.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetCurrentCallbackThreshold = namedtuple('CurrentCallbackThreshold', ['option', 'min', 'max']) +GetAnalogValueCallbackThreshold = namedtuple('AnalogValueCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletCurrent25(Device): + """ + Device for sensing current of up to 25A + """ + + DEVICE_IDENTIFIER = 24 + + CALLBACK_CURRENT = 15 + CALLBACK_ANALOG_VALUE = 16 + CALLBACK_CURRENT_REACHED = 17 + CALLBACK_ANALOG_VALUE_REACHED = 18 + CALLBACK_OVER_CURRENT = 19 + + FUNCTION_GET_CURRENT = 1 + FUNCTION_CALIBRATE = 2 + FUNCTION_IS_OVER_CURRENT = 3 + FUNCTION_GET_ANALOG_VALUE = 4 + FUNCTION_SET_CURRENT_CALLBACK_PERIOD = 5 + FUNCTION_GET_CURRENT_CALLBACK_PERIOD = 6 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD = 7 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD = 8 + FUNCTION_SET_CURRENT_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_CURRENT_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD = 11 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD = 12 + FUNCTION_SET_DEBOUNCE_PERIOD = 13 + FUNCTION_GET_DEBOUNCE_PERIOD = 14 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletCurrent25.FUNCTION_GET_CURRENT] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_CALIBRATE] = BrickletCurrent25.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletCurrent25.FUNCTION_IS_OVER_CURRENT] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_GET_ANALOG_VALUE] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_SET_CURRENT_CALLBACK_PERIOD] = BrickletCurrent25.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_GET_CURRENT_CALLBACK_PERIOD] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletCurrent25.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_SET_CURRENT_CALLBACK_THRESHOLD] = BrickletCurrent25.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_GET_CURRENT_CALLBACK_THRESHOLD] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletCurrent25.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletCurrent25.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletCurrent25.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletCurrent25.CALLBACK_CURRENT] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletCurrent25.CALLBACK_ANALOG_VALUE] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletCurrent25.CALLBACK_CURRENT_REACHED] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletCurrent25.CALLBACK_ANALOG_VALUE_REACHED] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletCurrent25.CALLBACK_OVER_CURRENT] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletCurrent25.FUNCTION_GET_IDENTITY] = BrickletCurrent25.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletCurrent25.CALLBACK_CURRENT] = 'h' + self.callback_formats[BrickletCurrent25.CALLBACK_ANALOG_VALUE] = 'H' + self.callback_formats[BrickletCurrent25.CALLBACK_CURRENT_REACHED] = 'h' + self.callback_formats[BrickletCurrent25.CALLBACK_ANALOG_VALUE_REACHED] = 'H' + self.callback_formats[BrickletCurrent25.CALLBACK_OVER_CURRENT] = '' + + def get_current(self): + """ + Returns the current of the sensor. The value is in mA + and between -25000mA and 25000mA. + + If you want to get the current periodically, it is recommended to use the + callback :func:`Current` and set the period with + :func:`SetCurrentCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_GET_CURRENT, (), '', 'h') + + def calibrate(self): + """ + Calibrates the 0 value of the sensor. You have to call this function + when there is no current present. + + The zero point of the current sensor + is depending on the exact properties of the analog-to-digital converter, + the length of the Bricklet cable and the temperature. Thus, if you change + the Brick or the environment in which the Bricklet is used, you might + have to recalibrate. + + The resulting calibration will be saved on the EEPROM of the Current + Bricklet. + """ + self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_CALIBRATE, (), '', '') + + def is_over_current(self): + """ + Returns *true* if more than 25A were measured. + + .. note:: + To reset this value you have to power cycle the Bricklet. + """ + return self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_IS_OVER_CURRENT, (), '', '?') + + def get_analog_value(self): + """ + Returns the value as read by a 12-bit analog-to-digital converter. + The value is between 0 and 4095. + + .. note:: + The value returned by :func:`GetCurrent` is averaged over several samples + to yield less noise, while :func:`GetAnalogValue` gives back raw + unfiltered analog values. The only reason to use :func:`GetAnalogValue` is, + if you need the full resolution of the analog-to-digital converter. + + If you want the analog value periodically, it is recommended to use the + callback :func:`AnalogValue` and set the period with + :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_GET_ANALOG_VALUE, (), '', 'H') + + def set_current_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Current` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Current` is only triggered if the current has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_SET_CURRENT_CALLBACK_PERIOD, (period,), 'I', '') + + def get_current_callback_period(self): + """ + Returns the period as set by :func:`SetCurrentCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_GET_CURRENT_CALLBACK_PERIOD, (), '', 'I') + + def set_analog_value_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AnalogValue` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AnalogValue` is only triggered if the analog value has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_analog_value_callback_period(self): + """ + Returns the period as set by :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD, (), '', 'I') + + def set_current_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`CurrentReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the current is *outside* the min and max values" + "'i'", "Callback is triggered when the current is *inside* the min and max values" + "'<'", "Callback is triggered when the current is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the current is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_SET_CURRENT_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_current_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetCurrentCallbackThreshold`. + """ + return GetCurrentCallbackThreshold(*self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_GET_CURRENT_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_analog_value_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AnalogValueReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the analog value is *outside* the min and max values" + "'i'", "Callback is triggered when the analog value is *inside* the min and max values" + "'<'", "Callback is triggered when the analog value is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the analog value is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_analog_value_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAnalogValueCallbackThreshold`. + """ + return GetAnalogValueCallbackThreshold(*self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`CurrentReached`, :func:`AnalogValueReached` + + are triggered, if the thresholds + + :func:`SetCurrentCallbackThreshold`, :func:`SetAnalogValueCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletCurrent25.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +Current25 = BrickletCurrent25 # for backward compatibility diff --git a/tinkerforge/bricklet_distance_ir.py b/tinkerforge/bricklet_distance_ir.py new file mode 100644 index 0000000..b2d40ad --- /dev/null +++ b/tinkerforge/bricklet_distance_ir.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetDistanceCallbackThreshold = namedtuple('DistanceCallbackThreshold', ['option', 'min', 'max']) +GetAnalogValueCallbackThreshold = namedtuple('AnalogValueCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletDistanceIR(Device): + """ + Device for sensing distance via infrared + """ + + DEVICE_IDENTIFIER = 25 + + CALLBACK_DISTANCE = 15 + CALLBACK_ANALOG_VALUE = 16 + CALLBACK_DISTANCE_REACHED = 17 + CALLBACK_ANALOG_VALUE_REACHED = 18 + + FUNCTION_GET_DISTANCE = 1 + FUNCTION_GET_ANALOG_VALUE = 2 + FUNCTION_SET_SAMPLING_POINT = 3 + FUNCTION_GET_SAMPLING_POINT = 4 + FUNCTION_SET_DISTANCE_CALLBACK_PERIOD = 5 + FUNCTION_GET_DISTANCE_CALLBACK_PERIOD = 6 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD = 7 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD = 8 + FUNCTION_SET_DISTANCE_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_DISTANCE_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD = 11 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD = 12 + FUNCTION_SET_DEBOUNCE_PERIOD = 13 + FUNCTION_GET_DEBOUNCE_PERIOD = 14 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletDistanceIR.FUNCTION_GET_DISTANCE] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_GET_ANALOG_VALUE] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_SET_SAMPLING_POINT] = BrickletDistanceIR.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletDistanceIR.FUNCTION_GET_SAMPLING_POINT] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_SET_DISTANCE_CALLBACK_PERIOD] = BrickletDistanceIR.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_GET_DISTANCE_CALLBACK_PERIOD] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletDistanceIR.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_SET_DISTANCE_CALLBACK_THRESHOLD] = BrickletDistanceIR.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_GET_DISTANCE_CALLBACK_THRESHOLD] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletDistanceIR.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletDistanceIR.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletDistanceIR.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletDistanceIR.CALLBACK_DISTANCE] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletDistanceIR.CALLBACK_ANALOG_VALUE] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletDistanceIR.CALLBACK_DISTANCE_REACHED] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletDistanceIR.CALLBACK_ANALOG_VALUE_REACHED] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletDistanceIR.FUNCTION_GET_IDENTITY] = BrickletDistanceIR.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletDistanceIR.CALLBACK_DISTANCE] = 'H' + self.callback_formats[BrickletDistanceIR.CALLBACK_ANALOG_VALUE] = 'H' + self.callback_formats[BrickletDistanceIR.CALLBACK_DISTANCE_REACHED] = 'H' + self.callback_formats[BrickletDistanceIR.CALLBACK_ANALOG_VALUE_REACHED] = 'H' + + def get_distance(self): + """ + Returns the distance measured by the sensor. The value is in mm and possible + distance ranges are 40 to 300, 100 to 800 and 200 to 1500, depending on the + selected IR sensor. + + If you want to get the distance periodically, it is recommended to use the + callback :func:`Distance` and set the period with + :func:`SetDistanceCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_GET_DISTANCE, (), '', 'H') + + def get_analog_value(self): + """ + Returns the value as read by a 12-bit analog-to-digital converter. + The value is between 0 and 4095. + + .. note:: + The value returned by :func:`GetDistance` is averaged over several samples + to yield less noise, while :func:`GetAnalogValue` gives back raw + unfiltered analog values. The only reason to use :func:`GetAnalogValue` is, + if you need the full resolution of the analog-to-digital converter. + + If you want the analog value periodically, it is recommended to use the + callback :func:`AnalogValue` and set the period with + :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_GET_ANALOG_VALUE, (), '', 'H') + + def set_sampling_point(self, position, distance): + """ + Sets a sampling point value to a specific position of the lookup table. + The lookup table comprises 128 equidistant analog values with + corresponding distances. + + If you measure a distance of 50cm at the analog value 2048, you + should call this function with (64, 5000). The utilized analog-to-digital + converter has a resolution of 12 bit. With 128 sampling points on the + whole range, this means that every sampling point has a size of 32 + analog values. Thus the analog value 2048 has the corresponding sampling + point 64 = 2048/32. + + Sampling points are saved on the EEPROM of the Distance IR Bricklet and + loaded again on startup. + + .. note:: + An easy way to calibrate the sampling points of the Distance IR Bricklet is + implemented in the Brick Viewer. If you want to calibrate your Bricklet it is + highly recommended to use this implementation. + """ + self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_SET_SAMPLING_POINT, (position, distance), 'B H', '') + + def get_sampling_point(self, position): + """ + Returns the distance to a sampling point position as set by + :func:`SetSamplingPoint`. + """ + return self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_GET_SAMPLING_POINT, (position,), 'B', 'H') + + def set_distance_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Distance` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Distance` is only triggered if the distance has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_SET_DISTANCE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_distance_callback_period(self): + """ + Returns the period as set by :func:`SetDistanceCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_GET_DISTANCE_CALLBACK_PERIOD, (), '', 'I') + + def set_analog_value_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AnalogValue` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AnalogValue` is only triggered if the analog value has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_analog_value_callback_period(self): + """ + Returns the period as set by :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD, (), '', 'I') + + def set_distance_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`DistanceReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the distance is *outside* the min and max values" + "'i'", "Callback is triggered when the distance is *inside* the min and max values" + "'<'", "Callback is triggered when the distance is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the distance is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_SET_DISTANCE_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_distance_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetDistanceCallbackThreshold`. + """ + return GetDistanceCallbackThreshold(*self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_GET_DISTANCE_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_analog_value_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AnalogValueReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the analog value is *outside* the min and max values" + "'i'", "Callback is triggered when the analog value is *inside* the min and max values" + "'<'", "Callback is triggered when the analog value is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the analog value is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_analog_value_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAnalogValueCallbackThreshold`. + """ + return GetAnalogValueCallbackThreshold(*self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`DistanceReached`, :func:`AnalogValueReached` + + are triggered, if the thresholds + + :func:`SetDistanceCallbackThreshold`, :func:`SetAnalogValueCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletDistanceIR.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +DistanceIR = BrickletDistanceIR # for backward compatibility diff --git a/tinkerforge/bricklet_dual_relay.py b/tinkerforge/bricklet_dual_relay.py new file mode 100644 index 0000000..0bddd27 --- /dev/null +++ b/tinkerforge/bricklet_dual_relay.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetState = namedtuple('State', ['relay1', 'relay2']) +GetMonoflop = namedtuple('Monoflop', ['state', 'time', 'time_remaining']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletDualRelay(Device): + """ + Device for controlling two relays + """ + + DEVICE_IDENTIFIER = 26 + + CALLBACK_MONOFLOP_DONE = 5 + + FUNCTION_SET_STATE = 1 + FUNCTION_GET_STATE = 2 + FUNCTION_SET_MONOFLOP = 3 + FUNCTION_GET_MONOFLOP = 4 + FUNCTION_SET_SELECTED_STATE = 6 + FUNCTION_GET_IDENTITY = 255 + + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletDualRelay.FUNCTION_SET_STATE] = BrickletDualRelay.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletDualRelay.FUNCTION_GET_STATE] = BrickletDualRelay.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletDualRelay.FUNCTION_SET_MONOFLOP] = BrickletDualRelay.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletDualRelay.FUNCTION_GET_MONOFLOP] = BrickletDualRelay.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletDualRelay.CALLBACK_MONOFLOP_DONE] = BrickletDualRelay.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletDualRelay.FUNCTION_SET_SELECTED_STATE] = BrickletDualRelay.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletDualRelay.FUNCTION_GET_IDENTITY] = BrickletDualRelay.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletDualRelay.CALLBACK_MONOFLOP_DONE] = 'B ?' + + def set_state(self, relay1, relay2): + """ + Sets the state of the relays, *true* means on and *false* means off. + For example: (true, false) turns relay 1 on and relay 2 off. + + If you just want to set one of the relays and don't know the current state + of the other relay, you can get the state with :func:`GetState` or you + can use :func:`SetSelectedState`. + + Running monoflop timers will be overwritten if this function is called. + + The default value is (*false*, *false*). + """ + self.ipcon.send_request(self, BrickletDualRelay.FUNCTION_SET_STATE, (relay1, relay2), '? ?', '') + + def get_state(self): + """ + Returns the state of the relays, *true* means on and *false* means off. + """ + return GetState(*self.ipcon.send_request(self, BrickletDualRelay.FUNCTION_GET_STATE, (), '', '? ?')) + + def set_monoflop(self, relay, state, time): + """ + The first parameter can be 1 or 2 (relay 1 or relay 2). The second parameter + is the desired state of the relay (*true* means on and *false* means off). + The third parameter indicates the time (in ms) that the relay should hold + the state. + + If this function is called with the parameters (1, true, 1500): + Relay 1 will turn on and in 1.5s it will turn off again. + + A monoflop can be used as a failsafe mechanism. For example: Lets assume you + have a RS485 bus and a Dual Relay Bricklet connected to one of the slave + stacks. You can now call this function every second, with a time parameter + of two seconds. The relay will be on all the time. If now the RS485 + connection is lost, the relay will turn off in at most two seconds. + + .. versionadded:: 1.1.1~(Plugin) + """ + self.ipcon.send_request(self, BrickletDualRelay.FUNCTION_SET_MONOFLOP, (relay, state, time), 'B ? I', '') + + def get_monoflop(self, relay): + """ + Returns (for the given relay) the current state and the time as set by + :func:`SetMonoflop` as well as the remaining time until the state flips. + + If the timer is not running currently, the remaining time will be returned + as 0. + + .. versionadded:: 1.1.1~(Plugin) + """ + return GetMonoflop(*self.ipcon.send_request(self, BrickletDualRelay.FUNCTION_GET_MONOFLOP, (relay,), 'B', '? I I')) + + def set_selected_state(self, relay, state): + """ + Sets the state of the selected relay (1 or 2), *true* means on and *false* means off. + + The other relay remains untouched. + + .. versionadded:: 2.0.0~(Plugin) + """ + self.ipcon.send_request(self, BrickletDualRelay.FUNCTION_SET_SELECTED_STATE, (relay, state), 'B ?', '') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletDualRelay.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +DualRelay = BrickletDualRelay # for backward compatibility diff --git a/tinkerforge/bricklet_gps.py b/tinkerforge/bricklet_gps.py new file mode 100644 index 0000000..54575fa --- /dev/null +++ b/tinkerforge/bricklet_gps.py @@ -0,0 +1,308 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetCoordinates = namedtuple('Coordinates', ['latitude', 'ns', 'longitude', 'ew', 'pdop', 'hdop', 'vdop', 'epe']) +GetStatus = namedtuple('Status', ['fix', 'satellites_view', 'satellites_used']) +GetAltitude = namedtuple('Altitude', ['altitude', 'geoidal_separation']) +GetMotion = namedtuple('Motion', ['course', 'speed']) +GetDateTime = namedtuple('DateTime', ['date', 'time']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletGPS(Device): + """ + Device for receiving GPS position + """ + + DEVICE_IDENTIFIER = 222 + + CALLBACK_COORDINATES = 17 + CALLBACK_STATUS = 18 + CALLBACK_ALTITUDE = 19 + CALLBACK_MOTION = 20 + CALLBACK_DATE_TIME = 21 + + FUNCTION_GET_COORDINATES = 1 + FUNCTION_GET_STATUS = 2 + FUNCTION_GET_ALTITUDE = 3 + FUNCTION_GET_MOTION = 4 + FUNCTION_GET_DATE_TIME = 5 + FUNCTION_RESTART = 6 + FUNCTION_SET_COORDINATES_CALLBACK_PERIOD = 7 + FUNCTION_GET_COORDINATES_CALLBACK_PERIOD = 8 + FUNCTION_SET_STATUS_CALLBACK_PERIOD = 9 + FUNCTION_GET_STATUS_CALLBACK_PERIOD = 10 + FUNCTION_SET_ALTITUDE_CALLBACK_PERIOD = 11 + FUNCTION_GET_ALTITUDE_CALLBACK_PERIOD = 12 + FUNCTION_SET_DATE_TIME_CALLBACK_PERIOD = 13 + FUNCTION_GET_DATE_TIME_CALLBACK_PERIOD = 14 + FUNCTION_SET_MOTION_CALLBACK_PERIOD = 15 + FUNCTION_GET_MOTION_CALLBACK_PERIOD = 16 + FUNCTION_GET_IDENTITY = 255 + + FIX_NO_FIX = 1 + FIX_2D_FIX = 2 + FIX_3D_FIX = 3 + RESTART_TYPE_HOT_START = 0 + RESTART_TYPE_WARM_START = 1 + RESTART_TYPE_COLD_START = 2 + RESTART_TYPE_FACTORY_RESET = 3 + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletGPS.FUNCTION_GET_COORDINATES] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletGPS.FUNCTION_GET_STATUS] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletGPS.FUNCTION_GET_ALTITUDE] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletGPS.FUNCTION_GET_MOTION] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletGPS.FUNCTION_GET_DATE_TIME] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletGPS.FUNCTION_RESTART] = BrickletGPS.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletGPS.FUNCTION_SET_COORDINATES_CALLBACK_PERIOD] = BrickletGPS.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletGPS.FUNCTION_GET_COORDINATES_CALLBACK_PERIOD] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletGPS.FUNCTION_SET_STATUS_CALLBACK_PERIOD] = BrickletGPS.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletGPS.FUNCTION_GET_STATUS_CALLBACK_PERIOD] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletGPS.FUNCTION_SET_ALTITUDE_CALLBACK_PERIOD] = BrickletGPS.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletGPS.FUNCTION_GET_ALTITUDE_CALLBACK_PERIOD] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletGPS.FUNCTION_SET_DATE_TIME_CALLBACK_PERIOD] = BrickletGPS.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletGPS.FUNCTION_GET_DATE_TIME_CALLBACK_PERIOD] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletGPS.FUNCTION_SET_MOTION_CALLBACK_PERIOD] = BrickletGPS.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletGPS.FUNCTION_GET_MOTION_CALLBACK_PERIOD] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletGPS.CALLBACK_COORDINATES] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletGPS.CALLBACK_STATUS] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletGPS.CALLBACK_ALTITUDE] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletGPS.CALLBACK_MOTION] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletGPS.CALLBACK_DATE_TIME] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletGPS.FUNCTION_GET_IDENTITY] = BrickletGPS.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletGPS.CALLBACK_COORDINATES] = 'I c I c H H H H' + self.callback_formats[BrickletGPS.CALLBACK_STATUS] = 'B B B' + self.callback_formats[BrickletGPS.CALLBACK_ALTITUDE] = 'I I' + self.callback_formats[BrickletGPS.CALLBACK_MOTION] = 'I I' + self.callback_formats[BrickletGPS.CALLBACK_DATE_TIME] = 'I I' + + def get_coordinates(self): + """ + Returns the GPS coordinates. Latitude and longitude are given in the + DD.dddddd° format, the value 57123468 means 57.123468°. + The parameter ns and ew are the cardinal directions for + latitude and longitude. Possible values for ns and ew are 'N', 'S', 'E' + and 'W' (north, south, east and west). + + PDOP, HDOP and VDOP are the dilution of precision (DOP) values. They specify + the additional multiplicative effect of GPS satellite geometry on GPS + precision. See + `here `__ + for more information. The values are give in hundredths. + + EPE is the "Estimated Position Error". The EPE is given in cm. This is not the + absolute maximum error, it is the error with a specific confidence. See + `here `__ for more information. + + This data is only valid if there is currently a fix as indicated by + :func:`GetStatus`. + """ + return GetCoordinates(*self.ipcon.send_request(self, BrickletGPS.FUNCTION_GET_COORDINATES, (), '', 'I c I c H H H H')) + + def get_status(self): + """ + Returns the current fix status, the number of satellites that are in view and + the number of satellites that are currently used. + + Possible fix status values can be: + + .. csv-table:: + :header: "Value", "Description" + :widths: 10, 100 + + "1", "No Fix" + "2", "2D Fix" + "3", "3D Fix" + """ + return GetStatus(*self.ipcon.send_request(self, BrickletGPS.FUNCTION_GET_STATUS, (), '', 'B B B')) + + def get_altitude(self): + """ + Returns the current altitude and corresponding geoidal separation. + + Both values are given in cm. + + This data is only valid if there is currently a fix as indicated by + :func:`GetStatus`. + """ + return GetAltitude(*self.ipcon.send_request(self, BrickletGPS.FUNCTION_GET_ALTITUDE, (), '', 'I I')) + + def get_motion(self): + """ + Returns the current course and speed. Course is given in hundredths degree + and speed is given in hundredths km/h. A course of 0° means the Bricklet is + traveling north bound and 90° means it is traveling east bound. + + Please note that this only returns useful values if an actual movement + is present. + + This data is only valid if there is currently a fix as indicated by + :func:`GetStatus`. + """ + return GetMotion(*self.ipcon.send_request(self, BrickletGPS.FUNCTION_GET_MOTION, (), '', 'I I')) + + def get_date_time(self): + """ + Returns the current date and time. The date is + given in the format ddmmyy and the time is given + in the format hhmmss.sss. For example, 140713 means + 14.05.13 as date and 195923568 means 19:59:23.568 as time. + """ + return GetDateTime(*self.ipcon.send_request(self, BrickletGPS.FUNCTION_GET_DATE_TIME, (), '', 'I I')) + + def restart(self, restart_type): + """ + Restarts the GPS Bricklet, the following restart types are available: + + .. csv-table:: + :header: "Value", "Description" + :widths: 10, 100 + + "0", "Hot start (use all available data in the NV store)" + "1", "Warm start (don't use ephemeris at restart)" + "2", "Cold start (don't use time, position, almanacs and ephemeris at restart)" + "3", "Factory reset (clear all system/user configurations at restart)" + """ + self.ipcon.send_request(self, BrickletGPS.FUNCTION_RESTART, (restart_type,), 'B', '') + + def set_coordinates_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Coordinates` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Coordinates` is only triggered if the coordinates changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletGPS.FUNCTION_SET_COORDINATES_CALLBACK_PERIOD, (period,), 'I', '') + + def get_coordinates_callback_period(self): + """ + Returns the period as set by :func:`SetCoordinatesCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletGPS.FUNCTION_GET_COORDINATES_CALLBACK_PERIOD, (), '', 'I') + + def set_status_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Status` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Status` is only triggered if the status changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletGPS.FUNCTION_SET_STATUS_CALLBACK_PERIOD, (period,), 'I', '') + + def get_status_callback_period(self): + """ + Returns the period as set by :func:`SetStatusCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletGPS.FUNCTION_GET_STATUS_CALLBACK_PERIOD, (), '', 'I') + + def set_altitude_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Altitude` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Altitude` is only triggered if the altitude changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletGPS.FUNCTION_SET_ALTITUDE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_altitude_callback_period(self): + """ + Returns the period as set by :func:`SetAltitudeCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletGPS.FUNCTION_GET_ALTITUDE_CALLBACK_PERIOD, (), '', 'I') + + def set_date_time_callback_period(self, period): + """ + Sets the period in ms with which the :func:`DateTime` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`DateTime` is only triggered if the date or time changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletGPS.FUNCTION_SET_DATE_TIME_CALLBACK_PERIOD, (period,), 'I', '') + + def get_date_time_callback_period(self): + """ + Returns the period as set by :func:`SetDateTimeCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletGPS.FUNCTION_GET_DATE_TIME_CALLBACK_PERIOD, (), '', 'I') + + def set_motion_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Motion` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Motion` is only triggered if the motion changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletGPS.FUNCTION_SET_MOTION_CALLBACK_PERIOD, (period,), 'I', '') + + def get_motion_callback_period(self): + """ + Returns the period as set by :func:`SetMotionCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletGPS.FUNCTION_GET_MOTION_CALLBACK_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletGPS.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +GPS = BrickletGPS # for backward compatibility diff --git a/tinkerforge/bricklet_humidity.py b/tinkerforge/bricklet_humidity.py new file mode 100644 index 0000000..60e649a --- /dev/null +++ b/tinkerforge/bricklet_humidity.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetHumidityCallbackThreshold = namedtuple('HumidityCallbackThreshold', ['option', 'min', 'max']) +GetAnalogValueCallbackThreshold = namedtuple('AnalogValueCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletHumidity(Device): + """ + Device for sensing Humidity + """ + + DEVICE_IDENTIFIER = 27 + + CALLBACK_HUMIDITY = 13 + CALLBACK_ANALOG_VALUE = 14 + CALLBACK_HUMIDITY_REACHED = 15 + CALLBACK_ANALOG_VALUE_REACHED = 16 + + FUNCTION_GET_HUMIDITY = 1 + FUNCTION_GET_ANALOG_VALUE = 2 + FUNCTION_SET_HUMIDITY_CALLBACK_PERIOD = 3 + FUNCTION_GET_HUMIDITY_CALLBACK_PERIOD = 4 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD = 5 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD = 6 + FUNCTION_SET_HUMIDITY_CALLBACK_THRESHOLD = 7 + FUNCTION_GET_HUMIDITY_CALLBACK_THRESHOLD = 8 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_DEBOUNCE_PERIOD = 11 + FUNCTION_GET_DEBOUNCE_PERIOD = 12 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletHumidity.FUNCTION_GET_HUMIDITY] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletHumidity.FUNCTION_GET_ANALOG_VALUE] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletHumidity.FUNCTION_SET_HUMIDITY_CALLBACK_PERIOD] = BrickletHumidity.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletHumidity.FUNCTION_GET_HUMIDITY_CALLBACK_PERIOD] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletHumidity.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletHumidity.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletHumidity.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletHumidity.FUNCTION_SET_HUMIDITY_CALLBACK_THRESHOLD] = BrickletHumidity.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletHumidity.FUNCTION_GET_HUMIDITY_CALLBACK_THRESHOLD] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletHumidity.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletHumidity.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletHumidity.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletHumidity.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletHumidity.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletHumidity.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletHumidity.CALLBACK_HUMIDITY] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletHumidity.CALLBACK_ANALOG_VALUE] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletHumidity.CALLBACK_HUMIDITY_REACHED] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletHumidity.CALLBACK_ANALOG_VALUE_REACHED] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletHumidity.FUNCTION_GET_IDENTITY] = BrickletHumidity.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletHumidity.CALLBACK_HUMIDITY] = 'H' + self.callback_formats[BrickletHumidity.CALLBACK_ANALOG_VALUE] = 'H' + self.callback_formats[BrickletHumidity.CALLBACK_HUMIDITY_REACHED] = 'H' + self.callback_formats[BrickletHumidity.CALLBACK_ANALOG_VALUE_REACHED] = 'H' + + def get_humidity(self): + """ + Returns the humidity of the sensor. The value + has a range of 0 to 1000 and is given in %RH/10 (Relative Humidity), + i.e. a value of 421 means that a humidity of 42.1 %RH is measured. + + If you want to get the humidity periodically, it is recommended to use the + callback :func:`Humidity` and set the period with + :func:`SetHumidityCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletHumidity.FUNCTION_GET_HUMIDITY, (), '', 'H') + + def get_analog_value(self): + """ + Returns the value as read by a 12-bit analog-to-digital converter. + The value is between 0 and 4095. + + .. note:: + The value returned by :func:`GetHumidity` is averaged over several samples + to yield less noise, while :func:`GetAnalogValue` gives back raw + unfiltered analog values. The returned humidity value is calibrated for + room temperatures, if you use the sensor in extreme cold or extreme + warm environments, you might want to calculate the humidity from + the analog value yourself. See the `HIH 5030 datasheet + `__. + + If you want the analog value periodically, it is recommended to use the + callback :func:`AnalogValue` and set the period with + :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletHumidity.FUNCTION_GET_ANALOG_VALUE, (), '', 'H') + + def set_humidity_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Humidity` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Humidity` is only triggered if the humidity has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletHumidity.FUNCTION_SET_HUMIDITY_CALLBACK_PERIOD, (period,), 'I', '') + + def get_humidity_callback_period(self): + """ + Returns the period as set by :func:`SetHumidityCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletHumidity.FUNCTION_GET_HUMIDITY_CALLBACK_PERIOD, (), '', 'I') + + def set_analog_value_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AnalogValue` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AnalogValue` is only triggered if the analog value has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletHumidity.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_analog_value_callback_period(self): + """ + Returns the period as set by :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletHumidity.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD, (), '', 'I') + + def set_humidity_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`HumidityReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the humidity is *outside* the min and max values" + "'i'", "Callback is triggered when the humidity is *inside* the min and max values" + "'<'", "Callback is triggered when the humidity is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the humidity is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletHumidity.FUNCTION_SET_HUMIDITY_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_humidity_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetHumidityCallbackThreshold`. + """ + return GetHumidityCallbackThreshold(*self.ipcon.send_request(self, BrickletHumidity.FUNCTION_GET_HUMIDITY_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_analog_value_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AnalogValueReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the analog value is *outside* the min and max values" + "'i'", "Callback is triggered when the analog value is *inside* the min and max values" + "'<'", "Callback is triggered when the analog value is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the analog value is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletHumidity.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_analog_value_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAnalogValueCallbackThreshold`. + """ + return GetAnalogValueCallbackThreshold(*self.ipcon.send_request(self, BrickletHumidity.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`HumidityReached`, :func:`AnalogValueReached` + + are triggered, if the thresholds + + :func:`SetHumidityCallbackThreshold`, :func:`SetAnalogValueCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletHumidity.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletHumidity.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletHumidity.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +Humidity = BrickletHumidity # for backward compatibility diff --git a/tinkerforge/bricklet_humidity.pyc b/tinkerforge/bricklet_humidity.pyc new file mode 100644 index 0000000..6ef2931 Binary files /dev/null and b/tinkerforge/bricklet_humidity.pyc differ diff --git a/tinkerforge/bricklet_industrial_digital_in_4.py b/tinkerforge/bricklet_industrial_digital_in_4.py new file mode 100644 index 0000000..5577fce --- /dev/null +++ b/tinkerforge/bricklet_industrial_digital_in_4.py @@ -0,0 +1,180 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletIndustrialDigitalIn4(Device): + """ + Device for controlling up to 4 optically coupled digital inputs + """ + + DEVICE_IDENTIFIER = 223 + + CALLBACK_INTERRUPT = 9 + + FUNCTION_GET_VALUE = 1 + FUNCTION_SET_GROUP = 2 + FUNCTION_GET_GROUP = 3 + FUNCTION_GET_AVAILABLE_FOR_GROUP = 4 + FUNCTION_SET_DEBOUNCE_PERIOD = 5 + FUNCTION_GET_DEBOUNCE_PERIOD = 6 + FUNCTION_SET_INTERRUPT = 7 + FUNCTION_GET_INTERRUPT = 8 + FUNCTION_GET_IDENTITY = 255 + + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletIndustrialDigitalIn4.FUNCTION_GET_VALUE] = BrickletIndustrialDigitalIn4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialDigitalIn4.FUNCTION_SET_GROUP] = BrickletIndustrialDigitalIn4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIndustrialDigitalIn4.FUNCTION_GET_GROUP] = BrickletIndustrialDigitalIn4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialDigitalIn4.FUNCTION_GET_AVAILABLE_FOR_GROUP] = BrickletIndustrialDigitalIn4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialDigitalIn4.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletIndustrialDigitalIn4.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletIndustrialDigitalIn4.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletIndustrialDigitalIn4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialDigitalIn4.FUNCTION_SET_INTERRUPT] = BrickletIndustrialDigitalIn4.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletIndustrialDigitalIn4.FUNCTION_GET_INTERRUPT] = BrickletIndustrialDigitalIn4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialDigitalIn4.CALLBACK_INTERRUPT] = BrickletIndustrialDigitalIn4.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletIndustrialDigitalIn4.FUNCTION_GET_IDENTITY] = BrickletIndustrialDigitalIn4.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletIndustrialDigitalIn4.CALLBACK_INTERRUPT] = 'H H' + + def get_value(self): + """ + Returns the input value with a bitmask. The bitmask + is 16 bit long, *true* refers to high and *false* refers to + low. + + For example: The value 0b0000000000000011 means that pins 0-1 + are high and the other pins are low. + + If no groups are used (see :func:`SetGroup`), the pins correspond to the + markings on the Digital In 4 Bricklet. + + If groups are used, the pins correspond to the element in the group. + Element 1 in the group will get pins 0-3, element 2 pins 4-7, element 3 + pins 8-11 and element 4 pins 12-15. + """ + return self.ipcon.send_request(self, BrickletIndustrialDigitalIn4.FUNCTION_GET_VALUE, (), '', 'H') + + def set_group(self, group): + """ + Sets a group of Digital In 4 Bricklets that should work together. You can + find Bricklets that can be grouped together with :func:`GetAvailableForGroup`. + + The group consists of 4 elements. Element 1 in the group will get pins 0-3, + element 2 pins 4-7, element 3 pins 8-11 and element 4 pins 12-15. + + Each element can either be one of the ports ('a' to 'd') or 'n' if it should + not be used. + + For example: If you have two Digital In 4 Bricklets connected to port A and + port B respectively, you could call with "['a', 'b', 'n', 'n']". + + Now the pins on the Digital In 4 on port A are assigned to 0-3 and the + pins on the Digital In 4 on port B are assigned to 4-7. It is now possible + to call :func:`GetValue` and read out two Bricklets at the same time. + """ + self.ipcon.send_request(self, BrickletIndustrialDigitalIn4.FUNCTION_SET_GROUP, (group,), '4c', '') + + def get_group(self): + """ + Returns the group as set by :func:`SetGroup` + """ + return self.ipcon.send_request(self, BrickletIndustrialDigitalIn4.FUNCTION_GET_GROUP, (), '', '4c') + + def get_available_for_group(self): + """ + Returns a bitmask of ports that are available for grouping. For example the + value 0b0101 means: Port *A* and Port *C* are connected to Bricklets that + can be grouped together. + """ + return self.ipcon.send_request(self, BrickletIndustrialDigitalIn4.FUNCTION_GET_AVAILABLE_FOR_GROUP, (), '', 'B') + + def set_debounce_period(self, debounce): + """ + Sets the debounce period of the :func:`Interrupt` callback in ms. + + For example: If you set this value to 100, you will get the interrupt + maximal every 100ms. This is necessary if something that bounces is + connected to the Digital In 4 Bricklet, such as a button. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletIndustrialDigitalIn4.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletIndustrialDigitalIn4.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def set_interrupt(self, interrupt_mask): + """ + Sets the pins on which an interrupt is activated with a bitmask. + Interrupts are triggered on changes of the voltage level of the pin, + i.e. changes from high to low and low to high. + + For example: An interrupt bitmask of 9 (0b0000000000001001) will + enable the interrupt for pins 0 and 3. + + The interrupts use the grouping as set by :func:`SetGroup`. + + The interrupt is delivered with the callback :func:`Interrupt`. + """ + self.ipcon.send_request(self, BrickletIndustrialDigitalIn4.FUNCTION_SET_INTERRUPT, (interrupt_mask,), 'H', '') + + def get_interrupt(self): + """ + Returns the interrupt bitmask as set by :func:`SetInterrupt`. + """ + return self.ipcon.send_request(self, BrickletIndustrialDigitalIn4.FUNCTION_GET_INTERRUPT, (), '', 'H') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletIndustrialDigitalIn4.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +IndustrialDigitalIn4 = BrickletIndustrialDigitalIn4 # for backward compatibility diff --git a/tinkerforge/bricklet_industrial_digital_out_4.py b/tinkerforge/bricklet_industrial_digital_out_4.py new file mode 100644 index 0000000..c444a00 --- /dev/null +++ b/tinkerforge/bricklet_industrial_digital_out_4.py @@ -0,0 +1,202 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetMonoflop = namedtuple('Monoflop', ['value', 'time', 'time_remaining']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletIndustrialDigitalOut4(Device): + """ + Device for controlling up to 4 optically coupled digital outputs + """ + + DEVICE_IDENTIFIER = 224 + + CALLBACK_MONOFLOP_DONE = 8 + + FUNCTION_SET_VALUE = 1 + FUNCTION_GET_VALUE = 2 + FUNCTION_SET_MONOFLOP = 3 + FUNCTION_GET_MONOFLOP = 4 + FUNCTION_SET_GROUP = 5 + FUNCTION_GET_GROUP = 6 + FUNCTION_GET_AVAILABLE_FOR_GROUP = 7 + FUNCTION_SET_SELECTED_VALUES = 9 + FUNCTION_GET_IDENTITY = 255 + + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletIndustrialDigitalOut4.FUNCTION_SET_VALUE] = BrickletIndustrialDigitalOut4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIndustrialDigitalOut4.FUNCTION_GET_VALUE] = BrickletIndustrialDigitalOut4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialDigitalOut4.FUNCTION_SET_MONOFLOP] = BrickletIndustrialDigitalOut4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIndustrialDigitalOut4.FUNCTION_GET_MONOFLOP] = BrickletIndustrialDigitalOut4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialDigitalOut4.FUNCTION_SET_GROUP] = BrickletIndustrialDigitalOut4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIndustrialDigitalOut4.FUNCTION_GET_GROUP] = BrickletIndustrialDigitalOut4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialDigitalOut4.FUNCTION_GET_AVAILABLE_FOR_GROUP] = BrickletIndustrialDigitalOut4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialDigitalOut4.CALLBACK_MONOFLOP_DONE] = BrickletIndustrialDigitalOut4.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletIndustrialDigitalOut4.FUNCTION_SET_SELECTED_VALUES] = BrickletIndustrialDigitalOut4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIndustrialDigitalOut4.FUNCTION_GET_IDENTITY] = BrickletIndustrialDigitalOut4.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletIndustrialDigitalOut4.CALLBACK_MONOFLOP_DONE] = 'H H' + + def set_value(self, value_mask): + """ + Sets the output value with a bitmask. The bitmask + is 16 bit long, *true* refers to high and *false* refers to + low. + + For example: The value 0b0000000000000011 will turn pins 0-1 + high and the other pins low. + + If no groups are used (see :func:`SetGroup`), the pins correspond to the + markings on the Digital Out 4 Bricklet. + + If groups are used, the pins correspond to the element in the group. + Element 1 in the group will get pins 0-3, element 2 pins 4-7, element 3 + pins 8-11 and element 4 pins 12-15. + """ + self.ipcon.send_request(self, BrickletIndustrialDigitalOut4.FUNCTION_SET_VALUE, (value_mask,), 'H', '') + + def get_value(self): + """ + Returns the bitmask as set by :func:`SetValue`. + """ + return self.ipcon.send_request(self, BrickletIndustrialDigitalOut4.FUNCTION_GET_VALUE, (), '', 'H') + + def set_monoflop(self, selection_mask, value_mask, time): + """ + Configures a monoflop of the pins specified by the first parameter + bitmask. + + The second parameter is a bitmask with the desired value of the specified + pins (*true* means high and *false* means low). + + The third parameter indicates the time (in ms) that the pins should hold + the value. + + If this function is called with the parameters + ((1 << 0) | (1 << 3), (1 << 0), 1500): + Pin 0 will get high and pin 3 will get low. In 1.5s pin 0 will get low and + pin 3 will get high again. + + A monoflop can be used as a fail-safe mechanism. For example: Lets assume you + have a RS485 bus and a Digital Out 4 Bricklet connected to one of the slave + stacks. You can now call this function every second, with a time parameter + of two seconds and pin 0 high. Pin 0 will be high all the time. If now + the RS485 connection is lost, then pin 0 will turn low in at most two seconds. + """ + self.ipcon.send_request(self, BrickletIndustrialDigitalOut4.FUNCTION_SET_MONOFLOP, (selection_mask, value_mask, time), 'H H I', '') + + def get_monoflop(self, pin): + """ + Returns (for the given pin) the current value and the time as set by + :func:`SetMonoflop` as well as the remaining time until the value flips. + + If the timer is not running currently, the remaining time will be returned + as 0. + """ + return GetMonoflop(*self.ipcon.send_request(self, BrickletIndustrialDigitalOut4.FUNCTION_GET_MONOFLOP, (pin,), 'B', 'H I I')) + + def set_group(self, group): + """ + Sets a group of Digital Out 4 Bricklets that should work together. You can + find Bricklets that can be grouped together with :func:`GetAvailableForGroup`. + + The group consists of 4 elements. Element 1 in the group will get pins 0-3, + element 2 pins 4-7, element 3 pins 8-11 and element 4 pins 12-15. + + Each element can either be one of the ports ('a' to 'd') or 'n' if it should + not be used. + + For example: If you have two Digital Out 4 Bricklets connected to port A and + port B respectively, you could call with "['a', 'b', 'n', 'n']". + + Now the pins on the Digital Out 4 on port A are assigned to 0-3 and the + pins on the Digital Out 4 on port B are assigned to 4-7. It is now possible + to call :func:`SetValue` and control two Bricklets at the same time. + """ + self.ipcon.send_request(self, BrickletIndustrialDigitalOut4.FUNCTION_SET_GROUP, (group,), '4c', '') + + def get_group(self): + """ + Returns the group as set by :func:`SetGroup` + """ + return self.ipcon.send_request(self, BrickletIndustrialDigitalOut4.FUNCTION_GET_GROUP, (), '', '4c') + + def get_available_for_group(self): + """ + Returns a bitmask of ports that are available for grouping. For example the + value 0b0101 means: Port *A* and Port *C* are connected to Bricklets that + can be grouped together. + """ + return self.ipcon.send_request(self, BrickletIndustrialDigitalOut4.FUNCTION_GET_AVAILABLE_FOR_GROUP, (), '', 'B') + + def set_selected_values(self, selection_mask, value_mask): + """ + Sets the output value with a bitmask, according to the selction mask. + The bitmask is 16 bit long, *true* refers to high and *false* refers to + low. + + For example: The values 0b0000000000000011, b0000000000000001 will turn + pin 0 high, pin 1 low the other pins remain untouched. + + If no groups are used (see :func:`SetGroup`), the pins correspond to the + markings on the Digital Out 4 Bricklet. + + If groups are used, the pins correspond to the element in the group. + Element 1 in the group will get pins 0-3, element 2 pins 4-7, element 3 + pins 8-11 and element 4 pins 12-15. + + .. versionadded:: 2.0.0~(Plugin) + """ + self.ipcon.send_request(self, BrickletIndustrialDigitalOut4.FUNCTION_SET_SELECTED_VALUES, (selection_mask, value_mask), 'H H', '') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletIndustrialDigitalOut4.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +IndustrialDigitalOut4 = BrickletIndustrialDigitalOut4 # for backward compatibility diff --git a/tinkerforge/bricklet_industrial_quad_relay.py b/tinkerforge/bricklet_industrial_quad_relay.py new file mode 100644 index 0000000..5caf8f0 --- /dev/null +++ b/tinkerforge/bricklet_industrial_quad_relay.py @@ -0,0 +1,202 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetMonoflop = namedtuple('Monoflop', ['value', 'time', 'time_remaining']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletIndustrialQuadRelay(Device): + """ + Device for controlling up to 4 Solid State Relays + """ + + DEVICE_IDENTIFIER = 225 + + CALLBACK_MONOFLOP_DONE = 8 + + FUNCTION_SET_VALUE = 1 + FUNCTION_GET_VALUE = 2 + FUNCTION_SET_MONOFLOP = 3 + FUNCTION_GET_MONOFLOP = 4 + FUNCTION_SET_GROUP = 5 + FUNCTION_GET_GROUP = 6 + FUNCTION_GET_AVAILABLE_FOR_GROUP = 7 + FUNCTION_SET_SELECTED_VALUES = 9 + FUNCTION_GET_IDENTITY = 255 + + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletIndustrialQuadRelay.FUNCTION_SET_VALUE] = BrickletIndustrialQuadRelay.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIndustrialQuadRelay.FUNCTION_GET_VALUE] = BrickletIndustrialQuadRelay.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialQuadRelay.FUNCTION_SET_MONOFLOP] = BrickletIndustrialQuadRelay.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIndustrialQuadRelay.FUNCTION_GET_MONOFLOP] = BrickletIndustrialQuadRelay.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialQuadRelay.FUNCTION_SET_GROUP] = BrickletIndustrialQuadRelay.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIndustrialQuadRelay.FUNCTION_GET_GROUP] = BrickletIndustrialQuadRelay.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialQuadRelay.FUNCTION_GET_AVAILABLE_FOR_GROUP] = BrickletIndustrialQuadRelay.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIndustrialQuadRelay.CALLBACK_MONOFLOP_DONE] = BrickletIndustrialQuadRelay.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletIndustrialQuadRelay.FUNCTION_SET_SELECTED_VALUES] = BrickletIndustrialQuadRelay.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIndustrialQuadRelay.FUNCTION_GET_IDENTITY] = BrickletIndustrialQuadRelay.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletIndustrialQuadRelay.CALLBACK_MONOFLOP_DONE] = 'H H' + + def set_value(self, value_mask): + """ + Sets the output value with a bitmask. The bitmask + is 16 bit long, *true* refers to a closed relay and *false* refers to + an open relay. + + For example: The value 0b0000000000000011 will close the relay + of pins 0-1 and open the other pins. + + If no groups are used (see :func:`SetGroup`), the pins correspond to the + markings on the Quad Relay Bricklet. + + If groups are used, the pins correspond to the element in the group. + Element 1 in the group will get pins 0-3, element 2 pins 4-7, element 3 + pins 8-11 and element 4 pins 12-15. + """ + self.ipcon.send_request(self, BrickletIndustrialQuadRelay.FUNCTION_SET_VALUE, (value_mask,), 'H', '') + + def get_value(self): + """ + Returns the bitmask as set by :func:`SetValue`. + """ + return self.ipcon.send_request(self, BrickletIndustrialQuadRelay.FUNCTION_GET_VALUE, (), '', 'H') + + def set_monoflop(self, selection_mask, value_mask, time): + """ + Configures a monoflop of the pins specified by the first parameter + bitmask. + + The second parameter is a bitmask with the desired value of the specified + pins (*true* means relay closed and *false* means relay open). + + The third parameter indicates the time (in ms) that the pins should hold + the value. + + If this function is called with the parameters + ((1 << 0) | (1 << 3), (1 << 0), 1500): + Pin 0 will close and pin 3 will open. In 1.5s pin 0 will open and pin + 3 will close again. + + A monoflop can be used as a fail-safe mechanism. For example: Lets assume you + have a RS485 bus and a Quad Relay Bricklet connected to one of the slave + stacks. You can now call this function every second, with a time parameter + of two seconds and pin 0 closed. Pin 0 will be closed all the time. If now + the RS485 connection is lost, then pin 0 will be opened in at most two seconds. + """ + self.ipcon.send_request(self, BrickletIndustrialQuadRelay.FUNCTION_SET_MONOFLOP, (selection_mask, value_mask, time), 'H H I', '') + + def get_monoflop(self, pin): + """ + Returns (for the given pin) the current value and the time as set by + :func:`SetMonoflop` as well as the remaining time until the value flips. + + If the timer is not running currently, the remaining time will be returned + as 0. + """ + return GetMonoflop(*self.ipcon.send_request(self, BrickletIndustrialQuadRelay.FUNCTION_GET_MONOFLOP, (pin,), 'B', 'H I I')) + + def set_group(self, group): + """ + Sets a group of Quad Relay Bricklets that should work together. You can + find Bricklets that can be grouped together with :func:`GetAvailableForGroup`. + + The group consists of 4 elements. Element 1 in the group will get pins 0-3, + element 2 pins 4-7, element 3 pins 8-11 and element 4 pins 12-15. + + Each element can either be one of the ports ('a' to 'd') or 'n' if it should + not be used. + + For example: If you have two Quad Relay Bricklets connected to port A and + port B respectively, you could call with "['a', 'b', 'n', 'n']". + + Now the pins on the Quad Relay on port A are assigned to 0-3 and the + pins on the Quad Relay on port B are assigned to 4-7. It is now possible + to call :func:`SetValue` and control two Bricklets at the same time. + """ + self.ipcon.send_request(self, BrickletIndustrialQuadRelay.FUNCTION_SET_GROUP, (group,), '4c', '') + + def get_group(self): + """ + Returns the group as set by :func:`SetGroup` + """ + return self.ipcon.send_request(self, BrickletIndustrialQuadRelay.FUNCTION_GET_GROUP, (), '', '4c') + + def get_available_for_group(self): + """ + Returns a bitmask of ports that are available for grouping. For example the + value 0b0101 means: Port *A* and Port *C* are connected to Bricklets that + can be grouped together. + """ + return self.ipcon.send_request(self, BrickletIndustrialQuadRelay.FUNCTION_GET_AVAILABLE_FOR_GROUP, (), '', 'B') + + def set_selected_values(self, selection_mask, value_mask): + """ + Sets the output value with a bitmask, according to the selction mask. + The bitmask is 16 bit long, *true* refers to a closed relay and + *false* refers to an open relay. + + For example: The values 00b0000000000000011, b0000000000000001 will close + the relay of pin 0, open the relay of pin 1 and leave the others untouched. + + If no groups are used (see :func:`SetGroup`), the pins correspond to the + markings on the Quad Relay Bricklet. + + If groups are used, the pins correspond to the element in the group. + Element 1 in the group will get pins 0-3, element 2 pins 4-7, element 3 + pins 8-11 and element 4 pins 12-15. + + .. versionadded:: 2.0.0~(Plugin) + """ + self.ipcon.send_request(self, BrickletIndustrialQuadRelay.FUNCTION_SET_SELECTED_VALUES, (selection_mask, value_mask), 'H H', '') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletIndustrialQuadRelay.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +IndustrialQuadRelay = BrickletIndustrialQuadRelay # for backward compatibility diff --git a/tinkerforge/bricklet_io16.py b/tinkerforge/bricklet_io16.py new file mode 100644 index 0000000..355ec7e --- /dev/null +++ b/tinkerforge/bricklet_io16.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetPortConfiguration = namedtuple('PortConfiguration', ['direction_mask', 'value_mask']) +GetPortMonoflop = namedtuple('PortMonoflop', ['value', 'time', 'time_remaining']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletIO16(Device): + """ + Device for controlling up to 16 general purpose input/output pins + """ + + DEVICE_IDENTIFIER = 28 + + CALLBACK_INTERRUPT = 9 + CALLBACK_MONOFLOP_DONE = 12 + + FUNCTION_SET_PORT = 1 + FUNCTION_GET_PORT = 2 + FUNCTION_SET_PORT_CONFIGURATION = 3 + FUNCTION_GET_PORT_CONFIGURATION = 4 + FUNCTION_SET_DEBOUNCE_PERIOD = 5 + FUNCTION_GET_DEBOUNCE_PERIOD = 6 + FUNCTION_SET_PORT_INTERRUPT = 7 + FUNCTION_GET_PORT_INTERRUPT = 8 + FUNCTION_SET_PORT_MONOFLOP = 10 + FUNCTION_GET_PORT_MONOFLOP = 11 + FUNCTION_SET_SELECTED_VALUES = 13 + FUNCTION_GET_IDENTITY = 255 + + DIRECTION_IN = 'i' + DIRECTION_OUT = 'o' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletIO16.FUNCTION_SET_PORT] = BrickletIO16.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIO16.FUNCTION_GET_PORT] = BrickletIO16.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIO16.FUNCTION_SET_PORT_CONFIGURATION] = BrickletIO16.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIO16.FUNCTION_GET_PORT_CONFIGURATION] = BrickletIO16.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIO16.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletIO16.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletIO16.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletIO16.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIO16.FUNCTION_SET_PORT_INTERRUPT] = BrickletIO16.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletIO16.FUNCTION_GET_PORT_INTERRUPT] = BrickletIO16.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIO16.CALLBACK_INTERRUPT] = BrickletIO16.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletIO16.FUNCTION_SET_PORT_MONOFLOP] = BrickletIO16.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIO16.FUNCTION_GET_PORT_MONOFLOP] = BrickletIO16.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIO16.CALLBACK_MONOFLOP_DONE] = BrickletIO16.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletIO16.FUNCTION_SET_SELECTED_VALUES] = BrickletIO16.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIO16.FUNCTION_GET_IDENTITY] = BrickletIO16.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletIO16.CALLBACK_INTERRUPT] = 'c B B' + self.callback_formats[BrickletIO16.CALLBACK_MONOFLOP_DONE] = 'c B B' + + def set_port(self, port, value_mask): + """ + Sets the output value (high or low) for a port ("a" or "b") with a bitmask. + The bitmask is 8 bit long, *true* refers to high and *false* refers to low. + + For example: The value 0b00001111 will turn the pins 0-3 high and the + pins 4-7 low for the specified port. + + .. note:: + This function does nothing for pins that are configured as input. + Pull-up resistors can be switched on with :func:`SetPortConfiguration`. + """ + self.ipcon.send_request(self, BrickletIO16.FUNCTION_SET_PORT, (port, value_mask), 'c B', '') + + def get_port(self, port): + """ + Returns a bitmask of the values that are currently measured on the + specified port. This function works if the pin is configured to input + as well as if it is configured to output. + """ + return self.ipcon.send_request(self, BrickletIO16.FUNCTION_GET_PORT, (port,), 'c', 'B') + + def set_port_configuration(self, port, selection_mask, direction, value): + """ + Configures the value and direction of a specified port. Possible directions + are "i" and "o" for input and output. + + If the direction is configured as output, the value is either high or low + (set as *true* or *false*). + + If the direction is configured as input, the value is either pull-up or + default (set as *true* or *false*). + + For example: + + * ("a", 0xFF, 'i', true) will set all pins of port a as input pull-up. + * ("a", 128, 'i', false) will set pin 7 of port a as input default (floating if nothing is connected). + * ("b", 3, 'o', false) will set pins 0 and 1 of port b as output low. + * ("b", 4, 'o', true) will set pin 2 of port b as output high. + """ + self.ipcon.send_request(self, BrickletIO16.FUNCTION_SET_PORT_CONFIGURATION, (port, selection_mask, direction, value), 'c B c ?', '') + + def get_port_configuration(self, port): + """ + Returns a direction bitmask and a value bitmask for the specified port. + + For example: A return value of 0b00001111 and 0b00110011 for + direction and value means that: + + * pins 0 and 1 are configured as input pull-up, + * pins 2 and 3 are configured as input default, + * pins 4 and 5 are configured as output high + * and pins 6 and 7 are configured as output low. + """ + return GetPortConfiguration(*self.ipcon.send_request(self, BrickletIO16.FUNCTION_GET_PORT_CONFIGURATION, (port,), 'c', 'B B')) + + def set_debounce_period(self, debounce): + """ + Sets the debounce period of the :func:`Interrupt` callback in ms. + + For example: If you set this value to 100, you will get the interrupt + maximal every 100ms. This is necessary if something that bounces is + connected to the IO-16 Bricklet, such as a button. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletIO16.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletIO16.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def set_port_interrupt(self, port, interrupt_mask): + """ + Sets the pins on which an interrupt is activated with a bitmask. + Interrupts are triggered on changes of the voltage level of the pin, + i.e. changes from high to low and low to high. + + For example: ('a', 129) will enable the interrupt for pins 0 and 7 of + port a. + + The interrupt is delivered with the callback :func:`Interrupt`. + """ + self.ipcon.send_request(self, BrickletIO16.FUNCTION_SET_PORT_INTERRUPT, (port, interrupt_mask), 'c B', '') + + def get_port_interrupt(self, port): + """ + Returns the interrupt bitmask for the specified port as set by + :func:`SetPortInterrupt`. + """ + return self.ipcon.send_request(self, BrickletIO16.FUNCTION_GET_PORT_INTERRUPT, (port,), 'c', 'B') + + def set_port_monoflop(self, port, selection_mask, value_mask, time): + """ + Configures a monoflop of the pins specified by the second parameter as 8 bit + long bitmask. The specified pins must be configured for output. Non-output + pins will be ignored. + + The third parameter is a bitmask with the desired value of the specified + output pins (*true* means high and *false* means low). + + The forth parameter indicates the time (in ms) that the pins should hold + the value. + + If this function is called with the parameters ('a', (1 << 0) | (1 << 3), (1 << 0), 1500): + Pin 0 will get high and pin 3 will get low on port 'a'. In 1.5s pin 0 will get + low and pin 3 will get high again. + + A monoflop can be used as a fail-safe mechanism. For example: Lets assume you + have a RS485 bus and an IO-16 Bricklet connected to one of the slave + stacks. You can now call this function every second, with a time parameter + of two seconds and pin 0 set to high. Pin 0 will be high all the time. If now + the RS485 connection is lost, then pin 0 will get low in at most two seconds. + + .. versionadded:: 1.1.2~(Plugin) + """ + self.ipcon.send_request(self, BrickletIO16.FUNCTION_SET_PORT_MONOFLOP, (port, selection_mask, value_mask, time), 'c B B I', '') + + def get_port_monoflop(self, port, pin): + """ + Returns (for the given pin) the current value and the time as set by + :func:`SetPortMonoflop` as well as the remaining time until the value flips. + + If the timer is not running currently, the remaining time will be returned + as 0. + + .. versionadded:: 1.1.2~(Plugin) + """ + return GetPortMonoflop(*self.ipcon.send_request(self, BrickletIO16.FUNCTION_GET_PORT_MONOFLOP, (port, pin), 'c B', 'B I I')) + + def set_selected_values(self, port, selection_mask, value_mask): + """ + Sets the output value (high or low) for a port ("a" or "b" with a bitmask, + according to the selction mask. The bitmask is 4 bit long, *true* refers + to high and *false* refers to low. + + For example: The values 0b11000000, 0b10000000 will turn pin 7 high and + pin 6 low, pins 0-6 will remain untouched. + + .. note:: + This function does nothing for pins that are configured as input. + Pull-up resistors can be switched on with :func:`SetConfiguration`. + + .. versionadded:: 2.0.0~(Plugin) + """ + self.ipcon.send_request(self, BrickletIO16.FUNCTION_SET_SELECTED_VALUES, (port, selection_mask, value_mask), 'c B B', '') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletIO16.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +IO16 = BrickletIO16 # for backward compatibility diff --git a/tinkerforge/bricklet_io4.py b/tinkerforge/bricklet_io4.py new file mode 100644 index 0000000..13128f5 --- /dev/null +++ b/tinkerforge/bricklet_io4.py @@ -0,0 +1,250 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetConfiguration = namedtuple('Configuration', ['direction_mask', 'value_mask']) +GetMonoflop = namedtuple('Monoflop', ['value', 'time', 'time_remaining']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletIO4(Device): + """ + Device for controlling up to 4 general purpose input/output pins + """ + + DEVICE_IDENTIFIER = 29 + + CALLBACK_INTERRUPT = 9 + CALLBACK_MONOFLOP_DONE = 12 + + FUNCTION_SET_VALUE = 1 + FUNCTION_GET_VALUE = 2 + FUNCTION_SET_CONFIGURATION = 3 + FUNCTION_GET_CONFIGURATION = 4 + FUNCTION_SET_DEBOUNCE_PERIOD = 5 + FUNCTION_GET_DEBOUNCE_PERIOD = 6 + FUNCTION_SET_INTERRUPT = 7 + FUNCTION_GET_INTERRUPT = 8 + FUNCTION_SET_MONOFLOP = 10 + FUNCTION_GET_MONOFLOP = 11 + FUNCTION_SET_SELECTED_VALUES = 13 + FUNCTION_GET_IDENTITY = 255 + + DIRECTION_IN = 'i' + DIRECTION_OUT = 'o' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletIO4.FUNCTION_SET_VALUE] = BrickletIO4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIO4.FUNCTION_GET_VALUE] = BrickletIO4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIO4.FUNCTION_SET_CONFIGURATION] = BrickletIO4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIO4.FUNCTION_GET_CONFIGURATION] = BrickletIO4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIO4.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletIO4.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletIO4.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletIO4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIO4.FUNCTION_SET_INTERRUPT] = BrickletIO4.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletIO4.FUNCTION_GET_INTERRUPT] = BrickletIO4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIO4.CALLBACK_INTERRUPT] = BrickletIO4.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletIO4.FUNCTION_SET_MONOFLOP] = BrickletIO4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIO4.FUNCTION_GET_MONOFLOP] = BrickletIO4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletIO4.CALLBACK_MONOFLOP_DONE] = BrickletIO4.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletIO4.FUNCTION_SET_SELECTED_VALUES] = BrickletIO4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletIO4.FUNCTION_GET_IDENTITY] = BrickletIO4.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletIO4.CALLBACK_INTERRUPT] = 'B B' + self.callback_formats[BrickletIO4.CALLBACK_MONOFLOP_DONE] = 'B B' + + def set_value(self, value_mask): + """ + Sets the output value (high or low) with a bitmask. The bitmask + is 4 bit long, *true* refers to high and *false* refers to low. + + For example: The value 0b0011 will turn the pins 0-1 high and the + pins 2-3 low. + + .. note:: + This function does nothing for pins that are configured as input. + Pull-up resistors can be switched on with :func:`SetConfiguration`. + """ + self.ipcon.send_request(self, BrickletIO4.FUNCTION_SET_VALUE, (value_mask,), 'B', '') + + def get_value(self): + """ + Returns a bitmask of the values that are currently measured. + This function works if the pin is configured to input + as well as if it is configured to output. + """ + return self.ipcon.send_request(self, BrickletIO4.FUNCTION_GET_VALUE, (), '', 'B') + + def set_configuration(self, selection_mask, direction, value): + """ + Configures the value and direction of the specified pins. Possible directions + are "i" and "o" for input and output. + + If the direction is configured as output, the value is either high or low + (set as *true* or *false*). + + If the direction is configured as input, the value is either pull-up or + default (set as *true* or *false*). + + For example: + + * (15, 'i', true) will set all pins of as input pull-up. + * (8, 'i', false) will set pin 3 of as input default (floating if nothing is connected). + * (3, 'o', false) will set pins 0 and 1 as output low. + * (4, 'o', true) will set pin 2 of as output high. + """ + self.ipcon.send_request(self, BrickletIO4.FUNCTION_SET_CONFIGURATION, (selection_mask, direction, value), 'B c ?', '') + + def get_configuration(self): + """ + Returns a value bitmask and a direction bitmask. + + For example: A return value of 0b0011 and 0b0101 for + direction and value means that: + + * pin 0 is configured as input pull-up, + * pin 1 is configured as input default, + * pin 2 is configured as output high + * and pin 3 is are configured as output low. + """ + return GetConfiguration(*self.ipcon.send_request(self, BrickletIO4.FUNCTION_GET_CONFIGURATION, (), '', 'B B')) + + def set_debounce_period(self, debounce): + """ + Sets the debounce period of the :func:`Interrupt` callback in ms. + + For example: If you set this value to 100, you will get the interrupt + maximal every 100ms. This is necessary if something that bounces is + connected to the IO-4 Bricklet, such as a button. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletIO4.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletIO4.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def set_interrupt(self, interrupt_mask): + """ + Sets the pins on which an interrupt is activated with a bitmask. + Interrupts are triggered on changes of the voltage level of the pin, + i.e. changes from high to low and low to high. + + For example: An interrupt bitmask of 9 will enable the interrupt for + pins 0 and 3. + + The interrupt is delivered with the callback :func:`Interrupt`. + """ + self.ipcon.send_request(self, BrickletIO4.FUNCTION_SET_INTERRUPT, (interrupt_mask,), 'B', '') + + def get_interrupt(self): + """ + Returns the interrupt bitmask as set by :func:`SetInterrupt`. + """ + return self.ipcon.send_request(self, BrickletIO4.FUNCTION_GET_INTERRUPT, (), '', 'B') + + def set_monoflop(self, selection_mask, value_mask, time): + """ + Configures a monoflop of the pins specified by the first parameter as 4 bit + long bitmask. The specified pins must be configured for output. Non-output + pins will be ignored. + + The second parameter is a bitmask with the desired value of the specified + output pins (*true* means high and *false* means low). + + The third parameter indicates the time (in ms) that the pins should hold + the value. + + If this function is called with the parameters ((1 << 0) | (1 << 3), (1 << 0), 1500): + Pin 0 will get high and pin 3 will get low. In 1.5s pin 0 will get low and pin + 3 will get high again. + + A monoflop can be used as a fail-safe mechanism. For example: Lets assume you + have a RS485 bus and an IO-4 Bricklet connected to one of the slave + stacks. You can now call this function every second, with a time parameter + of two seconds and pin 0 set to high. Pin 0 will be high all the time. If now + the RS485 connection is lost, then pin 0 will get low in at most two seconds. + + .. versionadded:: 1.1.1~(Plugin) + """ + self.ipcon.send_request(self, BrickletIO4.FUNCTION_SET_MONOFLOP, (selection_mask, value_mask, time), 'B B I', '') + + def get_monoflop(self, pin): + """ + Returns (for the given pin) the current value and the time as set by + :func:`SetMonoflop` as well as the remaining time until the value flips. + + If the timer is not running currently, the remaining time will be returned + as 0. + + .. versionadded:: 1.1.1~(Plugin) + """ + return GetMonoflop(*self.ipcon.send_request(self, BrickletIO4.FUNCTION_GET_MONOFLOP, (pin,), 'B', 'B I I')) + + def set_selected_values(self, selection_mask, value_mask): + """ + Sets the output value (high or low) with a bitmask, according to + the selction mask. The bitmask is 4 bit long, *true* refers to high + and *false* refers to low. + + For example: The values 0b0110, 0b0011 will turn pin 2 high and + pin 1 low, pin 0 and 3 will remain untouched. + + .. note:: + This function does nothing for pins that are configured as input. + Pull-up resistors can be switched on with :func:`SetConfiguration`. + + .. versionadded:: 2.0.0~(Plugin) + """ + self.ipcon.send_request(self, BrickletIO4.FUNCTION_SET_SELECTED_VALUES, (selection_mask, value_mask), 'B B', '') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletIO4.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +IO4 = BrickletIO4 # for backward compatibility diff --git a/tinkerforge/bricklet_joystick.py b/tinkerforge/bricklet_joystick.py new file mode 100644 index 0000000..fba2636 --- /dev/null +++ b/tinkerforge/bricklet_joystick.py @@ -0,0 +1,284 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetPosition = namedtuple('Position', ['x', 'y']) +GetAnalogValue = namedtuple('AnalogValue', ['x', 'y']) +GetPositionCallbackThreshold = namedtuple('PositionCallbackThreshold', ['option', 'min_x', 'max_x', 'min_y', 'max_y']) +GetAnalogValueCallbackThreshold = namedtuple('AnalogValueCallbackThreshold', ['option', 'min_x', 'max_x', 'min_y', 'max_y']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletJoystick(Device): + """ + Dual-Axis Joystick with Button + """ + + DEVICE_IDENTIFIER = 210 + + CALLBACK_POSITION = 15 + CALLBACK_ANALOG_VALUE = 16 + CALLBACK_POSITION_REACHED = 17 + CALLBACK_ANALOG_VALUE_REACHED = 18 + CALLBACK_PRESSED = 19 + CALLBACK_RELEASED = 20 + + FUNCTION_GET_POSITION = 1 + FUNCTION_IS_PRESSED = 2 + FUNCTION_GET_ANALOG_VALUE = 3 + FUNCTION_CALIBRATE = 4 + FUNCTION_SET_POSITION_CALLBACK_PERIOD = 5 + FUNCTION_GET_POSITION_CALLBACK_PERIOD = 6 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD = 7 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD = 8 + FUNCTION_SET_POSITION_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_POSITION_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD = 11 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD = 12 + FUNCTION_SET_DEBOUNCE_PERIOD = 13 + FUNCTION_GET_DEBOUNCE_PERIOD = 14 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletJoystick.FUNCTION_GET_POSITION] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletJoystick.FUNCTION_IS_PRESSED] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletJoystick.FUNCTION_GET_ANALOG_VALUE] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletJoystick.FUNCTION_CALIBRATE] = BrickletJoystick.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletJoystick.FUNCTION_SET_POSITION_CALLBACK_PERIOD] = BrickletJoystick.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletJoystick.FUNCTION_GET_POSITION_CALLBACK_PERIOD] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletJoystick.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletJoystick.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletJoystick.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletJoystick.FUNCTION_SET_POSITION_CALLBACK_THRESHOLD] = BrickletJoystick.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletJoystick.FUNCTION_GET_POSITION_CALLBACK_THRESHOLD] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletJoystick.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletJoystick.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletJoystick.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletJoystick.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletJoystick.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletJoystick.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletJoystick.CALLBACK_POSITION] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletJoystick.CALLBACK_ANALOG_VALUE] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletJoystick.CALLBACK_POSITION_REACHED] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletJoystick.CALLBACK_ANALOG_VALUE_REACHED] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletJoystick.CALLBACK_PRESSED] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletJoystick.CALLBACK_RELEASED] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletJoystick.FUNCTION_GET_IDENTITY] = BrickletJoystick.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletJoystick.CALLBACK_POSITION] = 'h h' + self.callback_formats[BrickletJoystick.CALLBACK_ANALOG_VALUE] = 'H H' + self.callback_formats[BrickletJoystick.CALLBACK_POSITION_REACHED] = 'h h' + self.callback_formats[BrickletJoystick.CALLBACK_ANALOG_VALUE_REACHED] = 'H H' + self.callback_formats[BrickletJoystick.CALLBACK_PRESSED] = '' + self.callback_formats[BrickletJoystick.CALLBACK_RELEASED] = '' + + def get_position(self): + """ + Returns the position of the Joystick. The value ranges between -100 and + 100 for both axis. The middle position of the joystick is x=0, y=0. The + returned values are averaged and calibrated (see :func:`Calibrate`). + + If you want to get the position periodically, it is recommended to use the + callback :func:`Position` and set the period with + :func:`SetPositionCallbackPeriod`. + """ + return GetPosition(*self.ipcon.send_request(self, BrickletJoystick.FUNCTION_GET_POSITION, (), '', 'h h')) + + def is_pressed(self): + """ + Returns *true* if the button is pressed and *false* otherwise. + + It is recommended to use the :func:`Pressed` and :func:`Released` callbacks + to handle the button. + """ + return self.ipcon.send_request(self, BrickletJoystick.FUNCTION_IS_PRESSED, (), '', '?') + + def get_analog_value(self): + """ + Returns the values as read by a 12-bit analog-to-digital converter. + The values are between 0 and 4095 for both axis. + + .. note:: + The values returned by :func:`GetPosition` are averaged over several samples + to yield less noise, while :func:`GetAnalogValue` gives back raw + unfiltered analog values. The only reason to use :func:`GetAnalogValue` is, + if you need the full resolution of the analog-to-digital converter. + + If you want the analog values periodically, it is recommended to use the + callback :func:`AnalogValue` and set the period with + :func:`SetAnalogValueCallbackPeriod`. + """ + return GetAnalogValue(*self.ipcon.send_request(self, BrickletJoystick.FUNCTION_GET_ANALOG_VALUE, (), '', 'H H')) + + def calibrate(self): + """ + Calibrates the middle position of the Joystick. If your Joystick Bricklet + does not return x=0 and y=0 in the middle position, call this function + while the Joystick is standing still in the middle position. + + The resulting calibration will be saved on the EEPROM of the Joystick + Bricklet, thus you only have to calibrate it once. + """ + self.ipcon.send_request(self, BrickletJoystick.FUNCTION_CALIBRATE, (), '', '') + + def set_position_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Position` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Position` is only triggered if the position has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletJoystick.FUNCTION_SET_POSITION_CALLBACK_PERIOD, (period,), 'I', '') + + def get_position_callback_period(self): + """ + Returns the period as set by :func:`SetPositionCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletJoystick.FUNCTION_GET_POSITION_CALLBACK_PERIOD, (), '', 'I') + + def set_analog_value_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AnalogValue` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AnalogValue` is only triggered if the analog values have changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletJoystick.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_analog_value_callback_period(self): + """ + Returns the period as set by :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletJoystick.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD, (), '', 'I') + + def set_position_callback_threshold(self, option, min_x, max_x, min_y, max_y): + """ + Sets the thresholds for the :func:`PositionReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the position is *outside* the min and max values" + "'i'", "Callback is triggered when the position is *inside* the min and max values" + "'<'", "Callback is triggered when the position is smaller than the min values (max is ignored)" + "'>'", "Callback is triggered when the position is greater than the min values (max is ignored)" + + The default value is ('x', 0, 0, 0, 0). + """ + self.ipcon.send_request(self, BrickletJoystick.FUNCTION_SET_POSITION_CALLBACK_THRESHOLD, (option, min_x, max_x, min_y, max_y), 'c h h h h', '') + + def get_position_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetPositionCallbackThreshold`. + """ + return GetPositionCallbackThreshold(*self.ipcon.send_request(self, BrickletJoystick.FUNCTION_GET_POSITION_CALLBACK_THRESHOLD, (), '', 'c h h h h')) + + def set_analog_value_callback_threshold(self, option, min_x, max_x, min_y, max_y): + """ + Sets the thresholds for the :func:`AnalogValueReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the analog values are *outside* the min and max values" + "'i'", "Callback is triggered when the analog values are *inside* the min and max values" + "'<'", "Callback is triggered when the analog values are smaller than the min values (max is ignored)" + "'>'", "Callback is triggered when the analog values are greater than the min values (max is ignored)" + + The default value is ('x', 0, 0, 0, 0). + """ + self.ipcon.send_request(self, BrickletJoystick.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD, (option, min_x, max_x, min_y, max_y), 'c H H H H', '') + + def get_analog_value_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAnalogValueCallbackThreshold`. + """ + return GetAnalogValueCallbackThreshold(*self.ipcon.send_request(self, BrickletJoystick.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD, (), '', 'c H H H H')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`PositionReached`, :func:`AnalogValueReached` + + are triggered, if the thresholds + + :func:`SetPositionCallbackThreshold`, :func:`SetAnalogValueCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletJoystick.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletJoystick.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletJoystick.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +Joystick = BrickletJoystick # for backward compatibility diff --git a/tinkerforge/bricklet_lcd_16x2.py b/tinkerforge/bricklet_lcd_16x2.py new file mode 100644 index 0000000..46dbc04 --- /dev/null +++ b/tinkerforge/bricklet_lcd_16x2.py @@ -0,0 +1,200 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetConfig = namedtuple('Config', ['cursor', 'blinking']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletLCD16x2(Device): + """ + Device for controlling a LCD with 2 lines a 16 characters + """ + + DEVICE_IDENTIFIER = 211 + + CALLBACK_BUTTON_PRESSED = 9 + CALLBACK_BUTTON_RELEASED = 10 + + FUNCTION_WRITE_LINE = 1 + FUNCTION_CLEAR_DISPLAY = 2 + FUNCTION_BACKLIGHT_ON = 3 + FUNCTION_BACKLIGHT_OFF = 4 + FUNCTION_IS_BACKLIGHT_ON = 5 + FUNCTION_SET_CONFIG = 6 + FUNCTION_GET_CONFIG = 7 + FUNCTION_IS_BUTTON_PRESSED = 8 + FUNCTION_SET_CUSTOM_CHARACTER = 11 + FUNCTION_GET_CUSTOM_CHARACTER = 12 + FUNCTION_GET_IDENTITY = 255 + + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletLCD16x2.FUNCTION_WRITE_LINE] = BrickletLCD16x2.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD16x2.FUNCTION_CLEAR_DISPLAY] = BrickletLCD16x2.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD16x2.FUNCTION_BACKLIGHT_ON] = BrickletLCD16x2.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD16x2.FUNCTION_BACKLIGHT_OFF] = BrickletLCD16x2.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD16x2.FUNCTION_IS_BACKLIGHT_ON] = BrickletLCD16x2.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLCD16x2.FUNCTION_SET_CONFIG] = BrickletLCD16x2.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD16x2.FUNCTION_GET_CONFIG] = BrickletLCD16x2.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLCD16x2.FUNCTION_IS_BUTTON_PRESSED] = BrickletLCD16x2.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLCD16x2.CALLBACK_BUTTON_PRESSED] = BrickletLCD16x2.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletLCD16x2.CALLBACK_BUTTON_RELEASED] = BrickletLCD16x2.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletLCD16x2.FUNCTION_SET_CUSTOM_CHARACTER] = BrickletLCD16x2.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD16x2.FUNCTION_GET_CUSTOM_CHARACTER] = BrickletLCD16x2.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLCD16x2.FUNCTION_GET_IDENTITY] = BrickletLCD16x2.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletLCD16x2.CALLBACK_BUTTON_PRESSED] = 'B' + self.callback_formats[BrickletLCD16x2.CALLBACK_BUTTON_RELEASED] = 'B' + + def write_line(self, line, position, text): + """ + Writes text to a specific line (0 to 1) with a specific position + (0 to 15). The text can have a maximum of 16 characters. + + For example: (0, 5, "Hello") will write *Hello* in the middle of the + first line of the display. + + The display uses a special charset that includes all ASCII characters except + backslash and tilde. The LCD charset also includes several other non-ASCII characters, see + the `charset specification `__ + for details. The Unicode example above shows how to specify non-ASCII characters + and how to translate from Unicode to the LCD charset. + """ + self.ipcon.send_request(self, BrickletLCD16x2.FUNCTION_WRITE_LINE, (line, position, text), 'B B 16s', '') + + def clear_display(self): + """ + Deletes all characters from the display. + """ + self.ipcon.send_request(self, BrickletLCD16x2.FUNCTION_CLEAR_DISPLAY, (), '', '') + + def backlight_on(self): + """ + Turns the backlight on. + """ + self.ipcon.send_request(self, BrickletLCD16x2.FUNCTION_BACKLIGHT_ON, (), '', '') + + def backlight_off(self): + """ + Turns the backlight off. + """ + self.ipcon.send_request(self, BrickletLCD16x2.FUNCTION_BACKLIGHT_OFF, (), '', '') + + def is_backlight_on(self): + """ + Returns *true* if the backlight is on and *false* otherwise. + """ + return self.ipcon.send_request(self, BrickletLCD16x2.FUNCTION_IS_BACKLIGHT_ON, (), '', '?') + + def set_config(self, cursor, blinking): + """ + Configures if the cursor (shown as "_") should be visible and if it + should be blinking (shown as a blinking block). The cursor position + is one character behind the the last text written with + :func:`WriteLine`. + + The default is (false, false). + """ + self.ipcon.send_request(self, BrickletLCD16x2.FUNCTION_SET_CONFIG, (cursor, blinking), '? ?', '') + + def get_config(self): + """ + Returns the configuration as set by :func:`SetConfig`. + """ + return GetConfig(*self.ipcon.send_request(self, BrickletLCD16x2.FUNCTION_GET_CONFIG, (), '', '? ?')) + + def is_button_pressed(self, button): + """ + Returns *true* if the button (0 to 2) is pressed. If you want to react + on button presses and releases it is recommended to use the + :func:`ButtonPressed` and :func:`ButtonReleased` callbacks. + """ + return self.ipcon.send_request(self, BrickletLCD16x2.FUNCTION_IS_BUTTON_PRESSED, (button,), 'B', '?') + + def set_custom_character(self, index, character): + """ + The LCD 16x2 Bricklet can store up to 8 custom characters. The characters + consist of 5x8 pixels and can be addressed with the index 0-7. To describe + the pixels, the first 5 bits of 8 bytes are used. For example, to make + a custom character "H", you should transfer the following: + + * character[0] = 0b00010001 (decimal value 17) + * character[1] = 0b00010001 (decimal value 17) + * character[2] = 0b00010001 (decimal value 17) + * character[3] = 0b00011111 (decimal value 31) + * character[4] = 0b00010001 (decimal value 17) + * character[5] = 0b00010001 (decimal value 17) + * character[6] = 0b00010001 (decimal value 17) + * character[7] = 0b00000000 (decimal value 0) + + The characters can later be written with :func:`WriteLine` by using the + characters with the byte representation 8 to 15. + + You can play around with the custom characters in Brick Viewer version + >= 2.0.1. + + Custom characters are stored by the LCD in RAM, so they have to be set + after each startup. + + .. versionadded:: 2.0.1~(Plugin) + """ + self.ipcon.send_request(self, BrickletLCD16x2.FUNCTION_SET_CUSTOM_CHARACTER, (index, character), 'B 8B', '') + + def get_custom_character(self, index): + """ + Returns the custom character for a given index, as set with + :func:`SetCustomCharacter`. + + .. versionadded:: 2.0.1~(Plugin) + """ + return self.ipcon.send_request(self, BrickletLCD16x2.FUNCTION_GET_CUSTOM_CHARACTER, (index,), 'B', '8B') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletLCD16x2.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +LCD16x2 = BrickletLCD16x2 # for backward compatibility diff --git a/tinkerforge/bricklet_lcd_20x4.py b/tinkerforge/bricklet_lcd_20x4.py new file mode 100644 index 0000000..6966674 --- /dev/null +++ b/tinkerforge/bricklet_lcd_20x4.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetConfig = namedtuple('Config', ['cursor', 'blinking']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletLCD20x4(Device): + """ + Device for controlling a LCD with 4 lines a 20 characters + """ + + DEVICE_IDENTIFIER = 212 + + CALLBACK_BUTTON_PRESSED = 9 + CALLBACK_BUTTON_RELEASED = 10 + + FUNCTION_WRITE_LINE = 1 + FUNCTION_CLEAR_DISPLAY = 2 + FUNCTION_BACKLIGHT_ON = 3 + FUNCTION_BACKLIGHT_OFF = 4 + FUNCTION_IS_BACKLIGHT_ON = 5 + FUNCTION_SET_CONFIG = 6 + FUNCTION_GET_CONFIG = 7 + FUNCTION_IS_BUTTON_PRESSED = 8 + FUNCTION_SET_CUSTOM_CHARACTER = 11 + FUNCTION_GET_CUSTOM_CHARACTER = 12 + FUNCTION_GET_IDENTITY = 255 + + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletLCD20x4.FUNCTION_WRITE_LINE] = BrickletLCD20x4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD20x4.FUNCTION_CLEAR_DISPLAY] = BrickletLCD20x4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD20x4.FUNCTION_BACKLIGHT_ON] = BrickletLCD20x4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD20x4.FUNCTION_BACKLIGHT_OFF] = BrickletLCD20x4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD20x4.FUNCTION_IS_BACKLIGHT_ON] = BrickletLCD20x4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLCD20x4.FUNCTION_SET_CONFIG] = BrickletLCD20x4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD20x4.FUNCTION_GET_CONFIG] = BrickletLCD20x4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLCD20x4.FUNCTION_IS_BUTTON_PRESSED] = BrickletLCD20x4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLCD20x4.CALLBACK_BUTTON_PRESSED] = BrickletLCD20x4.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletLCD20x4.CALLBACK_BUTTON_RELEASED] = BrickletLCD20x4.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletLCD20x4.FUNCTION_SET_CUSTOM_CHARACTER] = BrickletLCD20x4.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletLCD20x4.FUNCTION_GET_CUSTOM_CHARACTER] = BrickletLCD20x4.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLCD20x4.FUNCTION_GET_IDENTITY] = BrickletLCD20x4.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletLCD20x4.CALLBACK_BUTTON_PRESSED] = 'B' + self.callback_formats[BrickletLCD20x4.CALLBACK_BUTTON_RELEASED] = 'B' + + def write_line(self, line, position, text): + """ + Writes text to a specific line (0 to 3) with a specific position + (0 to 19). The text can have a maximum of 20 characters. + + For example: (0, 7, "Hello") will write *Hello* in the middle of the + first line of the display. + + The display uses a special charset that includes all ASCII characters except + backslash and tilde. The LCD charset also includes several other non-ASCII characters, see + the `charset specification `__ + for details. The Unicode example above shows how to specify non-ASCII characters + and how to translate from Unicode to the LCD charset. + """ + self.ipcon.send_request(self, BrickletLCD20x4.FUNCTION_WRITE_LINE, (line, position, text), 'B B 20s', '') + + def clear_display(self): + """ + Deletes all characters from the display. + """ + self.ipcon.send_request(self, BrickletLCD20x4.FUNCTION_CLEAR_DISPLAY, (), '', '') + + def backlight_on(self): + """ + Turns the backlight on. + """ + self.ipcon.send_request(self, BrickletLCD20x4.FUNCTION_BACKLIGHT_ON, (), '', '') + + def backlight_off(self): + """ + Turns the backlight off. + """ + self.ipcon.send_request(self, BrickletLCD20x4.FUNCTION_BACKLIGHT_OFF, (), '', '') + + def is_backlight_on(self): + """ + Returns *true* if the backlight is on and *false* otherwise. + """ + return self.ipcon.send_request(self, BrickletLCD20x4.FUNCTION_IS_BACKLIGHT_ON, (), '', '?') + + def set_config(self, cursor, blinking): + """ + Configures if the cursor (shown as "_") should be visible and if it + should be blinking (shown as a blinking block). The cursor position + is one character behind the the last text written with + :func:`WriteLine`. + + The default is (false, false). + """ + self.ipcon.send_request(self, BrickletLCD20x4.FUNCTION_SET_CONFIG, (cursor, blinking), '? ?', '') + + def get_config(self): + """ + Returns the configuration as set by :func:`SetConfig`. + """ + return GetConfig(*self.ipcon.send_request(self, BrickletLCD20x4.FUNCTION_GET_CONFIG, (), '', '? ?')) + + def is_button_pressed(self, button): + """ + Returns *true* if the button (0 to 2 or 0 to 3 with hardware version >= 1.2) + is pressed. If you want to react + on button presses and releases it is recommended to use the + :func:`ButtonPressed` and :func:`ButtonReleased` callbacks. + """ + return self.ipcon.send_request(self, BrickletLCD20x4.FUNCTION_IS_BUTTON_PRESSED, (button,), 'B', '?') + + def set_custom_character(self, index, character): + """ + The LCD 20x4 Bricklet can store up to 8 custom characters. The characters + consist of 5x8 pixels and can be addressed with the index 0-7. To describe + the pixels, the first 5 bits of 8 bytes are used. For example, to make + a custom character "H", you should transfer the following: + + * character[0] = 0b00010001 (decimal value 17) + * character[1] = 0b00010001 (decimal value 17) + * character[2] = 0b00010001 (decimal value 17) + * character[3] = 0b00011111 (decimal value 31) + * character[4] = 0b00010001 (decimal value 17) + * character[5] = 0b00010001 (decimal value 17) + * character[6] = 0b00010001 (decimal value 17) + * character[7] = 0b00000000 (decimal value 0) + + The characters can later be written with :func:`WriteLine` by using the + characters with the byte representation 8 to 15. + + You can play around with the custom characters in Brick Viewer version + >= 2.0.1. + + Custom characters are stored by the LCD in RAM, so they have to be set + after each startup. + + .. versionadded:: 2.0.1~(Plugin) + """ + self.ipcon.send_request(self, BrickletLCD20x4.FUNCTION_SET_CUSTOM_CHARACTER, (index, character), 'B 8B', '') + + def get_custom_character(self, index): + """ + Returns the custom character for a given index, as set with + :func:`SetCustomCharacter`. + + .. versionadded:: 2.0.1~(Plugin) + """ + return self.ipcon.send_request(self, BrickletLCD20x4.FUNCTION_GET_CUSTOM_CHARACTER, (index,), 'B', '8B') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletLCD20x4.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +LCD20x4 = BrickletLCD20x4 # for backward compatibility diff --git a/tinkerforge/bricklet_linear_poti.py b/tinkerforge/bricklet_linear_poti.py new file mode 100644 index 0000000..058387b --- /dev/null +++ b/tinkerforge/bricklet_linear_poti.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetPositionCallbackThreshold = namedtuple('PositionCallbackThreshold', ['option', 'min', 'max']) +GetAnalogValueCallbackThreshold = namedtuple('AnalogValueCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletLinearPoti(Device): + """ + Device for sensing Linear Potentiometer input + """ + + DEVICE_IDENTIFIER = 213 + + CALLBACK_POSITION = 13 + CALLBACK_ANALOG_VALUE = 14 + CALLBACK_POSITION_REACHED = 15 + CALLBACK_ANALOG_VALUE_REACHED = 16 + + FUNCTION_GET_POSITION = 1 + FUNCTION_GET_ANALOG_VALUE = 2 + FUNCTION_SET_POSITION_CALLBACK_PERIOD = 3 + FUNCTION_GET_POSITION_CALLBACK_PERIOD = 4 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD = 5 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD = 6 + FUNCTION_SET_POSITION_CALLBACK_THRESHOLD = 7 + FUNCTION_GET_POSITION_CALLBACK_THRESHOLD = 8 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_DEBOUNCE_PERIOD = 11 + FUNCTION_GET_DEBOUNCE_PERIOD = 12 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletLinearPoti.FUNCTION_GET_POSITION] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLinearPoti.FUNCTION_GET_ANALOG_VALUE] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLinearPoti.FUNCTION_SET_POSITION_CALLBACK_PERIOD] = BrickletLinearPoti.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletLinearPoti.FUNCTION_GET_POSITION_CALLBACK_PERIOD] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLinearPoti.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletLinearPoti.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletLinearPoti.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLinearPoti.FUNCTION_SET_POSITION_CALLBACK_THRESHOLD] = BrickletLinearPoti.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletLinearPoti.FUNCTION_GET_POSITION_CALLBACK_THRESHOLD] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLinearPoti.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletLinearPoti.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletLinearPoti.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLinearPoti.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletLinearPoti.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletLinearPoti.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletLinearPoti.CALLBACK_POSITION] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletLinearPoti.CALLBACK_ANALOG_VALUE] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletLinearPoti.CALLBACK_POSITION_REACHED] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletLinearPoti.CALLBACK_ANALOG_VALUE_REACHED] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletLinearPoti.FUNCTION_GET_IDENTITY] = BrickletLinearPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletLinearPoti.CALLBACK_POSITION] = 'H' + self.callback_formats[BrickletLinearPoti.CALLBACK_ANALOG_VALUE] = 'H' + self.callback_formats[BrickletLinearPoti.CALLBACK_POSITION_REACHED] = 'H' + self.callback_formats[BrickletLinearPoti.CALLBACK_ANALOG_VALUE_REACHED] = 'H' + + def get_position(self): + """ + Returns the position of the Linear Potentiometer. The value is + between 0 (slider down) and 100 (slider up). + + If you want to get the position periodically, it is recommended to use the + callback :func:`Position` and set the period with + :func:`SetPositionCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_GET_POSITION, (), '', 'H') + + def get_analog_value(self): + """ + Returns the value as read by a 12-bit analog-to-digital converter. + The value is between 0 and 4095. + + .. note:: + The value returned by :func:`GetPosition` is averaged over several samples + to yield less noise, while :func:`GetAnalogValue` gives back raw + unfiltered analog values. The only reason to use :func:`GetAnalogValue` is, + if you need the full resolution of the analog-to-digital converter. + + If you want the analog value periodically, it is recommended to use the + callback :func:`AnalogValue` and set the period with + :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_GET_ANALOG_VALUE, (), '', 'H') + + def set_position_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Position` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Position` is only triggered if the position has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_SET_POSITION_CALLBACK_PERIOD, (period,), 'I', '') + + def get_position_callback_period(self): + """ + Returns the period as set by :func:`SetPositionCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_GET_POSITION_CALLBACK_PERIOD, (), '', 'I') + + def set_analog_value_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AnalogValue` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AnalogValue` is only triggered if the analog value has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_analog_value_callback_period(self): + """ + Returns the period as set by :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD, (), '', 'I') + + def set_position_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`PositionReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the position is *outside* the min and max values" + "'i'", "Callback is triggered when the position is *inside* the min and max values" + "'<'", "Callback is triggered when the position is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the position is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_SET_POSITION_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_position_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetPositionCallbackThreshold`. + """ + return GetPositionCallbackThreshold(*self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_GET_POSITION_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_analog_value_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AnalogValueReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the analog value is *outside* the min and max values" + "'i'", "Callback is triggered when the analog value is *inside* the min and max values" + "'<'", "Callback is triggered when the analog value is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the analog value is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_analog_value_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAnalogValueCallbackThreshold`. + """ + return GetAnalogValueCallbackThreshold(*self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`PositionReached`, :func:`AnalogValueReached` + + are triggered, if the thresholds + + :func:`SetPositionCallbackThreshold`, :func:`SetAnalogValueCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletLinearPoti.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +LinearPoti = BrickletLinearPoti # for backward compatibility diff --git a/tinkerforge/bricklet_piezo_buzzer.py b/tinkerforge/bricklet_piezo_buzzer.py new file mode 100644 index 0000000..dd001da --- /dev/null +++ b/tinkerforge/bricklet_piezo_buzzer.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletPiezoBuzzer(Device): + """ + Device for controlling a piezo buzzer + """ + + DEVICE_IDENTIFIER = 214 + + CALLBACK_BEEP_FINISHED = 3 + CALLBACK_MORSE_CODE_FINISHED = 4 + + FUNCTION_BEEP = 1 + FUNCTION_MORSE_CODE = 2 + FUNCTION_GET_IDENTITY = 255 + + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletPiezoBuzzer.FUNCTION_BEEP] = BrickletPiezoBuzzer.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletPiezoBuzzer.FUNCTION_MORSE_CODE] = BrickletPiezoBuzzer.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletPiezoBuzzer.CALLBACK_BEEP_FINISHED] = BrickletPiezoBuzzer.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletPiezoBuzzer.CALLBACK_MORSE_CODE_FINISHED] = BrickletPiezoBuzzer.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletPiezoBuzzer.FUNCTION_GET_IDENTITY] = BrickletPiezoBuzzer.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletPiezoBuzzer.CALLBACK_BEEP_FINISHED] = '' + self.callback_formats[BrickletPiezoBuzzer.CALLBACK_MORSE_CODE_FINISHED] = '' + + def beep(self, duration): + """ + Beeps with the duration in ms. For example: If you set a value of 1000, + the piezo buzzer will beep for one second. + """ + self.ipcon.send_request(self, BrickletPiezoBuzzer.FUNCTION_BEEP, (duration,), 'I', '') + + def morse_code(self, morse): + """ + Sets morse code that will be played by the piezo buzzer. The morse code + is given as a string consisting of "." (dot), "-" (minus) and " " (space) + for *dits*, *dahs* and *pauses*. Every other character is ignored. + + For example: If you set the string "...---...", the piezo buzzer will beep + nine times with the durations "short short short long long long short + short short". + + The maximum string size is 60. + """ + self.ipcon.send_request(self, BrickletPiezoBuzzer.FUNCTION_MORSE_CODE, (morse,), '60s', '') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletPiezoBuzzer.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +PiezoBuzzer = BrickletPiezoBuzzer # for backward compatibility diff --git a/tinkerforge/bricklet_rotary_poti.py b/tinkerforge/bricklet_rotary_poti.py new file mode 100644 index 0000000..84222a9 --- /dev/null +++ b/tinkerforge/bricklet_rotary_poti.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetPositionCallbackThreshold = namedtuple('PositionCallbackThreshold', ['option', 'min', 'max']) +GetAnalogValueCallbackThreshold = namedtuple('AnalogValueCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletRotaryPoti(Device): + """ + Device for sensing Rotary Potentiometer input + """ + + DEVICE_IDENTIFIER = 215 + + CALLBACK_POSITION = 13 + CALLBACK_ANALOG_VALUE = 14 + CALLBACK_POSITION_REACHED = 15 + CALLBACK_ANALOG_VALUE_REACHED = 16 + + FUNCTION_GET_POSITION = 1 + FUNCTION_GET_ANALOG_VALUE = 2 + FUNCTION_SET_POSITION_CALLBACK_PERIOD = 3 + FUNCTION_GET_POSITION_CALLBACK_PERIOD = 4 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD = 5 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD = 6 + FUNCTION_SET_POSITION_CALLBACK_THRESHOLD = 7 + FUNCTION_GET_POSITION_CALLBACK_THRESHOLD = 8 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_DEBOUNCE_PERIOD = 11 + FUNCTION_GET_DEBOUNCE_PERIOD = 12 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletRotaryPoti.FUNCTION_GET_POSITION] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletRotaryPoti.FUNCTION_GET_ANALOG_VALUE] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletRotaryPoti.FUNCTION_SET_POSITION_CALLBACK_PERIOD] = BrickletRotaryPoti.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletRotaryPoti.FUNCTION_GET_POSITION_CALLBACK_PERIOD] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletRotaryPoti.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletRotaryPoti.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletRotaryPoti.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletRotaryPoti.FUNCTION_SET_POSITION_CALLBACK_THRESHOLD] = BrickletRotaryPoti.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletRotaryPoti.FUNCTION_GET_POSITION_CALLBACK_THRESHOLD] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletRotaryPoti.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletRotaryPoti.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletRotaryPoti.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletRotaryPoti.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletRotaryPoti.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletRotaryPoti.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletRotaryPoti.CALLBACK_POSITION] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletRotaryPoti.CALLBACK_ANALOG_VALUE] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletRotaryPoti.CALLBACK_POSITION_REACHED] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletRotaryPoti.CALLBACK_ANALOG_VALUE_REACHED] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletRotaryPoti.FUNCTION_GET_IDENTITY] = BrickletRotaryPoti.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletRotaryPoti.CALLBACK_POSITION] = 'h' + self.callback_formats[BrickletRotaryPoti.CALLBACK_ANALOG_VALUE] = 'H' + self.callback_formats[BrickletRotaryPoti.CALLBACK_POSITION_REACHED] = 'h' + self.callback_formats[BrickletRotaryPoti.CALLBACK_ANALOG_VALUE_REACHED] = 'H' + + def get_position(self): + """ + Returns the position of the Rotary Potentiometer. The value is in degree + and between -150° (turned left) and 150° (turned right). + + If you want to get the position periodically, it is recommended to use the + callback :func:`Position` and set the period with + :func:`SetPositionCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_GET_POSITION, (), '', 'h') + + def get_analog_value(self): + """ + Returns the value as read by a 12-bit analog-to-digital converter. + The value is between 0 and 4095. + + .. note:: + The value returned by :func:`GetPosition` is averaged over several samples + to yield less noise, while :func:`GetAnalogValue` gives back raw + unfiltered analog values. The only reason to use :func:`GetAnalogValue` is, + if you need the full resolution of the analog-to-digital converter. + + If you want the analog value periodically, it is recommended to use the + callback :func:`AnalogValue` and set the period with + :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_GET_ANALOG_VALUE, (), '', 'H') + + def set_position_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Position` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Position` is only triggered if the position has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_SET_POSITION_CALLBACK_PERIOD, (period,), 'I', '') + + def get_position_callback_period(self): + """ + Returns the period as set by :func:`SetPositionCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_GET_POSITION_CALLBACK_PERIOD, (), '', 'I') + + def set_analog_value_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AnalogValue` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AnalogValue` is only triggered if the analog value has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_analog_value_callback_period(self): + """ + Returns the period as set by :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD, (), '', 'I') + + def set_position_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`PositionReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the position is *outside* the min and max values" + "'i'", "Callback is triggered when the position is *inside* the min and max values" + "'<'", "Callback is triggered when the position is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the position is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_SET_POSITION_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_position_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetPositionCallbackThreshold`. + """ + return GetPositionCallbackThreshold(*self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_GET_POSITION_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_analog_value_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AnalogValueReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the analog value is *outside* the min and max values" + "'i'", "Callback is triggered when the analog value is *inside* the min and max values" + "'<'", "Callback is triggered when the analog value is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the analog value is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_analog_value_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAnalogValueCallbackThreshold`. + """ + return GetAnalogValueCallbackThreshold(*self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`PositionReached`, :func:`AnalogValueReached` + + are triggered, if the thresholds + + :func:`SetPositionCallbackThreshold`, :func:`SetAnalogValueCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletRotaryPoti.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +RotaryPoti = BrickletRotaryPoti # for backward compatibility diff --git a/tinkerforge/bricklet_temperature.py b/tinkerforge/bricklet_temperature.py new file mode 100644 index 0000000..c928db1 --- /dev/null +++ b/tinkerforge/bricklet_temperature.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetTemperatureCallbackThreshold = namedtuple('TemperatureCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletTemperature(Device): + """ + Device for sensing Temperature + """ + + DEVICE_IDENTIFIER = 216 + + CALLBACK_TEMPERATURE = 8 + CALLBACK_TEMPERATURE_REACHED = 9 + + FUNCTION_GET_TEMPERATURE = 1 + FUNCTION_SET_TEMPERATURE_CALLBACK_PERIOD = 2 + FUNCTION_GET_TEMPERATURE_CALLBACK_PERIOD = 3 + FUNCTION_SET_TEMPERATURE_CALLBACK_THRESHOLD = 4 + FUNCTION_GET_TEMPERATURE_CALLBACK_THRESHOLD = 5 + FUNCTION_SET_DEBOUNCE_PERIOD = 6 + FUNCTION_GET_DEBOUNCE_PERIOD = 7 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletTemperature.FUNCTION_GET_TEMPERATURE] = BrickletTemperature.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperature.FUNCTION_SET_TEMPERATURE_CALLBACK_PERIOD] = BrickletTemperature.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletTemperature.FUNCTION_GET_TEMPERATURE_CALLBACK_PERIOD] = BrickletTemperature.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperature.FUNCTION_SET_TEMPERATURE_CALLBACK_THRESHOLD] = BrickletTemperature.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletTemperature.FUNCTION_GET_TEMPERATURE_CALLBACK_THRESHOLD] = BrickletTemperature.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperature.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletTemperature.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletTemperature.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletTemperature.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperature.CALLBACK_TEMPERATURE] = BrickletTemperature.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletTemperature.CALLBACK_TEMPERATURE_REACHED] = BrickletTemperature.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletTemperature.FUNCTION_GET_IDENTITY] = BrickletTemperature.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletTemperature.CALLBACK_TEMPERATURE] = 'h' + self.callback_formats[BrickletTemperature.CALLBACK_TEMPERATURE_REACHED] = 'h' + + def get_temperature(self): + """ + Returns the temperature of the sensor. The value + has a range of -2500 to 8500 and is given in °C/100, + e.g. a value of 4223 means that a temperature of 42.23 °C is measured. + + If you want to get the temperature periodically, it is recommended + to use the callback :func:`Temperature` and set the period with + :func:`SetTemperatureCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletTemperature.FUNCTION_GET_TEMPERATURE, (), '', 'h') + + def set_temperature_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Temperature` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Temperature` is only triggered if the temperature has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletTemperature.FUNCTION_SET_TEMPERATURE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_temperature_callback_period(self): + """ + Returns the period as set by :func:`SetTemperatureCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletTemperature.FUNCTION_GET_TEMPERATURE_CALLBACK_PERIOD, (), '', 'I') + + def set_temperature_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`TemperatureReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the temperature is *outside* the min and max values" + "'i'", "Callback is triggered when the temperature is *inside* the min and max values" + "'<'", "Callback is triggered when the temperature is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the temperature is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletTemperature.FUNCTION_SET_TEMPERATURE_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_temperature_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetTemperatureCallbackThreshold`. + """ + return GetTemperatureCallbackThreshold(*self.ipcon.send_request(self, BrickletTemperature.FUNCTION_GET_TEMPERATURE_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callback + + :func:`TemperatureReached` + + is triggered, if the threshold + + :func:`SetTemperatureCallbackThreshold` + + keeps being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletTemperature.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletTemperature.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletTemperature.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +Temperature = BrickletTemperature # for backward compatibility diff --git a/tinkerforge/bricklet_temperature.pyc b/tinkerforge/bricklet_temperature.pyc new file mode 100644 index 0000000..f2add31 Binary files /dev/null and b/tinkerforge/bricklet_temperature.pyc differ diff --git a/tinkerforge/bricklet_temperature_ir.py b/tinkerforge/bricklet_temperature_ir.py new file mode 100644 index 0000000..1710468 --- /dev/null +++ b/tinkerforge/bricklet_temperature_ir.py @@ -0,0 +1,287 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetAmbientTemperatureCallbackThreshold = namedtuple('AmbientTemperatureCallbackThreshold', ['option', 'min', 'max']) +GetObjectTemperatureCallbackThreshold = namedtuple('ObjectTemperatureCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletTemperatureIR(Device): + """ + Device for non-contact temperature sensing + """ + + DEVICE_IDENTIFIER = 217 + + CALLBACK_AMBIENT_TEMPERATURE = 15 + CALLBACK_OBJECT_TEMPERATURE = 16 + CALLBACK_AMBIENT_TEMPERATURE_REACHED = 17 + CALLBACK_OBJECT_TEMPERATURE_REACHED = 18 + + FUNCTION_GET_AMBIENT_TEMPERATURE = 1 + FUNCTION_GET_OBJECT_TEMPERATURE = 2 + FUNCTION_SET_EMISSIVITY = 3 + FUNCTION_GET_EMISSIVITY = 4 + FUNCTION_SET_AMBIENT_TEMPERATURE_CALLBACK_PERIOD = 5 + FUNCTION_GET_AMBIENT_TEMPERATURE_CALLBACK_PERIOD = 6 + FUNCTION_SET_OBJECT_TEMPERATURE_CALLBACK_PERIOD = 7 + FUNCTION_GET_OBJECT_TEMPERATURE_CALLBACK_PERIOD = 8 + FUNCTION_SET_AMBIENT_TEMPERATURE_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_AMBIENT_TEMPERATURE_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_OBJECT_TEMPERATURE_CALLBACK_THRESHOLD = 11 + FUNCTION_GET_OBJECT_TEMPERATURE_CALLBACK_THRESHOLD = 12 + FUNCTION_SET_DEBOUNCE_PERIOD = 13 + FUNCTION_GET_DEBOUNCE_PERIOD = 14 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletTemperatureIR.FUNCTION_GET_AMBIENT_TEMPERATURE] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_GET_OBJECT_TEMPERATURE] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_SET_EMISSIVITY] = BrickletTemperatureIR.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletTemperatureIR.FUNCTION_GET_EMISSIVITY] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_SET_AMBIENT_TEMPERATURE_CALLBACK_PERIOD] = BrickletTemperatureIR.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_GET_AMBIENT_TEMPERATURE_CALLBACK_PERIOD] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_SET_OBJECT_TEMPERATURE_CALLBACK_PERIOD] = BrickletTemperatureIR.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_GET_OBJECT_TEMPERATURE_CALLBACK_PERIOD] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_SET_AMBIENT_TEMPERATURE_CALLBACK_THRESHOLD] = BrickletTemperatureIR.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_GET_AMBIENT_TEMPERATURE_CALLBACK_THRESHOLD] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_SET_OBJECT_TEMPERATURE_CALLBACK_THRESHOLD] = BrickletTemperatureIR.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_GET_OBJECT_TEMPERATURE_CALLBACK_THRESHOLD] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletTemperatureIR.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletTemperatureIR.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletTemperatureIR.CALLBACK_AMBIENT_TEMPERATURE] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletTemperatureIR.CALLBACK_OBJECT_TEMPERATURE] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletTemperatureIR.CALLBACK_AMBIENT_TEMPERATURE_REACHED] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletTemperatureIR.CALLBACK_OBJECT_TEMPERATURE_REACHED] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletTemperatureIR.FUNCTION_GET_IDENTITY] = BrickletTemperatureIR.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletTemperatureIR.CALLBACK_AMBIENT_TEMPERATURE] = 'h' + self.callback_formats[BrickletTemperatureIR.CALLBACK_OBJECT_TEMPERATURE] = 'h' + self.callback_formats[BrickletTemperatureIR.CALLBACK_AMBIENT_TEMPERATURE_REACHED] = 'h' + self.callback_formats[BrickletTemperatureIR.CALLBACK_OBJECT_TEMPERATURE_REACHED] = 'h' + + def get_ambient_temperature(self): + """ + Returns the ambient temperature of the sensor. The value + has a range of -400 to 1250 and is given in °C/10, + e.g. a value of 423 means that an ambient temperature of 42.3 °C is + measured. + + If you want to get the ambient temperature periodically, it is recommended + to use the callback :func:`AmbientTemperature` and set the period with + :func:`SetAmbientTemperatureCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_GET_AMBIENT_TEMPERATURE, (), '', 'h') + + def get_object_temperature(self): + """ + Returns the object temperature of the sensor, i.e. the temperature + of the surface of the object the sensor is aimed at. The value + has a range of -700 to 3800 and is given in °C/10, + e.g. a value of 3001 means that a temperature of 300.1 °C is measured + on the surface of the object. + + The temperature of different materials is dependent on their `emissivity + `__. The emissivity of the material + can be set with :func:`SetEmissivity`. + + If you want to get the object temperature periodically, it is recommended + to use the callback :func:`ObjectTemperature` and set the period with + :func:`SetObjectTemperatureCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_GET_OBJECT_TEMPERATURE, (), '', 'h') + + def set_emissivity(self, emissivity): + """ + Sets the `emissivity `__ that is + used to calculate the surface temperature as returned by + :func:`GetObjectTemperature`. + + The emissivity is usually given as a value between 0.0 and 1.0. A list of + emissivities of different materials can be found + `here `__. + + The parameter of :func:`SetEmissivity` has to be given with a factor of + 65535 (16-bit). For example: An emissivity of 0.1 can be set with the + value 6553, an emissivity of 0.5 with the value 32767 and so on. + + .. note:: + If you need a precise measurement for the object temperature, it is + absolutely crucial that you also provide a precise emissivity. + + The default emissivity is 1.0 (value of 65535) and the minimum emissivity the + sensor can handle is 0.1 (value of 6553). + """ + self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_SET_EMISSIVITY, (emissivity,), 'H', '') + + def get_emissivity(self): + """ + Returns the emissivity as set by :func:`SetEmissivity`. + """ + return self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_GET_EMISSIVITY, (), '', 'H') + + def set_ambient_temperature_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AmbientTemperature` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AmbientTemperature` is only triggered if the temperature has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_SET_AMBIENT_TEMPERATURE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_ambient_temperature_callback_period(self): + """ + Returns the period as set by :func:`SetAmbientTemperatureCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_GET_AMBIENT_TEMPERATURE_CALLBACK_PERIOD, (), '', 'I') + + def set_object_temperature_callback_period(self, period): + """ + Sets the period in ms with which the :func:`ObjectTemperature` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`ObjectTemperature` is only triggered if the temperature has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_SET_OBJECT_TEMPERATURE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_object_temperature_callback_period(self): + """ + Returns the period as set by :func:`SetObjectTemperatureCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_GET_OBJECT_TEMPERATURE_CALLBACK_PERIOD, (), '', 'I') + + def set_ambient_temperature_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AmbientTemperatureReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the ambient temperature is *outside* the min and max values" + "'i'", "Callback is triggered when the ambient temperature is *inside* the min and max values" + "'<'", "Callback is triggered when the ambient temperature is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the ambient temperature is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_SET_AMBIENT_TEMPERATURE_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_ambient_temperature_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAmbientTemperatureCallbackThreshold`. + """ + return GetAmbientTemperatureCallbackThreshold(*self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_GET_AMBIENT_TEMPERATURE_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_object_temperature_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`ObjectTemperatureReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the object temperature is *outside* the min and max values" + "'i'", "Callback is triggered when the object temperature is *inside* the min and max values" + "'<'", "Callback is triggered when the object temperature is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the object temperature is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_SET_OBJECT_TEMPERATURE_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_object_temperature_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetObjectTemperatureCallbackThreshold`. + """ + return GetObjectTemperatureCallbackThreshold(*self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_GET_OBJECT_TEMPERATURE_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`AmbientTemperatureReached`, :func:`ObjectTemperatureReached` + + are triggered, if the thresholds + + :func:`SetAmbientTemperatureCallbackThreshold`, :func:`SetObjectTemperatureCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletTemperatureIR.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +TemperatureIR = BrickletTemperatureIR # for backward compatibility diff --git a/tinkerforge/bricklet_voltage.py b/tinkerforge/bricklet_voltage.py new file mode 100644 index 0000000..81b69a4 --- /dev/null +++ b/tinkerforge/bricklet_voltage.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetVoltageCallbackThreshold = namedtuple('VoltageCallbackThreshold', ['option', 'min', 'max']) +GetAnalogValueCallbackThreshold = namedtuple('AnalogValueCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletVoltage(Device): + """ + Device for sensing Voltages between 0 and 50V + """ + + DEVICE_IDENTIFIER = 218 + + CALLBACK_VOLTAGE = 13 + CALLBACK_ANALOG_VALUE = 14 + CALLBACK_VOLTAGE_REACHED = 15 + CALLBACK_ANALOG_VALUE_REACHED = 16 + + FUNCTION_GET_VOLTAGE = 1 + FUNCTION_GET_ANALOG_VALUE = 2 + FUNCTION_SET_VOLTAGE_CALLBACK_PERIOD = 3 + FUNCTION_GET_VOLTAGE_CALLBACK_PERIOD = 4 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD = 5 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD = 6 + FUNCTION_SET_VOLTAGE_CALLBACK_THRESHOLD = 7 + FUNCTION_GET_VOLTAGE_CALLBACK_THRESHOLD = 8 + FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD = 9 + FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD = 10 + FUNCTION_SET_DEBOUNCE_PERIOD = 11 + FUNCTION_GET_DEBOUNCE_PERIOD = 12 + FUNCTION_GET_IDENTITY = 255 + + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletVoltage.FUNCTION_GET_VOLTAGE] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltage.FUNCTION_GET_ANALOG_VALUE] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltage.FUNCTION_SET_VOLTAGE_CALLBACK_PERIOD] = BrickletVoltage.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltage.FUNCTION_GET_VOLTAGE_CALLBACK_PERIOD] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltage.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletVoltage.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltage.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltage.FUNCTION_SET_VOLTAGE_CALLBACK_THRESHOLD] = BrickletVoltage.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltage.FUNCTION_GET_VOLTAGE_CALLBACK_THRESHOLD] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltage.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletVoltage.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltage.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltage.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletVoltage.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltage.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltage.CALLBACK_VOLTAGE] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletVoltage.CALLBACK_ANALOG_VALUE] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletVoltage.CALLBACK_VOLTAGE_REACHED] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletVoltage.CALLBACK_ANALOG_VALUE_REACHED] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletVoltage.FUNCTION_GET_IDENTITY] = BrickletVoltage.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletVoltage.CALLBACK_VOLTAGE] = 'H' + self.callback_formats[BrickletVoltage.CALLBACK_ANALOG_VALUE] = 'H' + self.callback_formats[BrickletVoltage.CALLBACK_VOLTAGE_REACHED] = 'H' + self.callback_formats[BrickletVoltage.CALLBACK_ANALOG_VALUE_REACHED] = 'H' + + def get_voltage(self): + """ + Returns the voltage of the sensor. The value is in mV and + between 0mV and 50000mV. + + If you want to get the voltage periodically, it is recommended to use the + callback :func:`Voltage` and set the period with + :func:`SetVoltageCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltage.FUNCTION_GET_VOLTAGE, (), '', 'H') + + def get_analog_value(self): + """ + Returns the value as read by a 12-bit analog-to-digital converter. + The value is between 0 and 4095. + + .. note:: + The value returned by :func:`GetVoltage` is averaged over several samples + to yield less noise, while :func:`GetAnalogValue` gives back raw + unfiltered analog values. The only reason to use :func:`GetAnalogValue` is, + if you need the full resolution of the analog-to-digital converter. + + If you want the analog value periodically, it is recommended to use the + callback :func:`AnalogValue` and set the period with + :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltage.FUNCTION_GET_ANALOG_VALUE, (), '', 'H') + + def set_voltage_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Voltage` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Voltage` is only triggered if the voltage has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletVoltage.FUNCTION_SET_VOLTAGE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_voltage_callback_period(self): + """ + Returns the period as set by :func:`SetVoltageCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltage.FUNCTION_GET_VOLTAGE_CALLBACK_PERIOD, (), '', 'I') + + def set_analog_value_callback_period(self, period): + """ + Sets the period in ms with which the :func:`AnalogValue` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`AnalogValue` is only triggered if the analog value has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletVoltage.FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_analog_value_callback_period(self): + """ + Returns the period as set by :func:`SetAnalogValueCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltage.FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD, (), '', 'I') + + def set_voltage_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`VoltageReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the voltage is *outside* the min and max values" + "'i'", "Callback is triggered when the voltage is *inside* the min and max values" + "'<'", "Callback is triggered when the voltage is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the voltage is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletVoltage.FUNCTION_SET_VOLTAGE_CALLBACK_THRESHOLD, (option, min, max), 'c h h', '') + + def get_voltage_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetVoltageCallbackThreshold`. + """ + return GetVoltageCallbackThreshold(*self.ipcon.send_request(self, BrickletVoltage.FUNCTION_GET_VOLTAGE_CALLBACK_THRESHOLD, (), '', 'c h h')) + + def set_analog_value_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`AnalogValueReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the analog value is *outside* the min and max values" + "'i'", "Callback is triggered when the analog value is *inside* the min and max values" + "'<'", "Callback is triggered when the analog value is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the analog value is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletVoltage.FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD, (option, min, max), 'c H H', '') + + def get_analog_value_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetAnalogValueCallbackThreshold`. + """ + return GetAnalogValueCallbackThreshold(*self.ipcon.send_request(self, BrickletVoltage.FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD, (), '', 'c H H')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`VoltageReached`, :func:`AnalogValueReached` + + are triggered, if the thresholds + + :func:`SetVoltageCallbackThreshold`, :func:`SetAnalogValueCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletVoltage.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltage.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletVoltage.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +Voltage = BrickletVoltage # for backward compatibility diff --git a/tinkerforge/bricklet_voltage_current.py b/tinkerforge/bricklet_voltage_current.py new file mode 100644 index 0000000..ec68675 --- /dev/null +++ b/tinkerforge/bricklet_voltage_current.py @@ -0,0 +1,400 @@ +# -*- coding: utf-8 -*- +############################################################# +# This file was automatically generated on 2013-02-19. # +# # +# Bindings Version 2.0.4 # +# # +# If you have a bugfix for this file and want to commit it, # +# please fix the bug in the generator. You can find a link # +# to the generator git on tinkerforge.com # +############################################################# + +try: + from collections import namedtuple +except ImportError: + try: + from .ip_connection import namedtuple + except ValueError: + from ip_connection import namedtuple + +try: + from .ip_connection import Device, IPConnection, Error +except ValueError: + from ip_connection import Device, IPConnection, Error + +GetConfiguration = namedtuple('Configuration', ['averaging', 'voltage_conversion_time', 'current_conversion_time']) +GetCalibration = namedtuple('Calibration', ['gain_multiplier', 'gain_divisor']) +GetCurrentCallbackThreshold = namedtuple('CurrentCallbackThreshold', ['option', 'min', 'max']) +GetVoltageCallbackThreshold = namedtuple('VoltageCallbackThreshold', ['option', 'min', 'max']) +GetPowerCallbackThreshold = namedtuple('PowerCallbackThreshold', ['option', 'min', 'max']) +GetIdentity = namedtuple('Identity', ['uid', 'connected_uid', 'position', 'hardware_version', 'firmware_version', 'device_identifier']) + +class BrickletVoltageCurrent(Device): + """ + Device for high precision sensing of voltage and current + """ + + DEVICE_IDENTIFIER = 227 + + CALLBACK_CURRENT = 22 + CALLBACK_VOLTAGE = 23 + CALLBACK_POWER = 24 + CALLBACK_CURRENT_REACHED = 25 + CALLBACK_VOLTAGE_REACHED = 26 + CALLBACK_POWER_REACHED = 27 + + FUNCTION_GET_CURRENT = 1 + FUNCTION_GET_VOLTAGE = 2 + FUNCTION_GET_POWER = 3 + FUNCTION_SET_CONFIGURATION = 4 + FUNCTION_GET_CONFIGURATION = 5 + FUNCTION_SET_CALIBRATION = 6 + FUNCTION_GET_CALIBRATION = 7 + FUNCTION_SET_CURRENT_CALLBACK_PERIOD = 8 + FUNCTION_GET_CURRENT_CALLBACK_PERIOD = 9 + FUNCTION_SET_VOLTAGE_CALLBACK_PERIOD = 10 + FUNCTION_GET_VOLTAGE_CALLBACK_PERIOD = 11 + FUNCTION_SET_POWER_CALLBACK_PERIOD = 12 + FUNCTION_GET_POWER_CALLBACK_PERIOD = 13 + FUNCTION_SET_CURRENT_CALLBACK_THRESHOLD = 14 + FUNCTION_GET_CURRENT_CALLBACK_THRESHOLD = 15 + FUNCTION_SET_VOLTAGE_CALLBACK_THRESHOLD = 16 + FUNCTION_GET_VOLTAGE_CALLBACK_THRESHOLD = 17 + FUNCTION_SET_POWER_CALLBACK_THRESHOLD = 18 + FUNCTION_GET_POWER_CALLBACK_THRESHOLD = 19 + FUNCTION_SET_DEBOUNCE_PERIOD = 20 + FUNCTION_GET_DEBOUNCE_PERIOD = 21 + FUNCTION_GET_IDENTITY = 255 + + AVERAGING_1 = 0 + AVERAGING_4 = 1 + AVERAGING_16 = 2 + AVERAGING_64 = 3 + AVERAGING_128 = 4 + AVERAGING_256 = 5 + AVERAGING_512 = 6 + AVERAGING_1024 = 7 + THRESHOLD_OPTION_OFF = 'x' + THRESHOLD_OPTION_OUTSIDE = 'o' + THRESHOLD_OPTION_INSIDE = 'i' + THRESHOLD_OPTION_SMALLER = '<' + THRESHOLD_OPTION_GREATER = '>' + + def __init__(self, uid, ipcon): + """ + Creates an object with the unique device ID *uid* and adds it to + the IP Connection *ipcon*. + """ + Device.__init__(self, uid, ipcon) + + self.api_version = (2, 0, 0) + + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_CURRENT] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_VOLTAGE] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_POWER] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_SET_CONFIGURATION] = BrickletVoltageCurrent.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_CONFIGURATION] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_SET_CALIBRATION] = BrickletVoltageCurrent.RESPONSE_EXPECTED_FALSE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_CALIBRATION] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_SET_CURRENT_CALLBACK_PERIOD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_CURRENT_CALLBACK_PERIOD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_SET_VOLTAGE_CALLBACK_PERIOD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_VOLTAGE_CALLBACK_PERIOD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_SET_POWER_CALLBACK_PERIOD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_POWER_CALLBACK_PERIOD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_SET_CURRENT_CALLBACK_THRESHOLD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_CURRENT_CALLBACK_THRESHOLD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_SET_VOLTAGE_CALLBACK_THRESHOLD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_VOLTAGE_CALLBACK_THRESHOLD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_SET_POWER_CALLBACK_THRESHOLD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_POWER_CALLBACK_THRESHOLD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_SET_DEBOUNCE_PERIOD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_TRUE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_DEBOUNCE_PERIOD] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[BrickletVoltageCurrent.CALLBACK_CURRENT] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletVoltageCurrent.CALLBACK_VOLTAGE] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletVoltageCurrent.CALLBACK_POWER] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletVoltageCurrent.CALLBACK_CURRENT_REACHED] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletVoltageCurrent.CALLBACK_VOLTAGE_REACHED] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletVoltageCurrent.CALLBACK_POWER_REACHED] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[BrickletVoltageCurrent.FUNCTION_GET_IDENTITY] = BrickletVoltageCurrent.RESPONSE_EXPECTED_ALWAYS_TRUE + + self.callback_formats[BrickletVoltageCurrent.CALLBACK_CURRENT] = 'i' + self.callback_formats[BrickletVoltageCurrent.CALLBACK_VOLTAGE] = 'i' + self.callback_formats[BrickletVoltageCurrent.CALLBACK_POWER] = 'i' + self.callback_formats[BrickletVoltageCurrent.CALLBACK_CURRENT_REACHED] = 'i' + self.callback_formats[BrickletVoltageCurrent.CALLBACK_VOLTAGE_REACHED] = 'i' + self.callback_formats[BrickletVoltageCurrent.CALLBACK_POWER_REACHED] = 'i' + + def get_current(self): + """ + Returns the current. The value is in mA + and between 0mA and 20000mA. + + If you want to get the current periodically, it is recommended to use the + callback :func:`Current` and set the period with + :func:`SetCurrentCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_CURRENT, (), '', 'i') + + def get_voltage(self): + """ + Returns the voltage. The value is in mV + and between 0mV and 36000mV. + + If you want to get the voltage periodically, it is recommended to use the + callback :func:`Voltage` and set the period with + :func:`SetVoltageCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_VOLTAGE, (), '', 'i') + + def get_power(self): + """ + Returns the power. The value is in mW + and between 0mV and 720000mW. + + If you want to get the power periodically, it is recommended to use the + callback :func:`Power` and set the period with + :func:`SetPowerCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_POWER, (), '', 'i') + + def set_configuration(self, averaging, voltage_conversion_time, current_conversion_time): + """ + Sets the configuration of the Voltage/Current Bricklet. It is + possible to configure number of averages as well as + voltage and current conversion time. + + Averaging: + + .. csv-table:: + :header: "Value", "Number of Averages" + :widths: 20, 20 + + "0", "1" + "1", "4" + "2", "16" + "3", "64" + "4", "128" + "5", "256" + "6", "512" + ">=7", "1024" + + Voltage/Current conversion: + + .. csv-table:: + :header: "Value", "Conversion time" + :widths: 20, 20 + + "0", "140µs" + "1", "204µs" + "2", "332µs" + "3", "588µs" + "4", "1.1ms" + "5", "2.116ms" + "6", "4.156ms" + ">=7", "8.244ms" + + The default values are 3, 4 and 4 (64, 1.1ms, 1.1ms) for averaging, voltage + conversion and current conversion. + """ + self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_SET_CONFIGURATION, (averaging, voltage_conversion_time, current_conversion_time), 'B B B', '') + + def get_configuration(self): + """ + Returns the configuration as set by :func:`SetConfiguration`. + """ + return GetConfiguration(*self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_CONFIGURATION, (), '', 'B B B')) + + def set_calibration(self, gain_multiplier, gain_divisor): + """ + Since the shunt resistor that is used to measure the current is not + perfectly precise, it needs to be calibrated by a multiplier and + divisor if a very precise reading is needed. + + For example, if you are expecting a measurement of 1000mA and you + are measuring 1023mA, you can calibrate the Voltage/Current Bricklet + by setting the multiplier to 1000 and the divisior to 1023. + """ + self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_SET_CALIBRATION, (gain_multiplier, gain_divisor), 'H H', '') + + def get_calibration(self): + """ + Returns the calibration as set by :func:`SetCalibration`. + """ + return GetCalibration(*self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_CALIBRATION, (), '', 'H H')) + + def set_current_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Current` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Current` is only triggered if the current has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_SET_CURRENT_CALLBACK_PERIOD, (period,), 'I', '') + + def get_current_callback_period(self): + """ + Returns the period as set by :func:`SetCurrentCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_CURRENT_CALLBACK_PERIOD, (), '', 'I') + + def set_voltage_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Voltage` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Voltage` is only triggered if the voltage has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_SET_VOLTAGE_CALLBACK_PERIOD, (period,), 'I', '') + + def get_voltage_callback_period(self): + """ + Returns the period as set by :func:`SetVoltageCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_VOLTAGE_CALLBACK_PERIOD, (), '', 'I') + + def set_power_callback_period(self, period): + """ + Sets the period in ms with which the :func:`Power` callback is triggered + periodically. A value of 0 turns the callback off. + + :func:`Power` is only triggered if the power has changed since the + last triggering. + + The default value is 0. + """ + self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_SET_POWER_CALLBACK_PERIOD, (period,), 'I', '') + + def get_power_callback_period(self): + """ + Returns the period as set by :func:`GetPowerCallbackPeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_POWER_CALLBACK_PERIOD, (), '', 'I') + + def set_current_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`CurrentReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the current is *outside* the min and max values" + "'i'", "Callback is triggered when the current is *inside* the min and max values" + "'<'", "Callback is triggered when the current is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the current is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_SET_CURRENT_CALLBACK_THRESHOLD, (option, min, max), 'c i i', '') + + def get_current_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetCurrentCallbackThreshold`. + """ + return GetCurrentCallbackThreshold(*self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_CURRENT_CALLBACK_THRESHOLD, (), '', 'c i i')) + + def set_voltage_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`VoltageReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the voltage is *outside* the min and max values" + "'i'", "Callback is triggered when the voltage is *inside* the min and max values" + "'<'", "Callback is triggered when the voltage is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the voltage is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_SET_VOLTAGE_CALLBACK_THRESHOLD, (option, min, max), 'c i i', '') + + def get_voltage_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetVoltageCallbackThreshold`. + """ + return GetVoltageCallbackThreshold(*self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_VOLTAGE_CALLBACK_THRESHOLD, (), '', 'c i i')) + + def set_power_callback_threshold(self, option, min, max): + """ + Sets the thresholds for the :func:`PowerReached` callback. + + The following options are possible: + + .. csv-table:: + :header: "Option", "Description" + :widths: 10, 100 + + "'x'", "Callback is turned off" + "'o'", "Callback is triggered when the power is *outside* the min and max values" + "'i'", "Callback is triggered when the power is *inside* the min and max values" + "'<'", "Callback is triggered when the power is smaller than the min value (max is ignored)" + "'>'", "Callback is triggered when the power is greater than the min value (max is ignored)" + + The default value is ('x', 0, 0). + """ + self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_SET_POWER_CALLBACK_THRESHOLD, (option, min, max), 'c i i', '') + + def get_power_callback_threshold(self): + """ + Returns the threshold as set by :func:`SetPowerCallbackThreshold`. + """ + return GetPowerCallbackThreshold(*self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_POWER_CALLBACK_THRESHOLD, (), '', 'c i i')) + + def set_debounce_period(self, debounce): + """ + Sets the period in ms with which the threshold callbacks + + :func:`CurrentReached`, :func:`VoltageReached`, :func:`PowerReached` + + are triggered, if the thresholds + + :func:`SetCurrentCallbackThreshold`, :func:`SetVoltageCallbackThreshold`, :func:`SetPowerCallbackThreshold` + + keep being reached. + + The default value is 100. + """ + self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_SET_DEBOUNCE_PERIOD, (debounce,), 'I', '') + + def get_debounce_period(self): + """ + Returns the debounce period as set by :func:`SetDebouncePeriod`. + """ + return self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_DEBOUNCE_PERIOD, (), '', 'I') + + def get_identity(self): + """ + Returns the UID, the UID where the Bricklet is connected to, + the position, the hardware and firmware version as well as the + device identifier. + + The position can be 'a', 'b', 'c' or 'd'. + + The device identifiers can be found :ref:`here `. + + .. versionadded:: 2.0.0~(Plugin) + """ + return GetIdentity(*self.ipcon.send_request(self, BrickletVoltageCurrent.FUNCTION_GET_IDENTITY, (), '', '8s 8s c 3B 3B H')) + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + self.registered_callbacks[id] = callback + +VoltageCurrent = BrickletVoltageCurrent # for backward compatibility diff --git a/tinkerforge/ip_connection.py b/tinkerforge/ip_connection.py new file mode 100644 index 0000000..5bb3edc --- /dev/null +++ b/tinkerforge/ip_connection.py @@ -0,0 +1,890 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2012-2013 Matthias Bolte +# Copyright (C) 2011-2012 Olaf Lüke +# +# Redistribution and use in source and binary forms of this file, +# with or without modification, are permitted. + +from threading import Thread, Lock, Semaphore + +# current_thread for python 2.6, currentThread for python 2.5 +try: + from threading import current_thread +except ImportError: + from threading import currentThread as current_thread + +# Queue for python 2, queue for python 3 +try: + from Queue import Queue, Empty +except ImportError: + from queue import Queue, Empty + +import struct +import socket +import types +import sys +import time + +# use normal tuples instead of namedtuples in python version below 2.6 +if sys.hexversion < 0x02060000: + def namedtuple(typename, field_names, verbose=False, rename=False): + def ntuple(*args): + return args + + return ntuple +else: + from collections import namedtuple + +def get_uid_from_data(data): + return struct.unpack('> 4) & 0x0F + +def get_error_code_from_data(data): + return (struct.unpack('> 6) & 0x03 + +BASE58 = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ' +def base58encode(value): + encoded = '' + while value >= 58: + div, mod = divmod(value, 58) + encoded = BASE58[mod] + encoded + value = div + encoded = BASE58[value] + encoded + return encoded + +def base58decode(encoded): + value = 0 + column_multiplier = 1 + for c in encoded[::-1]: + column = BASE58.index(c) + value += column * column_multiplier + column_multiplier *= 58 + return value + +def uid64_to_uid32(uid64): + value1 = uid64 & 0xFFFFFFFF + value2 = (uid64 >> 32) & 0xFFFFFFFF + + uid32 = (value1 & 0x00000FFF) + uid32 |= (value1 & 0x0F000000) >> 12 + uid32 |= (value2 & 0x0000003F) << 16 + uid32 |= (value2 & 0x000F0000) << 6 + uid32 |= (value2 & 0x3F000000) << 2 + + return uid32 + +class Error(Exception): + TIMEOUT = -1 + NOT_ADDED = -6 # obsolete since v2.0 + ALREADY_CONNECTED = -7 + NOT_CONNECTED = -8 + INVALID_PARAMETER = -9 + NOT_SUPPORTED = -10 + UNKNOWN_ERROR_CODE = -11 + + def __init__(self, value, description): + self.value = value + self.description = description + + def __str__(self): + return str(self.value) + ': ' + str(self.description) + +class Device: + RESPONSE_EXPECTED_INVALID_FUNCTION_ID = 0 + RESPONSE_EXPECTED_ALWAYS_TRUE = 1 # getter + RESPONSE_EXPECTED_ALWAYS_FALSE = 2 # callback + RESPONSE_EXPECTED_TRUE = 3 # setter + RESPONSE_EXPECTED_FALSE = 4 # setter, default + + def __init__(self, uid, ipcon): + """ + Creates the device object with the unique device ID *uid* and adds + it to the IPConnection *ipcon*. + """ + + uid_ = base58decode(uid) + + if uid_ > 0xFFFFFFFF: + uid_ = uid64_to_uid32(uid_) + + self.uid = uid_ + self.ipcon = ipcon + self.api_version = (0, 0, 0) + self.registered_callbacks = {} + self.callback_formats = {} + self.expected_response_function_id = None # protected by request_lock + self.expected_response_sequence_number = None # protected by request_lock + self.response_queue = Queue() + self.request_lock = Lock() + self.auth_key = None + + self.response_expected = [Device.RESPONSE_EXPECTED_INVALID_FUNCTION_ID] * 256 + self.response_expected[IPConnection.FUNCTION_ENUMERATE] = Device.RESPONSE_EXPECTED_ALWAYS_FALSE + self.response_expected[IPConnection.FUNCTION_ADC_CALIBRATE] = Device.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[IPConnection.FUNCTION_GET_ADC_CALIBRATION] = Device.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[IPConnection.FUNCTION_READ_BRICKLET_UID] = Device.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[IPConnection.FUNCTION_WRITE_BRICKLET_UID] = Device.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[IPConnection.FUNCTION_READ_BRICKLET_PLUGIN] = Device.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[IPConnection.FUNCTION_WRITE_BRICKLET_PLUGIN] = Device.RESPONSE_EXPECTED_ALWAYS_TRUE + self.response_expected[IPConnection.CALLBACK_ENUMERATE] = Device.RESPONSE_EXPECTED_ALWAYS_FALSE + + ipcon.devices[self.uid] = self # FIXME: maybe use a weakref here + + def get_api_version(self): + """ + Returns the API version (major, minor, revision) of the bindings for + this device. + """ + + return self.api_version + + def get_response_expected(self, function_id): + """ + Returns the response expected flag for the function specified by the + *function_id* parameter. It is *true* if the function is expected to + send a response, *false* otherwise. + + For getter functions this is enabled by default and cannot be disabled, + because those functions will always send a response. For callback + configuration functions it is enabled by default too, but can be + disabled via the set_response_expected function. For setter functions + it is disabled by default and can be enabled. + + Enabling the response expected flag for a setter function allows to + detect timeouts and other error conditions calls of this setter as + well. The device will then send a response for this purpose. If this + flag is disabled for a setter function then no response is send and + errors are silently ignored, because they cannot be detected. + """ + + if function_id < 0 or function_id >= len(self.response_expected): + raise ValueError('Function ID {0} out of range'.format(function_id)) + + flag = self.response_expected[function_id] + + if flag == Device.RESPONSE_EXPECTED_INVALID_FUNCTION_ID: + raise ValueError('Invalid function ID {0}'.format(function_id)) + + return flag in [Device.RESPONSE_EXPECTED_ALWAYS_TRUE, Device.RESPONSE_EXPECTED_TRUE] + + def set_response_expected(self, function_id, response_expected): + """ + Changes the response expected flag of the function specified by the + *function_id* parameter. This flag can only be changed for setter + (default value: *false*) and callback configuration functions + (default value: *true*). For getter functions it is always enabled + and callbacks it is always disabled. + + Enabling the response expected flag for a setter function allows to + detect timeouts and other error conditions calls of this setter as + well. The device will then send a response for this purpose. If this + flag is disabled for a setter function then no response is send and + errors are silently ignored, because they cannot be detected. + """ + + if function_id < 0 or function_id >= len(self.response_expected): + raise ValueError('Function ID {0} out of range'.format(function_id)) + + flag = self.response_expected[function_id] + + if flag == Device.RESPONSE_EXPECTED_INVALID_FUNCTION_ID: + raise ValueError('Invalid function ID {0}'.format(function_id)) + + if flag in [Device.RESPONSE_EXPECTED_ALWAYS_TRUE, Device.RESPONSE_EXPECTED_ALWAYS_FALSE]: + raise ValueError('Response Expected flag cannot be changed for function ID {0}'.format(function_id)) + + if bool(response_expected): + self.response_expected[function_id] = Device.RESPONSE_EXPECTED_TRUE + else: + self.response_expected[function_id] = Device.RESPONSE_EXPECTED_FALSE + + def set_response_expected_all(self, response_expected): + """ + Changes the response expected flag for all setter and callback + configuration functions of this device at once. + """ + + if bool(response_expected): + flag = Device.RESPONSE_EXPECTED_TRUE + else: + flag = Device.RESPONSE_EXPECTED_FALSE + + for i in range(len(self.response_expected)): + if self.response_expected[i] in [Device.RESPONSE_EXPECTED_TRUE, Device.RESPONSE_EXPECTED_FALSE]: + self.response_expected[i] = flag + +class IPConnection: + FUNCTION_ENUMERATE = 254 + FUNCTION_ADC_CALIBRATE = 251 + FUNCTION_GET_ADC_CALIBRATION = 250 + FUNCTION_READ_BRICKLET_UID = 249 + FUNCTION_WRITE_BRICKLET_UID = 248 + FUNCTION_READ_BRICKLET_PLUGIN = 247 + FUNCTION_WRITE_BRICKLET_PLUGIN = 246 + + CALLBACK_ENUMERATE = 253 + CALLBACK_CONNECTED = 0 + CALLBACK_DISCONNECTED = 1 + + BROADCAST_UID = 0 + + PLUGIN_CHUNK_SIZE = 32 + + # enumeration_type parameter to the enumerate callback + ENUMERATION_TYPE_AVAILABLE = 0 + ENUMERATION_TYPE_CONNECTED = 1 + ENUMERATION_TYPE_DISCONNECTED = 2 + + # connect_reason parameter to the connected callback + CONNECT_REASON_REQUEST = 0 + CONNECT_REASON_AUTO_RECONNECT = 1 + + # disconnect_reason parameter to the disconnected callback + DISCONNECT_REASON_REQUEST = 0 + DISCONNECT_REASON_ERROR = 1 + DISCONNECT_REASON_SHUTDOWN = 2 + + # returned by get_connection_state + CONNECTION_STATE_DISCONNECTED = 0 + CONNECTION_STATE_CONNECTED = 1 + CONNECTION_STATE_PENDING = 2 # auto-reconnect in process + + QUEUE_EXIT = 0 + QUEUE_META = 1 + QUEUE_PACKET = 2 + + def __init__(self): + """ + Creates an IP Connection object that can be used to enumerate the available + devices. It is also required for the constructor of Bricks and Bricklets. + """ + + self.host = None + self.port = None + self.timeout = 2.5 + self.auto_reconnect = True + self.auto_reconnect_allowed = False + self.auto_reconnect_pending = False + self.sequence_number_lock = Lock() + self.next_sequence_number = 0 + self.auth_key = None + self.devices = {} + self.registered_callbacks = {} + self.socket = None + self.socket_lock = Lock() + self.receive_flag = False + self.receive_thread = None + self.callback_queue = None + self.callback_thread = None + self.waiter = Semaphore() + + def connect(self, host, port): + """ + Creates a TCP/IP connection to the given *host* and *port*. The host + and port can point to a Brick Daemon or to a WIFI/Ethernet Extension. + + Devices can only be controlled when the connection was established + successfully. + + Blocks until the connection is established and throws an exception if + there is no Brick Daemon or WIFI/Ethernet Extension listening at the + given host and port. + """ + + with self.socket_lock: + if self.socket is not None: + raise Error(Error.ALREADY_CONNECTED, + 'Already connected to {0}:{1}'.format(self.host, self.port)) + + self.host = host + self.port = port + + self.connect_unlocked(False) + + def disconnect(self): + """ + Disconnects the TCP/IP connection from the Brick Daemon or the + WIFI/Ethernet Extension. + """ + + with self.socket_lock: + self.auto_reconnect_allowed = False + + if self.auto_reconnect_pending: + # abort potentially pending auto reconnect + self.auto_reconnect_pending = False + else: + if self.socket is None: + raise Error(Error.NOT_CONNECTED, 'Not connected') + + # end receive thread + self.receive_flag = False + + try: + self.socket.shutdown(socket.SHUT_RDWR) + except socket.error: + pass + + if self.receive_thread is not None: + self.receive_thread.join() # FIXME: use a timeout? + + self.receive_thread = None + + # close socket + self.socket.close() + self.socket = None + + # end callback thread + callback_queue = self.callback_queue + callback_thread = self.callback_thread + + self.callback_queue = None + self.callback_thread = None + + # do this outside of socket_lock to allow calling (dis-)connect from + # the callbacks while blocking on the join call here + callback_queue.put((IPConnection.QUEUE_META, + (IPConnection.CALLBACK_DISCONNECTED, + IPConnection.DISCONNECT_REASON_REQUEST))) + callback_queue.put((IPConnection.QUEUE_EXIT, None)) + + if current_thread() is not callback_thread: + callback_thread.join() + + def get_connection_state(self): + """ + Can return the following states: + + - CONNECTION_STATE_DISCONNECTED: No connection is established. + - CONNECTION_STATE_CONNECTED: A connection to the Brick Daemon or + the WIFI/Ethernet Extension is established. + - CONNECTION_STATE_PENDING: IP Connection is currently trying to + connect. + """ + + if self.socket is not None: + return IPConnection.CONNECTION_STATE_CONNECTED + elif self.auto_reconnect_pending: + return IPConnection.CONNECTION_STATE_PENDING + else: + return IPConnection.CONNECTION_STATE_DISCONNECTED + + def set_auto_reconnect(self, auto_reconnect): + """ + Enables or disables auto-reconnect. If auto-reconnect is enabled, + the IP Connection will try to reconnect to the previously given + host and port, if the connection is lost. + + Default value is *True*. + """ + + self.auto_reconnect = bool(auto_reconnect) + + if not self.auto_reconnect: + # abort potentially pending auto reconnect + self.auto_reconnect_allowed = False + + def get_auto_reconnect(self): + """ + Returns *true* if auto-reconnect is enabled, *false* otherwise. + """ + + return self.auto_reconnect + + def set_timeout(self, timeout): + """ + Sets the timeout in seconds for getters and for setters for which the + response expected flag is activated. + + Default timeout is 2.5. + """ + + timeout = float(timeout) + + if timeout < 0: + raise ValueError('Timeout cannot be negative') + + self.timeout = timeout + + def get_timeout(self): + """ + Returns the timeout as set by set_timeout. + """ + + return self.timeout + + def enumerate(self): + """ + Broadcasts an enumerate request. All devices will respond with an + enumerate callback. + """ + + request, _, _ = self.create_packet_header(None, 8, IPConnection.FUNCTION_ENUMERATE) + + self.send(request) + + def wait(self): + """ + Stops the current thread until unwait is called. + + This is useful if you rely solely on callbacks for events, if you want + to wait for a specific callback or if the IP Connection was created in + a thread. + + Wait and unwait act in the same way as "acquire" and "release" of a + semaphore. + """ + self.waiter.acquire() + + def unwait(self): + """ + Unwaits the thread previously stopped by wait. + + Wait and unwait act in the same way as "acquire" and "release" of + a semaphore. + """ + self.waiter.release() + + def register_callback(self, id, callback): + """ + Registers a callback with ID *id* to the function *callback*. + """ + + self.registered_callbacks[id] = callback + + def connect_unlocked(self, is_auto_reconnect): + # NOTE: assumes that socket_lock is locked + + if self.callback_thread is None: + try: + self.callback_queue = Queue() + self.callback_thread = Thread(name='Callback-Processor', + target=self.callback_loop, + args=(self.callback_queue, )) + self.callback_thread.daemon = True + self.callback_thread.start() + except: + self.callback_queue = None + self.callback_thread = None + raise + + try: + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + self.socket.connect((self.host, self.port)) + except: + self.socket = None + raise + + try: + self.receive_flag = True + self.receive_thread = Thread(name='Brickd-Receiver', + target=self.receive_loop) + self.receive_thread.daemon = True + self.receive_thread.start() + except: + def cleanup(): + # end receive thread + self.receive_flag = False + + try: + self.socket.shutdown(socket.SHUT_RDWR) + except socket.error: + pass + + if self.receive_thread is not None: + self.receive_thread.join() # FIXME: use a timeout? + + self.receive_thread = None + + # close socket + self.socket.close() + self.socket = None + + # end callback thread + if not is_auto_reconnect: + self.callback_queue.put((IPConnection.QUEUE_EXIT, None)) + + if current_thread() is not self.callback_thread: + self.callback_thread.join() + + self.callback_queue = None + self.callback_thread = None + + cleanup() + raise + + self.auto_reconnect_allowed = False + self.auto_reconnect_pending = False + + if is_auto_reconnect: + connect_reason = IPConnection.CONNECT_REASON_AUTO_RECONNECT + else: + connect_reason = IPConnection.CONNECT_REASON_REQUEST + + self.callback_queue.put((IPConnection.QUEUE_META, + (IPConnection.CALLBACK_CONNECTED, + connect_reason))) + + def receive_loop(self): + if sys.hexversion < 0x03000000: + pending_data = '' + else: + pending_data = bytes() + + while self.receive_flag: + try: + data = self.socket.recv(8192) + except socket.error: + self.auto_reconnect_allowed = True + self.receive_flag = False + self.callback_queue.put((IPConnection.QUEUE_META, + (IPConnection.CALLBACK_DISCONNECTED, + IPConnection.DISCONNECT_REASON_ERROR))) + return + + if len(data) == 0: + if self.receive_flag: + self.auto_reconnect_allowed = True + self.receive_flag = False + self.callback_queue.put((IPConnection.QUEUE_META, + (IPConnection.CALLBACK_DISCONNECTED, + IPConnection.DISCONNECT_REASON_SHUTDOWN))) + return + + pending_data += data + + while True: + if len(pending_data) < 8: + # Wait for complete header + break + + length = get_length_from_data(pending_data) + + if len(pending_data) < length: + # Wait for complete packet + break + + packet = pending_data[0:length] + pending_data = pending_data[length:] + + self.handle_response(packet) + + def dispatch_meta(self, function_id, parameter): + if function_id == IPConnection.CALLBACK_CONNECTED: + if IPConnection.CALLBACK_CONNECTED in self.registered_callbacks and \ + self.registered_callbacks[IPConnection.CALLBACK_CONNECTED] is not None: + self.registered_callbacks[IPConnection.CALLBACK_CONNECTED](parameter) + elif function_id == IPConnection.CALLBACK_DISCONNECTED: + # need to do this here, the receive_loop is not allowed to + # hold the socket_lock because this could cause a deadlock + # with a concurrent call to the (dis-)connect function + with self.socket_lock: + if self.socket is not None: + self.socket.close() + self.socket = None + + # FIXME: wait a moment here, otherwise the next connect + # attempt will succeed, even if there is no open server + # socket. the first receive will then fail directly + time.sleep(0.1) + + if IPConnection.CALLBACK_DISCONNECTED in self.registered_callbacks and \ + self.registered_callbacks[IPConnection.CALLBACK_DISCONNECTED] is not None: + self.registered_callbacks[IPConnection.CALLBACK_DISCONNECTED](parameter) + + if parameter != IPConnection.DISCONNECT_REASON_REQUEST and \ + self.auto_reconnect and self.auto_reconnect_allowed: + self.auto_reconnect_pending = True + retry = True + + # block here until reconnect. this is okay, there is no + # callback to deliver when there is no connection + while retry: + retry = False + + with self.socket_lock: + if self.auto_reconnect_allowed and self.socket is None: + try: + self.connect_unlocked(True) + except: + retry = True + else: + self.auto_reconnect_pending = False + + if retry: + time.sleep(0.1) + + def dispatch_packet(self, packet): + uid = get_uid_from_data(packet) + length = get_length_from_data(packet) + function_id = get_function_id_from_data(packet) + payload = packet[8:] + + if function_id == IPConnection.CALLBACK_ENUMERATE and \ + IPConnection.CALLBACK_ENUMERATE in self.registered_callbacks: + uid, connected_uid, position, hardware_version, \ + firmware_version, device_identifier, enumeration_type = \ + self.deserialize_data(payload, '8s 8s c 3B 3B H B') + + cb = self.registered_callbacks[IPConnection.CALLBACK_ENUMERATE] + cb(uid, connected_uid, position, hardware_version, + firmware_version, device_identifier, enumeration_type) + return + + if uid not in self.devices: + return + + device = self.devices[uid] + + if function_id in device.registered_callbacks and \ + device.registered_callbacks[function_id] is not None: + cb = device.registered_callbacks[function_id] + form = device.callback_formats[function_id] + + if len(form) == 0: + cb() + elif len(form) == 1: + cb(self.deserialize_data(payload, form)) + else: + cb(*self.deserialize_data(payload, form)) + + def callback_loop(self, callback_queue): + while True: + kind, data = callback_queue.get() + + if kind == IPConnection.QUEUE_EXIT: + return + elif kind == IPConnection.QUEUE_META: + self.dispatch_meta(*data) + elif kind == IPConnection.QUEUE_PACKET: + if not self.receive_flag: + # don't dispatch callbacks when the receive thread isn't running + continue + + self.dispatch_packet(data) + + def deserialize_data(self, data, form): + ret = [] + for f in form.split(' '): + f = '<' + f + length = struct.calcsize(f) + + x = struct.unpack(f, data[:length]) + if len(x) > 1: + ret.append(x) + elif 's' in f: + ret.append(self.trim_deserialized_string(x[0])) + else: + ret.append(x[0]) + + data = data[length:] + + if len(ret) == 1: + return ret[0] + + return ret + + def trim_deserialized_string(self, s): + if sys.hexversion >= 0x03000000: + s = s.decode('ascii') + + i = s.find(chr(0)) + if i >= 0: + s = s[:i] + + return s + + def send(self, packet): + with self.socket_lock: + if self.socket is None: + raise Error(Error.NOT_CONNECTED, 'Not connected') + + try: + self.socket.send(packet) + except socket.error: + pass + + def send_request(self, device, function_id, data, form, form_ret): + length = 8 + struct.calcsize('<' + form) + request, response_expected, sequence_number = \ + self.create_packet_header(device, length, function_id) + + def pack_string(f, d): + if sys.hexversion < 0x03000000: + if type(d) == types.UnicodeType: + return struct.pack('<' + f, d.encode('ascii')) + else: + return struct.pack('<' + f, d) + else: + if isinstance(d, str): + return struct.pack('<' + f, bytes(d, 'ascii')) + else: + return struct.pack('<' + f, d) + + for f, d in zip(form.split(' '), data): + if len(f) > 1 and not 's' in f and not 'c' in f: + request += struct.pack('<' + f, *d) + elif 's' in f: + request += pack_string(f, d) + elif 'c' in f: + if len(f) > 1: + if int(f.replace('c', '')) != len(d): + raise ValueError('Incorrect char list length'); + for k in d: + request += pack_string('c', k) + else: + request += pack_string(f, d) + else: + request += struct.pack('<' + f, d) + + if response_expected: + with device.request_lock: + device.expected_response_function_id = function_id + device.expected_response_sequence_number = sequence_number + + try: + self.send(request) + response = device.response_queue.get(True, self.timeout) + except Empty: + msg = 'Did not receive response for function {0} in time'.format(function_id) + raise Error(Error.TIMEOUT, msg) + finally: + device.expected_response_function_id = None + device.expected_response_sequence_number = None + + error_code = get_error_code_from_data(response) + + if error_code == 0: + # no error + pass + elif error_code == 1: + msg = 'Got invalid parameter for function {0}'.format(function_id) + raise Error(Error.INVALID_PARAMETER, msg) + elif error_code == 2: + msg = 'Function {0} is not supported'.format(function_id) + raise Error(Error.NOT_SUPPORTED, msg) + else: + msg = 'Function {0} returned an unknown error'.format(function_id) + raise Error(Error.UNKNOWN_ERROR_CODE, msg) + + if len(form_ret) > 0: + return self.deserialize_data(response[8:], form_ret) + else: + self.send(request) + + def get_next_sequence_number(self): + with self.sequence_number_lock: + sequence_number = self.next_sequence_number + 1 + self.next_sequence_number = sequence_number % 15 + return sequence_number + + def handle_response(self, packet): + function_id = get_function_id_from_data(packet) + sequence_number = get_sequence_number_from_data(packet) + + if sequence_number == 0 and function_id == IPConnection.CALLBACK_ENUMERATE: + if IPConnection.CALLBACK_ENUMERATE in self.registered_callbacks: + self.callback_queue.put((IPConnection.QUEUE_PACKET, packet)) + return + + uid = get_uid_from_data(packet) + + if not uid in self.devices: + # Response from an unknown device, ignoring it + return + + device = self.devices[uid] + + if sequence_number == 0: + if function_id in device.registered_callbacks: + self.callback_queue.put((IPConnection.QUEUE_PACKET, packet)) + return + + if device.expected_response_function_id == function_id and \ + device.expected_response_sequence_number == sequence_number: + device.response_queue.put(packet) + return + + # Response seems to be OK, but can't be handled, most likely + # a callback without registered function + + def create_packet_header(self, device, length, function_id): + uid = IPConnection.BROADCAST_UID + sequence_number = self.get_next_sequence_number() + r_bit = 0 + a_bit = 0 + + if device is not None: + uid = device.uid + + if device.get_response_expected(function_id): + r_bit = 1 + + if device.auth_key is not None: + a_bit = 1 + else: + if self.auth_key is not None: + a_bit = 1 + + sequence_number_and_options = \ + (sequence_number << 4) | (r_bit << 3) | (a_bit << 2) + + return (struct.pack('