What is type (like "object") in ERC721 Metadata JSON schema - json

According to the standard, there's a type such as "object" shown below. What is this type for and what other types can we use? Can I use like "art?"
{
"title": "Asset Metadata",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Identifies the asset to which this NFT represents"
},
"description": {
"type": "string",
"description": "Describes the asset to which this NFT represents"
},
"image": {
"type": "string",
"description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive."
}
}
}

It's the datatype of the described item according to the JSON Schema specification. It's a standard used in other development fields as well - not limited just to NFTs or blockchain development.
There is a list of default allowed type values: http://json-schema.org/understanding-json-schema/reference/type.html
It's possible to create a custom type in JSON Schema, but the limited scope of what the "ERC-721 Metadata Document" document allows, doesn't effectively allow for custom types.
TLDR: Cannot use type: "art" in an "ERC-721 Metadata Document". Can use it in a larger scope (e.g. a REST endpoint definition).

Related

Fiware Upload Image

I want to know how to use NSGI-LD to upload an image even though these static files are not stored in Orion Context Broker or Mongo. I want to know if there is a way to configure the NSGI-LD to forward the images to AWS S3 Buck or another location?
As you correctly identified, binary files are not a good candidate for context data, and should not be held directly within a context broker. The usual paradigm would be as follows:
Imagine you have a number plate reader library linked to Kurento and wish to store the images of vehicles as they pass. In this case the event from the media stream should cause two separate actions:
Upload the raw image to a storage server
Upsert the context data to the context broker including an attribute holding the URI of the stored image.
Doing things this way means you can confirm that the image is safely stored, and then send the following:
{
"vehicle_registration_number": {
"type": "Property",
"value": "X123RPD"
},
"image_download": {
"type": "Property",
"value": "http://example.com/url/to/image"
}
}
The alternative would be to simply include some link back to the source file somehow as metadata:
{
"vehicle_registration_number": {
"type": "Property",
"value": "X123RPD",
"origin": {
"type": "Property",
"value": "file://localimage"
}
}
}
Then if you have a registration on vehicle_registration_number which somehow links back to the server with the original file, it could upload the image after the context broker has been updated (and then do another upsert)
Option one is simpler. Option two would make more sense if the registration is narrower. For example, only upload images of VRNs for cars whose speed attribute is greater than 70 km/h.
Ontologically you could say that Device has a relationship to a Photograph which would mean that Device could have an additional latestRecord attribute:
{
"latestRecord": {
"type": "Relationship",
"object": "urn:ngsi-ld:CatalogueRecordDCAT-AP:0001"
},
}
And and create a separate entity holding the details of the Photograph itself using a standard data model such as CatalogueRecordDCAT-AP which is defined here. Attributes such as source and sourceMetadata help define the location of the raw file.
{
"id": "urn:ngsi-ld:CatalogueRecordDCAT-AP:0001",
"type": "CatalogueRecordDCAT-AP",
"dateCreated": "2020-11-02T21:25:54Z",
"dateModified": "2021-07-02T18:37:55Z",
"description": "Speeding Ticket",
"dataProvider": "European open data portal",
"location": {
"type": "Point",
"coordinates": [
36.633152,
-85.183315
]
},
"address": {
"streetAddress": "2, rue Mercier",
"addressLocality": "Luxembourg",
"addressRegion": "Luxembourg",
"addressCountry": "Luxembourg",
"postalCode": "2985",
"postOfficeBoxNumber": ""
},
"areaServed": "European Union and beyond",
"primaryTopic": "Public administration",
"modificationDate": "2021-07-02T18:37:55Z",
"applicationProfile": "DCAT Application profile for data portals in Europe",
"changeType": "First version",
"source": "http://example.com/url/to/image"
"sourceMetadata": {"type" :"jpeg", "height" : 100, "width": 100},
"#context": [
"https://smartdatamodels.org/context.jsonld"
]
}

FIWARE, NGSI-LD - Understand the #context

