Not populating switch data on Start of OSC?

I have a custom module to go read and XML and convert it to JSON so I can create a switch grid of buttons. I call the submodule in the main custom module, at the start. It functions properly. However, the switchgrid isn't populating at the start. If I reload the custom module after OSC has already been started, then the switchgrid populates correctly.

I tried placing my function outside of the module.exports, and also inside the module.exports.init() and both resulted in the same.

I'm assuming that my script might be running before the switch is even created so its sending the info no nothing I guess? Is there a correct way to go about this or is it not possible?

// divisiMate
receive("/divisiMate_switches", getPresetInfo())
// divisiMate submodule
const { readFileSync } = nativeRequire("fs")
const { parse, basename } = nativeRequire("path")
const { xml2json } = nativeRequire("xml-js")

const filePath = `${process.env.APPDATA}/Application Support/Nextmidi/Divisimate/Performances/DMD.dpf`
const readXML = readFileSync(filePath, { encoding: "utf-8" })
let xmlToJson = xml2json(readXML, {
  compact: true,
  spaces: 4,
  ignoreDeclaration: true,
})

xmlToJson = JSON.parse(xmlToJson).Performance
const dmAttributes = xmlToJson._attributes
const dmPresets = xmlToJson.PresetSlot

const getPresetInfo = () => {
  const switches = {}
  dmPresets.forEach((preset, i) => {
    const { PresetSlotNumber, PresetFile, PresetUuid } = preset._attributes

    if (PresetFile === undefined) return

    const presetName = basename(PresetFile, ".dmpreset")

    switches[presetName] = i + 1
  })
  return switches
}

module.exports = {
  getPresetInfo,
}

Start of OSC looks like this:

I'm expecting it to look like this which it does after a refresh of the custom module (just using ctrl+s in vsCode to simulate a refresh)

Cheers,
DMDComposer

You can confirm that is a timing issue wrapping the receive function in a setTimeout().

Another thing you could try is to call the receive function in an app.on("sessionOpened", callback), like so: (check details here: Custom module - Open Stage Control)

app.on("sessionOpened", (data, client) => {
    receive("/divisiMate_switches", getPresetInfo())
})

Cheers

1 Like

Thank you Clelson,

Using setTimeout() for some reason escaped my thought process of error checking. That did prove it was a timing issue. And using app.on worked as well, which I like using that better so I went with that option.

Cheers,
DMDComposer

1 Like

@DMDComposer Thanks for this, I would also like to integrate Divisimate in OSC.
I try to make your code work... but I stumble.

Could you share a picture of the json with the variables so I can understand better.

Hi Zig,

Here is a codeclip.io link that will walk you through the code that uses my divisimate file. Click the green Play/Start button, and it'll walk through. Feel free to pause it as it shows the console logs.

Just copy the code to yours, and replace the filePath with your divismate *.dpf file. And you should populate the same results. Note, to replace require to nativeRequire in order to use the npm packages within the custom module.

getPresetInfo() should return an object with the preset name as the key and the preset number as the value. Then use that to populate your switch or button grids. For example:

{ 'V1 + V2 8va': 1, 'Vc + Cb 8va': 2, 'Vc + Cb Unison': 3 }

custom module divisiMate script.

const { readFileSync } = nativeRequire("fs")
const { parse, basename } = nativeRequire("path")
const { xml2json } = nativeRequire("xml-js")

const filePath = `${process.env.APPDATA}/Application Support/Nextmidi/Divisimate/Performances/DMD.dpf`
const readXML = readFileSync(filePath, { encoding: "utf-8" })
let xmlToJson = xml2json(readXML, {
  compact: true,
  spaces: 4,
  ignoreDeclaration: true,
})

xmlToJson = JSON.parse(xmlToJson).Performance
const dmAttributes = xmlToJson._attributes
const dmPresets = xmlToJson.PresetSlot

const getPresetInfo = () => {
  const switches = {}
  dmPresets.forEach((preset, i) => {
    const { PresetSlotNumber, PresetFile, PresetUuid } = preset._attributes

    if (PresetFile === undefined) return

    const presetName = basename(PresetFile, ".dmpreset")

    switches[presetName] = i + 1
  })
  return switches
}

Cheers,
DMDComposer