Beispiel #1
0
class SimplifyPolyline(GroupBy, Block):

    version = VersionProperty('0.1.0')
    high_quality = BoolProperty(default=True, title='High Quality')
    tolerance = FloatProperty(default=0.1, title='Tolerance')
    x_attr = Property(default='{{ $x }}', title='X Attribute')
    y_attr = Property(default='{{ $y }}', title='Y Attribute')

    def process_group_signals(self, signals, group, input_id=None):
        points = []
        for signal in signals:
            point = {'x': self.x_attr(signal),
                     'y': self.y_attr(signal)}
            points.append(point)

        simplified = simplify(points, self.tolerance(), self.high_quality())

        outgoing_signals = []
        for result in simplified:
            signal_dict = {'x': result['x'],
                           'y': result['y'],
                           'group': group}
            outgoing_signals.append(Signal(signal_dict))

        return outgoing_signals
class AndroidThingsRGB(TerminatorBlock):

    version = VersionProperty('0.1.0')

    red = Property(title='Red', default=False, order=0)
    green = Property(title='Green', default=False, order=1)
    blue = Property(title='Blue', default=False, order=2)

    def _all_off(self, signal):
        prop_array = \
            [self.red(signal), self.blue(signal), self.green(signal)]
        if True in prop_array:
            return False
        else:
            return True

    def process_signals(self, signals):
        for signal in signals:
            if self._all_off(signal):
                rh.lights.rgb(0, 0, 0)
            else:
                if self.red(signal):
                    rh.lights.red.on()
                if self.green(signal):
                    rh.lights.green.on()
                if self.blue(signal):
                    rh.lights.blue.on()
class XBeeDigiMeshTXFrame(XBeeFrameBase):
    """Generate TX_LONG_ADDR command frame

    This block generates an XBee 0x10 digimesh tx long frame.

    Parameters:
        dest_addr: 8 byte address of remote xbee to send AT command to.
            Default value when left blank is "FF FF" which sends a broadcast.
        data: Data to send, default is 100 bytes
        frame_id: Hidden property that can be used to order data.
    """

    version = VersionProperty(version='1.0.0')
    data = Property(title="Data", default="{{ $.to_dict() }}")
    dest_addr = Property(title='Destination Address \
                         (8 bytes hex, ex: "01 23 45 67 89 AA 00 05")',
                         default='',
                         allow_none=True)
    frame_id = Property(title='Frame id',
                        default="{{ $frame_id }}",
                        hidden=True)

    def configure(self, context):
        super().configure(context)
        self._protocol = xbee.DigiMesh
        self._connect()

    def process_signals(self, signals):
        for signal in signals:
            data_encoded = "{}".format(self.data(signal)).encode()
            dest_addr = \
                binascii.unhexlify(self.dest_addr(signal).replace(" ", "")) \
                if self.dest_addr(signal) else None
            try:
                frame_id = binascii.unhexlify(self.frame_id(signal))
                self.logger.debug("Frame ID = {}".format(frame_id))
            except:
                frame_id = None
            self.logger.debug('Creating frame, data: {}'.format(data_encoded))
            # tx_long_addr: 0x10 "Tx (Transmit) Request: 64-bit address"
            # frame_id: 0x01
            # dest_addr: 0xFFFF is the broadcast address
            # data: RF data bytes to be transmitted
            #
            # frame_id is an arbitrary value, 1 hex byte, used to associate
            # sent packets with their responses. If set to 0 no response will
            # be sent. Could be a block property.

            packet = self._xbee._build_command(
                'tx',
                id=b'\x10',
                frame_id=frame_id or b'\x01',
                dest_addr=dest_addr or b'\x00\x00\x00\x00\x00\x00\xFF\xFF',
                data=data_encoded,
                reserved=b'\xFF\xFE',
                broadcast_radius=b'\x00',
                options=b'\x00')
            self.notify_signals(
                [Signal({"frame": self._API_frame_packer(packet)})])
