예제 #1
0
def test_calculate_circular_drive_chains():
    blocks = [
        Block(id='block-1',
              type='test',
              data={'ptr1': blox_link('block-2', 'test', True)}),
        Block(id='block-2',
              type='test',
              data={'ptr2': blox_link('block-3', 'test', True)}),
        Block(id='block-3',
              type='test',
              data={'ptr3': blox_link('block-1', 'test', True)}),
    ]
    result = block_analysis.calculate_drive_chains(blocks)
    result = sorted(result, key=lambda v: v['target'])
    assert result == [
        {
            'target': 'block-1',
            'source': 'block-1',
            'intermediate': ['block-3', 'block-2']
        },
        {
            'target': 'block-2',
            'source': 'block-2',
            'intermediate': ['block-1', 'block-3']
        },
        {
            'target': 'block-3',
            'source': 'block-3',
            'intermediate': ['block-2', 'block-1']
        },
    ]
예제 #2
0
def serialize(block: Block):
    """
    Converts instructions in given Sequence block from dict to line format.
    """
    if 'instructions' in block.data:
        block.data['instructions'] = [to_line(d)
                                      for d in block.data['instructions']]
예제 #3
0
def parse(block: Block):
    """
    Converts instructions in given Sequence block from line to dict format.
    """
    if 'instructions' in block.data:
        block.data['instructions'] = [from_line(s, idx + 1)
                                      for idx, s in enumerate(block.data['instructions'])]
def test_partial():
    # Logged blocks will not include instructions
    # User input may not include instructions
    block = Block(id='sequence', type='Sequence', data={})
    sequence.parse(block)
    assert not block.data
    sequence.serialize(block)
    assert not block.data
예제 #5
0
def block_args(app):
    return Block(id='testobj',
                 serviceId=app['config']['name'],
                 type='TempSensorOneWire',
                 data={
                     'value': 12345,
                     'offset': 20,
                     'address': 'FF'
                 })
예제 #6
0
    async def post(self, block: Block) -> r200[Block]:
        """
        Validate block data.
        This checks whether the block can be serialized.
        It will not be sent to the controller.

        Tags: Blocks
        """
        block = await self.controller.validate(block)
        return web.json_response(block.dict())
예제 #7
0
    def _to_block(self, block: FirmwareBlock, find_sid=True) -> Block:
        block = Block(**block.dict(), id=None, serviceId=self._name)

        block.id = self._find_sid(block.nid, block.type) if find_sid else None
        resolve_data_ids(block.data, self._find_sid)

        # Special case, where the API data format differs from proto-ready format
        if block.type == const.SEQUENCE_BLOCK_TYPE:
            sequence.serialize(block)

        return block
async def test_to_firmware_block(app, client, store):
    store['alias', 123] = dict()
    store['4-2', 24] = dict()

    ctrl = controller.fget(app)

    assert ctrl._to_firmware_block(Block(id='alias', type='',
                                         data={})).nid == 123
    assert ctrl._to_firmware_block(Block(nid=840, type='', data={})).nid == 840

    assert ctrl._to_firmware_block_identity(
        BlockIdentity(id='alias')).nid == 123
    assert ctrl._to_firmware_block_identity(BlockIdentity(nid=840)).nid == 840

    # When both present, NID takes precedence
    assert ctrl._to_firmware_block(Block(id='alias', nid=444, type='',
                                         data={})).nid == 444

    with pytest.raises(exceptions.UnknownId):
        ctrl._to_firmware_block(Block(type='', data={}))

    with pytest.raises(exceptions.UnknownId):
        ctrl._to_firmware_block_identity(BlockIdentity())
