-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from makers-for-life/warpscript
Initial commit of WarpScript code for encoding/decoding
- Loading branch information
Showing
3 changed files
with
421 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// | ||
// Set the TTL of the macro to 1 minute so we can modify it and have | ||
// it reloaded in Warp 10 within 60 seconds. | ||
// | ||
1 m MSTU / MACROTTL | ||
{ | ||
'name' 'makair/decode' | ||
'since' '2.5.1' | ||
'desc' | ||
<' | ||
Decode a message encoded via `@makair/encode` and output the individual frames. | ||
'> | ||
'sig' [ | ||
[ [ 'message:BYTES' ] [ 'frames:LIST<MAP>' ] ] | ||
] | ||
'params' { | ||
'message' 'Encoded message that needs to be decoded.' | ||
'frames' 'List of extracted frames.' | ||
} | ||
} '.info' STORE | ||
<% | ||
!$.info INFO | ||
SAVE '.context' STORE | ||
// | ||
// Decode the Protobuf message | ||
// | ||
@makair/proto | ||
'MakAirTelemetry' PB-> | ||
'message' STORE | ||
// | ||
// Extract the device_id | ||
// | ||
$message 'device_id' GET 'device_id' STORE | ||
$message 'timestamp' GET 'timestamp' STORE | ||
$message 'encoded' GET 0 GET | ||
// Decompress content | ||
@senx/gzip/UNOPTGZIP | ||
'encoded' STORE | ||
|
||
// | ||
// Decode the VARINTs | ||
// | ||
$encoded VARINT-> 'varints' STORE | ||
|
||
// | ||
// Reshape the array. | ||
// Each frame contains 9 numbers | ||
// | ||
$varints [ $varints SIZE 9 / 9 ] RESHAPE | ||
|
||
<% | ||
0 != | ||
<% | ||
'current' STORE | ||
// Add the current values with those from the previous | ||
// reconstructed array | ||
[ $last $current ] ZIP | ||
<% | ||
LIST-> DROP | ||
// Undo the zig zag trick | ||
'unsigned' STORE | ||
$unsigned 63 << 63 >> $unsigned ^ 1 >> | ||
// Flip the top bit | ||
$unsigned 1 63 << & ^ | ||
+ | ||
%> false LMAP | ||
%> | ||
IFT | ||
'last' STORE $last | ||
%> LMAP | ||
|
||
// | ||
// We now have an array with arrays containing the original | ||
// values from each frame. We will rebuild the frames. | ||
// | ||
<% | ||
{} SWAP | ||
[ | ||
'systick' | ||
'cycle' | ||
'peak_command' | ||
'plateau_command' | ||
'peep_command' | ||
'cpm_command' | ||
'previous_peak_pressure' | ||
'previous_plateau_pressure' | ||
'previous_peep_pressure' | ||
] | ||
2 ->LIST ZIP | ||
<% | ||
LIST-> DROP PUT | ||
%> FOREACH | ||
$device_id 'device_id' PUT | ||
%> false LMAP | ||
$.context RESTORE | ||
%> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// | ||
// Set the TTL of the macro to 1 minute so we can modify it and have | ||
// it reloaded in Warp 10 within 60 seconds. | ||
// | ||
1 m MSTU / MACROTTL | ||
|
||
{ | ||
'name' 'makair/encode' | ||
// This macro needs the ->VARINT function which appeared in 2.5.1 | ||
'since' '2.5.1' | ||
'desc' | ||
<' | ||
Encodes a number of MakAir telemetry `MachineStateSnapshot` frames into a Protobuf message suitable for transmission over LoRa. | ||
|
||
The current alarm codes from the frames are NOT included in the message. They need to be transmitted independently. Since they are related to a life threatening situation, they can be transmitted over LoRa without respecting the air time limit. | ||
'> | ||
'sig' [ | ||
[ [ 'timestamp:LONG' 'frames:LIST<BYTES>' ] [ 'message:BYTES' ] ] | ||
] | ||
'params' { | ||
'timestamp' 'Timestamp (in platform time units) of the first frame of the list.' | ||
'frames' 'List of telemetry frames of type `MachineStateSnapshot`.' | ||
'message' 'Protobuf messages containing the input frames.' | ||
} | ||
} '.info' STORE | ||
<% | ||
!$.info INFO | ||
SAVE '.context' STORE | ||
[ 'frames' 'timestamp' ] STORE | ||
|
||
// | ||
// Iterate over the frames, keeping only the `MachineStateSnapshot` ones | ||
// | ||
[] | ||
$frames | ||
<% | ||
MAKAIR.TELEMETRY-> 'frame' STORE | ||
$frame 'type' GET | ||
'MachineStateSnapshot' != <% CONTINUE %> IFT | ||
// Add the frame to the list | ||
$frame +! | ||
%> FOREACH | ||
|
||
// Replace the original list with only the `MachineStateSnapshot` | ||
'frames' STORE | ||
|
||
// | ||
// Now extract all fields in an array for each frame | ||
// Note: we ignore the current alarm codes | ||
// | ||
|
||
// Remove variable $device_id if set | ||
'device_id' FORGET | ||
|
||
$frames | ||
<% | ||
'telemetry' STORE | ||
// Extract the device_id, the first one will be used | ||
// for all frames | ||
$telemetry 'device_id' GET 'device_id' CSTORE | ||
[ | ||
$telemetry 'systick' GET | ||
$telemetry 'cycle' GET | ||
$telemetry 'peak_command' GET | ||
$telemetry 'plateau_command' GET | ||
$telemetry 'peep_command' GET | ||
$telemetry 'cpm_command' GET | ||
$telemetry 'previous_peak_pressure' GET | ||
$telemetry 'previous_plateau_pressure' GET | ||
$telemetry 'previous_peep_pressure' GET | ||
] | ||
%> false LMAP | ||
'values' STORE | ||
|
||
// | ||
// Compute deltas | ||
// | ||
$values | ||
<% | ||
'idx' STORE | ||
// Keep the first array as is | ||
$idx 0 == | ||
<% | ||
'last' STORE $last | ||
// We do not ZigZag encode the first array as we assume | ||
// numbers are not negative and we want to encode the | ||
// first systick value on as few bytes as possible | ||
%> | ||
<% | ||
'current' STORE | ||
[ $current $last ] ZIP | ||
<% | ||
LIST-> DROP - | ||
%> false LMAP | ||
$current 'last' STORE | ||
// Adapt value so we alternatively encode positive and negative values | ||
<% | ||
DUP 1 << SWAP 63 >> ^ | ||
%> false LMAP | ||
%> | ||
IFTE | ||
// Encode all the LONGs using VARINT encoding, producing | ||
// a single byte array | ||
->VARINT | ||
%> LMAP | ||
|
||
// | ||
// Concatenate the byte arrays resulting from the ->VARINT calls | ||
// | ||
'' 'ASCII' ->BYTES SWAP | ||
<% + %> FOREACH | ||
|
||
// | ||
// Compress the resulting byte array using optimized GZIP | ||
// This macro in on SenX' WarpFleet repository: | ||
// | ||
// https://warpfleet.senx.io/macros/senx/gzip/OPTGZIP.mc2 | ||
// | ||
@senx/gzip/OPTGZIP | ||
'encoded' STORE | ||
|
||
// | ||
// Now build the protobuf message | ||
// | ||
{ | ||
'device_id' $device_id | ||
'timestamp' $timestamp | ||
// We do not need to set 'encoding' since the default | ||
// enum value for Encoding is MAKAIR_DELTA_OPTGZIP | ||
'encoded' [ $encoded ] | ||
} @makair/proto 'MakAirTelemetry' ->PB | ||
$.context RESTORE | ||
%> |
Oops, something went wrong.