class QueryFilter(PropertyHolder):

    key = Property(title='Filter Key',
                   default='id__eq',
                   attr_default=Exception)
    value = Property(title='Filter Value',
                     default='{{ $id }}',
                     attr_default=Exception)
Beispiel #5
0
class XBeeTX(XBeeBase):

    """Execute TX Command.

    XBee sends the serialized version of each input signal to thie block. It is
    sent to the configured "Distnation Address" of the XBee. That destination
    XBee will receive that serialized signal. If that block is connected to nio
    then the block will notify the signal.

    Parameters:
        dest_addr: 2 or 8 byte address of remote xbee to send AT command to.
            must be 8 bytes when using digimesh.
            Default value when left blank is "FF FF" which sends a broadcast.
    """

    version = VersionProperty(version='0.2.1')
    data = Property(title="Data", default="{{ $.to_dict() }}")
    dest_addr = Property(title='Destination Address \
                         (2 or 8 bytes hex, ex: "00 05")',
                         default='',
                         allow_none=True)

    def process_signals(self, signals):
        for signal in signals:
            data_encoded = "{}".format(self.data(signal)).encode()
            dest_addr = \
                binascii.unhexlify(self.dest_addr(signal).replace(" ", "")) \
                if self.dest_addr(signal) else None
            self.logger.debug('Sending data: {}'.format(data_encoded))
            # tx: 0x01 "Tx (Transmit) Request: 16-bit address"
            # tx: 0x10 "Tx (Transmit) Request: 64-bit address", DigiMesh
            # frame_id: 0x01
            # dest_addr: 0xFFFF appears to make it so that it sends to the
            # configured "Destination Address" on the XBee
            # data: RF data bytes to be transmitted
            #
            # frame_id is an arbitrary value, 1 hex byte, used to associate
            # sent packets with their responses. If set to 0 no response will
            # be sent. Could be a block property.
            if self.digimesh():
                # pass all arguments to work around bug in
                # python-xbee/xbee/digimesh.py where default values are not
                # bytes
                self._xbee.send(
                    'tx',
                    id=b'\x10',
                    frame_id=b'\x01',
                    dest_addr=dest_addr or b'\x00\x00\x00\x00\x00\x00\xFF\xFF',
                    reserved=b'\xFF\xFE',
                    broadcast_radius=b'\x00',
                    options=b'\x00',
                    data=data_encoded
                )
            else:
                self._xbee.send('tx',
                                frame_id=b'\x01',
                                dest_addr=dest_addr or b'\xFF\xFF',
                                data=data_encoded)
Beispiel #6
0
class RethinkDBUpdate(EnrichSignals, RethinkDBBase):

    """a block for updating info in a RethinkDB table"""

    table = StringProperty(title="Table to update", default='test',
                           allow_none=False)
    filter = Property(title='Filter dictionary',
                      default='{{ $.to_dict() }}',
                      allow_none=False)
    object = Property(title='Dictionary data to update',
                      default='{{ $.to_dict() }}',
                      allow_none=False)

    def _locked_process_signals(self, signals):
        notify_list = []
        for signal in signals:
            self.logger.debug('Update is Processing signal: {}'.format(signal))
            # update incoming signals with results of the update
            result = self.execute_with_retry(self._update, signal)
            out_sig = self.get_output_signal(result, signal)
            self.logger.debug(out_sig)
            notify_list.append(out_sig)
        self.notify_signals(notify_list)

    def _update(self, signal):
        """filter by given fields and update the document in the table"""
        data = self.object(signal)
        # rethink does not allow updating of id.
        if 'id' in data:
            data.pop('id')
        with rdb.connect(
                host=self.host(),
                port=self.port(),
                db=self.database_name(),
                timeout=self.connect_timeout().total_seconds()) as conn:

            # Query table configuration to get primary key
            table_config = rdb.db(self.database_name()).table(self.table()).\
                config()
            primary_key = [table_config["primary_key"]]
            filter_condition = self.filter(signal)

            # Check if filter condition is only primary key, if so, use
            # .get rather than .filter for better performance
            if list(filter_condition.keys()) == primary_key:
                result = rdb.db(self.database_name()).table(self.table()).\
                    get(filter_condition).update(data).run(conn)
            else:
                result = rdb.db(self.database_name()).table(self.table()).\
                    filter(self.filter(signal)).update(data).run(conn)

        self.logger.debug("Sent update request, result: {}".format(result))
        if result['errors'] > 0:
            # only first error is collected
            self.logger.error(
                'Error updating table: {}'.format(result['first_error']))
        return result
