Beispiel #1
0
    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))
Beispiel #2
0
    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)
Beispiel #4
0
    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'), ''))
Beispiel #5
0
    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))
Beispiel #6
0
    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)
Beispiel #7
0
    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))
Beispiel #11
0
    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))
Beispiel #12
0
    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)
Beispiel #13
0
    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))
Beispiel #14
0
    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):
        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_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_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_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_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_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()), ','))
Beispiel #31
0
    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_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_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)
Beispiel #36
0
    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))
Beispiel #37
0
    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)
Beispiel #39
0
    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))
Beispiel #45
0
    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_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
Beispiel #51
0
    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), ''))
Beispiel #53
0
    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())