Beispiel #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)
Beispiel #2
0
 def _initialize_slaves(self):
     """Sets up the slave contexts for the server"""
     slaves = []
     collection = self.cb_system.Collection(self.cb_auth, collectionName=self.cb_slaves)
     query = Query()
     if self.ip_address is not None:
         self.log.debug("Querying ClearBlade based on ip_address: {}".format(self.ip_address))
         query.equalTo(COL_PROXY_IP_ADDRESS, self.ip_address)
     else:
         self.log.debug("No ip_address found in ClearBlade, querying based on non-empty slave_id")
         query.notEqualTo(COL_SLAVE_ID, '')
     rows = collection.getItems(query)
     self.log.debug("Found {} rows in ClearBlade adapter config".format(len(rows)))
     for row in rows:
         slave_id = int(row[COL_SLAVE_ID])
         if slave_id not in slaves:
             slaves.append(slave_id)
             self[slave_id] = ClearBladeModbusProxySlaveContext(server_context=self, config=row, log=self.log)
         else:
             self.log.warning("Duplicate slave_id {} found in RTUs collection - only 1 RTU per server context"
                              .format(slave_id))
def get_adapter_config():
    """Retrieve the runtime configuration for the adapter from a ClearBlade Platform data \
    collection"""
    logging.debug("Begin get_adapter_config")

    logging.debug('Retrieving the adapter configuration from data collection %s', \
        CB_CONFIG['adapterSettingsCollectionName'])

    collection = CB_SYSTEM.Collection(CB_AUTH,
                                      collectionName=CB_CONFIG['adapterSettingsCollectionName'])

    the_query = Query()
    if CB_CONFIG['adapterSettingsItemID'] != "":
        the_query.equalTo("item_id", CB_CONFIG['adapterSettingsItemID'])

    rows = collection.getItems(the_query)

    # Iterate through rows and display them
    for row in rows:
        logging.debug(row)

    logging.debug("End get_adapter_config")
    def __fetch_adapter_config(self):
        cbLogs.info("AdapterLibrary - __fetch_adapter_config - Retrieving adapter config")

        adapter_config = {"topic_root": self.adapter_name, "adapter_settings": ""}

        collection = self._cb_system.Collection(self._device_client, collectionName=self._args[self.ADAPTER_CONFIG_COLLECTION_NAME_ARG_KEY])

        query = Query()
        query.equalTo("adapter_name", self.adapter_name)

        rows = collection.getItems(query)

        if len(rows) == 1:
            if rows[0]["topic_root"] != "":
                adapter_config["topic_root"] = str(rows[0]["topic_root"])
            if rows[0]["adapter_settings"] != "":
                raw_json = json.loads(str(rows[0]["adapter_settings"]))
                adapter_config["adapter_settings"] = self.__byteify(raw_json)
        else:
            cbLogs.warn("No adapter config found for adapter name " + self.adapter_name + ". Using defaults")

        cbLogs.info("AdapterLibrary - __fetch_adapter_config - Using adapter config: " + str(adapter_config))
        return adapter_config
Beispiel #5
0
def write_collection_data(cbsystem, cbauth, slave, address, data, collection):
    """Retrieve input register values from the Analog_Input_Registers 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 data: The data values to write to the Analog_Output_Holding_Registers collection
    :param collection: The name of the ClearBlade platform data collection in which to write
                        the data to
    """
    logging.debug("Begin write_collection_data")

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

    for ndx in range(0, len(data)):

        the_query = Query()
        the_query.equalTo("unit_id", slave)
        the_query.equalTo("data_address", address + ndx)

        collection.updateItems(the_query, {"data_value": data[ndx]})
Beispiel #6
0
def write_collection_data(context, register_type, address, data):
    """
    Retrieve input register values from the Analog_Input_Registers collection

    :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 data: The data value(s) to write
    """
    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)
    query.equalTo(COL_REG_ADDRESS, address)
    collection.updateItems(query, {COL_REG_DATA: data})
Beispiel #7
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