class ImageFilters(PropertyHolder):
    obj = StringProperty(title='Object name', default='TrackMe')
    filter_type = SelectProperty(FilterTypes,
                                 title='Filter type',
                                 default=FilterTypes.hsv)
    filter_lo = Property(title='Lower bounds for image filter',
                         default='',
                         allow_none=True)
    filter_hi = Property(title='Upper bounds for image filter',
                         default='',
                         allow_none=True)
class XBeeATCommandFrame(XBeeFrameBase):
    """ Generate AT commands frames
    Parameters:
        command: The command to execute, ex. 'D0', WR'
        parameter: The command parameter, ex. '05' for 'D0' command
           to set pin high
        frame_id: Hidden parameter to specify frame_id
    """

    version = VersionProperty(version='1.0.0')
    command = Property(title='AT Command (ascii)', default='ID')
    parameter = Property(title='Command Parameter (hex, ex: "05")', default='')
    frame_id = Property(title='Frame id',
                        default="{{ $frame_id }}",
                        hidden=True)

    def process_signals(self, signals):
        for signal in signals:
            try:
                command = self.command(signal)
                parameter = self.parameter(signal).replace(" ", "")
                try:
                    frame_id = binascii.unhexlify(self.frame_id(signal))
                    self.logger.debug("Frame ID = {}".format(frame_id))
                except:
                    frame_id = None
                self._at(command, parameter, frame_id)
            except:
                self.logger.exception("Failed to execute at command")

    def _at(self, command, parameter, frame_id):
        command = command.encode('ascii')
        parameter = binascii.unhexlify(parameter)
        self.logger.debug(
            "Executing AT command: {}, with parameter: {}".format(
                command, parameter))
        # at: 0x08 "AT Command"
        # frame_id: 0x01
        # data: RF data bytes to be transmitted
        # command: The command to execute, ex. 'D0', WR'
        # parameter: The command parameter, ex. b'\x05' for 'D0' command
        #    to set pin high
        #
        # frame_id is an arbitrary value, 1 hex byte, used to associate sent
        # packets with their responses. If set to 0 no response will be sent.
        # Could be a block property.
        packet = self._xbee._build_command('at',
                                           frame_id=frame_id or b'\x01',
                                           command=command,
                                           parameter=parameter)
        self.notify_signals(
            [Signal({"frame": self._API_frame_packer(packet)})])
Beispiel #9
0
class XBeeTXFrame(XBeeFrameBase):

    """Generate TX command frame

    Parameters:
        dest_addr: 2 byte hex address of remote xbee to send AT command to.
            Default value when left blank is "FF FF" which sends a broadcast.
        data: Data to send, default maximum is 100 bytes
        frame_id: Hidden parameter to set frame_id
    """

    version = VersionProperty(version='1.0.0')
    data = Property(title="Data", default="{{ $.to_dict() }}")
    dest_addr = Property(title='Destination Address \
                         (2 bytes hex, ex: "00 05")',
                         default='',
                         allow_none=True)
    frame_id = Property(title='Frame id', 
                        default="{{ $frame_id }}", 
                        hidden=True)

    def process_signals(self, signals):
        for signal in signals:
            data_encoded = "{}".format(self.data(signal)).encode()
            dest_addr = \
                binascii.unhexlify(self.dest_addr(signal).replace(" ", "")) \
                if self.dest_addr(signal) else None
            try:
                frame_id = binascii.unhexlify(self.frame_id(signal))
                self.logger.debug("Frame ID = {}".format(frame_id))
            except:
                frame_id = None
            self.logger.debug('Creating frame, data: {}'.format(data_encoded))
            # tx: 0x01 "Tx (Transmit) Request: 16-bit address"
            # frame_id: 0x01
            # dest_addr: 0xFFFF is the broadcast address
            # data: RF data bytes to be transmitted
            #
            # frame_id is an arbitrary value, 1 hex byte, used to associate
            # sent packets with their responses. If set to 0 no response will
            # be sent. Could be a block property.
            packet = self._xbee._build_command('tx',
                        frame_id=frame_id or b'\x01',
                        dest_addr=dest_addr or b'\xFF\xFF',
                        data=data_encoded)
            self.notify_signals([Signal( { "frame" :
                        self._API_frame_packer(packet)
                        } )])
