'Event handler for reception of a Message with set command - this is a
direct control command.
Verifies that
- all the requested nodes are available
(if no nodes are specified in the request, assume all nodes)
- all the control fields are available from all requested nodes
(if no nodes are specified in the request, assume all nodes)
If the request passes verification, the control request is passed
to the devices (in a separate thread).
If the verification fails, do nothing.'

def _handle_direct_set(self, msg):

    req_ok = True
    if (len(msg['set']['nodes']) > 0):
        for n in msg['set']['nodes']:
            if (not (n['nodeId'] in self.nodes)):
                req_ok = False
                error_msg = ('Invalid    nodeId    ' + n['nodeId'])
        process_nodes = [n['nodeId'] for n in msg['set']['nodes']]
    else:
        process_nodes = self.nodes.keys()
    process_fields = []
    if (len(msg['set']['datas']) > 0):
        for f in msg['set']['datas']:
            for node in self.nodes:
                if (not self.nodes[node]['device'].has_control_field(f['name'], f._get_typename())):
                    req_ok = False
                    missing_field = f['name']
                    error_msg = ('Invalid    field    ' + f['name'])
                    break
        process_fields = [(f['name'], f._get_typename(), f['value']) for f in msg['set']['datas']]
    if req_ok:
        session = self._new_session()
        self.sessions[session] = {'from': msg['from'], 'to': msg['to']}
        self.sessions[session]['commTimers'] = {}
        self.sessions[session]['nodeDone'] = {}
        self.sessions[session]['reply'] = False
        self.sessions[session]['node_list'] = process_nodes
        if self.threaded:
            tr_req = Thread(target=self._threaded_node_request, args=(session, process_fields))
            tr_req.start()
        else:
            self._threaded_node_request(session, process_fields)
