Some Watson IoT samples use a d in device payloads {"d":{"temp":20}}. As here in embedded c: :
"{\"d\" : {\"temp\" : 34 }}"
Others don't use this d, they just send in format {"temp":20}. Like this java sample:
//Generate a JSON object of the event to be published
JsonObject event = new JsonObject();
event.addProperty("name", "foo");
event.addProperty("cpu", 90);
event.addProperty("mem", 70);
Both work but I've had situations where I had to put in a d as a downstream app failed - and they said it was part of the api specification. I couldn't find that it actually is part of any specification. To d or not to d, that is the question?
All data is carried under a top level "d" element and an optional "ts" element exists, containing a timestamp for the message. If no ts element is present, the timestamp defaults to the time the message is received.
According to Bryan from the IoT team here:
IoT Foundation doesn't explicitly require a "d" top-level property in the JSON payload, however it does encourage this format to allow IoT Foundation to make some assumptions about how data is organized in the payload. If the IoT Foundation payload format is not followed, we refer to this as a "custom payload" in our documentation. IoT Foundation will allow you to publish a custom payload...
Related
In OCPP 1.6, the client (Charging Station) sends a CALL (similar to request in HTTP) to server (Charging Station Management Systems). All CALLs have a strict structure of 4 elements:
MessageTypeId (integer)
UniqueId (UUID, string)
Action (string)
Payload (JSON object containing the arguments relevant to the
Action.)
I have gone through the documentation but I cannot find MessageTypeId. So I want to know whether it is just a random number?
Example request payload:
[
2,// <----- I want to know, where I can find this.
"a7caa7a1-c309-43bd-af3f-b5c1c4f9657e",
"Authorize",
{
"idTag": "${req.body.idTag}"
}
]
MessageTypeId Defines the type of Message, whether it is Call, CallResult or CallError:
MessageType | MessageTypeId | Direction
CALL | 2 | Client-to-Server
CALLRESULT | 3 | Server-to-Client
CALLERROR | 4 | Server-to-Client
You can read more on page 9 of This document .
The OCA is authorized site for getting every single documented information for EV related software like different protocol of OCPP.
Link is as below from which you can download all documentation which contains,
Schema of request and response
Defination
Connection details
Structure of Messaging
Details of when to you which request and its meaning
https://www.openchargealliance.org/downloads/
More over, for your query, once you downloaded there is a document named "ocpp-j-1.6-specification" on where page 10 contains official details
Message type OCPP 1.6 from OCPP 1.6 but from this its not means that CALL will be always from client to server. some request CALL are also there which can be initiated from CSMS(Charging station management system) to CS(Charging station)
Thus below is another documented image for same purpose with newer version of ocpp 2.0.1
Message type OCPP 2.0.1 In here its clearly saying that the request will contains CALL to identifying its a request irrespective of source of generation (Either from CSMS or from CS)
I could not understand the exact difference between Yang action vs Yang rpc and as well the difference between anydata vs anyxml. Why someone should model using anydata or anyxml? I tried finding more information about this, but I could not find. Any information on this is very helpful.
"rpc" vs. "action"
The difference between an "rpc" and an "action" is that the latter is attached to a specific data node. This node may serve as metadata for the operation to be performed.
The difference between an action and an rpc is that an action is tied
to a node in the datastore, whereas an rpc is not. When an action is
invoked, the node in the datastore is specified along with the name
of the action and the input parameters.
RFC7950, Section 7.15
Suppose you have an array of items, each of which supports individual operations, such as "start", "stop" and "restart". When someone performs such an operation, they are saying something like: "Hey, please restart this specific item instance only". You would model this in YANG 1.1 using a "list" with embedded actions. That way when the operation is performed the server knows exactly which instance you want restarted, stopped or started, since its unique identifier becomes an integral part of the <rpc> payload (or a RESTCONF operation payload).
RFC7950 uses a "server farm" example to demonstrate this. Each server in the farm may be reset.
module example-server-farm {
yang-version 1.1;
namespace "urn:example:server-farm";
prefix "sfarm";
import ietf-yang-types {
prefix "yang";
}
list server {
key name;
leaf name {
type string;
}
action reset {
input {
leaf reset-at {
type yang:date-and-time;
mandatory true;
}
}
output {
leaf reset-finished-at {
type yang:date-and-time;
mandatory true;
}
}
}
}
}
The matching NETCONF payload followed by a RESTCONF payload ("Hey, please reset 'apache-1' server"):
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<action xmlns="urn:ietf:params:xml:ns:yang:1">
<server xmlns="urn:example:server-farm">
<name>apache-1</name>
<reset>
<reset-at>2014-07-29T13:42:00Z</reset-at>
</reset>
</server>
</action>
</rpc>
POST /restconf/data/example-server-farm:server=apache-1/reset HTTP/1.1
Host: example.com
Content-Type: application/yang-data+xml
<input xmlns="urn:example:server-farm">
<reset-at>2014-07-29T13:42:00Z</reset-at>
</input>
Note the difference in payload encoding. For NETCONF, the <rpc> for actions contains an <action> element in the standard urn:ietf:params:xml:ns:yang:1 namespace followed by an element branch identifying the data node instance, for RESTONF there is /restconf/data instead of /restconf/operations preceding the URI.
In comparison, rpcs are "globals". They always appear at top-level of a YANG module and may or may not apply to the entire device. You could of course implement any action using an rpc statement, but that would require some non-standard way to supply the referenced data node in an argument to the operation with the "input" statement. Someone is also more likely to perform this operation on non-existent instances.
So, the real reason for introducing this statement was convenience. A lot of server implementations relied own YANG extensions to support the same behavior, so it made sense to create a real YANG keyword to define it in a standard way.
"anyxml" vs. "anydata"
The newer keyword has now become the preferred way to model a blob of arbitrary data.
It should be noted that in YANG version 1, "anyxml" was the only
statement that could model an unknown hierarchy of data. In many
cases, this unknown hierarchy of data is actually modeled in YANG,
but the specific YANG data model is not known at design time. In
these situations, it is RECOMMENDED to use "anydata" (Section 7.10)
instead of "anyxml".
RFC7950, Section 7.11
When RFC6020 was published, YANG modeled data could only be encoded in XML. It made sense to introduce a keyword that represents a blob of arbitrary well-formed XML. But with time, new encodings popped up, such as the JSON encoding used in RESTCONF.
"anyxml" now makes much less sense. Why would a JSON oriented device need to embed XML in its payloads? That is way too cumbersome. So "anydata" was introduced - it models a blob of encoding-agnostic data. If the server is using XML it will be encoded as XML, if JSON is used it will be encoded in JSON, if X is used it will be encoded in X. The only constraint on this data is that it may be modeled with YANG!
The "anydata" statement is used to represent an unknown set of nodes
that can be modeled with YANG, except anyxml, but for which the data
model is not known at module design time. It is possible, though not
required, for the data model for anydata content to become known
through protocol signaling or other means that are outside the scope
of this document.
RFC7950, Section 7.10
I have REST service running on a server using Python flask. I have REST client which is built using java. I need to send two binary message in single Http REST request. The reason these are two because they both different protobuff message type but are inter-related to each other and should go in single HTTP request. How can we accomplish that at send and receive side.
The simplest option here may be to simply declare a wrapper message type:
message FooRequest {
// remove "required" if using proto3 syntax
required Request1MessageType part1 = 1;
required Request2MessageType part2 = 2;
}
and send a single FooRequest composed of the two inner messages. This is not always possible, however, in which case you'll have to implement your own framing mechanism inside the binary payload. A simple but pragmatic option might be to measure the size of the first message (in bytes) - i.e. len, and send:
[len, 4 bytes little endian][message 1, len bytes][message 2]
and decode it again at the other end - i.e. take the first 4 bytes and use that to calculate the ranges of the two inner messages. In anticipation of requiring more messages in the future, it might make sense to include a length prefix against every message (i.e. also include a length prefix for message 2) - but strictly speaking it would be redundant in the current case.
Thanks to NiFi How to use InvokeHTTP Processor with SOAP, I've been able to make a SOAP call. Strategy used was to use the GenerateFlowFile processor, and insert my content into custom content. The call needed a username and password, as well as another variable or two, and expression language neatly populated it.
Good.
Now, what I really need is two SOAP calls, where the first SOAP call returns a sequence number that I provide to the second call to get the specific data file I'm returning. I've set up a ProcessorGroup for the first SOAP interaction, which results in a flow attribute being set for the sequence number.
The rub: GenerateFlowFile just works on a timer. I've not been able to fathom a way where I can use the result from the first SOAP flow to then trigger an appropriately built FlowFile for the 2nd call.
Thoughts? Things I've puzzled over but haven't yet wrestled a solution forth include RouteOnAttribute, RouteOnContent, MergeContent, Wait, ...
You can use ReplaceText to accept an incoming flowfile with the correct sequenceNumber attribute and populate the flowfile content with the new SOAP body you need. The Replacement Value property supports Expression Language, so you could provide a value like:
Search Value: (?s)(^.*$)
Replacement Value: <xml><sequenceNumber>${sequence_number}</sequenceNumber></xml>
If you only need to replace part of the content or maintain some of the existing content text, you can use regex matching groups and backreferences to identify those.
The output from the ReplaceText processor would then be routed to a second InvokeHTTP processor to perform the second SOAP call.
Just to add on top of what #Andy had said. The response that you receive which contains the sequenceNumber will be in XML, right? So you could use EvaluateXPath processor to parse and get the sequence number and then use the approach that Andy had mentioned. i.e. Use ReplaceText processor to generate the SOAP Request body which would be sent to the second InvokeHTTP
So the overall flow would look like:
GenerateFlowfile -> InvokeHTTP -> EvaluateXPath -> ReplaceText -> InvokeHTTP -> (YOUR_LOGIC)
The task is to send an XML object from Channel-A to Channel-B
<MyMessage>
<ID>42</ID>
<hl7v2>
MSH|^~\&|LAB|....
PID|1|....
</hl7v2>
</MyMessage>
The steps of the channel communication:
in the Channel-B's source transformer, extract the HL7v2 contents
OVERWRITE the current msg object in Channel-B with the extracted contents
continue in the other Channel-B source transformers and expecting to reference msg['PID']['PID.5'] as normal.
The good news is that I can extract the HL7v2 'payload' into a variable. The problem or difficulty is resetting the msg object, or any other object to be able to reference the HL7 properties as expected.
When I create a new variable with the SerializerFactory.getHL7Serializer, it wraps with the tags <HL7Message>.
channelMap.put('MessageID', msg['ID']); //successful
channelMap.put('v2payload',msg['HL7v2']); //also looks good
var v2Msg = SerializerFactory.getHL7Serializer(false,false,true).toXML(msg['HL7v2']);
channelMap.put('v2Msg', v2Msg );
link to full size image
Question: Do you have any suggestions on how to overwrite the msg object?
How can I start referencing the msg as such:
msg['PID']['PID.5']
Current Conditions
the receiving channel's input type is XML
the need is to take extract all the properties from that XML object; ID is a database PK to be used later in the destination.
I'm sorry my original answer was bogged down with the peculiarities of my own scenario. I have reworked and tested to ensure that this works in your scenario.
Sending Channel - wraps the raw hl7 into your xml structure, and forwards to a channel called ReceiveXML. I have coded this in the Source Transformer, but you should code it where it works for you.
var wrappedHL7 = <MyMessage><ID>123</ID>
<hl7v2>{messageObject.getRawData()}</hl7v2>
</MyMessage>;
router.routeMessage("ReceiveXML", wrappedHL7);
Receiving Channel - extracts the hl7 from the xml, converts it to xml, and assigns back to the msg object. I have coded this in the source Filter - hence "return true;"
msg = new XML(SerializerFactory.getHL7Serializer(false,false,true).toXML(msg['hl7v2'].toString()));
return true;
All you have to do is put your incoming xml message into the inbound template area in mirth and then use the message tree to drag and drop the info from the XML that you need to the javascript section of the connector.