Beispiel #10
0
class Conditions(PropertyHolder):
    column = StringProperty(title='Column', order=20)
    operation = SelectProperty(Operator,
                               title='Operator',
                               default="EQ",
                               order=21)
    value = Property(title='Value', order=22)
Beispiel #11
0
class MongoDBFind(Limitable, Sortable, MongoDBBase):

    """ A block for running `find` against a mongodb.

    Properties:
        condition (expression): A dictionary form of a find expression. This is
        an expression property that can evaluate to a dictionary or be a
        parseable JSON string

    """
    condition = Property(
        title='Condition', default="{'id': {'$gt': 0}}")

    def execute_query(self, collection, signal):
        condition = self.evaluate_expression(self.condition, signal)
        self.logger.debug("Searching condition {}".format(condition))

        if self.pymongo3():
            cursor = collection.find(filter=condition, **(self.query_args()))
        else:
            cursor = collection.find(spec=condition, **(self.query_args()))

        if cursor.count() == 0:
            self.notify_signals([signal], 'no_results')

        return cursor

    def write_results(self, results):
        """ Notify the signals on the results output """
        if results:
            self.notify_signals(results, 'results')
Beispiel #12
0
class HarperDBBulkData(HarperDBBase, Block, EnrichSignals):

    version = VersionProperty('0.1.0')
    operation = SelectProperty(Operation,
                               title='Data Source',
                               default=Operation.DATA,
                               order=2)
    schema = StringProperty(title='Schema', default='dev', order=3)
    table = StringProperty(title='Table', default='dog', order=4)
    data = Property(title='Data (escaped string, file, or url)',
                    default='{{ $data }}',
                    order=5)

    def process_signals(self, signals):
        out_sigs = []
        for signal in signals:
            payload = {
                'schema': self.schema(),
                'table': self.table(),
                'action': 'insert',
                'operation': self.operation().value,
            }
            if self.operation() is Operation.DATA:
                payload['data'] = self.data(signal).replace('\\n', '\n')
            if self.operation() is Operation.FILE:
                payload['file_path'] = self.data(signal)
            if self.operation() is Operation.URL:
                payload['csv_url'] = self.data(signal)
            result = self.sendQuery(payload)
            job_result = self.get_job_result(result["message"].replace(
                "Starting job with id ", ""))
            out_sigs.append(self.get_output_signal(job_result, signal))

        self.notify_signals(out_sigs)
class AzureIoTSendReportedState(AzureIoTBase, TerminatorBlock):
    """A block to send reported state to Azure cloud.
    """
    version = VersionProperty("1.0.0")
    state_to_report = Property(title="State to Report",
                               default="{{ $.to_dict() }}", order=2)

    def process_signals(self, signals):
        for signal in signals:
            data = self.state_to_report(signal)
            if not isinstance(data, dict):
                self.logger.error("Data: {} rejected, a dict is expected".
                                  format(data))
                return

            self.logger.info("Sending: {}".format(data))
            self._client.send_reported_state(data)

    def get_callbacks(self):
        return {"reported_state_callback": self._reported_state_callback}

    def _reported_state_callback(self, result):
        self.logger.debug(
            "Confirmation for reported state received with result: {}".
            format(result))