I am creating a data model for a particular application and I did not start from any base model; since I did not start from any base model, the context below is sufficient, correct?
"#context": [
"https://schema.lab.fiware.org/ld/context",
"https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.3.jsonld"
]
My data model is not complicated, with just these properties and entity being more "complex":
"address": {
"type": "Property",
"value": {
"streetAddress": "",
"postalCode": "",
"addressLocality": "",
"addressCountry": ""
}
},
"location": {
"type": "Point",
"coordinates": [
,
]
},
{
"id": "urn:ngsi-ld:MeasurementSensor:",
"type": "MeasurementSensor",
"measurementVariable": {
"type": "Property",
"value": "Temperature"
},
"measurementValue": {
"type": "Property",
"value": 32.0,
"unitCode": "ÂșC",
"observedAt": "2022-05-10T11:09:00.000Z"
},
"refX": {
"type": "Relationship",
"object": "urn:ngsi-ld:"
},
"#context": [
"https://schema.lab.fiware.org/ld/context",
"https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.3.jsonld"
]
}
If you are using your own custom vocabulary you should declare your types and properties in your own LD #context. For instance,
{
"#context": [
{
"MeasurementSensor": "https://example.org/my-types/MesaurementSensor"
},
"https://schema.lab.fiware.org/ld/context",
"https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.3.jsonld"
]
}
it also seems you are not using URNs properly, you should check. unitCode seems to be broken as well, as it must follow the UN/CEFACT unit codes.
Nonetheless, I would not recommend to define your own vocabulary for sensors, given there are existing Vocabularies such as SAREF or W3C SOSA that can and should be reused.
I'm not a data model expert but I do know a thing or two about NGSI-LD and NGSI-LD brokers.
The #context you use is an array of "https://schema.lab.fiware.org/ld/context" and v1.3 of the core context.
"https://schema.lab.fiware.org/ld/context" in its turn is an array of "https://fiware.github.io/data-models/context.jsonld" and v1.1 of the core context ...
And, ""https://fiware.github.io/data-models/context.jsonld" doesn't define any of the three terms you are using, so, no need to give any context for that. The terms will be expanded using the default URL of the core context (the value of the #vocab member of the core context defines the default URL).
An NGSI-LD broker has the core context built-in, you don't need to pass it, so do yourself a favor, and get faster responses by not passing the core context to the broker. No need.
And, if you need a user context, pass it in the HTTP Header "Link" instead.
Host it somewhere (an NGSi-LD broker offers that service), so you don't force the poor broker to parse the #conterxt in each and every request.
Lastly, do follow Jose Manuels recommendations and use standard names for your attributes (and value for unitCode).

How to define which time_index attribute is used when notifing Quantumleap?

I am using FIWARE for some time-series data of heat-pumps. I use Orion 2.5.2 and Quantumleap 0.7.6.
My entities have a lot of attributes which are reported in batches. Those data-batches have individual time-stamps for each attribute, so the exact time of a measurement is known (this is also rather important). I use a little python tool to split these batches and send them to the iot-agent seperately via http, using the time-stamp parameter.
I end up with an entity like this:
...
"attrs": {
"temp_outdoor": {
"value": "-6.6",
"type": "Number",
"md": {
"TimeInstant": {
"type": "DateTime",
"value": 1613148707.7509995
}
},
"mdNames": [
"TimeInstant"
],
"creDate": 1612780352.3855166,
"modDate": 1613148716.1449544
},
"temp_return_flow": {
"value": "40.8",
"type": "Number",
"md": {
"TimeInstant": {
"type": "DateTime",
"value": 1613149016.394001
}
},
"mdNames": [
"TimeInstant"
],
"creDate": 1612780352.3855166,
"modDate": 1613149021.5991328
},
"TimeInstant": {
"value": 1613149101.1790009,
"type": "DateTime",
"mdNames": [],
"creDate": 1612780352.3855166,
"modDate": 1613149102.5100079
},
...
I don't really care about the creDate and modDate but about the TimeInstant in "md" of each attribute. Also the bottom "TimeInstant" attribute is just the value of the last Data-Point I think? I would like to use the "md" TimeInstant to create the time_index in CrateDB. Hence, the reported time has to be the custom-metadata one. I tried some different values while subscribing to Quantumleap but can't get it right.
Can someone tell me how to specify md->TimeInstant as value for time_index?
I find the documentation to be rather unconclusive on that topic and hope that someone has already solved that mistery and might let me in on it :)
Thanks!
Looking at your payload, it is not clear what's the NGSI model used, which would be the information need to help you. Anyhow, as reported by the documentation:
A fundamental element in the time-series database is the time index. You may be wondering... where is it stored? QuantumLeap will persist the time index for each notification in a special column called time_index.
The value that is used for the time index of a received notification is defined according to the following policy, which choses the first present and valid time value chosen from the following ordered list of options.
Custom time index. The value of the Fiware-TimeIndex-Attribute http header. Note that for a notification to contain such header, the corresponding subscription has to be created with an httpCustom block, as detailed in the Subscriptions and Custom Notifications section of the NGSI spec. This is the way you can instruct QL to use custom attributes of the notification payload to be taken as time index indicators.
Custom time index metadata. The most recent custom time index (the value of the Fiware-TimeIndex-Attribute) attribute value found in any of the attribute metadata sections in the notification. See the previous option about the details regarding subscriptions.
TimeInstant attribute. As specified in the FIWARE IoT agent documentation.
TimeInstant metadata. The most recent TimeInstant attribute value found in any of the attribute metadata sections in the notification. (Again, refer to the FIWARE IoT agent documentation.)
timestamp attribute.
timestamp metadata. The most recent timestamp attribute value found in any of the attribute metadata sections in the notification. As specified in the FIWARE data models documentation.
dateModified attribute. If you payed attention in the Orion Subscription section, this is the "dateModified" value notified by Orion.
dateModified metadata. The most recent dateModified attribute value found in any of the attribute metadata sections in the notification.
Finally, QL will use the Current Time (the time of notification reception) if none of the above options is present or none of the values found can actually be converted to a datetime.
This means that (and if you understand NGSI model, the documentation is quite clear), with the following payload
{
"id": "Room1",
"type": "Room",
"temperature": {
"value": 24.2,
"type": "Number",
"metadata": {
"myTime": {
"type": "DateTime",
"value": "2020-12-16T17:13:46.00Z"
}
}
},
"pressure": {
"value": 720,
"type": "Number",
"metadata": {
"TimeInstant": {
"type": "DateTime",
"value": "2020-12-16T17:13:46.00Z"
}
}
},
"dateObserved": "2021-02-02T00:00:00.00Z",
"dateCreated": "2019-09-24T12:49:02.00Z",
"dateModified": "2021-02-02T23:00:50.00Z",
"TimeInstant": {
"type": "DateTime",
"value": "2020-12-16T17:13:46.00Z"
}
}
If in the notification you set a custom header Fiware-TimeIndex-Attribute=dateObserved, time_index will be the value of dateObserved. If you set Fiware-TimeIndex-Attribute=myTime it will be the myTime attribute metadata linked to temperature. If not Fiware-TimeIndex-Attribute header is passed, the most recent value of metadata attribute TimeInstant will be picked. Suppose to remove the metadata attribute TimeInstant in the payload above, then attribute TimeInstant will be picked. If TimeInstant attribute is removed as well, dateModified value will be picked. In case that attribute is not received as well, current time is used.

