@em-foundation/emscope 25.2.0 → 25.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## VERSION-25-3.0
2
+
3
+ * aligned with new `BlueJoule/capture` directory structure
4
+ * streamlined generation of `ABOUT.md` with automatic HW/SW inclusion
5
+ * one digit of precision after the decimal point in most results
6
+
1
7
  ## VERSION-25-2.0
2
8
 
3
9
  * new `emscope grab -p, --ppk-supply` option
package/dist/emscope CHANGED
@@ -12614,9 +12614,6 @@ var Window = class {
12614
12614
  return this.#off >= 0 && this.#off + this.#wid <= this.#sig.data.length;
12615
12615
  }
12616
12616
  };
12617
- function amps(val) {
12618
- return toEng(val, "A");
12619
- }
12620
12617
  function fail(msg, cond = true) {
12621
12618
  if (cond) {
12622
12619
  console.log(`*** ${msg} ***`);
@@ -12627,7 +12624,7 @@ function infoMsg(msg) {
12627
12624
  console.log(`${TAB}${msg}`);
12628
12625
  }
12629
12626
  function joules(j) {
12630
- return toEng(j, "J");
12627
+ return toEng(j, "J", 0);
12631
12628
  }
12632
12629
  function parseHms(s) {
12633
12630
  if (/^\d+$/.test(s)) return Number(s);
@@ -12645,12 +12642,18 @@ function secsToHms(total) {
12645
12642
  const pad = (n) => n.toString().padStart(2, "0");
12646
12643
  return `${pad(h)}:${pad(m)}:${pad(s)}`;
12647
12644
  }
12648
- function toEng(x, u) {
12645
+ function toEng(x, u, e) {
12649
12646
  if (x == 0) return `0 ${u}`;
12650
- const exp = Math.floor(Math.log10(Math.abs(x)) / 3) * 3;
12647
+ const exp = e ?? Math.floor(Math.log10(Math.abs(x)) / 3) * 3;
12651
12648
  const mantissa = x / 10 ** exp;
12652
12649
  const unit = { [-9]: ` n${u}`, [-6]: ` \xB5${u}`, [-3]: ` m${u}`, [0]: ` ${u}`, [3]: ` k${u}` }[exp] || `e${exp} ${u}`;
12653
- return `${mantissa.toFixed(3).padStart(7, " ")}${unit}`;
12650
+ return `${mantissa.toFixed(1).padStart(4, " ")}${unit}`;
12651
+ }
12652
+ function uAmps(val) {
12653
+ return toEng(val, "A", -6);
12654
+ }
12655
+ function uJoules(j) {
12656
+ return toEng(j, "J", -6);
12654
12657
  }
12655
12658
  function version() {
12656
12659
  const path = import_path.default.resolve(__dirname, "..", "package.json");
@@ -12817,6 +12820,7 @@ function trimEvents(cap, markers, count) {
12817
12820
  }
12818
12821
 
12819
12822
  // src/AboutFile.ts
12823
+ var ChildProc = __toESM(require("child_process"));
12820
12824
  var Fs3 = __toESM(require("fs"));
12821
12825
  var Path3 = __toESM(require("path"));
12822
12826
  var TAG = "@emscope-pack";
@@ -12825,25 +12829,10 @@ var END = `<!-- ${TAG}:end -->`;
12825
12829
  var RE = /<!--\s*@emscope-pack:start\s*-->[\s\S]*?<!--\s*@emscope-pack:end\s*-->/m;
12826
12830
  function update(capdir) {
12827
12831
  const cap = Capture.load(capdir);
12828
- const TXT = `
12829
- <h1 align="center">Hardware Platform \xB7 Software Environment</h1>
12830
-
12831
- ## HW/SW configuration
12832
-
12833
- ## EM&bull;Scope results
12832
+ const TXT = `<h1 align="center">Hardware Platform \xB7 Software Environment \xB7 xVx</h1>
12834
12833
 
12835
12834
  ${START}
12836
-
12837
12835
  ${END}
12838
-
12839
- ## Typical event
12840
-
12841
- <p align="center">
12842
- <img src="event-ID.png" alt="Event" width="900">
12843
- </p>
12844
-
12845
- ## Observations
12846
-
12847
12836
  `;
12848
12837
  const file = Path3.join(cap.rootdir, "ABOUT.md");
12849
12838
  if (!Fs3.existsSync(file)) {
@@ -12851,10 +12840,7 @@ ${END}
12851
12840
  }
12852
12841
  const src = Fs3.readFileSync(file, "utf-8");
12853
12842
  const gen = mkGen(cap);
12854
- const block = `${START}
12855
-
12856
- ${gen}
12857
-
12843
+ const block = `${START}${gen}
12858
12844
  ${END}`;
12859
12845
  const out = RE.test(src) ? src.replace(RE, block) : `${src.replace(/\s*$/, "")}
12860
12846
 
@@ -12862,8 +12848,25 @@ ${block}
12862
12848
  `;
12863
12849
  Fs3.writeFileSync(file, out);
12864
12850
  }
12851
+ function getBuildDir(cap) {
12852
+ const bn = Path3.basename(cap.rootdir).split("-")[0];
12853
+ return Path3.join(Path3.dirname(cap.rootdir), bn);
12854
+ }
12855
+ function getEvtId(cap) {
12856
+ for (const fn of Fs3.readdirSync(cap.rootdir)) {
12857
+ const m = fn.match(/^event\-([A-Z])\.png$/);
12858
+ if (m) return m[1];
12859
+ }
12860
+ fail(`no 'event-ID.png' file found`);
12861
+ return "";
12862
+ }
12865
12863
  function mkGen(cap) {
12866
12864
  fail(`no prior analysis: run 'emscope scan ...'`, cap.analysis === void 0);
12865
+ const brd = Path3.basename(Path3.dirname(cap.rootdir));
12866
+ const brd_txt = readBrdTxt(brd);
12867
+ const bld_dir = getBuildDir(cap);
12868
+ const bld_txt = readBldTxt(bld_dir);
12869
+ const eid = getEvtId(cap);
12867
12870
  const aobj = cap.analysis;
12868
12871
  const si = aobj.sleep;
12869
12872
  const sl_v = cap.avg_voltage;
@@ -12877,31 +12880,83 @@ function mkGen(cap) {
12877
12880
  const egy10_s = sl_pwr * 10 + egy1_e;
12878
12881
  const egy10_d = egy10_s * 86400 / 10;
12879
12882
  const ems10 = 80 / egy10_d;
12880
- const date = (/* @__PURE__ */ new Date()).toISOString();
12883
+ const cap_date = mkTimestamp(cap.creation_date);
12884
+ const gen_date = mkTimestamp(/* @__PURE__ */ new Date());
12881
12885
  const GEN = `
12886
+
12887
+ <!-- *** AUTOMATICALLY GENERATED CONTENT \u2013 DO NOT EDIT *** -->
12888
+
12889
+ <p align="right"><sub>captured on ${cap_date}<br>generated on ${gen_date}</sub></p>
12890
+
12891
+ ## HW/SW Configuration
12892
+
12893
+ ${brd_txt}
12894
+ ${bld_txt}
12895
+
12896
+
12897
+ ## EM&bull;Scope results \xB7 ${cap.device}
12898
+
12882
12899
  ### \u{1F7E0}&ensp;sleep
12883
12900
 
12884
12901
  | supply voltage | &emsp;current (avg)&emsp; | &emsp;current (std)&emsp; | &emsp;average power&emsp;
12885
12902
  |:---:|:---:|:---:|:---:|
12886
- | ${sl_v.toFixed(2)} V | ${amps(sl_avg)} | ${amps(sl_std)} | ${toEng(sl_pwr, "W")} |
12903
+ | ${sl_v.toFixed(1)} V | ${uAmps(sl_avg)} | ${uAmps(sl_std)} | ${toEng(sl_pwr, "W")} |
12887
12904
 
12888
12905
  ### \u{1F7E0}&ensp;1&thinsp;s event period
12889
12906
 
12890
12907
  | &emsp;&emsp;event energy (avg)&emsp;&emsp; | &emsp;&emsp;energy per period&emsp;&emsp; | &emsp;&emsp;energy per day&emsp;&emsp; | &emsp;&emsp;&emsp;**EM&bull;eralds**&emsp;&emsp;&emsp;
12891
12908
  |:---:|:---:|:---:|:---:|
12892
- | ${joules(egy1_e)} | ${joules(egy1_s)} | ${joules(egy1_d)} | ${ems1.toFixed(2)} |
12909
+ | ${uJoules(egy1_e)} | ${uJoules(egy1_s)} | ${joules(egy1_d)} | ${ems1.toFixed(2)} |
12893
12910
 
12894
12911
  ### \u{1F7E0}&ensp;10&thinsp;s event period
12895
12912
 
12896
12913
  | &emsp;&emsp;event energy (avg)&emsp;&emsp; | &emsp;&emsp;energy per period&emsp;&emsp; | &emsp;&emsp;energy per day&emsp;&emsp; | &emsp;&emsp;&emsp;**EM&bull;eralds**&emsp;&emsp;&emsp;
12897
12914
  |:---:|:---:|:---:|:---:|
12898
- | ${joules(egy1_e)} | ${joules(egy10_s)} | ${joules(egy10_d)} | ${ems10.toFixed(2)} |
12915
+ | ${uJoules(egy1_e)} | ${uJoules(egy10_s)} | ${joules(egy10_d)} | ${ems10.toFixed(2)} |
12916
+
12917
+ ## Typical Event
12899
12918
 
12900
- <br>
12901
- <p align="right"><sub>generated at ${date}</sub></p>
12902
- `;
12919
+ <p align="center"><img src="event-${eid}.png" alt="Event" width="900"></p>
12920
+
12921
+ ## Notes
12922
+ `;
12903
12923
  return GEN;
12904
12924
  }
12925
+ function mkTimestamp(d) {
12926
+ const ds = d.toISOString().split("T")[0];
12927
+ const pad = (n) => String(n).padStart(2, "0");
12928
+ const HH = pad(d.getUTCHours());
12929
+ const MM = pad(d.getUTCMinutes());
12930
+ const SS = pad(d.getUTCSeconds());
12931
+ const ts = `${HH}:${MM}:${SS}`;
12932
+ return `${ds} @ ${ts}`;
12933
+ }
12934
+ function readBldTxt(bld_dir) {
12935
+ try {
12936
+ const txt = Fs3.readFileSync(Path3.join(bld_dir, "BUILD.md"), { encoding: "utf-8" });
12937
+ return `${txt}
12938
+ * [BUILD ARTIFACTS](../${Path3.basename(bld_dir)}) &thinsp;\u2699\uFE0F
12939
+ `;
12940
+ } catch (e) {
12941
+ console.log(`... skipping 'BUILD.md' inclusion`);
12942
+ }
12943
+ return "";
12944
+ }
12945
+ function readBrdTxt(brd) {
12946
+ const url = `https://raw.githubusercontent.com/em-foundation/emscope/docs-stable/docs/boards/${brd}.md`;
12947
+ const is_win = process.platform === "win32";
12948
+ const cmd = is_win ? "curl.exe" : "curl";
12949
+ const args = is_win ? ["-fsSL", "--tlsv1.2", "--ssl-no-revoke", url] : ["-fsSL", url];
12950
+ try {
12951
+ const txt = ChildProc.execFileSync(cmd, args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
12952
+ return `${txt}
12953
+ * [BOARD PINOUT](https://github.com/em-foundation/emscope/blob/docs-stable/docs/boards/${brd}.png) &thinsp;\u2699\uFE0F
12954
+ `;
12955
+ } catch (e) {
12956
+ console.log(`... skipping 'BOARD.md' inclusion`);
12957
+ }
12958
+ return "";
12959
+ }
12905
12960
 
12906
12961
  // src/Exporter.ts
12907
12962
  var import_adm_zip = __toESM(require_adm_zip());
@@ -13514,34 +13569,33 @@ function printEventInfo(cap, markers) {
13514
13569
  for (const m of markers) {
13515
13570
  const egy = cap.energyWithin(m);
13516
13571
  avg += egy * scale;
13517
- const dur = (cap.current_sig.offToSecs(m.width) * 1e3).toFixed(3).padStart(7, " ");
13518
- const dur_s = cap.current_sig.offToSecs(m.width);
13572
+ const dur = (cap.current_sig.offToSecs(m.width) * 1e3).toFixed(2).padStart(5, " ");
13519
13573
  const off_s = cap.current_sig.offToSecs(m.offset).toFixed(2).padStart(5, " ");
13520
- infoMsg(`${lab} :: time = ${off_s} s, energy = ${joules(egy)}, duration = ${toEng(dur_s, "s")}`);
13574
+ infoMsg(`${lab} :: time = ${off_s} s, energy = ${uJoules(egy)}, duration = ${dur} s`);
13521
13575
  lab = String.fromCharCode(lab.charCodeAt(0) + 1);
13522
13576
  }
13523
13577
  infoMsg("----");
13524
- infoMsg(`average energy over ${markers.length} event(s): ${joules(avg)}`);
13578
+ infoMsg(`average energy over ${markers.length} event(s): ${uJoules(avg)}`);
13525
13579
  }
13526
13580
  function printResults(cap, aobj, ev_rate, score_only) {
13527
13581
  const sleep_pwr = aobj.sleep.avg * cap.avg_voltage;
13528
- score_only || infoMsg(`event period: ${secsToHms(ev_rate)}`);
13529
- score_only || infoMsg(`average sleep power: ${toEng(sleep_pwr, "W")}`);
13582
+ score_only || infoMsg(`event period: ${secsToHms(ev_rate)}`);
13583
+ score_only || infoMsg(`average sleep power: ${toEng(sleep_pwr, "W")}`);
13530
13584
  score_only || infoMsg("----");
13531
13585
  const egy_1s = cap.energyWithin(aobj.span) / cap.current_sig.offToSecs(aobj.span.width);
13532
13586
  const egy_1e = egy_1s - sleep_pwr * 1;
13533
13587
  const egy_1c = sleep_pwr * ev_rate + egy_1e;
13534
- score_only || infoMsg(`representative event: ${joules(egy_1e)}`);
13535
- score_only || infoMsg(`energy per period: ${joules(egy_1c)}`);
13588
+ score_only || infoMsg(`representative event: ${uJoules(egy_1e)}`);
13589
+ score_only || infoMsg(`energy per period: ${uJoules(egy_1c)}`);
13536
13590
  const egy_1d = egy_1c * 86400 / ev_rate;
13537
- score_only || infoMsg(`energy per day: ${joules(egy_1d)}`);
13591
+ score_only || infoMsg(`energy per day: ${joules(egy_1d)}`);
13538
13592
  const egy_1m = egy_1d * 30;
13539
13593
  const ems = 2400 / egy_1m;
13540
13594
  score_only || infoMsg("----");
13541
13595
  infoMsg(`${ems.toFixed(2)} EM\u2022eralds`);
13542
13596
  }
13543
13597
  function printSleepInfo(cap, si) {
13544
- infoMsg(`sleep current = ${amps(si.avg)} @ ${cap.avg_voltage.toFixed(2)} V, standard deviation = ${amps(si.std)}`);
13598
+ infoMsg(`sleep current = ${uAmps(si.avg).trim()} @ ${cap.avg_voltage.toFixed(1)} V, standard deviation = ${uAmps(si.std).trim()}`);
13545
13599
  }
13546
13600
 
13547
13601
  // node_modules/commander/esm.mjs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@em-foundation/emscope",
3
- "version": "25.2.0",
3
+ "version": "25.3.0",
4
4
  "description": "benchmark energy efficiency in resource-constrained embedded systems",
5
5
  "bin": {
6
6
  "emscope": "dist/emscope"