class WatsonToneAnalyzer(EnrichSignals, Block):

    version = VersionProperty("1.0.0")
    creds = ObjectProperty(AuthCreds,
                           title="Bluemix Credentials",
                           default=AuthCreds())
    data_attr = Property(title='Data Field', default='{{ $text }}')

    def __init__(self):
        self.tone_analyzer = None
        super().__init__()

    def configure(self, context):
        super().configure(context)
        self.tone_analyzer = ToneAnalyzerV3(username=self.creds().username(),
                                            password=self.creds().password(),
                                            version='2016-05-19')

    def process_signals(self, signals):
        new_signals = []
        for signal in signals:
            out_sig = self.get_output_signal(
                self.tone_analyzer.tone(self.data_attr(signal)), signal)
            new_signals.append(out_sig)
        self.notify_signals(new_signals)
Beispiel #15
0
class GoogleIoTMQTTPublish(GoogleIoTMQTTBase, TerminatorBlock):
    """A publisher block for the MQTT protocol that is used by google IoT.
    This block will publish messages to a topic."""

    version = VersionProperty("1.0.1")
    topic = StringProperty(title="Topic", default="state",
                           allow_none=False, order=1)
    data_to_publish = Property(title="Data to Publish",
                               default="{{ $text }}", order=2)

    def __init__(self):
        super().__init__()
        self._topic = None

    def configure(self, context):
        super().configure(context)
        self._topic = '/devices/{}/{}'.format(self.device_id(), self.topic())

    def process_signals(self, signals):
        for signal in signals:
            data = self.data_to_publish(signal)
            if isinstance(data, bytes):
                # cannot publish bytes, converting to string
                data = data.decode()

            self.logger.info("Publishing signal to topic '{}': {}".
                             format(self._topic, data))

            response = self._client.publish(topic=self.topic(),
                                            payload=data)
            self.logger.debug(
                "Got response {0}".format(response))
Beispiel #16
0
class When(Block):
    subject = Property(default=None, title='Subject', allow_none=True, order=0)
    cases = ListProperty(Case, title='Cases', default=[], order=1)
    version = VersionProperty('0.1.0')

    def process_signals(self, in_sigs):
        then_signals = []
        else_signals = []

        for signal in in_sigs:

            subject = self.subject(signal)
            for case in self.cases():
                if subject != case.when(signal):
                    continue

                sig = Signal() if case.exclude(signal) else signal

                for attr in case.attributes():
                    title = attr.title(signal)
                    value = attr.formula(signal)
                    setattr(sig, title, value)

                then_signals.append(sig)
                break
Beispiel #17
0
class JWTCreate(EnrichSignals, JWTBase):

    version = VersionProperty('0.1.0')
    exp_minutes = Property(title='Valid For Minutes (blank for no exp claim)',
                           order=3,
                           allow_none=True)
    claims = ListProperty(ClaimField, title='Claims', order=4, allow_none=True)

    def process_signal(self, signal, input_id=None):
        _key = self.key(signal)
        _algorithm = self.algorithm(signal)
        _exp_minutes = self.exp_minutes(signal)
        _claims = self.claims(signal)
        _newclaims = {}

        try:
            if isinstance(_exp_minutes, int):
                _newclaims['exp'] = self.set_new_exp_time(_exp_minutes)
            for claim in _claims:
                if claim.name(signal) is not 'exp':
                    _newclaims[claim.name(signal)] = claim.value(signal)

            _token = jwt.encode(_newclaims, _key,
                                algorithm=_algorithm.value).decode('UTF-8')
            return self.get_output_signal({'token': _token}, signal)

        # jwt.encode throws ValueError if key is in wrong format
        except (PyJWTError, ValueError) as e:
            self.notify_signals(
                self.get_output_signal({'message': e.args[0]}, signal),
                'error')
class NewAttributes(PropertyHolder):
    format = SelectProperty(PythonType,
                            title='Format',
                            default=PythonType.integer)
    endian = SelectProperty(Endian, title='Endian', default=Endian.big)
    key = StringProperty(title='New Attribute Key', default='{{ $key }}')
    value = Property(title='Bytes to Unpack', default='{{ $value }}')
