Guide/tutorial for patch request button?

I have made an example preset with 3 controls of Kiwi JX3P and added a patch definition that instructs Electra how to fill these the controls with values out of the SysEx dump.

SysEx parsing example

{
   "version":2,
   "name":"KIWI-3P",
   "pages":[
  {
     "id":1,
     "name":"Page 1"
  }
   ],
   "groups":[
  {
     "pageId":1,
     "name":"DCO 1",
     "bounds":[
        0,
        16,
        486,
        16
     ],
     "color":"FFFFFF"
  }
   ],
   "devices":[
  {
     "id":1,
     "name":"Generic MIDI",
     "port":1,
     "channel":1,
     "patch":[
        {
           "request":[
              "7F",
              "7F",
              "7F",
              "60",
              "01",
              "00",
              "03"
           ],
           "responses":[
              {
                 "header":[
                    "00",
                    "21",
                    "16",
                    "60",
                    "01",
                    "00",
                    "04"
                 ],
                 "rules":[
                    {
                       "type":"cc7",
                       "id":1,
                       "pPos":0,
                       "byte":22,
                       "bPos":0,
                       "size":2
                    },
                    {
                       "type":"cc7",
                       "id":2,
                       "pPos":0,
                       "byte":22,
                       "bPos":2,
                       "size":2
                    },
                    {
                       "type":"cc7",
                       "id":3,
                       "pPos":0,
                       "byte":23,
                       "bPos":0,
                       "size":7
                    }
                 ]
              }
           ]
        }
     ]
  }
   ],
   "overlays":[
  {
     "id":1,
     "items":[
        {
           "value":0,
           "label":"16'"
        },
        {
           "value":32,
           "label":"8'"
        },
        {
           "value":64,
           "label":"4'"
        }
     ]
  },
  {
     "id":2,
     "items":[
        {
           "value":0,
           "label":"Sawtooth"
        },
        {
           "value":32,
           "label":"Pulse"
        },
        {
           "value":64,
           "label":"Square"
        }
     ]
  }
   ],
   "controls":[
  {
     "id":1,
     "type":"list",
     "name":"RANGE",
     "color":"FFFFFF",
     "bounds":[
        0,
        40,
        146,
        56
     ],
     "pageId":1,
     "controlSetId":1,
     "inputs":[
        {
           "potId":1,
           "valueId":"value"
        }
     ],
     "values":[
        {
           "defaultValue":32,
           "message":{
              "type":"cc7",
              "parameterNumber":8,
              "deviceId":1
           },
           "overlayId":1,
           "id":"value"
        }
     ]
  },
  {
     "id":2,
     "type":"list",
     "name":"WAVEFORM",
     "color":"FFFFFF",
     "bounds":[
        170,
        40,
        146,
        56
     ],
     "pageId":1,
     "controlSetId":1,
     "inputs":[
        {
           "potId":2,
           "valueId":"value"
        }
     ],
     "values":[
        {
           "message":{
              "type":"cc7",
              "parameterNumber":9,
              "deviceId":1
           },
           "overlayId":2,
           "id":"value"
        }
     ]
  },
  {
     "id":3,
     "type":"fader",
     "name":"TUNE",
     "color":"FFFFFF",
     "bounds":[
        340,
        40,
        146,
        56
     ],
     "pageId":1,
     "controlSetId":1,
     "inputs":[
        {
           "potId":3,
           "valueId":"value"
        }
     ],
     "values":[
        {
           "min":0,
           "max":127,
           "defaultValue":63,
           "message":{
              "type":"cc7",
              "parameterNumber":10,
              "min":0,
              "max":127,
              "deviceId":1
           },
           "id":"value"
        }
     ]
  }
   ]
}

The most important part here is the patch object in the device:

 "patch":[
    {
       "request":[
          "7F",
          "7F",
          "7F",
          "60",
          "01",
          "00",
          "03"
       ],
       "responses":[
          {
             "header":[
                "00",
                "21",
                "16",
                "60",
                "01",
                "00",
                "04"
             ],
             "rules":[
                {
                   "type":"cc7",
                   "id":1,
                   "pPos":0,
                   "byte":22,
                   "bPos":0,
                   "size":2
                },
                {
                   "type":"cc7",
                   "id":2,
                   "pPos":0,
                   "byte":22,
                   "bPos":2,
                   "size":2
                },
                {
                   "type":"cc7",
                   "id":3,
                   "pPos":0,
                   "byte":23,
                   "bPos":0,
                   "size":7
                }
             ]
          }
       ]
    }
 ]

The request defines bytes of the sysex message that will be sent when the [PATCH REQUEST] button is pressed.

       "request":[
          "7F",
          "7F",
          "7F",
          "60",
          "01",
          "00",
          "03"
       ]

This particular example requests dump of JX3P edit buffer.

The responses array defines sysex messages that are expected to arrive in response to the request. The header lists static bytes at the beginning of the incoming message.

             "header":[
                "00",
                "21",
                "16",
                "60",
                "01",
                "00",
                "04"
             ]

If the leading bytes of the incoming sysex message match the bytes of the header, Electra will start extraction of parameter values out of the message and will assign them to controls. The extraction is done with so-called rules. There are three rules in this example:

                {
                   "type":"cc7",
                   "id":1,
                   "pPos":0,
                   "byte":22,
                   "bPos":0,
                   "size":2
                }

this instructs Electra to get two bits (size = 2), out of 22nd byte of the sysex message (byte = 22). The position of the bits in the byte is 0 (bPos = 0). This extracted value should be stored in parameter 1 (id = 1) of the “cc7” type (type = “cc7”). The position of the value within the parameter is 0 (pPos = 0).

The location of the sysex byte (byte) is taken from the first byte after the header. It means the first byte after the header is byte = 0, second is byte = 1, and so on.

Applying above to the second rule:

                {
                   "type":"cc7",
                   "id":2,
                   "pPos":0,
                   "byte":22,
                   "bPos":2,
                   "size":2
                }

This tells Electra to pick 2 bits out of byte 22 from position 2 and make them value of parameter CC7 #2.

And finaly:

                {
                   "type":"cc7",
                   "id":3,
                   "pPos":0,
                   "byte":23,
                   "bPos":0,
                   "size":7
                }

tells Electra to pick value out of byte 23 and place it to CC7 #3.

I know this might be a little bit too much for start. I am available to help and I am working on the docs.

The Development Sandbox can be used to play around with the preset. Just copy and paste the contents of the file (above) to the Sandbox and modify it as you need.

I do not have JX3P around, so I wrote the example based on the screenshot yu sent me. I would say it could work but I cannot guarantee that.

Also, it is always useful to have ElectraOneConsole running when you experiment with things like this. The Log view can give you insight in what is happening in Electra when you load the preset and when you press the [PATCH REQUEST] button.

For the sake of completeness, this is what I expect to be the parameters I tried to parse: