Within firos turtlesim example (https://firos.readthedocs.io/en/latest/install/turtlesim-example.html) I'm trying to publish msg on /turtle1/cmd_vel topic from Non-ROS-World trough POST request in order to move the robot.
However I'm not sure how to do that because when I start firos/core.py the list of entities created is:
{"id":".turtle1.pose","type":"turtlesim%2FPose","angular_velocity":{"type":"number","value":0,"metadata":{"dataType":{"type":"dataType","value":"float32"}}},"linear_velocity":{"type":"number","value":0,"metadata":{"dataType":{"type":"dataType","value":"float32"}}},"theta":{"type":"number","value":0,"metadata":{"dataType":{"type":"dataType","value":"float32"}}},"x":{"type":"number","value":5.544444561,"metadata":{"dataType":{"type":"dataType","value":"float32"}}},"y":{"type":"number","value":5.544444561,"metadata":{"dataType":{"type":"dataType","value":"float32"}}}}
And the list of subscriptions is:
{"id":"XXXX","expires":"2021-06-09T22:10:17.000Z","status":"active","subject":{"entities":[{"id":".turtle1.cmd_vel","type":"geometry_msgs%2FTwist"}],"condition":{"attrs":[]}},"notification":{"attrs":["linear","angular"],"onlyChangedAttrs":false,"attrsFormat":"normalized","http":{"url":"http://XXX.XXX.X.XXX:YYYYY"}}}
None entity with .turtle1.cmd_vel id is created, so that I don't know how to update for example linear attr. Do I have to create .turtle1.cmd_vel entity manually first and update attr after? I tried it:
curl -iX POST \
'http://localhost:1026/v2/entities' \
-H 'Content-Type: application/json' \
-d '
{
"id": ".turtle1.cmd_vel",
"type": "geometry_msgs%2FTwist",
"linear": {
"type": "float64",
"value": {
"x": "1",
"y": "0",
"z": "0"
}
},
"angular": {
"type": "float64",
"value": {
"x": "0",
"y": "0",
"z": "0"
}
}
}'
but I got errors.
Finally I solved the problem as follows:
POST the entity:
curl -iX POST \
'http://localhost:1026/v2/entities' \
-H 'Content-Type: application/json' \
-d '
{
"id":".turtle1.cmd_vel",
"type":"geometry_msgs%2FTwist",
"angular":{
"type":"geometry_msgs%2FVector3",
"value":{
"y":{
"type":"number",
"value":0.0
},
"x":{
"type":"number",
"value":0.0
},
"z":{
"type":"number",
"value":0.0
}
},
"metadata":{
"dataType":{
"type":"dataType",
"value":{
"y":"float64",
"x":"float64",
"z":"float64"
}
}
}
},
"linear":{
"type":"geometry_msgs%2FVector3",
"value":{
"y":{
"type":"number",
"value":0.0
},
"x":{
"type":"number",
"value":0.0
},
"z":{
"type":"number",
"value":0.0
}
},
"metadata":{
"dataType":{
"type":"dataType",
"value":{
"y":"float64",
"x":"float64",
"z":"float64"
}
}
}
}
}'
To update values:
curl -iX PATCH \
--url 'http://localhost:1026/v2/entities/.turtle1.cmd_vel/attrs' \
--header 'Content-Type: application/json' \
--data-raw ' {
"angular": {
"type":"geometry_msgs%2FVector3",
"value":{
"y":{
"type":"number",
"value": 0.0
},
"x":{
"type":"number",
"value": 0.0
},
"z":{
"type":"number",
"value": 0.0
}
},
"metadata":{
"dataType":{
"type":"dataType",
"value":{
"y":"float64",
"x":"float64",
"z":"float64"
}
}
}
},
"linear": {
"type":"geometry_msgs%2FVector3",
"value":{
"y":{
"type":"number",
"value": 8.0
},
"x":{
"type":"number",
"value": 8.0
},
"z":{
"type":"number",
"value": 8.0
}
},
"metadata":{
"dataType":{
"type":"dataType",
"value":{
"y":"float64",
"x":"float64",
"z":"float64"
}
}
}
}
}'
Note about updating entity:
It cannot directly update the sub-attribute "x" (from "linear" attr) on its own, it needs to resupply the whole JSON Object.
The reasoning behind this is as follows: NGSI just deals with Properties and Relationships - it is an abstraction layer for interoperability. The Property "linear" is an atomic unit hence you either change the whole "linear" or none of it. The value of "linear" is in this case a JSON object.
Related
I tried to add an already active stream to a new broadcast, and can't get the broadcast started. The steps I took were.
Created a new Broadcast.
curl --request POST \
"https://youtube.googleapis.com/youtube/v3/liveBroadcasts?part=snippet,contentDetails,status" \
--header "Authorization: Bearer XXX" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "{'snippet':{'scheduledStartTime':'2021-05-18T17:28:00Z','title':'Tester','description':'descr'},'status':{'privacyStatus':'public','selfDeclaredMadeForKids':false},'contentDetails':{'enableAutoStart':true,'recordFromStart':true,'latencyPreference':'normal','enableAutoStop':false}}"
{
"kind": "youtube#liveBroadcast",
"etag": "gyv8ux9AiVL_NuZefS8SGXc3iZQ",
"id": "z--Lm8b1mU0",
"snippet": {
"publishedAt": "2021-05-18T17:27:39Z",
"channelId": "XXXXXXXXXXXXXXXX",
"title": "Tester",
"description": "descr",
...
},
"scheduledStartTime": "2021-05-18T17:28:00Z",
"isDefaultBroadcast": false,
"liveChatId": "KicKGFVDRUZXb015R0VtWFdrcDdkV1BMWWRXQRILei0tTG04YjFtVTA"
},
"status": {
"lifeCycleStatus": "created",
"privacyStatus": "public",
"recordingStatus": "notRecording",
"madeForKids": false,
"selfDeclaredMadeForKids": false
},
"contentDetails": {
"monitorStream": {
"enableMonitorStream": true,
"broadcastStreamDelayMs": 0,
...
},
"enableEmbed": false,
"enableDvr": true,
"enableContentEncryption": false,
"startWithSlate": false,
"recordFromStart": true,
"enableClosedCaptions": false,
"closedCaptionsType": "closedCaptionsDisabled",
"enableLowLatency": false,
"latencyPreference": "normal",
"projection": "rectangular",
"enableAutoStart": true,
"enableAutoStop": false
}
}
Bind the already active stream to the Broadcast. I expected the enableAutoStart in the created broadcast to auto start the broadcast, though it did not.
curl --request POST "https://youtube.googleapis.com/youtube/v3/liveBroadcasts/bind?id=z--Lm8b1mU0&part=snippet,contentDetails,status&streamId=EFWoMyGEmXWkp7dWPLYdWA1615776388366728" --header "Authorization: Bearer XXXXXXXX" --header "Accept: application/json"
{
"kind": "youtube#liveBroadcast",
"etag": "L_Q87yK0gMxEM7VZ-aKHCTZ7n8g",
"id": "z--Lm8b1mU0",
"snippet": {
"publishedAt": "2021-05-18T17:27:39Z",
"channelId": "UCEFWoMyGEmXWkp7dWPLYdWA",
"title": "Tester",
"description": "descr",
},
"scheduledStartTime": "2021-05-18T17:28:00Z",
"isDefaultBroadcast": false,
"liveChatId": "KicKGFVDRUZXb015R0VtWFdrcDdkV1BMWWRXQRILei0tTG04YjFtVTA"
},
"status": {
"lifeCycleStatus": "ready",
"privacyStatus": "public",
"recordingStatus": "notRecording",
"madeForKids": false,
"selfDeclaredMadeForKids": false
},
"contentDetails": {
"boundStreamId": "EFWoMyGEmXWkp7dWPLYdWA1615776388366728",
"boundStreamLastUpdateTimeMs": "2021-05-18T16:58:04Z",
"monitorStream": {
"enableMonitorStream": true,
"broadcastStreamDelayMs": 0,
...
},
"enableEmbed": false,
"enableDvr": true,
"enableContentEncryption": false,
"startWithSlate": false,
"recordFromStart": true,
"enableClosedCaptions": false,
"closedCaptionsType": "closedCaptionsDisabled",
"enableLowLatency": false,
"latencyPreference": "normal",
"projection": "rectangular",
"enableAutoStart": true,
"enableAutoStop": false
}
}
Attempted to transition the broadcast to live. I also tried transition to testing, which failed with the same error.
curl --request POST -H "Authorization: Bearer XXXXXX" "https://www.googleapis.com/youtube/v3/liveBroadcasts/transition?part=id,snippet,contentDetails,status&broadcastStatus=live&id=z--Lm8b1mU0"
{
"error": {
"code": 403,
"message": "Invalid transition",
"errors": [
{
"message": "Invalid transition",
"domain": "youtube.liveBroadcast",
"reason": "invalidTransition",
"extendedHelp": "https://developers.google.com/youtube/v3/live/docs/liveBroadcasts/transition#params"
}
]
}
}
Verified the stream is still active.
curl "https://youtube.googleapis.com/youtube/v3/liveStreams?part=snippet,cdn,contentDetails,status&id=EFWoMyGEmXWkp7dWPLYdWA1615776388366728" -H "Authorization: Bearer XXXXXXXXXXX" -H "Accept: application/json"
{
"kind": "youtube#liveStreamListResponse",
"etag": "ejyo1UhcC8AFCfiY-TxKo4yhwv0",
"pageInfo": {
"totalResults": 0,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#liveStream",
"etag": "IZNA8olA5tx8tu2fGKPg4ws0YpM",
"id": "EFWoMyGEmXWkp7dWPLYdWA1615776388366728",
"snippet": {
"publishedAt": "2021-03-15T02:46:29Z",
"channelId": "XXXXXXXXXXXXXXXXXXXXXXXX",
"title": "Default stream key",
"description": "Description for default stream key",
"isDefaultStream": false
},
"cdn": {
"ingestionType": "rtmp",
"ingestionInfo": {
"streamName": "XXXX-XXXX-XXXX-XXXX-XXXX",
"ingestionAddress": "rtmp://a.rtmp.youtube.com/live2",
"backupIngestionAddress": "rtmp://b.rtmp.youtube.com/live2?backup=1",
"rtmpsIngestionAddress": "rtmps://a.rtmps.youtube.com/live2",
"rtmpsBackupIngestionAddress": "rtmps://b.rtmps.youtube.com/live2?backup=1"
},
"resolution": "variable",
"frameRate": "variable"
},
"status": {
"streamStatus": "active",
"healthStatus": {
"status": "good"
}
},
"contentDetails": {
...
"isReusable": true
}
}
]
}
Thoughts on how to make this work?
I figured it out.
Apparently you cannot have a brodcast created with enableAutoStart=true and then add an active stream. It seems that enableAutoStart=true fails the broadcast transition API calls to change the status to testing or live or complete.
To get this to work, I stopped then started sending to the stream, which caused the stream to transition to inactive then back to active. The transition caused the broadcast to start.
Alternatively, to get this to work without the restart of the stream, I did the following:
create the broadcast with enableAutoStart=false
bind the active stream to the broadcast (as in the question).
transition the broadcast to testing, then to live.
This seems to work fine.
Would have been nice to have the error message for transitioning indicate it was the enableAutoStart which was the problem.
I have a test environment where I have configured a service group for the JSON IoT Agent with a legacy expression in it:
{
"_id": "60acc2d549e4721ae5087356",
"__v": 0,
"iotagent": "http://10.0.0.2:4062",
"apikey": "apikeyTest2",
"entity_type": "WasteContainer",
"service_path": "/subservice",
"service": "service",
"resource": "/iot/json",
"description": "IoTAgent JSON - Node.js",
"protocol": "IoTA-JSON",
"internal_attributes": [],
"attributes": [
{
"name": "temperature",
"object_id": "t",
"type": "Number"
},
{
"name": "fillingLevel",
"expression": "${#level/100}",
"type": "Number"
}
],
"lazy": [],
"static_attributes": [],
"commands": []
}
Apart from that I register manually a device with a "jexl" as expression language:
curl --location --request POST 'https://host/iot/devices' \
--header 'Fiware-Service: service' \
--header 'Fiware-ServicePath: /subservice' \
--header 'X-Auth-Token: gAAAAABgrQm..._R8r98aeNWQ' \
--header 'Content-Type: application/json' \
--data-raw '{
"devices": [
{
"device_id": "deviceJSON1",
"entity_name": "device:entity01",
"entity_type": "device",
"expressionLanguage": "jexl",
"attributes": [
{
"object_id": "b",
"name": "position",
"type": "Number",
"expression": "(a+b)"
}
],
"protocol": "IoTA-JSON",
"transport": "HTTP"
}
]
}
'
Then I send data from the device using the apikey of the previous service group, but without using any attribute configured there:
curl --location --request POST 'http://host/iot/json?k=apikeyTest2&i=deviceJSON1&getCmd=0' \
--header 'Content-Type: application/json' \
--data-raw '{
"a": 4,
"b": 5
}'
The response is 400 Bad Request:
{
"name": "INVALID_EXPRESSION",
"message": "Invalid expression in evaluation [${#level/100}]"
}
Is this the expected result or should the agent try to use the "jexl" to transform the payload as there is not level attribute in the iot data?
To solve this I can create another service group with a different apikey and without default attributes, but just wanted to know if the result was the expected.
I want to create an issue using Jira REST API. Below code will works to create simple issue:
curl --request POST \
--url 'https://company_name.atlassian.net/rest/api/3/issue' \
--user 'user:token' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data {
"fields": {
"summary": "Remote test with request type",
"issuetype": {
"id": "12542"
},
"project": {
"key": "Test"
},
"description": {
"type": "doc",
"version": 1,
"content": [
{
"type": "paragraph",
"content": [
{
"text": "Second remote test",
"type": "text"
}
]
}
]
}
}
}
The thing is I want to create an issue with custom field - customfield_10029. By default it's set as nil but when I changed it manually in my board I saw something few more things inside of it:
"customfield_10029":
{"_links": {"jiraRest": "https://company_name.atlassian.net/rest/api/2/issue/241495", "web": "https://company_name.atlassian.net/servicedesk/customer/portal/19/SUP-11", "self": "https://company_name.atlassian.net/rest/servicedeskapi/request/241495"},
"requestType":
{"_expands": ["field"],
"id": "358",
"_links": {"self": "https://company_name.atlassian.net/rest/servicedeskapi/servicedesk/19/requesttype/358"},
"name": "Add Colaborator / Team Member",
"description": "e.g. external dev",
"helpText": "you can find github nicks down here https://github.com/some_url",
"issueTypeId": "12542",
"serviceDeskId": "19",
"groupIds": ["70"],
"icon":
{"id": "19558",
"_links":
{"iconUrls":
{"48x48": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=large",
"24x24": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=small",
"16x16": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=xsmall",
"32x32": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=medium"}}}}
So I thought the only thing I need to do is to add above code to the first POST request, like below:
curl --request POST \
--url 'https://company_name.atlassian.net/rest/api/3/issue' \
--user 'user:token' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data {
"fields": {
"summary": "Remote test with request type",
"issuetype": {
"id": "12542"
},
"project": {
"key": "SUP"
},
"description": {
"type": "doc",
"version": 1,
"content": [
{
"type": "paragraph",
"content": [
{
"text": "Second remote test",
"type": "text"
}
]
}
]
},
"customfield_10029":
{"_links": {"jiraRest": "https://company_name.atlassian.net/rest/api/2/issue/241495", "web": "https://company_name.atlassian.net/servicedesk/customer/portal/19/SUP-11", "self": "https://company_name.atlassian.net/rest/servicedeskapi/request/241495"},
"requestType":
{"_expands": ["field"],
"id": "358",
"_links": {"self": "https://company_name.atlassian.net/rest/servicedeskapi/servicedesk/19/requesttype/358"},
"name": "Add Colaborator / Team Member",
"description": "e.g. external dev",
"helpText": "you can find github nicks down here https://github.com/some_url",
"issueTypeId": "12542",
"serviceDeskId": "19",
"groupIds": ["70"],
"icon":
{"id": "19558",
"_links":
{"iconUrls":
{"48x48": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=large",
"24x24": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=small",
"16x16": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=xsmall",
"32x32": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=medium"}}}}
}
}
But I'm getting an error:
{"errorMessages":["Unexpected end-of-input: expected close marker for OBJECT (from [Source: org.apache.catalina.connector.CoyoteInputStream#2e2743e7; line: 1, column: 0])\n at [Source: org.apache.catalina.connector.CoyoteInputStream#2e2743e7; line: 46, column: 1863]"]}
Is there any logic behind that? how to create such an issue with customfield?
Looks like you're missing a brace.
--data { #<- This brace has no closing brace
"fields": { #<- This brace closes with the very last brace
When I make a POST call to the Orion Context Broker and the entity
"type": "geo:json" contains the ":" character I obtain:
{"error":"InternalError","description":"Database Error (collection: orion-carouge.entities - insert(): { _id: { id: "10_Place_Nations"....
curl -X POST \
http://<entityID>:port/v2/entities \
-H 'Content-Type: application/json' \
-H 'fiware-service:carouge' \
-H 'Fiware-ServicePath:/Traffic' \
-d '{ "type": {
"value": "Traffic"
},
"dateObserved": {
"value": "2019-05-22T21:26:00"
},
"id": "10_Place_Nations",
"location": {
"value": {
"coordinates": [
[
6.130983321064038,
46.21602766413273
]
],
"type" : "Point"
},
"type": "geo:json"
},
}'\
Apparently this is not a problem in the MongoDB of Orion. I am able to insert the "type": "geo:json" in the MongoDB. Probably some validation before making the post call, cause the problem. Any contribution will be very appreciated.
I think the problem is that your request has two errors.
First, you cannot use a JSON object as entity type. Entity types must be strings. Thus you have to use:
"type": "Traffic"
Second, the GeoJSON object you are using for location value is incorrect. Point uses a single coordinate in coordinates, not a list.
In sum, the following request will work:
curl -X POST \
http://localhost:1026/v2/entities \
-H 'Content-Type: application/json' \
-H 'fiware-service:carouge' \
-H 'Fiware-ServicePath:/Traffic' \
-d '{ "type": "Traffic",
"dateObserved": {
"value": "2019-05-22T21:26:00"
},
"id": "10_Place_Nations",
"location": {
"value": {
"coordinates": [
6.130983321064038,
46.21602766413273
],
"type" : "Point"
},
"type": "geo:json"
}
}'
I want to trigger a travis run on the master branch of a repository. That works alright following the instructions in the travis docs, but then I don't know how to get the status of the execution. The request returns some IDs, but none seem to be the request id.
$ body='{
"request": {
"branch":"master"
}}'
$ curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Travis-API-Version: 3" -H "Authorization: token $TOKEN" -d "$body" https://api.travis-ci.org/repo/snapcore%2Fsnapcraft/requests
{
"#type": "pending",
"remaining_requests": 9,
"repository": {
"#type": "repository",
"#href": "/repo/6402925",
"#representation": "minimal",
"id": 6402925,
"name": "snapcraft",
"slug": "snapcore/snapcraft"
},
"request": {
"repository": {
"id": 45199136,
"owner_name": "snapcore",
"name": "snapcraft"
},
"user": {
"id": 38186
},
"message": null,
"branch": "master",
"config": {
}
},
"resource_type": "request"
}
I can get all the requests using this endpoint: https://docs.travis-ci.com/api?http#requests
But then I would have to find my request, and again I'm not sure how to identify it.
The response should include a request.id as well:
{
"#type": "pending",
"remaining_requests": 49,
"repository": {
"#type": "repository",
"#href": "/repo/7181875",
"#representation": "minimal",
"id": 7181875,
"name": "repo_name",
"slug": "repo_user/repo_name"
},
"request": {
"repository": {
"id": 160982756,
"owner_name": "repo_owner",
"name": "repo_name"
},
"user": {
"id": 919859
},
"id": 160105240, # <-- this is the request ID that can be used in /request/#id
"message": null,
"branch": "master",
"config": {
}
},
"resource_type": "request"
}
This seems to be missing from what you posted. Either this was added in the meantime, or it got lost for you somehow.