Beispiel #19
0
class XBeeParseFrame(XBeeFrameBase):
    """Parse Frame.

    Take a XBee Frame as an input signal and output a signal composed of the
    individual frame components.

    Parameters:
        data: An XBee frame with a start byte and checksum
            *TODO: allow only the data packet* 
    """

    version = VersionProperty(version='1.0.0')
    data = Property(title="Data", default="{{ $ }}")

    def process_signals(self, signals):
        for signal in signals:
            if isinstance(self.data(signal), bytes):
                data_encoded = self.data(signal)
            else:
                data_encoded = "{}".format(self.data(signal)).encode()
            try:
                frame = self._API_frame_unpacker(data_encoded)
                self.notify_signals([Signal(frame)])
            except:
                self.logger.exception("Failed to parse frame")
Beispiel #20
0
class JWTRefresh(EnrichSignals, JWTBase):

    version = VersionProperty('0.1.0')
    input = StringProperty(
        title='Token Value',
        default='{{ $headers.get(\'Authorization\').split()[1] }}',
        order=3)
    exp_minutes = Property(title='Valid For Minutes (exp claim)',
                           order=4,
                           allow_none=True)

    def process_signal(self, signal, input_id=None):
        _token = self.input(signal)
        _key = self.key(signal)
        _algorithm = self.algorithm(signal)
        _exp_minutes = self.exp_minutes(signal)

        try:
            _claims = jwt.decode(_token, _key, algorithms=[_algorithm.value])
            if isinstance(_exp_minutes, int):
                _claims['exp'] = self.set_new_exp_time(_exp_minutes)
            else:
                try:
                    del _claims['exp']
                except KeyError:
                    pass

            _token = jwt.encode(_claims, _key, algorithm=_algorithm.value)
            return self.get_output_signal({'token': _token.decode('UTF-8')},
                                          signal)

        except PyJWTError as e:
            self.notify_signals(
                self.get_output_signal({'message': e.args[0]}, signal),
                'error')
class HarperDBHashSearch(HarperDBBase, Block, EnrichSignals):

    version = VersionProperty('0.1.0')
    schema = StringProperty(title='Schema', default='dev', order=2)
    table = StringProperty(title='Table', default='dog', order=3)
    hash_attribute = StringProperty(title='Hash Attribute', default='id', order=4)
    hash_values = Property(title='Hash Values', default='1, 3', order=5)
    get_attributes = StringProperty(title='Get Attributes', default='name, breed', order=6)

    def process_signals(self, signals):
        out_sigs = []
        for signal in signals:
            payload = {
              'schema': self.schema(),
              'table': self.table(),
              'operation': 'search_by_hash',
              'hash_attribute': self.hash_attribute(signal),
              'hash_values': self.hash_values(signal).replace(" ","").split(","),
              'get_attributes': self.get_attributes(signal).replace(" ","").split(",")
            }
            result = self.sendQuery(payload)
            for r in result:
                out_sigs.append(self.get_output_signal(r, signal))

        self.notify_signals(out_sigs)
class NetworkConfig(PropertyHolder):
    input_dim = ListProperty(Dimensions,
                             title='Input Tensor Shape',
                             default=[{
                                 'value': -1
                             }, {
                                 'value': 28
                             }, {
                                 'value': 28
                             }, {
                                 'value': 1
                             }])
    learning_rate = FloatProperty(title='Learning Rate', default=0.01)
    loss = SelectProperty(LossFunctions,
                          title='Loss Function',
                          default=LossFunctions.cross_entropy)
    optimizer = SelectProperty(Optimizers,
                               title="Optimizer",
                               default=Optimizers.GradientDescentOptimizer)
    dropout = FloatProperty(title='Dropout Percentage During Training',
                            default=0)
    random_seed = Property(title="Random Seed",
                           default=None,
                           allow_none=True,
                           visible=False)
