How to read for ex. the PC-24 configuration files? We need some Epic example planes.- Thanks
PC 24 is encrypted… use pc 12
Thanks I’ll try.
I started off posting just these notes but decided to cut-paste the code from my gauge as well… Not sure how much code is appropriate in this forum but if it helps, here it is (cut down for clarity). BTW I think the panel.xml
support for html/js gauges is awesome. All my gauge work is RPN/HTML/JS so apologies if your interest is WASM.
Pls note inside my html/js ‘BaseInstrument’ class I consistently assign const instrument = this;
mainly to propagate instrument
through the calls, so the local instrument
var is an alias for the BaseInstrument object. Not essential but with async code in JS there are various reasons why you need to be wary of the this
variable, especially in callbacks.
General points:
- Your
parseXMLConfig()
function is called asynchronously by the html/js gauge framework, much likeconnectedCallback()
. When these async calls are made has no guarantees but your later code in the gauge will certainly have dependencies on these completing, so you’ll see I haveinstrument.config_complete = true;
at the end of myparseXMLConfig()
. I can use that e.g. to mask things in theUpdate()
loop until things are ready. - The ‘spec’ for the
panel.xml
is to repeat elements called<Instrument>
with an internal element called<Name>
for each of your instruments which is a bit awkward, and I noted Working Title have side-stepped that for their instruments, instead using a unique tag for each of them. Makes it a lot easier to pull out the pertinent entry from thepanel.xml
file, especially if you have multiple instruments of the same type on the panel. In my example I’ve written that ‘id’ asMY_GAUGE
but it’s whatever you think will be unique. The whole panel config is available to all gauges ininstrument.xmlConfig
so you can usegetElementsByTagName("MY_GAUGE")
from there. - FWIW I created a JS Class
B21Config
to hold the values from the config XML. Not really necessary but it’s super-simple and I included the code below. - It can be an important consideration how to differ the config across multiple instances of the same gauge on the same panel. This can be done by appending an ‘INDEX’ value to your instrument ‘BASENAME’ and that value can be picked up from the gauge URL in
panel.cfg
.
Your requirements may differ so a different approach could easily be better, but those hints might help. You could rightly be wary of going off-piste with panel XML element names, but I think I’m in good company. I actually have way of sharing the html/js between variants of a plane (different wingspans) and automatically pick up different config values for those (so they can share the same panel.xml file) but omitted that dimension here.
panel.xml
<PlaneHTMLConfig>
<MY_GAUGE>
<Name>MY_GAUGE</Name>
<SettingsId>JS3</SettingsId>
<Pages>["map","task","settings","grid"]</Pages>
<Circuit>30</Circuit>
</MY_GAUGE>
...
</PlaneHTMLConfig>
gauge js
I created a simple B21Config
class for JS to hold the config values loaded from the XML, and instantiate that as instrument.config
in the BaseInstrument constructor. As mentioned, not essential.
const instrument = this;
instrument.BASENAME = "MY_GAUGE";
instrument.INDEX = null;
...
instrument.config = new B21Config(
{
SETTINGS_ID: "",
PAGES: ["map","task","settings","grid"],
CIRCUIT: null,
}
parseXMLConfig()
// parseXMLConfig will load panel.xml and set instrument.config_complete = true
parseXMLConfig() {
const instrument = this;
console.log("parseXMLConfig()");
super.parseXMLConfig();
if (instrument.xmlConfig) {
try {
let xml = instrument.xmlConfig.getElementsByTagName(instrument.BASENAME)[0];
// All MY_GAUGE gauges load these common values
instrument.load_panel_config(xml);
// If this particular gauge has an INDEX, it can load more XML e.g. MY_GAUGE_1
// which can add additional values or override the BASENAME gauge values.
if (instrument.INDEX != null) {
let index_name = instrument.BASENAME+"_"+instrument.INDEX;
console.log("parseXMLConfig() loading indexed config from "+index_name);
let index_xml = instrument.xmlConfig.getElementsByTagName(index_name)[0];
if (index_xml != null) {
instrument.load_panel_config(index_xml);
}
}
} catch (e) {
console.error("parseXMLConfig() fail",e);
}
} else {
console.warn("No XML Config");
}
instrument.config_complete = true
}
load_panel_config(xml) {
const instrument = this;
console.log("instrument.load_panel_config() with index "+instrument.INDEX);
let settings_id = instrument.config.get_string(xml, "SettingsId","");
if (settings_id != null) {
instrument.config.SETTINGS_ID = settings_id;
}
let pages = instrument.config.get_array(xml, "Pages");
if (pages != null) {
instrument.config.PAGES = pages;
}
let circuit = instrument.config.get_number(xml, "Circuit", -1);
if (circuit >= 0) {
instrument.config.CIRCUIT = circuit;
}
}
B21Config class
This is my optional class used to hold the panel.xml values. In the instrument it’s instantiated as instrument.config
.
class B21Config {
constructor(init_obj) {
Object.assign(this, init_obj);
}
get_string(xml, tag_name, default_value) {
let el = xml.getElementsByTagName(tag_name)[0];
if (el) {
try {
let js_value = el.textContent;
console.log(`B21Config.get_string for ${tag_name} found "${js_value}"`);
return js_value;
} catch (e) {
console.warn(`B21Config.get_string failed for ${tag_name}`);
}
}
console.warn(`B21Config.get_string using default for ${tag_name}`);
return default_value;
}
get_number(xml, tag_name, default_value) {
let el = xml.getElementsByTagName(tag_name)[0];
if (el) {
try {
let js_value = JSON.parse(el.textContent);
if (typeof js_value == "number") {
console.log(`B21Config.get_number for ${tag_name} found a number ${JSON.stringify(js_value)}`);
return js_value;
} else {
console.warn(`B21Config.get_number not number for ${tag_name}`);
}
} catch (e) {
console.warn(`B21Config.get_number failed for ${tag_name}`);
}
}
console.warn(`B21Config.get_number using default for ${tag_name}`);
return default_value;
}
get_array(xml, tag_name) {
let el = xml.getElementsByTagName(tag_name)[0];
if (el) {
try {
let js_value = JSON.parse(el.textContent);
if (js_value instanceof Array) {
console.log(`B21Config.get_array for ${tag_name} found an array ${JSON.stringify(js_value)}`);
return js_value;
} else {
console.log(`B21Config.get_array for ${tag_name} not an array`);
}
} catch (e) {
console.warn(`B21Config.get_array failed for ${tag_name}`);
}
}
return null;
}
} // end class B21Config