Swagger v2 - Enums association

Unfortunately I could not locate anything relevant in the Swagger v2 documentation or in SO, so I am afraid I have to create this new thread.
What I would like to understand is whether it is feasible to associate enums with each other via Swagger. Consider the scenario where our Definitions specify a "Status" with two enum properties: "Code" and "Description" as per the below excerpt:
"definitions": {
"Status": {
"type": "object",
"properties": {
"Code": {
"type": "string",
"enum": ["01", "02", "03"]
},
"Description": {
"type": "string",
"enum": ["OK", "NOK - Please retry", "NOK - Do not retry"]
}
}
}
}
How could we specify that a given "Code" may only be associated to a specific "Description" (e.g. "01" for "OK", "02" for "NOK - Please retry", etc.)?
Obviously, using a property description (which actually acts as an embedded documentation) is not the way to go when having hundreds of Codes.
Thank you!

Creating a hierarchy of JSON schemas

I'm working on structuring some JSON data with information from different types of sources. I am focusing on only one type of source, documents, and I have a few data points collected and ready. So I decided I should try and write a JSON schema for data regarding the documents.
The first four properties, id, name, type and url must be present regardless of the type of source, but the other information contained in each varies. I would like to store all of them in the same database though. I suppose it will be of interest to write a schema for each of the other types of sources at a later point.
I am quite new to working with JSON, and the difficulty at the moment is understanding how I can fit these schemas together. What is the best practice? Is it possible to create a hierarchy of these different object types with a top level schema containing the information below and second level schemas for each type? Or is it better to make a larger schema containing all the information that could be present in all the different types of sources?
"$schema": "http://json-schema.org/schema#",
"title": "Document",
"description": "Information connected to a document",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier",
"type": "number"
},
"name": {
"description": "Title of the source",
"type": "string"
},
"type": {
"description": "Type of source",
"type": "string"
},
"url": {
"description": "URL of the source",
"type": "string"
},
"morePropertiesHere": {
"description": "the rest of the properties vary depending on type of source"
}
},
"required": ["id", "name", "type", "url"]
You can change the properties part in JSON like this, as it takes only number and text.
"properties": {
"id":1234,
"name":"Name of the source",
"description": "Title of the source",
"type": "Type of source",
"url": "URL of the source",
"morePropertiesHere": {
"description": "the rest of the properties vary depending on type of source"
}
}
If Id's are numbers then you can give them as it is instead of putting inside "".