class Replicator(Block):
    """Each incoming signal is replicated x times, where x
    is the length of list. Each output signal with have a
    new attribute, title, with the value of the list.

    """
    version = VersionProperty("1.1.0")
    list = Property(title='List', default='', order=0)
    title = StringProperty(title='Attribute Title', default='', order=1)

    def process_signals(self, signals):
        return_signals = []
        for signal in signals:
            try:
                values = self.list(signal)
            except Exception:
                values = [None]
                self.logger.exception("Failed to evaluate list")
            values = [None] if not values else values
            for value in values:
                sig = Signal(signal.to_dict())
                setattr(sig, self.title(), value)
                return_signals.append(sig)
        if return_signals:
            self.notify_signals(return_signals)
Beispiel #24
0
class GPIOWrite(Block):

    pin = IntProperty(default=0, title="Pin Number")
    value = Property(title='Write Value', default="{{ False }}")
    version = VersionProperty("0.1.1")

    def __init__(self):
        super().__init__()
        self._gpio = None

    def configure(self, context):
        super().configure(context)
        self._gpio = GPIODevice(self.logger)

    def stop(self):
        self._gpio.close()
        super().stop()

    def process_signals(self, signals):
        for signal in signals:
            self._write_gpio_pin(self.pin(signal), self.value(signal))
        self.notify_signals(signals)

    def _write_gpio_pin(self, pin, value):
        try:
            return self._gpio.write(pin, value)
        except:
            self.logger.warning(
                "Failed to write value {} to gpio pin: {}".format(value, pin),
                exc_info=True)
class AzureIoTSendEvent(AzureIoTBase, TerminatorBlock):
    """A block to send events to Azure cloud.
    """

    version = VersionProperty("1.0.0")
    event_to_send = Property(title="Event to Send",
                             default="{{ $.to_dict() }}", order=2)

    def process_signals(self, signals):
        for signal in signals:
            data = self.event_to_send(signal)
            if not isinstance(data, dict):
                self.logger.error("Data: {} rejected, a dict is expected".
                                  format(data))
                return

            self.logger.info("Sending: {}".format(data))
            self._client.send_event(data)

    def get_callbacks(self):
        return {"send_event_callback": self._send_event_callback}

    def _send_event_callback(self, result, message):
        self.logger.info(
            "Confirmation for event sent received with result: {} "
            "and message: {}".format(result, message))
class ObjectPath(PropertyHolder):

    class_id = IntProperty(title='Class ID', default=1, order=0)
    instance_num = IntProperty(title='Instance', default=1, order=1)
    attribute_num = Property(title='Attribute',
                             default=None,
                             allow_none=True,
                             order=2)
Beispiel #27
0
class Join(EnrichSignals, GroupBy, Block):
    """ Join block.

    Group a list of signals into one signal.
    The output signal will contain an attribute for each
    evaluated *key* and the value of that attribute will
    be a list with an item of *value* for each matching signal.

    If *one_value* is True, the Signal attributes will be just a
    single matching value instead of a list of all matching values.
    If multiple matches, then the last signal processed will be the
    value used.

    """
    key = StringProperty(title='Key', default="{{ $key }}")
    value = Property(title='Value', default="{{ $value }}", allow_none=True)
    group_attr = StringProperty(title="Group Attribute Name",
                                default="group",
                                visible=False)
    one_value = BoolProperty(title="One Value Per Key", default=False)
    version = VersionProperty("1.0.0")

    def process_signals(self, signals, input_id='default'):
        self.notify_signals(
            self.for_each_group(self._get_hash_from_group, signals))

    def _get_hash_from_group(self, signals, group):
        self.logger.debug("Processing group {} of {} signals".format(
            group, len(signals)))
        out_sig = self._perform_hash(signals)
        if out_sig:
            setattr(out_sig, self.group_attr(), group)
            return out_sig

    def _perform_hash(self, signals):
        hash_dict = defaultdict(None) if self.one_value() \
            else defaultdict(list)

        for signal in signals:
            sig_key = self.key(signal)
            sig_value = self.value(signal)

            # Add sig_value to the proper hash key
            try:
                if sig_key is not None:
                    if self.one_value():
                        hash_dict[sig_key] = sig_value
                    else:
                        hash_dict[sig_key].append(sig_value)
                else:
                    self.logger.debug("Skipping key: {}".format(sig_key))
            except:
                self.logger.exception(
                    "Failed to add value {} to key {}".format(
                        sig_value, sig_key))

        if len(hash_dict):
            return self.get_output_signal(hash_dict, signals[-1])
