Gravioプラットフォームは、新しいセンサーをインフラに追加する簡単な方法を提供します。
これを実現するにはセンサーが送出するデータの構造を定義する必要があります。これをSDD(Serial Data Definition)ファイルと呼びます。
SDDファイルは、シリアルデータをGravioがどのように解釈してデータ化するかを記述します。
ここではSDDファイルを作成する方法を説明します。
SDDファイルの作成手順
サンプルデータ:
データ長とデータ形式:
この資料では、上記のデータ構造を使用して、SDDファイル構造とサンプルSDDファイルの作成について説明します。
SDDファイルを使用すると、Gravioはシリアル・デバイスのセンサーを登録し、シリアル・デバイスから受信したデータを解釈して記録できます。
SDD基本構造
SDDファイルは有効なJSONファイルです。基本的な構造は次のようになります。
{
"Name": "Device Name",
"DataPoints": [],
"DataPackageSpec": {
"Fields": [],
"Validations": [],
"Mappings": []
}
}
この文書に沿って、この構造の各部分について説明します。
DataPackageSpec
"DataPackageSpec": {}
DataPackageSpecには、デバイスが送信したパケットの形式を理解するためにGravioが必要とする情報を定義します。通常、シリアル・データはバイト配列になっており、SDDファイルはあらゆる種類のデータをバイトデータとして処理します。
このデバイス用のDataPackageSpecを作成するには、上記のサンプルデータを参考にしてください。
Name
これはGravioに登録するデバイスの識別子です。デバイスの独自の名前で定義できます。
サンプルでは3つデバイスの名前とSDDファイル名は以下のように定義します。
ドア:
"Name": “SampleDoor”,
温度:
"Name": “SampleTemperature”,
加速度計:
"Name": “SampleAccelerometer”,
[仕様]
Nameで指定する名前はSDDファイル名と同じでなければなりません
次にDataPointsを定義しますが、この機能は別の機能に依存しているため、最後に説明します。
DataPackageSpec – Fields
"DataPackageSpec": {
"Fields": [],
}
Fieldsにはメッセージパケットの各フィールドを定義することができます。
サンプルのメッセージパケットの最初の3つのフィールド(Head、Type、およびDataLength)はすべて1バイトの固定サイズです。これらの3つを定数として定義します。
{
"Name": “Head”,
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": “Type",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": “DataLength",
"Size": {
"SizeType": "Constant",
"Size": 1
}
}
次のDataフィールドはペイロードです。サイズはDataLengthフィールドの値分の可変となりますので、DataLengthフィールドをペイロードのサイズの参照として使用します。
{
"Name": “Data",
"Size": {
"SizeType": “Reference",
"SizeRef": "DataLength"
}
}
FootフィールドとCRCフィールドを含むメッセージパケットの残りのフィールドもそれぞれ1バイトの定数として定義します。
{
"Name": “Foot",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": “CRC”,
"Size": {
"SizeType": "Constant",
"Size": 1
}
}
サンプルの3つのSDDファイルは、同じメッセージパケット構造を持っているため、これらのフィールドはすべて共通していますが、Dataフィールドはサイズが異なります。
[仕様]
FieldsはNameで名前を定義して、ValidationsとMappingsで参照します。
Sizeはフィールドのバイト数を定義しますが、SizeTypeにConstantを指定するとSizeの値を定数として使用します。Constant以外にはReference、Calculated、Optional、BitEnum、BitReferenceを指定することができます。
SizeTypeにReferenceを指定すると、SizeRefで参照指定しているフィールドの値が使用されます。
SizeTypeにCalculatedを指定するとTotalで指定したSizeからSubtrahendsで指定する配列にあるSizeの合計を引いた値でSizeを計算します。
SizeTypeにOptionalを指定するとValidationの条件が合致する場合のみSizeを使用します。
SizeTypeにBitEnumを指定するとRefSizeで参照するフィールドのビットと比較して、合致するSizeを使用します。
SizeTypeにBitReference指定するとRefSizeで参照するフィールドのビットをSizeとして使用します。
Calculated : 例
{
"Name": "Data",
"Size": {
"SizeType": "Calculated",
"Subtrahends": [
{
"SizeType": "Constant", < A
"Size": 1
},
{
"SizeType": "BitEnum", < B
"Length": 3,
"Offset": 5,
"RefSize": "DataHeader",
"BitEnum": [
{
"BitArray": [
false,
false,
false
],
"Size": 3
},
{
"BitArray": [
true,
false,
false
],
"Size": 4
},
{
"BitArray": [
false,
true,
false
],
"Size": 4
},
{
"BitArray": [
true,
true,
false
],
"Size": 6
}
]
},
{
"SizeType": "Optional", < C
"Size": {
"SizeType": "Constant",
"Size": 4
},
"Validation": {
"ValidationType": "BitEquals",
"Length": 3,
"Offset": 5,
"Input": "DataHeader",
"Output": [
false,
true,
false
]
}
},
{
"SizeType": "Optional", < D
"Size": {
"SizeType": "Constant",
"Size": 1
},
"Validation": {
"ValidationType": "BitEquals",
"Length": 4,
"Offset": 0,
"Input": "DataHeader",
"Output": [
true,
true,
true,
true
]
}
},
{
"SizeType": "Optional", < E
"Size": {
"SizeType": "Constant",
"Size": 1
},
"Validation": {
"ValidationType": "BitEquals",
"Length": 1,
"Offset": 4,
"Input": "DataHeader",
"Output": [
true
]
}
},
{
"SizeType": "Optional", < F
"Size": {
"SizeType": "BitReference",
"Length": 4,
"Offset": 0,
"SizeRef": "ExtendedHeader"
},
"Validation": {
"ValidationType": "BitEquals",
"Length": 1,
"Offset": 4,
"Input": "DataHeader",
"Output": [
true
]
}
},
{
"SizeType": "Constant", < G
"Size": 1
}
],
"Total": {
"SizeType": "Reference",
"SizeRef": "DataLength"
}
}
},
この場合のDataのSizeはTotalで参照しているDataLengthの値から、AからGのSizeの合計を引いた値が計算されます。
Optional、Validation : 例
{
"SizeType": "Optional",
"Size": {
"SizeType": "Constant",
"Size": 4
},
"Validation": {
"ValidationType": "BitEquals",
"Length": 3,
"Offset": 5,
"Input": "DataHeader",
"Output": [
false,
true,
false
]
}
},
この場合、ValidationでBitEqualsでビットの比較をInputで参照しているフィールドDataHeaderのOffset5からLength3のビット数をOutputの値と比較して、合致している場合にConstantは定数の指定ですので、Sizeは4を使用します。
BitEnum : 例
{
"SizeType": "BitEnum",
"Length": 3,
"Offset": 5,
"RefSize": "DataHeader",
"BitEnum": [
{
"BitArray": [
false,
false,
false
],
"Size": 3
},
{
"BitArray": [
true,
false,
false
],
"Size": 4
},
{
"BitArray": [
false,
true,
false
],
"Size": 4
},
{
"BitArray": [
true,
true,
false
],
"Size": 6
}
]
},
この場合、RefSizeで参照するフィールドDataHeaderのOffset5からLength3のビット数をBitEnumの配列と比較して、合致するBitArrayがある場合に、そのSizeを使用します。
BitReference : 例
{
"SizeType": "Optional",
"Size": {
"SizeType": "BitReference",
"Length": 4,
"Offset": 0,
"SizeRef": "ExtendedHeader"
},
"Validation": {
"ValidationType": "BitEquals",
"Length": 1,
"Offset": 4,
"Input": "DataHeader",
"Output": [
true
]
}
},
この場合、Validationが合致しているとSizeRefで参照するフィールドExtendedHeaderのOffset0からLength4のビット数の値をSizeとしてを使用します。
※Validationの使用方法は Optional、Validation : 例を参照してください。
—————————————————————
DataPackageSpec – Validations
"DataPackageSpec": {
“Validations": [],
}
Validationsはデータが正しい構造かどうかの検証と、受信したデータがどのシリアル・デバイスからのデータであるかを検証するために定義します。
サンプルではデータが正しい構造と検証するためにHead、Footフィールドの値とCRCフィールドの計算値の値を比較しています。
{
"ValidationType": "Equals",
"Input": "Head",
"Output": “FE"
}
{
"ValidationType": "Equals",
"Input": "Foot",
"Output": “FF”
}
{
"ValidationType": "CRC8",
"Inputs": [
"Head",
“Type",
"DataLength",
"Data",
“Foot"
],
"Output": "CRC"
}
受信したデータがどのシリアル・デバイスからのデータかを検証するためにDataLengthフィールドの値を比較しています。
DataLengthの値が1バイトの場合にはパケットはドアセンサーからのデータだと判断し、4バイトの場合には温度センサーからのデータ、
12バイトだと加速度計センサーからのデータだと判断するように検証を定義しています。
ドア:
{
"ValidationType": "Equals",
"Input": "DataLength",
"Output": “01”
}
温度:
{
"ValidationType": "Equals",
"Input": "DataLength",
"Output": “04”
}
加速度計:
{
"ValidationType": "Equals",
"Input": “DataLength",
"Output": “0C”
}
[仕様]
検証の種類はValidationTypeで定義し、Equalsは値の一致、BitEqualsはビット値の一致とCRC8はCRCを計算した値との一致の3つの定義があります。
Equalsでは比較対象となるフィールド名をInputで、比較する値をOutputで指定します。
※フィールド名は前述のDataPackageSpec – FieldsでNameとして定義した名前です。
Equals 例 :
{
"ValidationType": "Equals",
"Input": "Head",
"Output": “FE"
}
この例の場合、Headフィールドの値がFEかどうかが検証されます。
BitEqualsでは比較対象となるフィールド名をInputで、そのフィールドで比較するビット数をLengthで、
比較を始めるオフセットのビット数をOffsetで、比較する値をOutput配列で指定します。
BitEquals 例 :
{
"ValidationType": "BitEquals",
"Length": 6,
"Offset": 2,
"Input": "Type",
"Output": [
true,
false,
false,
true,
true,
true,
]
}
この例の場合、“Type“フィールドの値が“xx111001“かどうかが検証されます。
“CRC8“では比較対象となるフィールド名を“Inputs“配列で、比較するフィールド名を“Output“で指定します。
“CRC8” 例 :
{
"ValidationType": "CRC8",
"Inputs": [
"Head",
“Type",
"DataLength",
"Data",
“Foot"
],
"Output": "CRC"
}
この例の場合、CRCを計算するフィールドは、“Head”、“Type”、“DataLength”、“Data”、“Foot“フィールドの値が足し算されてCRC値が計算され、
CRCフィールドの値と一致しているかどうかが検証されます。
DataPackageSpec – Mappings
Mappingsでは、シリアル・デバイスからのデータ(メッセージパケット)を定義したDataPackageSpecのFieldsと、
Gravioにデータを渡すためのDataPoints(後述)との関連付けならびにデータの変換を行います。
サンプルではドアセンサー、温度センサーはどちらも1種類のデータを送信し、加速度センサーは3種類のデータを送信します。
ドアセンサーは1つの4バイトの整数、温度は1つの4バイトの浮動小数、加速度計の3つの4バイトの浮動小数と定義します。
ドア:
{
"MappingType": "Byte",
"Mapper": {
"MapperType": "Straight"
},
"Name": “Contact status",
"OutputType": 3,
"Size": 0,
"Start": 0,
"TargetField": “Data"
}
温度:
{
"MappingType": "Byte",
"Mapper": {
"MapperType": "Straight"
},
"Name": “Ambient temperature”,
"OutputType": 4,
"Size": 0,
"Start": 0,
"TargetField": “Data"
}
加速度計:
{
"MappingType": "Byte",
"Mapper": {
"MapperType": "Straight"
},
"Name": “Accelerometer X”,
"OutputType": 4,
"Size": 4,
"Start": 0,
"TargetField": “Data"
}
{
"MappingType": "Byte",
"Mapper": {
"MapperType": "Straight"
},
"Name": “Accelerometer Y”,
"OutputType": 4,
"Size": 4,
"Start": 4,
"TargetField": “Data"
}
{
"MappingType": "Byte",
"Mapper": {
"MapperType": "Straight"
},
"Name": “Accelerometer Z”,
"OutputType": 4,
"Size": 4,
"Start": 8,
"TargetField": “Data"
}
[仕様]
Mappingsでは、メッセージパケットからデータを取り出すときのデータタイプをMappingTypeでByte、BitかStringを指定します。
MappingTypeがByteの場合は、OutputTypeは0 : Byte、1 : ByteArray、3 : Integer、4 : Float、5 : Booleanを指定することができます。
MappingTypeがBitの場合は、OutputTypeは3 : Integer、4 : Floatか5 : Booleanを指定することができます。
MappingTypeがStringの場合は、OutputTypeは2 : Stringを指定することができます。
MapperのMapperTypeは、メッセージパケットから取り出したデータをそのまま出力する場合はStraight、変換する場合にはScaleかFunctionを指定します。
※ByteArray、Integerを扱う場合にはバイト配列はビッグエンディアンとして処理されます。
※FloatのフォーマットはIEEE754フォーマットとなります。
Scaleを指定する場合には合わせてScaleBottom、ScaleTop、RangeBottom、RangeTopを指定し、OutputTypeは3 : Integerか4 : Floatを指定します。
Scale 例 :
{
"MappingType": "Byte",
"Mapper": {
"MapperType": "Scale",
"RangeBottom": 255,
"RangeTop": 0,
"ScaleBottom": 0,
"ScaleTop": 40
},
演算式 :
var totalRange = Math.Abs(RangeTop - RangeBottom);
var totalScale = Math.Abs(ScaleTop - ScaleBottom);
var range = BitConverter.ToInt32(data.ToArray(), 0);
var factor = range / (double)totalRange;
if (RangeBottom > RangeTop)
factor = 1 - factor;
OutputTypeがIntegerの場合
計算値はInteger型で (factor * totalScale – (totalScale – ScaleTop)) となります
OutputTypeがFloatの場合
計算値はFloat型で (factor * totalScale – (totalScale – ScaleTop))となります
※この計算式はEnOceanのTemperatureの値の計算に使用しています。
C#スクリプトで作成する関数でメッセージパケットから取り出したデータを変換するにはFunctionを指定します。
Function 例 :
{
"MappingType": "Bit",
"Mapper": {
"MapperType": "Function",
"Function":"float result = (Data[1] << 8 ^ Data[0]) / (float)100;return BitConverter.GetBytes(result);"
},
"Name": "Temperature",
"OutputType": 4,
"Size": 16,
"Start": 280,
"TargetField": "Data"
},
※例ではDataの先頭から280バイト目から16ビット(2バイト)のデータが固定小数のため100で割り浮動小数に変換する処理を行っている
NameはDataPoints(後述)で使用するための名前を指定します。
OutputTypeは0から5までの数字で、0 : Byte、1 : ByteArray、2 : String、3 : Integer、4 : Float、5 : Booleanを指定します。
OutputTypeの型はDataPoints(後述)に渡されるデータの型となります。
Sizeはデータのサイズを指定します。MappingTypeがByteの場合はバイトサイズ、Bitの場合はビット数となります。
StartはTargetFieldで指定したデータの取得する先頭からの位置を指定します。
TargetFieldはFieldsにあるデータの変換元フィールドを指定します。
TargetFieldで指定したフィールドのStartを先頭にしてSize(MappingTypeがByteの場合はバイトサイズ、Bitの場合はビット数)分のデータを
Nameで指定した名前でOutputTypeを型としてDataPoints(後述)に渡されます。
またサンプルでは定義していませんが、データの送信元IDを指定するためにIdMappingを定義することもできます。
IdMappingでは、データのIDとなるフィールドをDataPackageSpecのFieldsから指定します。
指定しない場合にはGravioのDataViewerでは送信元IDにはZigbeeドングルがさされているCOMポート名が表示されます。
メッセージパケットからデータを取り出すときのデータタイプをMappingTypeにByteかBitを指定します。
MapperのMapperTypeはStraightを指定します。
Nameは“Id“を、OutputTypeは1(ByteArray)、Sizeは0とStartは0を指定します。
TargetFieldにはFieldsにあるデータの送信元が識別できるフィールドを指定します。
IdMapping 例 :
"IdMapping": {
"MappingType": "Byte",
"Mapper": {
"MapperType": "Straight"
},
"Name": "Id",
"OutputType": 1,
"Size": 0,
"Start": 0,
"TargetField": "SourceAddress"
},
例では、送信元が識別できるフィールドは“SourceAddress“として指定しています。
DataPoints
最後にDataPointsでは、Gravioで取得するデータを定義します。
これはSDDファイルの最上部に書かれていますが、この資料ではデータのフィールドを定義するFields、検証するValidations、FieldsとDataPointsをマッピングするMappingsを理解するために最後に説明する必要がありました。
DataPointsは、Mappingsで定義されたデータを指定します。また値によりラベルを指定することで人が理解しやすい文字として定義し、Gravioはその文字をデータとして取得することもできます。
ドア:
"DataPoints": [
{
"Name": "Contact status",
"Type": "int",
"DataRule": {
"RuleType": "set",
"Values": [
{
"Label": "Contact closed",
"Value": 1
},
{
"Label": "Contact open",
"Value": 0
}
]
}
}
]
ドアセンサーのデータは1つのInteger型の値(閉じた状態で1、開いた状態で0)であり、ラベルとして1はContact closed、0はContact openとして定義しています。
温度:
"DataPoints": [
{
"Name": “Ambient temperature",
"Type": “float",
}
]
温度センサーのデータは1つのFloat型の値として定義しています。
加速度計:
"DataPoints": [
{
"Name": “Accelerometer X",
"Type": “float",
},
{
"Name": “Accelerometer Y",
"Type": “float",
},
{
"Name": “Accelerometer Z”,
"Type": “float",
}
]
加速度計センサーのデータは3つのFloat型の値として定義しています。
1つのセンサーから複数のデータをGravioで取得する場合には、DataPointsに複数個定義します。
Gravioでは複数個分のデータはそれぞれ別々のデータとして取得されます。
加速度センサー以外にも例えばGPSのデータの場合には、緯度、経度、時刻の3つのデータを定義するにはDataPointsは以下のようになります。
GPS :
"DataPoints": [
{
"Name": "Latitude",
"Type": "float"
},
{
"Name": "Longitude",
"Type": "float"
},
{
"Name": "Timestamp",
"Type": "string"
}
],
[仕様]
DataPointsでは、Gravioにデータを渡す定義をします。
NameはMappingsで指定した名前を定義します。
Typeはint、float、doubleとstringを指定します。データはそれぞれの型でキャストされます。
戻り値を文字列にするには、DataRule、RuleTypeを定義して値はsetを指定します。
またValuesには戻り値で返す文字列をLabelに、その値をValueに指定します。
setの例 :
"DataPoints": [
{
"Name": "Contact status",
"Type": "int",
"DataRule": {
"RuleType": "set",
"Values": [
{
"Label": "Contact closed",
"Value": 1
},
{
"Label": "Contact open",
"Value": 0
}
]
}
}
]
この場合には、値が1の場合にはContact closedが返り、0の場合にはContact openが返ります。
SDDファイルの配置
SDDファイルはGravio Servicesの下記のディレクトリにコピーし、Gravio Edge Serviceを再起動することで有効となります。
Windowsの場合 :
C:¥ProgramData¥Gravio¥edge¥formats
※C:¥ProgramDataディレクトリはWindows標準では非表示のディレクトリとなっているためSDDファイルをコピーする場合には表示設定を予め変更してください。
参考url : https://support.microsoft.com/ja-jp/help/14201/windows-show-hidden-files
※Gravio Edge Serviceを再起動するにはサービスから“Gravio Edge Service“を再起動するか、Windowsを再起動してください。
Macの場合 :
/Library/Application Support/Gravio/edge/formats
※Gravio Edge Serviceを再起動するにはSettingのServicesからGravio Edge Serviceのチェックボックスをオフ、オンと切り替えるか、Macを再起動してください。
UbuntuとRaspberry PIの場合 :
/etc/opt/gravio/edge/formats
※Gravio Edge Serviceを再起動するにはTerminalから“systemctl restart gravioedge“を実行するか、Ubuntu/Raspberry PIを再起動してください。
Appendix: Resulting SDD files
SampleDoor.sdd
{
"Name": "SampleDoor",
"DataPoints": [
{
"Name": "Contact status",
"Type": "int",
"DataRule": {
"RuleType": "set",
"Values": [
{
"Label": "Contact closed",
"Value": 1
},
{
"Label": "Contact open",
"Value": 0
}
]
}
}
],
"DataPackageSpec": {
"Fields": [
{
"Name": "Head",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "Type",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "DataLength",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "Data",
"Size": {
"SizeType": "Reference",
"SizeRef": "DataLength"
}
},
{
"Name": "Foot",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "CRC",
"Size": {
"SizeType": "Constant",
"Size": 1
}
}
],
"Validations": [
{
"ValidationType": "Equals",
"Input": "Head",
"Output": "FE"
},
{
"ValidationType": "Equals",
"Input": "Foot",
"Output": "FF"
},
{
"ValidationType": "CRC8",
"Inputs": [
"Head",
"Type",
"DataLength",
"Data",
"Foot"
],
"Output": "CRC"
},
{
"ValidationType": "Equals",
"Input": "DataLength",
"Output": “01”
}
],
"Mappings": [
{
"MappingType": "Byte",
"Mapper": {
"MapperType": "Straight"
},
"Name": “Contact status",
"OutputType": 3,
"Size": 0,
"Start": 0,
"TargetField": “Data"
}
]
}
}
SampleTemperature.sdd
{
"Name": “SampleTemperature",
"DataPoints": [
{
"Name": “Ambient temperature",
"Type": “float",
}
],
"DataPackageSpec": {
"Fields": [
{
"Name": "Head",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "Type",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "DataLength",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "Data",
"Size": {
"SizeType": "Reference",
"SizeRef": "DataLength"
}
},
{
"Name": "Foot",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "CRC",
"Size": {
"SizeType": "Constant",
"Size": 1
}
}
],
"Validations": [
{
"ValidationType": "Equals",
"Input": "Head",
"Output": "FE"
},
{
"ValidationType": "Equals",
"Input": "Foot",
"Output": "FF"
},
{
"ValidationType": "CRC8",
"Inputs": [
"Head",
"Type",
"DataLength",
"Data",
"Foot"
],
"Output": "CRC"
},
{
"ValidationType": "Equals",
"Input": "DataLength",
"Output": “04”
}
],
"Mappings": [
{
"MappingType": "Byte",
"Mapper": {
"MapperType": "Straight"
},
"Name": “Ambient temperature”,
"OutputType": 4,
"Size": 0,
"Start": 0,
"TargetField": “Data"
}
]
}
}
SampleAccelerometer.sdd
{
"Name": "SampleAccelerometer",
"DataPoints": [
{
"Name": “Accelerometer X",
"Type": “float",
},
{
"Name": “Accelerometer Y",
"Type": “float",
},
{
"Name": “Accelerometer Z”,
"Type": “float",
}
],
"DataPackageSpec": {
"Fields": [
{
"Name": "Head",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "Type",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "DataLength",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "Data",
"Size": {
"SizeType": "Reference",
"SizeRef": "DataLength"
}
},
{
"Name": "Foot",
"Size": {
"SizeType": "Constant",
"Size": 1
}
},
{
"Name": "CRC",
"Size": {
"SizeType": "Constant",
"Size": 1
}
}
],
"Validations": [
{
"ValidationType": "Equals",
"Input": "Head",
"Output": "FE"
},
{
"ValidationType": "Equals",
"Input": "Foot",
"Output": "FF"
},
{
"ValidationType": "CRC8",
"Inputs": [
"Head",
"Type",
"DataLength",
"Data",
"Foot"
],
"Output": "CRC"
},
{
"ValidationType": "Equals",
"Input": “DataLength",
"Output": “0C”
}
],
"Mappings": [
{
"MappingType": "Byte",
"Mapper": {
"MapperType": "Straight"
},
"Name": “Accelerometer X”,
"OutputType": 4,
"Size": 4,
"Start": 0,
"TargetField": “Data"
},
{
"MappingType": "Byte",
"Mapper": {
"MapperType": "Straight"
},
"Name": “Accelerometer Y”,
"OutputType": 4,
"Size": 4,
"Start": 4,
"TargetField": “Data"
},
{
"MappingType": "Byte",
"Mapper": {
"MapperType": "Straight"
},
"Name": “Accelerometer Z”,
"OutputType": 4,
"Size": 4,
"Start": 8,
"TargetField": “Data"
}
]
}
}