def do_POST(self): ''' The ContextBroker is informing us via one of our subscriptions. We convert the received content back and publish it in ROS. self: The "request" from the Context-Broker we invoke """RosTopicHandler.publish""" here! ''' # retreive Data and get the updated information recData = self.rfile.read(int(self.headers['Content-Length'])) receivedData = json.loads(recData) data = receivedData['data'][0] # Specific to NGSIv2 jsonData = json.dumps(data) topics = data.keys() # Convention Topic-Names are the attributes by an JSON Object, except: type, id # iterate through every 'topic', since we only receive updates from one topic # Only id, type and 'topicname' are present for topic in topics: if topic != 'id' and topic != 'type': dataStruct = self._buildTypeStruct(data[topic]) # Convert Back into a Python-Object obj = self.TypeValue() ObjectFiwareConverter.fiware2Obj(jsonData, obj, setAttr=True, useMetaData=False) # Publish in ROS RosTopicHandler.publish(data['id'], topic, getattr(obj, topic), dataStruct) # Send OK! self.send_response(204) self.end_headers() # Python 3 needs an extra end_headers after send_response
def publish(self, topic, rawMsg, msgDefintionDict): ''' This is the actual publish-Routine which updates and creates Entities on the ContextBroker. It also keeps track via posted_history on already posted entities and topics topic: a string, corresponding to the topic in ros rawMsg: the raw data directly obtained from rospy msgDefintionDict: The Definition as obtained directly from ROS-Messages We do not need to invoke something special here. This method gets called automatically, after Firos received a Message from the ROS-World TODO DL During Runtime an Entitiy might get deleted, check it here! ''' # Do nothing if no Configuratuion if self.noConf: return # if struct not initilized, intitilize it even on ContextBroker! if topic not in self.posted_history: self.posted_history[topic] = rawMsg obj = {s: getattr(rawMsg, s, None) for s in rawMsg.__slots__} obj["type"] = rawMsg._type.replace("/", "%2F") # OCB Specific!! obj["id"] = (topic).replace("/", ".") # OCB Specific!! jsonStr = ObjectFiwareConverter.obj2Fiware( obj, ind=None, dataTypeDict=msgDefintionDict[topic], ignorePythonMetaData=True, encode=True) response = requests.post(self.CB_BASE_URL, data=jsonStr, headers=self.CB_HEADER) self._responseCheck(response, attrAction=0, topEnt=topic) return # Replace previous rawMsg with current one self.posted_history[topic] = rawMsg # Create Update-JSON obj = {s: getattr(rawMsg, s, None) for s in rawMsg.__slots__} obj["type"] = rawMsg._type.replace("/", "%2F") # OCB Specific!! obj["id"] = (topic).replace("/", ".") # OCB Specific!! jsonStr = ObjectFiwareConverter.obj2Fiware( obj, ind=None, dataTypeDict=msgDefintionDict[topic], ignorePythonMetaData=True, showIdValue=False, encode=True) #print(jsonStr) # Update attribute on ContextBroker response = requests.post(self.CB_BASE_URL + obj["id"] + "/attrs", data=jsonStr, headers=self.CB_HEADER) self._responseCheck(response, attrAction=1, topEnt=topic)
def do_POST(self): ''' The ContextBroker is informing us via one of our subscriptions. We convert the received content back and publish it in ROS. self: The "request" from the Context-Broker we invoke """RosTopicHandler.publish""" here! ''' # retreive Data and get the updated information recData = self.rfile.read(int(self.headers['Content-Length'])) receivedData = json.loads(recData) data = receivedData['data'][0] # Specific to NGSIv2 jsonData = json.dumps(data) obj = self.TypeValue() ObjectFiwareConverter.fiware2Obj(jsonData, obj, setAttr=True, useMetaData=False, encoded=True) obj.id = obj.id.replace("_slash_", "/") obj.type = obj.type.replace("_slash_", "/") objType = obj.type topic = obj.id del data["id"] del data["type"] tempDict = dict(type=objType, value=data) dataStruct = self._buildTypeStruct(tempDict) RosTopicHandler.publish(topic, obj.__dict__, dataStruct) # # Send OK! self.send_response(204) self.end_headers( ) # Python 3 needs an extra end_headers after send_response
def onRobotData(request, action): ''' Returns the actual Content of the last sent Data of this robot onto the page. No Manipulation is done here. NOTE: only the data the robot published is shown here! Depending what is written after 'robot', specific content is published ''' name = request.path[7:] lastPubData = ROS_SUBSCRIBER_LAST_MESSAGE[name] lastPubData["type"] = C.CONTEXT_TYPE lastPubData["id"] = name json = ObjectFiwareConverter.obj2Fiware(lastPubData, dataTypeDict=ROS_TOPIC_AS_DICT, ignorePythonMetaData=True, ind=0) # Return the Information provided by the Context-Broker end_request(request, ('Content-Type', 'application/json'), 200, json)
def onRobotData(request, action): ''' Returns the actual Content of the last sent Data of this robot onto the page. No Manipulation is done here. NOTE: only the data the robot published is shown here! Depending what is written after 'robot', specific content is published ''' name = request.path[6:] if name in ROS_SUBSCRIBER_LAST_MESSAGE: lastPubData = ROS_SUBSCRIBER_LAST_MESSAGE[name] if lastPubData is not None: obj = {s: getattr(lastPubData, s, None) for s in lastPubData.__slots__} obj["id"] = name obj["type"] = lastPubData._type json = ObjectFiwareConverter.obj2Fiware(obj, dataTypeDict=ROS_TOPIC_AS_DICT[name], ignorePythonMetaData=True, ind=None) else: json = "" else: json = "" # Return the Information provided by the Context-Broker end_request(request, ('Content-Type', 'application/json'), 200, json)
def publish(self, robotID, topic, rawMsg, msgDefintionDict): ''' This is the actual publish-Routine which updates and creates Entities on the ContextBroker. It also keeps track via posted_history on already posted entities and topics robotID: A string corresponding to the Robot-Id topic: Also a string, corresponding to the topic of the robot rawMsg: the raw data directly obtained from rospy msgDefintionDict: The Definition as obtained directly from ROS-Messages We do not need to invoke something special here. This method gets called automatically, after Firos received a Message from the ROS-World TODO DL During Runtime an Entitiy might get deleted, check it here! ''' # Do nothing if no Configuratuion if self.noConf: return # if struct not initilized, intitilize it even on ContextBroker! if robotID not in self.posted_history: self.posted_history[robotID] = {} self.posted_history[robotID]['type'] = C.CONTEXT_TYPE self.posted_history[robotID]['id'] = robotID # Intitialize Entitiy/Robot-Construct on ContextBroker jsonStr = ObjectFiwareConverter.obj2Fiware( self.posted_history[robotID], ind=0, ignorePythonMetaData=True) response = requests.post(self.CB_BASE_URL, data=jsonStr, headers=self.CB_HEADER) self._responseCheck(response, attrAction=0, topEnt=robotID) if topic not in self.posted_history[robotID]: self.posted_history[robotID][topic] = {} # Check if descriptions are already added, if not execute again with descriptions! if 'descriptions' not in self.posted_history[robotID]: self.posted_history[robotID][ 'descriptions'] = self._loadDescriptions(robotID) if self.posted_history[robotID]['descriptions'] is not None: self.publish(robotID, 'descriptions', self.posted_history[robotID]['descriptions'], None) # check if previous posted topic type is the same, iff not, we do not post it to the context broker if (self.posted_history[robotID][topic] != {} and topic != "descriptions" and rawMsg._type != self.posted_history[robotID][topic]._type): Log( "ERROR", "Received Msg-Type '{}' but expected '{}' on Topic '{}'". format(rawMsg._type, self.posted_history[robotID][topic]._type, topic)) return # Replace previous rawMsg with current one self.posted_history[robotID][topic] = rawMsg # Set Definition-Dict if not set if msgDefintionDict is None: msgDefintionDict = {} # Convert rawMsg completeJsonStr = ObjectFiwareConverter.obj2Fiware( self.posted_history[robotID], ind=0, dataTypeDict=msgDefintionDict, ignorePythonMetaData=True) # format json, so that the contextbroker accepts it. partJsonStr = json.dumps({topic: json.loads(completeJsonStr)[topic]}) # Update attribute on ContextBroker response = requests.post(self.CB_BASE_URL + robotID + "/attrs", data=partJsonStr, headers=self.CB_HEADER) self._responseCheck(response, attrAction=1, topEnt=topic)