class LedStrip(Block):

    version = VersionProperty("0.1.0")
    pixelrgb0 = Property(title='pixel 0 r g b', default='{{(0, 0, 0)}}')
    pixelrgb1 = Property(title='pixel 1 r g b', default='{{(0, 0, 0)}}')
    pixelrgb2 = Property(title='pixel 2 r g b', default='{{(0, 0, 0)}}')
    pixelrgb3 = Property(title='pixel 3 r g b', default='{{(0, 0, 0)}}')
    pixelrgb4 = Property(title='pixel 4 r g b', default='{{(0, 0, 0)}}')
    pixelrgb5 = Property(title='pixel 5 r g b', default='{{(0, 0, 0)}}')
    pixelrgb6 = Property(title='pixel 6 r g b', default='{{(0, 0, 0)}}')

    def configure(self, context):
        super().configure(context)
        rh.rainbow.clear()
        rh.rainbow.show()

    def process_signals(self, signals):

        for signal in signals:
            for pixel in range(0, 7):
                red = getattr(self, 'pixelrgb{}'.format(pixel))(signal)[0]
                green = getattr(self, 'pixelrgb{}'.format(pixel))(signal)[1]
                blue = getattr(self, 'pixelrgb{}'.format(pixel))(signal)[2]
                rh.rainbow.set_pixel(pixel, red, green, blue)
                rh.rainbow.show()
        self.notify_signals(signals)

    def stop(self):
        rh.rainbow.clear()
        rh.rainbow.show()
        super().stop()
class CvColorChange(Block):

    version = VersionProperty('0.1.0')
    input_array = Property(title='Array to Convert', default='{{ $image }}')

    def process_signals(self, signals, input_id='default'):
        for signal in signals:
            signal.image = cv2.cvtColor(self.input_array(signal), cv2.COLOR_BGR2RGB)
        self.notify_signals(signals)
Beispiel #30
0
class RethinkDBDelete(EnrichSignals, RethinkDBBase):
    """a block for deleting one or more documents from a rethinkdb table"""

    table = StringProperty(title="Table to query",
                           default='test',
                           allow_none=False)
    filter = Property(title='Filter by given fields',
                      default='{{ $.to_dict() }}',
                      allow_none=False)

    def _locked_process_signals(self, signals):
        notify_list = []
        for signal in signals:
            self.logger.debug('Delete is Processing signal: {}'.format(signal))
            # update incoming signals with results of the query
            delete_results = self.execute_with_retry(self._delete, signal)
            self.logger.debug("Delete results: {}".format(delete_results))
            out_sig = self.get_output_signal(delete_results, signal)
            notify_list.append(out_sig)

        self.notify_signals(notify_list)

    def _delete(self, signal):
        with rdb.connect(
                host=self.host(),
                port=self.port(),
                db=self.database_name(),
                timeout=self.connect_timeout().total_seconds()) as conn:

            # this will return the typical deleted, errors, unchanges, etc.
            # as well as changes. If the delete was successful, 'new_val' will
            # be none in changes.

            # Query table configuration to get primary key
            table_config = rdb.db(self.database_name()).table(self.table()).\
                config()
            primary_key = [table_config["primary_key"]]
            filter_condition = self.filter(signal)

            # Check if filter condition is only primary key, if so, use
            # .get rather than .filter for better performance
            if list(filter_condition.keys()) == primary_key:
                results = rdb.db(self.database_name()).table(self.table()). \
                    get(filter_condition).delete(return_changes=True). \
                    run(conn)
            else:
                results = rdb.db(self.database_name()).table(self.table()).\
                    filter(self.filter(signal)).delete(return_changes=True).\
                    run(conn)

        if results["deleted"] == 0:
            self.logger.debug(
                "Unable to delete document for signal: {}".format(signal))

        self.logger.debug("Deleting using filter {} return results: {}".format(
            self.filter(signal), results))
        return results