Exemplo n.º 1
0
def read_collection_data(cbsystem, cbauth, slave, address, count, collection):
    """Retrieve data from the specified collection

    :param cbsystem: The ClearBlade system object representing the ClearBlade System the adapter
                     will communicate with.
    :param cbauth: The object representing the ClearBlade Platform authentication credentials.
    :param slave: The unit id of the modbus device validation should be performed against.
    :param address: The starting address
    :param count: The number of values to retrieve
    :param collection: The name of the ClearBlade platform data collection in which to query

    :returns: Rows from the named data collection associated with the specified slave and data
              addresses
    """
    logging.debug("Begin read_collection_data")

    collection = cbsystem.Collection(cbauth, collectionName=collection)

    the_query = Query()
    the_query.equalTo("unit_id", slave)

    if count > 1:
        the_query.greaterThanEqualTo("data_address", address)
        the_query.lessThan("data_address", address + count)
    else:
        the_query.equalTo("data_address", address)

    return collection.getItems(the_query)
Exemplo n.º 2
0
def read_collection_data(context, register_type, address, count, fill=0):
    """
    Retrieve data from the specified collection.
    When retrieving sequential blocks if the ClearBlade collection is missing registers between the start and end,
    those will be filled (optionally)

    :param context.ClearBladeModbusProxySlaveContext context: The ClearBlade parent metadata to query against.
    :param str register_type: the type of register ('co', 'di', 'hr', 'ir')
    :param int address: The starting address
    :param int count: The number of values to retrieve
    :param int fill: automatically fills gaps in sequential register blocks with this value (or None)
    :returns: values, timestamps of the data read from the ClearBlade collection/proxy
    :rtype: list or dict (sequential or sparse)
    """
    collection = context.cb_system.Collection(
        context.cb_auth, collectionName=context.cb_data_collection)
    query = Query()
    query.equalTo(COL_PROXY_IP_ADDRESS, context.ip_proxy)
    query.equalTo(COL_SLAVE_ID, context.slave_id)
    query.equalTo(COL_REG_TYPE, register_type)
    if count > 1:
        query.greaterThanEqualTo(COL_REG_ADDRESS, address)
        query.lessThan(COL_REG_ADDRESS, address + count)
    else:
        query.equalTo(COL_REG_ADDRESS, address)
    reg_list = sorted(collection.getItems(query),
                      key=lambda k: k[COL_REG_ADDRESS])
    if len(reg_list) != count:
        context.log.warning(
            "Got {} rows from ClearBlade, expecting {} registers".format(
                len(reg_list), count))
    if context.sparse:
        values = {}
        timestamps = {}
        # Below commented code would fill in missing registers in a sparse data block (placeholder needs more thought)
        # for i in range(0, count-1):
        #     curr_addr = reg_list[i][COL_REG_ADDRESS]
        #     values[curr_addr] = reg_list[i][COL_REG_DATA]
        #     if i+1 < count and i+1 < len(reg_list):
        #         next_addr = curr_addr + 1
        #         if reg_list[i+1][COL_REG_ADDRESS] != next_addr and fill:
        #             context.log.info("Filling {} register {} with value {}"
        #                              .format(register_type, next_addr, FILL_VALUE))
        #             values[next_addr] = FILL_VALUE
        for reg in reg_list:
            values[reg[COL_REG_ADDRESS]] = reg[COL_REG_DATA]
            timestamps[reg[COL_REG_ADDRESS]] = reg[COL_DATA_TIMESTAMP]
    else:
        values = []
        timestamps = []
        for addr in range(address, address + count):
            if reg_list[addr][COL_REG_ADDRESS] != addr:
                if fill is not None:
                    if isinstance(fill, int):
                        context.log.info(
                            "Filling {} register {} with value {}".format(
                                register_type, addr, fill))
                        reg_list.insert(addr, {COL_REG_DATA: fill})
                    else:
                        raise ValueError(
                            "Fill parameter must be integer or None")
                else:
                    raise ParameterException(
                        "ClearBlade Collection missing register {} from block [{}:{}]"
                        .format(addr, address, address + count))
            values.append(reg_list[addr][COL_REG_DATA])
            timestamps.append(reg_list[addr][COL_DATA_TIMESTAMP])
    return values, timestamps