Beispiel #1
0
    def async_write(self, var_names, var_ids, values, trans_id):
        """
        Async read data by the variable name.
        Args:
            var_names: Variable name list.
            var_ids: Variable id list in integer.
            values: Variable data.
            trans_id: Transaction id.

        Returns:
            Status code.

        """
        if (not isinstance(var_names, list)) or (not isinstance(var_ids, list)) \
                or (not isinstance(values, list)):
            raise ValueError('Names, ids, values need to be list.')

        indexes = []
        for var_id in var_ids:
            for index, item in enumerate(self.vars):
                if item.tag_id == var_id:
                    indexes.append(index)
                    break
        if not indexes:
            return
        flow_var = FlowVar(names=var_names, indexes=indexes, values=values,
                           op_mode=GoOperation.OP_ASYNC_WRITE, op_results=[], trans_id=trans_id)
        self.in_queue.put(flow_var)
Beispiel #2
0
    def refresh_worker(self):
        """
        Overrides the base method.

        """
        names = []
        indexes = []
        op_results = []
        for i, var in enumerate(self.vars):
            names.append(var.name)
            indexes.append(i)
            op_results.append(GoStatus.S_OK)

        inc = 1
        while self.refreshing:
            values = list()
            values.append(str(inc))
            if (inc // 10) % 2:
                values.append(True)
            else:
                values.append(False)
            values.append(inc * 1.0)
            values.append(inc / 2.0)
            values.append(None)
            values.append(self.sim_5)

            flow_var = FlowVar(names, indexes, values,
                               GoOperation.OP_REFRESH, op_results, -1)
            self.out_queue.put(flow_var)
            inc += 1
            if inc > 10000:
                inc = 1
            time.sleep(0.1)
Beispiel #3
0
    def async_read_by_id(self, tag_ids, trans_id, callback_func):
        """
        Async read date by the tag id.

        Args:
            tag_ids: Tag id list. If the list is empty, nothing done.
            trans_id: Unique transaction id.
            callback_func: Call back function.

        Raises:
            ValueError.

        """
        if not isinstance(tag_ids, list):
            raise ValueError('tag_id is not list.')
        if (trans_id is None) or (callback_func is None):
            raise ValueError('trans_id or callback is None.')

        if not tag_ids:
            return
        for caller_info in self.callers:
            if caller_info.key == trans_id:
                raise ValueError('Caller existed.')

        caller_info = CallerInfo(key=trans_id, callback_func=callback_func, tag_ids=tag_ids)
        with self.caller_lock:
            self.callers.append(caller_info)
        tag_ids_copy = tag_ids[:]
        flow_var = FlowVar(names=None, indexes=tag_ids_copy, values=None,
                           op_mode=GoOperation.OP_ASYNC_READ, op_results=None, trans_id=hash(caller_info))
        self.request_queue.put(flow_var)
Beispiel #4
0
    def update_main_from_secondary(self):
        """
        Routine for update the main cache from the secondary cache.
        If a main entry is 'empty' or 'dummy', the operation jumps to the next
        entry update.

        """
        while self.keep_updating:
            if self.debug:
                print('update secondary -> main...')
            for i in range(self.main.reserved_size):
                if (self.main.slots[i].name is not None) or \
                        (self.main.slots[i].name != hashtable.GO_DUMMY_KEY):
                    self.main.slots[i].prim_value = self.secondary[i].value
                    self.main.slots[i].time = time.time()
            for caller_info in self.subscribers:
                values = []
                op_results = []
                indexes = caller_info.tag_ids[:]
                for index in indexes:
                    values.append(self.main.slots[index].prim_value)
                    op_results.append(self.main.slots[index].error)

                flow_var = FlowVar(names=None, indexes=indexes, values=values,
                                   op_mode=GoOperation.OP_REFRESH, op_results=op_results,
                                   trans_id=hash(caller_info))
                try:
                    self.reply_queue.put_nowait(flow_var)
                except QueueFull:
                    if self.debug:
                        print('update_main_from_secondary(): OP_REFRESH - reply_queue full.')
            time.sleep(self.update_interval)
Beispiel #5
0
    def write_completed(self, tag_ids, op_results, trans_id):
        """
        Notify the service by devices putting the tag data back.
        Push the tag results into the reply queue.

        Args:
            tag_ids: Tag id list.
            op_results: Tag operation result list.
            trans_id: Transaction id.

        """

        if not isinstance(tag_ids, list):
            raise ValueError('tag_ids is not a list.')
        if not isinstance(op_results, list):
            raise ValueError('op_results is not a list.')

        flow_var = FlowVar(names=None, indexes=tag_ids, values=None,
                           op_mode=GoOperation.OP_ASYNC_WRITE, op_results=op_results, trans_id=trans_id)
        self.reply_queue.put(flow_var)
Beispiel #6
0
    def request_dispatch_worker(self):
        """
        Request queue dispatch worker.

        """
        for flow_var in self.request_queue:
            if GoOperation.OP_ASYNC_READ == flow_var.op_mode:
                values = []
                op_results = []
                for tag_id in flow_var.indexes:
                    values.append(self.main.slots[tag_id].prim_value)
                    op_results.append(self.main.slots[tag_id].error)
                flow_var.values = values
                flow_var.op_results = op_results
                self.reply_queue.put(flow_var)
            elif GoOperation.OP_ASYNC_WRITE == flow_var.op_mode:
                var_grp = {}
                none_provider_indexes = []
                for var_index, value in zip(flow_var.indexes, flow_var.values):
                    provider = self.main.slots[var_index].provider
                    if provider is None:
                        none_provider_indexes.append(var_index)
                        continue
                    if provider in var_grp:
                        var_grp[provider][0].append(var_index)
                        var_grp[provider][1].append(value)
                    else:
                        var_grp[provider] = ([var_index], [value])
                if none_provider_indexes:
                    op_results = [GoStatus.S_INVALID_PROVIDER] * len(none_provider_indexes)
                    none_flow_var = FlowVar(names=None, indexes=none_provider_indexes,
                                            values=None, op_mode=GoOperation.OP_ASYNC_WRITE,
                                            op_results=op_results, trans_id=flow_var.trans_id)
                    self.reply_queue.put(none_flow_var)
                for key, content in var_grp.items():
                    key.async_write([], content[0], content[1], flow_var.trans_id)
            else:
                raise ValueError('Unexpected operation mode')
Beispiel #7
0
    def async_write_by_id(self, tag_ids, tag_values, trans_id, callback_func):
        """
        Async write tags by the tag id.

        Args:
            tag_ids: Tag id in list. If it is empty, nothing done.
            tag_values: Tag value in list.
            trans_id: Unique transaction id.
            callback_func: Callback function.

        Raises:
            ValueError

        Returns:

        """
        if not isinstance(tag_ids, list):
            raise ValueError('tag_ids is not list')
        if not isinstance(tag_values, list):
            raise ValueError('tag_values is not list')
        if trans_id is None or callback_func is None:
            raise ValueError('trans_id or callback_func is None')
        if not tag_ids:
            return

        for caller_info in self.callers:
            if caller_info.key == trans_id:
                raise ValueError('Caller existed.')

        caller_info = CallerInfo(key=trans_id, callback_func=callback_func, tag_ids=tag_ids[:])
        with self.caller_lock:
            self.callers.append(caller_info)
        tag_ids_copy = tag_ids[:]
        flow_var = FlowVar(names=None, indexes=tag_ids_copy, values=tag_values,
                           op_mode=GoOperation.OP_ASYNC_WRITE, op_results=None, trans_id=hash(caller_info))
        self.request_queue.put(flow_var)