def get_c_source(self): template = r""" // Configure threshold for {function_name_comment} "{option_comment}"{declarations} {device_name_under}_set_{function_name_under}_callback_threshold(&{device_name_initial}{arguments}, '{option_char}', {minimum_maximums}); """ minimum_maximums = [] for minimum_maximum in self.get_minimum_maximums(): minimum_maximums.append(minimum_maximum.get_c_source()) arg_declarations, arguments = self.get_c_arguments() declarations = common.wrap_non_empty( '\n', '\n'.join([ '{global_line_prefix}\t{decl}'.format( global_line_prefix=global_line_prefix, decl=decl) for decl in arg_declarations ]), '') return template.format( device_name_under=self.get_device().get_name().under, device_name_initial=self.get_device().get_initial_name(), function_name_under=self.get_name().under, function_name_comment=self.get_comment_name(), declarations=declarations, arguments=common.wrap_non_empty(', ', ', '.join(arguments), ''), option_char=self.get_option_char(), option_comment=self.get_option_comment(), minimum_maximums=', '.join(minimum_maximums))
def get_c_source(self): template = '{comment1}{declarations}{global_line_prefix}\t{device_name_under}_{function_name}(&{device_name_initial}{arguments});{comment2}\n' arg_declarations, arguments = self.get_c_arguments() declarations = common.wrap_non_empty( '', '\n'.join([ '{global_line_prefix}\t{decl}'.format( global_line_prefix=global_line_prefix, decl=decl) for decl in arg_declarations ]), '\n') result = template.format( global_line_prefix=global_line_prefix, device_name_under=self.get_device().get_name().under, device_name_initial=self.get_device().get_initial_name(), function_name=self.get_name().under, declarations=declarations, arguments=common.wrap_non_empty(',<BP>', ',<BP>'.join(arguments), ''), comment1=self.get_formatted_comment1( global_line_prefix + '\t// {0}\n', '\r', '\n' + global_line_prefix + '\t// '), comment2=self.get_formatted_comment2(' // {0}', '')) return common.break_string(result, '_{}('.format(self.get_name().under))
def get_c_source(self): templateA = r""" // Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms){declarations} {device_name_under}_set_{function_name_under}_period(&{device_name_initial}{arguments}, {period_msec}); """ templateB = r""" // Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) // Note: The {function_name_comment} callback is only called every {period_sec_long} // if the {function_name_comment} has changed since the last call!{declarations} {device_name_under}_set_{function_name_under}_callback_period(&{device_name_initial}{arguments}, {period_msec}); """ if self.get_device().get_name().space.startswith('IMU'): template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior and name mismatch else: template = templateB period_msec, period_sec_short, period_sec_long = self.get_formatted_period() arg_declarations, arguments = self.get_c_arguments() declarations = common.wrap_non_empty('\n', '\n'.join(['{global_line_prefix}\t{decl}'.format(global_line_prefix=global_line_prefix, decl=decl) for decl in arg_declarations]), '') return template.format(device_name_under=self.get_device().get_name().under, device_name_initial=self.get_device().get_initial_name(), function_name_under=self.get_name().under, function_name_comment=self.get_comment_name(), declarations=declarations, arguments=common.wrap_non_empty(', ', ', '.join(arguments), ''), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_perl_source(self): template = r"""#!/usr/bin/perl{incomplete} use Tinkerforge::IPConnection; use Tinkerforge::{device_camel_case_category}{device_camel_case_name}; use constant HOST => 'localhost'; use constant PORT => 4223; use constant UID => '{dummy_uid}'; # Change {dummy_uid} to the UID of your {device_long_display_name} {subroutines} my $ipcon = Tinkerforge::IPConnection->new(); # Create IP connection my ${device_initial_name} = Tinkerforge::{device_camel_case_category}{device_camel_case_name}->new(&UID, $ipcon); # Create device object $ipcon->connect(&HOST, &PORT); # Connect to brickd # Don't use device before ipcon is connected {sources} print "Press key to exit\n"; <STDIN>;{cleanups} $ipcon->disconnect(); """ if self.is_incomplete(): incomplete = '\n\n# FIXME: This example is incomplete' else: incomplete = '' subroutines = [] sources = [] cleanups = [] for function in self.get_functions(): subroutines.append(function.get_perl_subroutine()) sources.append(function.get_perl_source()) for cleanup in self.get_cleanups(): subroutines.append(cleanup.get_perl_subroutine()) cleanups.append(cleanup.get_perl_source()) while None in subroutines: subroutines.remove(None) while None in sources: sources.remove(None) if len(sources) == 0: sources = ['# TODO: Add example code here\n'] while None in cleanups: cleanups.remove(None) return template.format(incomplete=incomplete, device_camel_case_category=self.get_device().get_camel_case_category(), device_camel_case_name=self.get_device().get_camel_case_name(), device_initial_name=self.get_device().get_initial_name(), device_long_display_name=self.get_device().get_long_display_name(), dummy_uid=self.get_dummy_uid(), subroutines=common.wrap_non_empty('\n', '\n'.join(subroutines), ''), sources='\n' + '\n'.join(sources).replace('\n\r', '').lstrip('\r'), cleanups=common.wrap_non_empty('\n', '\n'.join(cleanups).replace('\n\r', '').lstrip('\r').rstrip('\n'), ''))
def get_c_function(self): template1A = r"""// Callback function for {function_name_comment} callback """ template1B = r"""{override_comment} """ template2 = r"""void cb_{function_name_under}({parameters}void *user_data) {{ {unuseds} {printfs}{extra_message} }} """ override_comment = self.get_formatted_override_comment( '// {0}', None, '\n// ') if override_comment == None: template1 = template1A else: template1 = template1B parameters = [] unuseds = [] printfs = [] for parameter in self.get_parameters(): parameters.append(parameter.get_c_source()) unuseds += parameter.get_c_unuseds() printfs += parameter.get_c_printfs() while None in unuseds: unuseds.remove(None) unuseds.append('(void)user_data;') unuseds = common.wrap_non_empty('', '<BP>'.join(unuseds), ' // avoid unused parameter warning') unuseds = common.break_string(unuseds, '').replace('\n', '\n\t') while None in printfs: printfs.remove(None) if len(printfs) > 1: printfs.append('\tprintf("\\n");') extra_message = self.get_formatted_extra_message( '\tprintf("{0}\\n");').replace('%', '%%') if len(extra_message) > 0 and len(printfs) > 0: extra_message = '\n' + extra_message result = template1.format(function_name_comment=self.get_comment_name(), override_comment=override_comment) + \ template2.format(function_name_under=self.get_name().under, parameters=common.wrap_non_empty('', ',<BP>'.join(parameters), ',<BP>'), unuseds=unuseds, printfs='\n'.join(printfs).replace('\r\n\r', '\n\n').strip('\r').replace('\r', '\n'), extra_message=extra_message) return common.break_string(result, 'cb_{}('.format(self.get_name().under))
def get_c_function(self): template1A = r"""// Callback function for {function_comment_name} callback{comments} """ template1B = r"""{override_comment} """ template2 = r"""void cb_{function_underscore_name}({parameters}void *user_data) {{{unuseds} (void)user_data; // avoid unused parameter warning {printfs}{extra_message} }} """ override_comment = self.get_formatted_override_comment( '// {0}', None, '\n// ') if override_comment == None: template1 = template1A else: template1 = template1B comments = [] parameters = [] unuseds = [] printfs = [] for parameter in self.get_parameters(): comments.append(parameter.get_formatted_comment()) parameters.append(parameter.get_c_source()) unuseds.append(parameter.get_c_unused()) printfs.append(parameter.get_c_printf()) if len(comments) > 1 and len(set(comments)) == 1: comments = [ comments[0].replace('parameter has', 'parameters have') ] while None in unuseds: unuseds.remove(None) while None in printfs: printfs.remove(None) if len(printfs) > 1: printfs.append('\tprintf("\\n");') extra_message = self.get_formatted_extra_message( '\tprintf("{0}\\n");').replace('%', '%%') if len(extra_message) > 0 and len(printfs) > 0: extra_message = '\n' + extra_message return template1.format(function_comment_name=self.get_comment_name(), comments=''.join(comments), override_comment=override_comment) + \ template2.format(function_underscore_name=self.get_underscore_name(), parameters=common.wrap_non_empty('', ', '.join(parameters), ', '), unuseds=common.wrap_non_empty('\n', '\n'.join(unuseds), ''), printfs='\n'.join(printfs), extra_message=extra_message)
def get_c_function(self): template1A = r"""// Callback function for {function_comment_name} callback{comments} """ template1B = r"""{override_comment} """ template2 = r"""void cb_{function_underscore_name}({parameters}void *user_data) {{{unuseds} (void)user_data; // avoid unused parameter warning {printfs}{extra_message} }} """ override_comment = self.get_formatted_override_comment('// {0}', None, '\n// ') if override_comment == None: template1 = template1A else: template1 = template1B comments = [] parameters = [] unuseds = [] printfs = [] for parameter in self.get_parameters(): comments.append(parameter.get_formatted_comment()) parameters.append(parameter.get_c_source()) unuseds.append(parameter.get_c_unused()) printfs.append(parameter.get_c_printf()) if len(comments) > 1 and len(set(comments)) == 1: comments = [comments[0].replace('parameter has', 'parameters have')] while None in unuseds: unuseds.remove(None) while None in printfs: printfs.remove(None) if len(printfs) > 1: printfs.append('\tprintf("\\n");') extra_message = self.get_formatted_extra_message('\tprintf("{0}\\n");').replace('%', '%%') if len(extra_message) > 0 and len(printfs) > 0: extra_message = '\n' + extra_message result = template1.format(function_comment_name=self.get_comment_name(), comments=''.join(comments), override_comment=override_comment) + \ template2.format(function_underscore_name=self.get_underscore_name(), parameters=common.wrap_non_empty('', ',<BP>'.join(parameters), ',<BP>'), unuseds=common.wrap_non_empty('\n', '\n'.join(unuseds), ''), printfs='\n'.join(printfs), extra_message=extra_message) return common.break_string(result, 'cb_{}('.format(self.get_underscore_name()))
def get_c_function(self): template1A = r"""// Callback function for {function_name_comment} callback """ template1B = r"""{override_comment} """ template2 = r"""void cb_{function_name_under}({parameters}void *user_data) {{ {unuseds} {printfs}{extra_message} }} """ override_comment = self.get_formatted_override_comment('// {0}', None, '\n// ') if override_comment == None: template1 = template1A else: template1 = template1B parameters = [] unuseds = [] printfs = [] for parameter in self.get_parameters(): parameters.append(parameter.get_c_source()) unuseds += parameter.get_c_unuseds() printfs += parameter.get_c_printfs() while None in unuseds: unuseds.remove(None) unuseds.append('(void)user_data;') unuseds = common.wrap_non_empty('', '<BP>'.join(unuseds), ' // avoid unused parameter warning') unuseds = common.break_string(unuseds, '').replace('\n', '\n\t') while None in printfs: printfs.remove(None) if len(printfs) > 1: printfs.append('\tprintf("\\n");') extra_message = self.get_formatted_extra_message('\tprintf("{0}\\n");').replace('%', '%%') if len(extra_message) > 0 and len(printfs) > 0: extra_message = '\n' + extra_message result = template1.format(function_name_comment=self.get_comment_name(), override_comment=override_comment) + \ template2.format(function_name_under=self.get_name().under, parameters=common.wrap_non_empty('', ',<BP>'.join(parameters), ',<BP>'), unuseds=unuseds, printfs='\n'.join(printfs).replace('\r\n\r', '\n\n').strip('\r').replace('\r', '\n'), extra_message=extra_message) return common.break_string(result, 'cb_{}('.format(self.get_name().under))
def get_mathematica_source(self): templateA = r"""(*Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms)*) {device_name_initial}@Set{function_name_camel}CallbackConfiguration[{arguments}{period_msec}{value_has_to_change}] """ templateB = r"""(*Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) without a threshold*) option=Tinkerforge`{device_category}{device_name_camel}`THRESHOLDUOPTIONU{option_name} {device_name_initial}@Set{function_name_camel}CallbackConfiguration[{arguments}{period_msec}{value_has_to_change},option,{minimum_maximums}] """ templateC = r"""(*Configure threshold for {function_name_comment} "{option_comment}"*) (*with a debounce period of {period_sec_short} ({period_msec}ms)*) option=Tinkerforge`{device_category}{device_name_camel}`THRESHOLDUOPTIONU{option_name} {device_name_initial}@Set{function_name_camel}CallbackConfiguration[{arguments}{period_msec}{value_has_to_change},option,{minimum_maximums}] """ if self.get_option_char() == None: template = templateA elif self.get_option_char() == 'x': template = templateB else: template = templateC period_msec, period_sec_short, period_sec_long = self.get_formatted_period( ) minimum_maximums = [] for minimum_maximum in self.get_minimum_maximums(): minimum_maximums.append(minimum_maximum.get_mathematica_source()) option_names = { None: '', 'x': 'OFF', 'o': 'OUTSIDE', '<': 'SMALLER', '>': 'GREATER' } return template.format( device_category=self.get_device().get_category().camel, device_name_camel=self.get_device().get_name().camel, device_name_initial=self.get_device().get_initial_name(), function_name_camel=self.get_name().camel, function_name_under=self.get_name().under, function_name_comment=self.get_comment_name(), option_name=option_names[self.get_option_char()], option_comment=self.get_option_comment(), arguments=common.wrap_non_empty( '', ','.join(self.get_mathematica_arguments()), ','), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long, value_has_to_change=common.wrap_non_empty( ',', self.get_value_has_to_change('True', 'False', ''), ''), minimum_maximums=','.join(minimum_maximums))
def get_shell_source(self): templateA = r"""# Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) tinkerforge call {device_name}-{device_category} $uid set-{function_name_dash}-callback-configuration {arguments}{period_msec}{value_has_to_change} """ templateB = r"""# Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) without a threshold tinkerforge call {device_name}-{device_category} $uid set-{function_name_dash}-callback-configuration {arguments}{period_msec}{value_has_to_change} {option_name_dash} {minimum_maximums} """ templateC = r"""# Configure threshold for {function_name_comment} "{option_comment}" # with a debounce period of {period_sec_short} ({period_msec}ms) tinkerforge call {device_name}-{device_category} $uid set-{function_name_dash}-callback-configuration {arguments}{period_msec}{value_has_to_change} {option_name_dash} {minimum_maximums} """ if self.get_option_char() == None: template = templateA elif self.get_option_char() == 'x': template = templateB else: template = templateC period_msec, period_sec_short, period_sec_long = self.get_formatted_period( ) minimum_maximums = [] for minimum_maximum in self.get_minimum_maximums(): minimum_maximums.append(minimum_maximum.get_shell_source()) option_name_dashs = { None: '', 'x': 'threshold-option-off', 'o': 'threshold-option-outside', '<': 'threshold-option-smaller', '>': 'threshold-option-greater' } return template.format( device_name=self.get_device().get_name().dash, device_category=self.get_device().get_category().dash, function_name_dash=self.get_name().dash, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty( '', ' '.join(self.get_shell_arguments()), ' '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long, value_has_to_change=common.wrap_non_empty( ' ', self.get_value_has_to_change('true', 'false', ''), ''), option_name_dash=option_name_dashs[self.get_option_char()], option_comment=self.get_option_comment(), minimum_maximums=' '.join(minimum_maximums))
def get_c_source(self): templateA = r""" // Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms){declarations} {device_name_under}_set_{function_name_under}_callback_configuration(&{device_name_initial}{arguments}, {period_msec}{value_has_to_change}); """ templateB = r""" // Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) without a threshold{declarations} {device_name_under}_set_{function_name_under}_callback_configuration(&{device_name_initial}{arguments}, {period_msec}{value_has_to_change}, '{option_char}', {minimum_maximums}); """ templateC = r""" // Configure threshold for {function_name_comment} "{option_comment}" // with a debounce period of {period_sec_short} ({period_msec}ms){declarations} {device_name_under}_set_{function_name_under}_callback_configuration(&{device_name_initial}{arguments}, {period_msec}{value_has_to_change}, '{option_char}', {minimum_maximums}); """ if self.get_option_char() == None: template = templateA elif self.get_option_char() == 'x': template = templateB else: template = templateC minimum_maximums = [] period_msec, period_sec_short, period_sec_long = self.get_formatted_period( ) for minimum_maximum in self.get_minimum_maximums(): minimum_maximums.append(minimum_maximum.get_c_source()) arg_declarations, arguments = self.get_c_arguments() declarations = common.wrap_non_empty( '\n', '\n'.join([ '{global_line_prefix}\t{decl}'.format( global_line_prefix=global_line_prefix, decl=decl) for decl in arg_declarations ]), '') return template.format( device_name_under=self.get_device().get_name().under, device_name_initial=self.get_device().get_initial_name(), function_name_under=self.get_name().under, function_name_comment=self.get_comment_name(), declarations=declarations, arguments=common.wrap_non_empty(', ', ', '.join(arguments), ''), period_msec=period_msec, period_sec_short=period_sec_short, value_has_to_change=common.wrap_non_empty( ', ', self.get_value_has_to_change('true', 'false', ''), ''), option_char=self.get_option_char(), option_comment=self.get_option_comment(), minimum_maximums=', '.join(minimum_maximums))
def get_c_source(self): templateA = r""" // Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) {device_name_under}_set_{function_name_under}_period(&{device_name_initial}{arguments}, {period_msec}); """ templateB = r""" // Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) // Note: The {function_name_comment} callback is only called every {period_sec_long} // if the {function_name_comment} has changed since the last call! {device_name_under}_set_{function_name_under}_callback_period(&{device_name_initial}{arguments}, {period_msec}); """ if self.get_device().get_name().space.startswith('IMU'): template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior and name mismatch else: template = templateB period_msec, period_sec_short, period_sec_long = self.get_formatted_period( ) return template.format( device_name_under=self.get_device().get_name().under, device_name_initial=self.get_device().get_initial_name(), function_name_under=self.get_name().under, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty(', ', ', '.join(self.get_c_arguments()), ''), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_shell_source(self): template = r"""# Configure threshold for {function_comment_name} "{option_comment}"{mininum_maximum_unit_comments} tinkerforge call {device_dash_name}-{device_dash_category} $uid set-{function_dash_name}-callback-threshold {arguments}{option_dash_name} {mininum_maximums} """ arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_shell_source()) mininum_maximums = [] mininum_maximum_unit_comments = [] for mininum_maximum in self.get_minimum_maximums(): mininum_maximums.append(mininum_maximum.get_shell_source()) mininum_maximum_unit_comments.append( mininum_maximum.get_unit_comment()) if len(mininum_maximum_unit_comments) > 1 and len( set(mininum_maximum_unit_comments)) == 1: mininum_maximum_unit_comments = mininum_maximum_unit_comments[:1] option_dash_names = {'o': 'outside', '<': 'smaller', '>': 'greater'} return template.format( device_dash_name=self.get_device().get_dash_name(), device_dash_category=self.get_device().get_dash_category(), function_dash_name=self.get_dash_name(), function_comment_name=self.get_comment_name(), arguments=common.wrap_non_empty('', ' '.join(arguments), ' '), option_dash_name=option_dash_names[self.get_option_char()], option_comment=self.get_option_comment(), mininum_maximums=' '.join(mininum_maximums), mininum_maximum_unit_comments=''.join( mininum_maximum_unit_comments))
def get_shell_source(self): template = r"""# Set period for {function_comment_name} callback to {period_sec_short} ({period_msec}ms) # Note: The {function_comment_name} callback is only called every {period_sec_long} # if the {function_comment_name} has changed since the last call! tinkerforge call {device_dash_name}-{device_dash_category} $uid set-{function_dash_name}{suffix}-period {arguments}{period_msec} """ if self.get_device().get_underscore_name().startswith('imu'): suffix = '' # FIXME: special hack for IMU Brick name mismatch else: suffix = '-callback' arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_shell_source()) period_msec, period_sec_short, period_sec_long = self.get_formatted_period( ) return template.format( device_dash_name=self.get_device().get_dash_name(), device_dash_category=self.get_device().get_dash_category(), function_dash_name=self.get_dash_name(), function_comment_name=self.get_comment_name(), suffix=suffix, arguments=common.wrap_non_empty('', ' '.join(arguments), ' '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_mqtt_source(self): template = "{comment1}{global_line_prefix}publish '{arguments}' to tinkerforge/request/{device_name}_{device_category}/{uid}/{function_name} {comment2}\n" bitmask_comments = [] for argument in self.get_arguments(): bitmask_comments.append(argument.get_mqtt_bitmask_comment()) while None in bitmask_comments: bitmask_comments.remove(None) comment1 = self.get_formatted_comment1(global_line_prefix + '# {0}\n', '\r', '\n' + global_line_prefix + '# ') comment2 = self.get_formatted_comment2(' # {0}', '') if len(bitmask_comments) > 0: if comment1 == '\r': if len(comment2) == 0: comment2 = ' # ' + ', '.join(bitmask_comments) else: comment2 += ': ' + ', '.join(bitmask_comments) else: comment1 = comment1.rstrip('\n') + ': ' + ', '.join(bitmask_comments) + '\n' return template.format(global_line_prefix=global_line_prefix, device_name=self.get_device().get_name().under, device_category=self.get_device().get_category().under, uid=self.get_example().get_dummy_uid(), function_name=self.get_name().under, arguments=common.wrap_non_empty('{', ', '.join(self.get_mqtt_arguments()), '}'), comment1=comment1, comment2=comment2)
def get_javascript_source(self): template = r"""{global_line_prefix} // Get current {function_name_comment} {global_line_prefix} {device_name}.{function_name_headless}({arguments} {global_line_prefix} function ({variables}) {{ {outputs} {global_line_prefix} }}, {global_line_prefix} function (error) {{ {global_line_prefix} {global_output_prefix}'Error: ' + error{global_output_suffix}; {global_line_prefix} }} {global_line_prefix} ); """ variables = [] outputs = [] for result in self.get_results(): variables.append(result.get_javascript_source()) outputs += result.get_javascript_outputs() while None in outputs: outputs.remove(None) return template.format(global_line_prefix=global_line_prefix, global_output_prefix=global_output_prefix, global_output_suffix=global_output_suffix, device_name=self.get_device().get_initial_name(), function_name_headless=self.get_name().headless, function_name_comment=self.get_comment_name(), variables=', '.join(variables), outputs='\n'.join(outputs).replace('\r\n\r', '\n\n').strip('\r').replace('\r', '\n'), arguments=common.wrap_non_empty('', ', '.join(self.get_javascript_arguments()), ','))
def get_mqtt_source(self): callback_fn = "set_{function_name_under}_period" if self.get_device().get_name().space.startswith('IMU') else "set_{function_name_under}_callback_period" callback_fn = callback_fn.format(function_name_under=self.get_name().under) templateA = r"""# Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) publish '{arguments}' to tinkerforge/request/{device_name}_{device_category}/{uid}/{callback_fn} """ templateB = r"""# Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) # Note: The {function_name_comment} callback is only called every {period_sec_long} # if the {function_name_comment} has changed since the last call! publish '{arguments}' to tinkerforge/request/{device_name}_{device_category}/{uid}/{callback_fn} """ if self.get_device().get_name().space.startswith('IMU'): template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior and name mismatch else: template = templateB period_msec, period_sec_short, period_sec_long = self.get_formatted_period() args = self.get_mqtt_arguments(callback_fn) + ['"period": ' + str(period_msec)] return template.format(device_name=self.get_device().get_name().under, uid=self.get_example().get_dummy_uid(), device_category=self.get_device().get_category().under, callback_fn=callback_fn, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty('{', ', '.join(args), '}'), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_mqtt_source(self): callback_fn = "set_{function_name_under}_callback_threshold".format(function_name_under=self.get_name().under) template = r"""# Configure threshold for {function_name_comment} "{option_comment}" publish '{arguments}' to tinkerforge/request/{device_name}_{device_category}/{uid}/{callback_fn} """ packet = None for p in self.get_device().get_packets('function'): if callback_fn in p.get_name().under: packet = p packet_min_max_names = [elem.get_name().under[3:] for elem in packet.get_elements(direction='in') if elem.get_name().under.startswith('min') ] minimum_maximums = [] for mm_name, minimum_maximum in zip(packet_min_max_names, self.get_minimum_maximums()): minimum_maximums.append(minimum_maximum.get_mqtt_source().format(mm_name=mm_name)) option_name_unders = {'o' : 'outside', '<': 'smaller', '>': 'greater'} args = self.get_mqtt_arguments(callback_fn) + ['"option": "' + option_name_unders[self.get_option_char()]+'"'] + minimum_maximums return template.format(device_name=self.get_device().get_name().under, device_category=self.get_device().get_category().under, callback_fn=callback_fn, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty('{', ', '.join(args), '}'), option_comment=self.get_option_comment(), uid=self.get_example().get_dummy_uid())
def get_javascript_source(self): templateA = r"""{global_line_prefix} // Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) {global_line_prefix} {device_name}.set{function_name_camel}Period({arguments}{period_msec}); """ templateB = r"""{global_line_prefix} // Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) {global_line_prefix} // Note: The {function_name_comment} callback is only called every {period_sec_long} {global_line_prefix} // if the {function_name_comment} has changed since the last call! {global_line_prefix} {device_name}.set{function_name_camel}CallbackPeriod({arguments}{period_msec}); """ if self.get_device().get_name().space.startswith('IMU'): template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior and name mismatch else: template = templateB period_msec, period_sec_short, period_sec_long = self.get_formatted_period( ) return template.format( global_line_prefix=global_line_prefix, device_name=self.get_device().get_initial_name(), function_name_camel=self.get_name().camel, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty( '', ', '.join(self.get_javascript_arguments()), ', '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_tvpl_source(self): template = r""" # Configure threshold for {function_comment_name} "{option_comment}"{mininum_maximum_unit_comments} {device_initial_name}.set_{function_underscore_name}_callback_threshold({arguments}"{option_char}", {mininum_maximums}) """ arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_tvpl_source()) mininum_maximums = [] mininum_maximum_unit_comments = [] for mininum_maximum in self.get_minimum_maximums(): mininum_maximums.append(mininum_maximum.get_tvpl_source()) mininum_maximum_unit_comments.append(mininum_maximum.get_unit_comment()) if len(mininum_maximum_unit_comments) > 1 and len(set(mininum_maximum_unit_comments)) == 1: mininum_maximum_unit_comments = mininum_maximum_unit_comments[:1] return template.format(device_initial_name=self.get_device().get_initial_name(), function_underscore_name=self.get_underscore_name(), function_comment_name=self.get_comment_name(), arguments=common.wrap_non_empty('', ', '.join(arguments), ', '), option_char=self.get_option_char(), option_comment=self.get_option_comment(), mininum_maximums=', '.join(mininum_maximums), mininum_maximum_unit_comments=''.join(mininum_maximum_unit_comments))
def get_javascript_source(self): templateA = r"""{global_line_prefix} // Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) {global_line_prefix} {device_name}.set{function_name_camel}Period({arguments}{period_msec}); """ templateB = r"""{global_line_prefix} // Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) {global_line_prefix} // Note: The {function_name_comment} callback is only called every {period_sec_long} {global_line_prefix} // if the {function_name_comment} has changed since the last call! {global_line_prefix} {device_name}.set{function_name_camel}CallbackPeriod({arguments}{period_msec}); """ if self.get_device().get_name().space.startswith('IMU'): template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior and name mismatch else: template = templateB period_msec, period_sec_short, period_sec_long = self.get_formatted_period() return template.format(global_line_prefix=global_line_prefix, device_name=self.get_device().get_initial_name(), function_name_camel=self.get_name().camel, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty('', ', '.join(self.get_javascript_arguments()), ', '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_c_source(self): template = '{comment1}{declarations}{global_line_prefix}\t{device_name_under}_{function_name}(&{device_name_initial}{arguments});{comment2}\n' arg_declarations, arguments = self.get_c_arguments() declarations = common.wrap_non_empty('', '\n'.join(['{global_line_prefix}\t{decl}'.format(global_line_prefix=global_line_prefix, decl=decl) for decl in arg_declarations]), '\n') result = template.format(global_line_prefix=global_line_prefix, device_name_under=self.get_device().get_name().under, device_name_initial=self.get_device().get_initial_name(), function_name=self.get_name().under, declarations=declarations, arguments=common.wrap_non_empty(',<BP>', ',<BP>'.join(arguments), ''), comment1=self.get_formatted_comment1(global_line_prefix + '\t// {0}\n', '\r', '\n' + global_line_prefix + '\t// '), comment2=self.get_formatted_comment2(' // {0}', '')) return common.break_string(result, '_{}('.format(self.get_name().under))
def get_rust_methods(self, type_): methods = '' func_start = '.. rust:function:: ' synchronous_methods = ["get_api_version", "get_response_expected", "set_response_expected", "set_response_expected_all"] for packet in self.get_packets('function'): if packet.get_doc_type() != type_: continue skip = -2 if packet.has_high_level() else 0 name = packet.get_name(skip=skip).under plist = common.wrap_non_empty(', ', packet.get_rust_parameters(high_level=True), '') returns = packet.get_rust_return_type(high_level = packet.has_high_level()) if not packet.has_high_level() and name not in synchronous_methods: returns = "ConvertingReceiver<" + returns + ">" if "et_response_expected" in name: params = '&mut self{}'.format(plist) else: params = '&self{}'.format(plist) desc = packet.get_rust_formatted_doc() func = '{start}{struct_name}::{func_name}({params})-> {returns}\n{desc}'.format(start=func_start, struct_name=self.get_rust_name(), func_name=name, params=params, returns = returns, desc=desc) methods += func + '\n' return methods
def get_python_init_method(self): template = """ 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 = ({0}, {1}, {2}) """ response_expected = '' for packet in self.get_packets('function'): if len(packet.get_elements(direction='out')) > 0: flag = 'RESPONSE_EXPECTED_ALWAYS_TRUE' elif packet.get_doc_type( ) == 'ccf' or packet.get_high_level('stream_in') != None: flag = 'RESPONSE_EXPECTED_TRUE' else: flag = 'RESPONSE_EXPECTED_FALSE' response_expected += ' self.response_expected[{0}.FUNCTION_{1}] = {0}.{2}\n' \ .format(self.get_python_class_name(), packet.get_name().upper, flag) return template.format( *self.get_api_version()) + common.wrap_non_empty( '', response_expected, '\n')
def get_tvpl_source(self): templateA = r""" # Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) {device_name}.set_{function_name_under}{suffix}_period({arguments}{period_msec}) """ templateB = r""" # Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) # Note: The {function_name_comment} callback is only called every {period_sec_long} # if the {function_name_comment} has changed since the last call! {device_name}.set_{function_name_under}{suffix}_period({arguments}{period_msec}) """ if self.get_device().get_name().space.startswith('IMU'): template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior suffix = '' # FIXME: special hack for IMU Brick name mismatch else: template = templateB suffix = '_callback' arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_tvpl_source()) period_msec, period_sec_short, period_sec_long = self.get_formatted_period( ) return template.format( device_name=self.get_device().get_initial_name(), function_name_under=self.get_name().under, function_name_comment=self.get_comment_name(), suffix=suffix, arguments=common.wrap_non_empty('', ', '.join(arguments), ', '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_tvpl_source(self): templateA = r""" # Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) {device_name}.set_{function_name_under}{suffix}_period({arguments}{period_msec}) """ templateB = r""" # Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) # Note: The {function_name_comment} callback is only called every {period_sec_long} # if the {function_name_comment} has changed since the last call! {device_name}.set_{function_name_under}{suffix}_period({arguments}{period_msec}) """ if self.get_device().get_name().space.startswith('IMU'): template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior suffix = '' # FIXME: special hack for IMU Brick name mismatch else: template = templateB suffix = '_callback' arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_tvpl_source()) period_msec, period_sec_short, period_sec_long = self.get_formatted_period() return template.format(device_name=self.get_device().get_initial_name(), function_name_under=self.get_name().under, function_name_comment=self.get_comment_name(), suffix=suffix, arguments=common.wrap_non_empty('', ', '.join(arguments), ', '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_javascript_source(self): template = r"""{global_line_prefix} // Get current {function_name_comment} {global_line_prefix} {device_name}.{function_name_headless}({arguments} {global_line_prefix} function ({variables}) {{ {outputs} {global_line_prefix} }}, {global_line_prefix} function (error) {{ {global_line_prefix} {global_output_prefix}'Error: ' + error{global_output_suffix}; {global_line_prefix} }} {global_line_prefix} ); """ variables = [] outputs = [] for result in self.get_results(): variables.append(result.get_javascript_source()) outputs += result.get_javascript_outputs() while None in outputs: outputs.remove(None) return template.format( global_line_prefix=global_line_prefix, global_output_prefix=global_output_prefix, global_output_suffix=global_output_suffix, device_name=self.get_device().get_initial_name(), function_name_headless=self.get_name().headless, function_name_comment=self.get_comment_name(), variables=', '.join(variables), outputs='\n'.join(outputs).replace('\r\n\r', '\n\n').strip('\r').replace( '\r', '\n'), arguments=common.wrap_non_empty( '', ', '.join(self.get_javascript_arguments()), ','))
def get_php_constructor(self): template = """ /** * Creates an object with the unique device ID $uid. This object can * then be added to the IP connection. * * @param string $uid */ public function __construct($uid, $ipcon) {{ parent::__construct($uid, $ipcon); $this->api_version = array({0}, {1}, {2}); """ response_expected = '' for packet in self.get_packets('function'): if len(packet.get_elements(direction='out')) > 0: flag = 'RESPONSE_EXPECTED_ALWAYS_TRUE' elif packet.get_doc_type( ) == 'ccf' or packet.get_high_level('stream_in') != None: flag = 'RESPONSE_EXPECTED_TRUE' else: flag = 'RESPONSE_EXPECTED_FALSE' response_expected += ' $this->response_expected[self::FUNCTION_{0}] = self::{1};\n' \ .format(packet.get_name().upper, flag) return template.format( *self.get_api_version()) + common.wrap_non_empty( '\n', response_expected, '')
def get_shell_source(self): templateA = r"""# Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) tinkerforge call {device_name}-{device_category} $uid set-{function_name_dash}-period {arguments}{period_msec} """ templateB = r"""# Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) # Note: The {function_name_comment} callback is only called every {period_sec_long} # if the {function_name_comment} has changed since the last call! tinkerforge call {device_name}-{device_category} $uid set-{function_name_dash}-callback-period {arguments}{period_msec} """ if self.get_device().get_name().space.startswith('IMU'): template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior and name mismatch else: template = templateB period_msec, period_sec_short, period_sec_long = self.get_formatted_period( ) return template.format( device_name=self.get_device().get_name().dash, device_category=self.get_device().get_category().dash, function_name_dash=self.get_name().dash, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty( '', ' '.join(self.get_shell_arguments()), ' '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_shell_source(self): templateA = r"""# Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) tinkerforge call {device_name}-{device_category} $uid set-{function_name_dash}-period {arguments}{period_msec} """ templateB = r"""# Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) # Note: The {function_name_comment} callback is only called every {period_sec_long} # if the {function_name_comment} has changed since the last call! tinkerforge call {device_name}-{device_category} $uid set-{function_name_dash}-callback-period {arguments}{period_msec} """ if self.get_device().get_name().space.startswith('IMU'): template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior and name mismatch else: template = templateB period_msec, period_sec_short, period_sec_long = self.get_formatted_period() return template.format(device_name=self.get_device().get_name().dash, device_category=self.get_device().get_category().dash, function_name_dash=self.get_name().dash, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty('', ' '.join(self.get_shell_arguments()), ' '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_shell_source(self): template = r"""# Set period for {function_comment_name} callback to {period_sec_short} ({period_msec}ms) # Note: The {function_comment_name} callback is only called every {period_sec_long} # if the {function_comment_name} has changed since the last call! tinkerforge call {device_dash_name}-{device_dash_category} $uid set-{function_dash_name}{suffix}-period {arguments}{period_msec} """ if self.get_device().get_underscore_name().startswith('imu'): suffix = '' # FIXME: special hack for IMU Brick name mismatch else: suffix = '-callback' arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_shell_source()) period_msec, period_sec_short, period_sec_long = self.get_formatted_period() return template.format(device_dash_name=self.get_device().get_dash_name(), device_dash_category=self.get_device().get_dash_category(), function_dash_name=self.get_dash_name(), function_comment_name=self.get_comment_name(), suffix=suffix, arguments=common.wrap_non_empty('', ' '.join(arguments), ' '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_mathematica_source(self): template = r"""(*Configure threshold for {function_comment_name} "{option_comment}"{mininum_maximum_unit_comments}*) option=Tinkerforge`{device_camel_case_category}{device_camel_case_name}`THRESHOLDUOPTIONU{option_upper_case_name} {device_initial_name}@Set{function_camel_case_name}CallbackThreshold[{arguments}option,{mininum_maximums}] """ arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_mathematica_source()) mininum_maximums = [] mininum_maximum_unit_comments = [] for mininum_maximum in self.get_minimum_maximums(): mininum_maximums.append(mininum_maximum.get_mathematica_source()) mininum_maximum_unit_comments.append(mininum_maximum.get_unit_comment()) if len(mininum_maximum_unit_comments) > 1 and len(set(mininum_maximum_unit_comments)) == 1: mininum_maximum_unit_comments = mininum_maximum_unit_comments[:1] option_upper_case_names = {'o' : 'OUTSIDE', '<': 'SMALLER', '>': 'GREATER'} return template.format(device_camel_case_category=self.get_device().get_camel_case_category(), device_camel_case_name=self.get_device().get_camel_case_name(), device_initial_name=self.get_device().get_initial_name(), function_camel_case_name=self.get_camel_case_name(), function_underscore_name=self.get_underscore_name(), function_comment_name=self.get_comment_name(), option_upper_case_name=option_upper_case_names[self.get_option_char()], option_comment=self.get_option_comment(), arguments=common.wrap_non_empty('', ','.join(arguments), ','), mininum_maximums=','.join(mininum_maximums), mininum_maximum_unit_comments=''.join(mininum_maximum_unit_comments))
def get_delphi_source(self): template = r""" {{ Configure threshold for {function_comment_name} "{option_comment}"{mininum_maximum_unit_comments} }} {device_initial_name}.Set{function_camel_case_name}CallbackThreshold({arguments}'{option_char}', {mininum_maximums}); """ arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_delphi_source()) mininum_maximums = [] mininum_maximum_unit_comments = [] for mininum_maximum in self.get_minimum_maximums(): mininum_maximums.append(mininum_maximum.get_delphi_source()) mininum_maximum_unit_comments.append(mininum_maximum.get_unit_comment()) if len(mininum_maximum_unit_comments) > 1 and len(set(mininum_maximum_unit_comments)) == 1: mininum_maximum_unit_comments = mininum_maximum_unit_comments[:1] return template.format(device_initial_name=self.get_device().get_initial_name(), function_camel_case_name=self.get_camel_case_name(), function_comment_name=self.get_comment_name(), arguments=common.wrap_non_empty('', ', '.join(arguments), ', '), option_char=self.get_option_char(), option_comment=self.get_option_comment(), mininum_maximums=', '.join(mininum_maximums), mininum_maximum_unit_comments=''.join(mininum_maximum_unit_comments))
def get_shell_source(self): template = '{comment1}{global_line_prefix}tinkerforge call {device_dash_name}-{device_dash_category} $uid {function_dash_name}{arguments}{comment2}\n' bitmask_comments = [] arguments = [] for argument in self.get_arguments(): bitmask_comments.append(argument.get_shell_bitmask_comment()) arguments.append(argument.get_shell_source()) while None in bitmask_comments: bitmask_comments.remove(None) comment1 = self.get_formatted_comment1(global_line_prefix + '# {0}\n', '\r', '\n' + global_line_prefix + '# ') comment2 = self.get_formatted_comment2(' # {0}', '') if len(bitmask_comments) > 0: if comment1 == '\r': if len(comment2) == 0: comment2 = ' # ' + ', '.join(bitmask_comments) else: comment2 += ': ' + ', '.join(bitmask_comments) else: comment1 = comment1.rstrip('\n') + ': ' + ', '.join(bitmask_comments) + '\n' return template.format(global_line_prefix=global_line_prefix, device_dash_name=self.get_device().get_dash_name(), device_dash_category=self.get_device().get_dash_category(), function_dash_name=self.get_dash_name(), arguments=common.wrap_non_empty(' ', ' '.join(arguments), ''), comment1=comment1, comment2=comment2)
def get_delphi_source(self): template = r""" {{ Set period for {function_comment_name} callback to {period_sec_short} ({period_msec}ms) Note: The {function_comment_name} callback is only called every {period_sec_long} if the {function_comment_name} has changed since the last call! }} {device_initial_name}.Set{function_camel_case_name}{suffix}Period({arguments}{period_msec}); """ if self.get_device().get_underscore_name().startswith('imu'): suffix = '' # FIXME: special hack for IMU Brick name mismatch else: suffix = 'Callback' arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_delphi_source()) period_msec, period_sec_short, period_sec_long = self.get_formatted_period() return template.format(device_initial_name=self.get_device().get_initial_name(), function_camel_case_name=self.get_camel_case_name(), function_comment_name=self.get_comment_name(), suffix=suffix, arguments=common.wrap_non_empty('', ', '.join(arguments), ', '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_shell_source(self): template = r"""# Configure threshold for {function_name_comment} "{option_comment}" tinkerforge call {device_name}-{device_category} $uid set-{function_name_dash}-callback-threshold {arguments}{option_name_dash} {minimum_maximums} """ minimum_maximums = [] for minimum_maximum in self.get_minimum_maximums(): minimum_maximums.append(minimum_maximum.get_shell_source()) option_name_dashs = { 'o': 'threshold-option-outside', '<': 'threshold-option-smaller', '>': 'threshold-option-greater' } return template.format( device_name=self.get_device().get_name().dash, device_category=self.get_device().get_category().dash, function_name_dash=self.get_name().dash, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty( '', ' '.join(self.get_shell_arguments()), ' '), option_name_dash=option_name_dashs[self.get_option_char()], option_comment=self.get_option_comment(), minimum_maximums=' '.join(minimum_maximums))
def get_rust_source(self): templateA = r""" // Set period for {function_name_comment} receiver to {period_sec_short} ({period_msec}ms). {device_name_initials}.set_{function_name_under}_period({arguments}{period_msec}); """ templateB = r""" // Set period for {function_name_comment} receiver to {period_sec_short} ({period_msec}ms). // Note: The {function_name_comment} callback is only called every {period_sec_long} // if the {function_name_comment} has changed since the last call! {device_name_initials}.set_{function_name_under}_callback_period({arguments}{period_msec}); """ if self.get_device().get_name().space.startswith('IMU'): template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior and name mismatch else: template = templateB period_msec, period_sec_short, period_sec_long = self.get_formatted_period() return template.format(device_name_under=self.get_device().get_name().under, device_name_initials=self.get_device().get_initial_name(), device_category_under=self.get_device().get_category().under, function_name_under=self.get_name().under, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty('', ', '.join(self.get_rust_arguments()), ', '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_shell_source(self): template = r"""# Configure threshold for {function_comment_name} "{option_comment}"{mininum_maximum_unit_comments} tinkerforge call {device_dash_name}-{device_dash_category} $uid set-{function_dash_name}-callback-threshold {arguments}{option_dash_name} {mininum_maximums} """ arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_shell_source()) mininum_maximums = [] mininum_maximum_unit_comments = [] for mininum_maximum in self.get_minimum_maximums(): mininum_maximums.append(mininum_maximum.get_shell_source()) mininum_maximum_unit_comments.append(mininum_maximum.get_unit_comment()) if len(mininum_maximum_unit_comments) > 1 and len(set(mininum_maximum_unit_comments)) == 1: mininum_maximum_unit_comments = mininum_maximum_unit_comments[:1] option_dash_names = {'o' : 'outside', '<': 'smaller', '>': 'greater'} return template.format(device_dash_name=self.get_device().get_dash_name(), device_dash_category=self.get_device().get_dash_category(), function_dash_name=self.get_dash_name(), function_comment_name=self.get_comment_name(), arguments=common.wrap_non_empty('', ' '.join(arguments), ' '), option_dash_name=option_dash_names[self.get_option_char()], option_comment=self.get_option_comment(), mininum_maximums=' '.join(mininum_maximums), mininum_maximum_unit_comments=''.join(mininum_maximum_unit_comments))
def get_shell_source(self): template = '{comment1}{global_line_prefix}tinkerforge call {device_name}-{device_category} $uid {function_name}{arguments}{comment2}\n' bitmask_comments = [] for argument in self.get_arguments(): bitmask_comments.append(argument.get_shell_bitmask_comment()) while None in bitmask_comments: bitmask_comments.remove(None) comment1 = self.get_formatted_comment1( global_line_prefix + '# {0}\n', '\r', '\n' + global_line_prefix + '# ') comment2 = self.get_formatted_comment2(' # {0}', '') if len(bitmask_comments) > 0: if comment1 == '\r': if len(comment2) == 0: comment2 = ' # ' + ', '.join(bitmask_comments) else: comment2 += ': ' + ', '.join(bitmask_comments) else: comment1 = comment1.rstrip('\n') + ': ' + ', '.join( bitmask_comments) + '\n' return template.format( global_line_prefix=global_line_prefix, device_name=self.get_device().get_name().dash, device_category=self.get_device().get_category().dash, function_name=self.get_name().dash, arguments=common.wrap_non_empty( ' ', ' '.join(self.get_shell_arguments()), ''), comment1=comment1, comment2=comment2)
def get_c_source(self): template = r""" // Configure threshold for {function_comment_name} "{option_comment}"{mininum_maximum_unit_comments} {device_underscore_name}_set_{function_underscore_name}_callback_threshold(&{device_initial_name}{arguments}, '{option_char}', {mininum_maximums}); """ arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_c_source()) mininum_maximums = [] mininum_maximum_unit_comments = [] for mininum_maximum in self.get_minimum_maximums(): mininum_maximums.append(mininum_maximum.get_c_source()) mininum_maximum_unit_comments.append(mininum_maximum.get_unit_comment()) if len(mininum_maximum_unit_comments) > 1 and len(set(mininum_maximum_unit_comments)) == 1: mininum_maximum_unit_comments = mininum_maximum_unit_comments[:1] return template.format(device_underscore_name=self.get_device().get_underscore_name(), device_initial_name=self.get_device().get_initial_name(), function_underscore_name=self.get_underscore_name(), function_comment_name=self.get_comment_name(), arguments=common.wrap_non_empty(', ', ', '.join(arguments), ''), option_char=self.get_option_char(), option_comment=self.get_option_comment(), mininum_maximums=', '.join(mininum_maximums), mininum_maximum_unit_comments=''.join(mininum_maximum_unit_comments))
def get_php_source(self): template = r"""// Configure threshold for {function_comment_name} "{option_comment}"{mininum_maximum_unit_comments} ${device_initial_name}->set{function_camel_case_name}CallbackThreshold({arguments}'{option_char}', {mininum_maximums}); """ arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_php_source()) mininum_maximums = [] mininum_maximum_unit_comments = [] for mininum_maximum in self.get_minimum_maximums(): mininum_maximums.append(mininum_maximum.get_php_source()) mininum_maximum_unit_comments.append(mininum_maximum.get_unit_comment()) if len(mininum_maximum_unit_comments) > 1 and len(set(mininum_maximum_unit_comments)) == 1: mininum_maximum_unit_comments = mininum_maximum_unit_comments[:1] return template.format(device_initial_name=self.get_device().get_initial_name(), function_camel_case_name=self.get_camel_case_name(), function_comment_name=self.get_comment_name(), arguments=common.wrap_non_empty('', ', '.join(arguments), ', '), option_char=self.get_option_char(), option_comment=self.get_option_comment(), mininum_maximums=', '.join(mininum_maximums), mininum_maximum_unit_comments=''.join(mininum_maximum_unit_comments))
def get_php_source(self): template = r"""// Set period for {function_comment_name} callback to {period_sec_short} ({period_msec}ms) // Note: The {function_comment_name} callback is only called every {period_sec_long} // if the {function_comment_name} has changed since the last call! ${device_initial_name}->set{function_camel_case_name}{suffix}Period({arguments}{period_msec}); """ if self.get_device().get_underscore_name().startswith('imu'): suffix = '' # FIXME: special hack for IMU Brick name mismatch else: suffix = 'Callback' arguments = [] for argument in self.get_arguments(): arguments.append(argument.get_php_source()) period_msec, period_sec_short, period_sec_long = self.get_formatted_period() return template.format(device_initial_name=self.get_device().get_initial_name(), function_camel_case_name=self.get_camel_case_name(), function_comment_name=self.get_comment_name(), suffix=suffix, arguments=common.wrap_non_empty('', ', '.join(arguments), ', '), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_shell_source(self): template1A = r"""# Handle incoming {function_name_comment} callbacks """ template1B = r"""{override_comment} """ template2 = r"""tinkerforge dispatch {device_name}-{device_category} $uid {function_name_dash}{extra_message} & """ override_comment = self.get_formatted_override_comment( '# {0}', None, '\n# ') if override_comment == None: template1 = template1A else: template1 = template1B parameters = [] for parameter in self.get_parameters(): parameters.append(parameter.get_shell_source()) while None in parameters: parameters.remove(None) extra_message = self.get_formatted_extra_message( '\\\n --execute "echo {parameters}{{0}}"'.format( parameters=common.wrap_non_empty('', '. '.join(parameters), '. '))) return template1.format(function_name_comment=self.get_comment_name(), override_comment=override_comment) + \ template2.format(device_name=self.get_device().get_name().dash, device_category=self.get_device().get_category().dash, function_name_dash=self.get_name().dash, extra_message=extra_message)
def get_mathematica_source(self): templateA = r"""(*Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms)*) {device_name}@Set{function_name_camel}Period[{arguments}{period_msec}] """ templateB = r"""(*Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms)*) (*Note: The {function_name_comment} callback is only called every {period_sec_long}*) (*if the {function_name_comment} has changed since the last call!*) {device_name}@Set{function_name_camel}CallbackPeriod[{arguments}{period_msec}] """ if self.get_device().get_name().space.startswith('IMU'): template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior and name mismatch else: template = templateB period_msec, period_sec_short, period_sec_long = self.get_formatted_period( ) return template.format( device_name=self.get_device().get_initial_name(), function_name_camel=self.get_name().camel, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty( '', ','.join(self.get_mathematica_arguments()), ','), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long)
def get_csharp_delegates(self): delegates = '\n' template = """ /// <summary> /// {2} /// </summary> public event {0}EventHandler {0}Callback; /// <summary> /// </summary> public delegate void {0}EventHandler({3} sender{1}); """ template_legacy = """ /// <summary> /// </summary> public event {0}EventHandler {0} // for backward compatibility {{ add {{ {0}Callback += value; }} remove {{ {0}Callback -= value; }} }} """ for packet in self.get_packets('callback'): name = packet.get_name().camel parameters = common.wrap_non_empty(', ', packet.get_csharp_parameters(), '') doc = packet.get_csharp_formatted_doc() delegates += template.format(name, parameters, doc, self.get_csharp_class_name()) if self.get_csharp_class_name() in LEGACY_CALLBACK_DEVICES: delegates += template_legacy.format(name) for packet in self.get_packets('callback'): if not packet.has_high_level(): continue name = packet.get_name(skip=-2).camel parameters = common.wrap_non_empty( ', ', packet.get_csharp_parameters(high_level=True), '') doc = packet.get_csharp_formatted_doc() delegates += template.format(name, parameters, doc, self.get_csharp_class_name()) return delegates
def get_mathematica_source(self): template = r"""Needs["NETLink`"] LoadNETAssembly["Tinkerforge",NotebookDirectory[]<>"../../.."]{incomplete} host="localhost" port=4223 uid="{dummy_uid}"(*Change {dummy_uid} to the UID of your {device_long_display_name}*) (*Create IPConnection and device object*) ipcon=NETNew["Tinkerforge.IPConnection"] {device_initial_name}=NETNew["Tinkerforge.{device_camel_case_category}{device_camel_case_name}",uid,ipcon] ipcon@Connect[host,port] {sources} (*Clean up*){cleanups} ipcon@Disconnect[] ReleaseNETObject[{device_initial_name}] ReleaseNETObject[ipcon] """ if self.is_incomplete(): incomplete = '\n\n(*FIXME: This example is incomplete*)' else: incomplete = '' sources = [] add_input_call = False for function in self.get_functions(): if isinstance(function, MathematicaExampleCallbackFunction): add_input_call = True elif isinstance(function, MathematicaExampleSpecialFunction) and function.get_type() == 'wait': add_input_call = True sources.append(function.get_mathematica_source()) while None in sources: sources.remove(None) if len(sources) == 0: sources = ['(*TODO: Add example code here*)\n'] elif add_input_call: sources.append('Input["Click OK to exit"]\n') cleanups = [] for cleanup in self.get_cleanups(): cleanups.append(cleanup.get_mathematica_source()) while None in cleanups: cleanups.remove(None) return template.format(incomplete=incomplete, device_camel_case_category=self.get_device().get_camel_case_category(), device_camel_case_name=self.get_device().get_camel_case_name(), device_initial_name=self.get_device().get_initial_name(), device_long_display_name=self.get_device().get_long_display_name(), dummy_uid=self.get_dummy_uid(), sources='\n' + '\n'.join(sources).replace(';\n\n\b', '\n\n').replace('\n\r', '').lstrip('\r'), cleanups=common.wrap_non_empty('\n', '\n'.join(cleanups).replace('\n\r', '').lstrip('\r').rstrip('\n'), ''))
def specialize(parameters_prefix): return template.format( device_camel_case_category=self.get_device( ).get_camel_case_category(), device_camel_case_name=self.get_device().get_camel_case_name(), function_camel_case_name=self.get_camel_case_name(), parameters=common.wrap_non_empty(parameters_prefix, '; '.join(parameters), ''))
def get_ruby_source(self): template = r"""#!/usr/bin/env ruby # -*- ruby encoding: utf-8 -*-{incomplete} require 'tinkerforge/ip_connection' require 'tinkerforge/{device_underscore_category}_{device_underscore_name}' include Tinkerforge HOST = 'localhost' PORT = 4223 UID = '{dummy_uid}' # Change {dummy_uid} to the UID of your {device_long_display_name} ipcon = IPConnection.new # Create IP connection {device_initial_name} = {device_camel_case_category}{device_camel_case_name}.new UID, ipcon # Create device object ipcon.connect HOST, PORT # Connect to brickd # Don't use device before ipcon is connected {sources} puts 'Press key to exit' $stdin.gets{cleanups} ipcon.disconnect """ if self.is_incomplete(): incomplete = '\n\n# FIXME: This example is incomplete' else: incomplete = '' sources = [] for function in self.get_functions(): sources.append(function.get_ruby_source()) while None in sources: sources.remove(None) if len(sources) == 0: sources = ['# TODO: Add example code here\n'] cleanups = [] for cleanup in self.get_cleanups(): cleanups.append(cleanup.get_ruby_source()) while None in cleanups: cleanups.remove(None) return template.format(incomplete=incomplete, device_camel_case_category=self.get_device().get_camel_case_category(), device_underscore_category=self.get_device().get_underscore_category(), device_camel_case_name=self.get_device().get_camel_case_name(), device_underscore_name=self.get_device().get_underscore_name(), device_initial_name=self.get_device().get_initial_name(), device_long_display_name=self.get_device().get_long_display_name(), dummy_uid=self.get_dummy_uid(), sources='\n' + '\n'.join(sources).replace('\n\r', '').lstrip('\r'), cleanups=common.wrap_non_empty('\n', '\n'.join(cleanups).replace('\n\r', '').lstrip('\r').rstrip('\n'), ''))
def get_vbnet_subroutine(self): template1A = r""" ' Callback subroutine for {function_comment_name} callback{comments} """ template1B = r"""{override_comment} """ template2 = ' Sub {function_camel_case_name}CB(' template3 = 'ByVal sender As {device_camel_case_category}{device_camel_case_name}' template4 = r""") {write_lines}{extra_message} End Sub """ override_comment = self.get_formatted_override_comment(" ' {0}", None, "\n ' ") if override_comment == None: template1 = template1A else: template1 = template1B comments = [] parameters = [] write_lines = [] for parameter in self.get_parameters(): comments.append(parameter.get_formatted_comment()) parameters.append(parameter.get_vbnet_source()) write_lines.append(parameter.get_vbnet_write_line()) if len(comments) > 1 and len(set(comments)) == 1: comments = [comments[0].replace('parameter has', 'parameters have')] while None in write_lines: write_lines.remove(None) if len(write_lines) > 1: write_lines.append(' Console.WriteLine("")') extra_message = self.get_formatted_extra_message(' Console.WriteLine("{0}")') if len(extra_message) > 0 and len(write_lines) > 0: extra_message = '\n' + extra_message specialized2 = template2.format(function_camel_case_name=self.get_camel_case_name()) specialized3 = template3.format(device_camel_case_category=self.get_device().get_camel_case_category(), device_camel_case_name=self.get_device().get_camel_case_name()) parameters = ', '.join(parameters) if len(parameters) > 0 and len(specialized2) + len(specialized3) + len(parameters) > 90: specialized23p = specialized2 + specialized3 + ', _\n' + ' ' * len(specialized2) + parameters else: specialized23p = specialized2 + specialized3 + common.wrap_non_empty(', ', parameters, '') return template1.format(function_comment_name=self.get_comment_name(), comments=''.join(comments), override_comment=override_comment) + \ specialized23p + \ template4.format(write_lines='\n'.join(write_lines), extra_message=extra_message)
def get_mathematica_source(self): template1A = r"""(*Callback function for {function_name_comment} callback*) """ template1B = r"""{override_comment} """ template2A = r"""{function_name_camel}CB[sender_{parameters}]:= Module[{{}}, {prints}{extra_message} ] AddEventHandler[{device_name}@{function_name_camel}Callback,{function_name_camel}CB] """ template2B = r"""{function_name_camel}CB[sender_{parameters}]:= {prints}{extra_message} AddEventHandler[{device_name}@{function_name_camel}Callback,{function_name_camel}CB] """ override_comment = self.get_formatted_override_comment('(*{0}*)', None, '*)\n(*') if override_comment == None: template1 = template1A else: template1 = template1B override_comment = re.sub('\\(\\*[ ]+\\*\\)\n', '', override_comment) parameters = [] prints = [] for parameter in self.get_parameters(): parameters.append(parameter.get_mathematica_source()) prints += parameter.get_mathematica_prints() while None in prints: prints.remove(None) extra_message = self.get_formatted_extra_message(' Print["{0}"]') if len(prints) > 1 or (len(prints) == 1 and len(extra_message) > 0) or sum([1 for p in prints if '\n' in p]) > 0: template2 = template2A prints = [' ' + prints for prints in prints] if len(extra_message) > 0: extra_message = ' ' + extra_message else: template2 = template2B if len(extra_message) > 0 and len(prints) > 0: extra_message = ';\n' + extra_message result = template1.format(function_name_comment=self.get_comment_name(), override_comment=override_comment) + \ template2.format(device_name=self.get_device().get_initial_name(), function_name_camel=self.get_name().camel, parameters=common.wrap_non_empty(',<BP>', ',<BP>'.join(parameters), ''), prints='\n'.join(prints).replace('\n', ';\n'), extra_message=extra_message) return common.break_string(result, '{}CB['.format(self.get_name().camel), space='')
def get_mathematica_source(self): templateA = r"""(*Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms)*) {device_name_initial}@Set{function_name_camel}CallbackConfiguration[{arguments}{period_msec}{value_has_to_change}] """ templateB = r"""(*Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) without a threshold*) option=Tinkerforge`{device_category}{device_name_camel}`THRESHOLDUOPTIONU{option_name} {device_name_initial}@Set{function_name_camel}CallbackConfiguration[{arguments}{period_msec}{value_has_to_change},option,{minimum_maximums}] """ templateC = r"""(*Configure threshold for {function_name_comment} "{option_comment}"*) (*with a debounce period of {period_sec_short} ({period_msec}ms)*) option=Tinkerforge`{device_category}{device_name_camel}`THRESHOLDUOPTIONU{option_name} {device_name_initial}@Set{function_name_camel}CallbackConfiguration[{arguments}{period_msec}{value_has_to_change},option,{minimum_maximums}] """ if self.get_option_char() == None: template = templateA elif self.get_option_char() == 'x': template = templateB else: template = templateC period_msec, period_sec_short, period_sec_long = self.get_formatted_period() minimum_maximums = [] for minimum_maximum in self.get_minimum_maximums(): minimum_maximums.append(minimum_maximum.get_mathematica_source()) option_names = {None: '', 'x': 'OFF', 'o' : 'OUTSIDE', '<': 'SMALLER', '>': 'GREATER'} return template.format(device_category=self.get_device().get_category().camel, device_name_camel=self.get_device().get_name().camel, device_name_initial=self.get_device().get_initial_name(), function_name_camel=self.get_name().camel, function_name_under=self.get_name().under, function_name_comment=self.get_comment_name(), option_name=option_names[self.get_option_char()], option_comment=self.get_option_comment(), arguments=common.wrap_non_empty('', ','.join(self.get_mathematica_arguments()), ','), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long, value_has_to_change=common.wrap_non_empty(',', self.get_value_has_to_change('True', 'False', ''), ''), minimum_maximums=','.join(minimum_maximums))
def get_shell_source(self): template = r"""#!/bin/sh # Connects to localhost:4223 by default, use --host and --port to change this{incomplete}{description} uid={dummy_uid} # Change {dummy_uid} to the UID of your {device_long_display_name} {sources}{cleanups}""" if self.is_incomplete(): incomplete = '\n\n# FIXME: This example is incomplete' else: incomplete = '' if self.get_description() != None: description = '\n\n# {0}'.format(self.get_description().replace('\n', '\n# ')) else: description = '' sources = [] add_read_call = False add_kill_call = False for function in self.get_functions(): if isinstance(function, ShellExampleCallbackFunction): add_read_call = True add_kill_call = True if isinstance(function, ShellExampleSpecialFunction) and function.get_type() == 'wait': add_read_call = True sources.append(function.get_shell_source()) while None in sources: sources.remove(None) if len(sources) == 0: sources = ['# TODO: Add example code here\n'] elif add_read_call: sources.append('echo "Press key to exit"; read dummy\n') cleanups = [] for cleanup in self.get_cleanups(): cleanups.append(cleanup.get_shell_source()) while None in cleanups: cleanups.remove(None) if add_kill_call: cleanups.append('kill -- -$$ # Stop callback dispatch in background\n') return template.format(incomplete=incomplete, description=description, device_long_display_name=self.get_device().get_long_display_name(), dummy_uid=self.get_dummy_uid(), sources='\n' + '\n'.join(sources).replace('\n\r', '').lstrip('\r'), cleanups=common.wrap_non_empty('\n', '\n'.join(cleanups).replace('\n\r', '').lstrip('\r').rstrip('\n'), '')).rstrip('\n') + '\n'
def specialize(parameters_prefix): return template1.format(function_comment_name=self.get_comment_name(), comments=''.join(comments), override_comment=override_comment) + \ template2.format(device_camel_case_category=self.get_device().get_camel_case_category(), device_camel_case_name=self.get_device().get_camel_case_name(), function_camel_case_name=self.get_camel_case_name(), parameters=common.wrap_non_empty(parameters_prefix, '; '.join(parameters), ''), write_lns='\n'.join(write_lns), extra_message=extra_message)
def get_csharp_delegates(self): delegates = '\n' template = """ /// <summary> /// {2} /// </summary> public event {0}EventHandler {0}Callback; /// <summary> /// </summary> public delegate void {0}EventHandler({3} sender{1}); """ template_legacy = """ /// <summary> /// </summary> public event {0}EventHandler {0} // for backward compatibility {{ add {{ {0}Callback += value; }} remove {{ {0}Callback -= value; }} }} """ for packet in self.get_packets('callback'): name = packet.get_name().camel parameters = common.wrap_non_empty(', ', packet.get_csharp_parameters(), '') doc = packet.get_csharp_formatted_doc() delegates += template.format(name, parameters, doc, self.get_csharp_class_name()) if self.get_csharp_class_name() in LEGACY_CALLBACK_DEVICES: delegates += template_legacy.format(name) for packet in self.get_packets('callback'): if not packet.has_high_level(): continue name = packet.get_name(skip=-2).camel parameters = common.wrap_non_empty(', ', packet.get_csharp_parameters(high_level=True), '') doc = packet.get_csharp_formatted_doc() delegates += template.format(name, parameters, doc, self.get_csharp_class_name()) return delegates
def get_mqtt_source(self): callback_fn = "set_{function_name_under}_callback_configuration".format(function_name_under=self.get_name().under) templateA = r"""# Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) publish '{arguments}' to tinkerforge/request/{device_name}_{device_category}/{uid}/{callback_fn} """ templateB = r"""# Set period for {function_name_comment} callback to {period_sec_short} ({period_msec}ms) without a threshold publish '{arguments}' to tinkerforge/request/{device_name}_{device_category}/{uid}/{callback_fn} """ templateC = r"""# Configure threshold for {function_name_comment} "{option_comment}" # with a debounce period of {period_sec_short} ({period_msec}ms) publish '{arguments}' to tinkerforge/request/{device_name}_{device_category}/{uid}/{callback_fn} """ if self.get_option_char() == None: template = templateA add_option = False elif self.get_option_char() == 'x': template = templateB add_option = True else: template = templateC add_option = True period_msec, period_sec_short, period_sec_long = self.get_formatted_period() packet = None for p in self.get_device().get_packets('function'): if callback_fn in p.get_name().under: packet = p packet_min_max_names = [elem.get_name().under[3:] for elem in packet.get_elements(direction='in') if elem.get_name().under.startswith('min') ] minimum_maximums = [] for mm_name, minimum_maximum in zip(packet_min_max_names, self.get_minimum_maximums()): minimum_maximums.append(minimum_maximum.get_mqtt_source().format(mm_name=mm_name)) option_name_unders = {None: '', 'x' : 'off', 'o' : 'outside', '<': 'smaller', '>': 'greater'} args = self.get_mqtt_arguments(callback_fn) + ['"period": ' + str(period_msec), '"value_has_to_change": ' + self.get_value_has_to_change('true', 'false', '')] if add_option: args += ['"option": "' + option_name_unders[self.get_option_char()]+'"'] args += minimum_maximums return template.format(device_name=self.get_device().get_name().under, uid=self.get_example().get_dummy_uid(), device_category=self.get_device().get_category().under, callback_fn=callback_fn, function_name_comment=self.get_comment_name(), arguments=common.wrap_non_empty('{', ', '.join(args), '}'), period_msec=period_msec, period_sec_short=period_sec_short, period_sec_long=period_sec_long, option_comment=self.get_option_comment())