예제 #9
0
def make_blocks() -> list[Block]:
    return [
        Block(
            id='Sensor',
            type='TempSensorOneWire',
            serviceId='test',
            data={
                'address': 'deadbeef',
                'offset': delta_temp_qty(0),
                'value': temp_qty(20),
                'oneWireBusId': blox_link(None),
            },
        ),
        Block(
            id='Setpoint',
            type='SetpointSensorPair',
            serviceId='test',
            data={
                'sensorId': blox_link('Sensor', 'TempSensorOneWire'),
                'storedSetting': temp_qty(20),
                'setting': temp_qty(None),
                'value': temp_qty(None),
                'valueUnfiltered': temp_qty(None),
                'resetFilter': False,
                'settingEnabled': True,
                'filter': 'FILTER_15s',
                'filterThreshold': delta_temp_qty(5),
            },
        ),
        Block(
            id='Heat PID',
            type='Pid',
            serviceId='test',
            data={
                'inputValue': temp_qty(0),
                'inputSetting': temp_qty(0),
                'outputValue': 0,
                'outputSetting': 0,
                'enabled': False,
                'active': True,
                'kp': blox_qty(20, '1 / degC'),
                'ti': blox_qty(2, 'h'),
                'td': blox_qty(0, 's'),
                'p': 0,
                'i': 0,
                'd': 0,
                'error': delta_temp_qty(0),
                'integral': blox_qty(0, 'delta_degC * hour'),
                'derivative': blox_qty(0, 'delta_degC / minute'),
                'derivativeFilter': 'FILTER_NONE',
                'integralReset': 0,
                'boilPointAdjust': delta_temp_qty(0),
                'boilMinOutput': 0,
                'boilModeActive': False,
                'inputId': blox_link('Setpoint', 'SetpointSensorPair'),
                'outputId': blox_link('Heat PWM', 'ActuatorPwm'),
                'drivenOutputId': blox_link('Heat PWM', 'ActuatorPwm', True),
            },
        ),
        Block(
            id='Heat PWM',
            type='ActuatorPwm',
            serviceId='test',
            data={
                'constrainedBy': {
                    'constraints': []
                },
                'desiredSetting':
                50,
                'setting':
                50,
                'value':
                50,
                'actuatorId':
                blox_link('Heat Actuator', 'DigitalActuator'),
                'drivenActuatorId':
                blox_link(
                    'Heat Actuator',
                    'DigitalActuator',
                    True,
                ),
                'enabled':
                True,
                'period':
                blox_qty(10, 's'),
            },
        ),
        Block(
            id='Heat Actuator',
            type='DigitalActuator',
            serviceId='test',
            data={
                'channel': 0,
                'constrainedBy': {
                    'constraints': [
                        {
                            'remaining': blox_qty(None, 's'),
                            'delayedOn': blox_qty(1, 'h'),
                        },
                    ],
                },
                'desiredState': 'STATE_ACTIVE',
                'state': 'STATE_ACTIVE',
                'hwDevice': blox_link('Spark Pins', 'Spark3Pins', True),
                'invert': False,
            },
        ),
        Block(
            id='Cool PID',
            type='Pid',
            serviceId='test',
            data={
                'inputValue': temp_qty(0),
                'inputSetting': temp_qty(0),
                'outputValue': 0,
                'outputSetting': 0,
                'enabled': False,
                'active': True,
                'kp': blox_qty(20, '1 / degC'),
                'ti': blox_qty(2, 'h'),
                'td': blox_qty(0, 's'),
                'p': 0,
                'i': 0,
                'd': 0,
                'error': delta_temp_qty(0),
                'integral': blox_qty(0, 'degC * hour'),
                'derivative': blox_qty(0, 'degC / minute'),
                'derivativeFilter': 'FILTER_NONE',
                'integralReset': 0,
                'boilPointAdjust': delta_temp_qty(0),
                'boilMinOutput': 0,
                'boilModeActive': False,
                'inputId': blox_link('Setpoint', 'SetpointSensorPair'),
                'outputId': blox_link('Cool PWM', 'ActuatorPwm'),
                'drivenOutputId': blox_link('Cool PWM', 'ActuatorPwm', True),
            },
        ),
        Block(
            id='Cool PWM',
            type='ActuatorPwm',
            serviceId='test',
            data={
                'constrainedBy': {
                    'constraints': [{
                        'limiting': True,
                        'balanced': {
                            'balancerId': blox_link('Balancer', 'Balancer'),
                            'granted': 10,
                            'id': 1,
                        },
                    }, {
                        'limiting': False,
                        'max': 100,
                    }],
                },
                'desiredSetting':
                50,
                'setting':
                50,
                'value':
                50,
                'actuatorId':
                blox_link('Cool Actuator', 'DigitalActuator'),
                'drivenActuatorId':
                blox_link(
                    'Cool Actuator',
                    'DigitalActuator',
                    True,
                ),
                'enabled':
                True,
                'period':
                blox_qty(10, 's'),
            },
        ),
        Block(
            id='Cool Actuator',
            type='DigitalActuator',
            serviceId='test',
            data={
                'channel': 0,
                'constrainedBy': {
                    'constraints': [{
                        'remaining': blox_qty(10, 'min'),
                        'delayedOn': blox_qty(1, 'h'),
                    }, {
                        'remaining': blox_qty(0, 'min'),
                        'delayedOff': blox_qty(1, 'h'),
                    }],
                },
                'desiredState': 'STATE_ACTIVE',
                'state': 'STATE_ACTIVE',
                'hwDevice': blox_link('Spark Pins', 'Spark3Pins', True),
                'invert': False,
            },
        ),
        Block(
            id='Spark Pins',
            type='Spark3Pins',
            serviceId='test',
            data={
                'enableIoSupply12V': True,
                'enableIoSupply5V': True,
                'channels': [],
                'soundAlarm': False,
                'voltage12': 12,
                'voltage5': 5,
            },
        ),
        Block(
            id='DisplaySettings',
            type='DisplaySettings',
            serviceId='test',
            data={
                'brightness':
                0,
                'name':
                'Suggestive Sensors',
                'tempUnit':
                'TEMP_CELSIUS',
                'timeZone':
                'UTC0',
                'widgets': [
                    {
                        'color':
                        '4169e1',
                        'name':
                        'Sensor 1',
                        'pos':
                        1,
                        'tempSensor':
                        blox_link('TempSensorOneWire-1',
                                  'TempSensorInterface'),
                    },
                ],
            },
        ),
    ]
예제 #10
0
 async def _patch(self, topic: str, msg: dict):
     block = Block(**msg)
     if block.serviceId == self.name:
         await self.controller.patch_block(block)