frugal-iot-client 1.3.11 → 1.3.12
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/.claude/settings.local.json +4 -1
- package/package.json +1 -1
- package/webcomponents.js +43 -18
|
@@ -22,7 +22,10 @@
|
|
|
22
22
|
"Bash(curl *)",
|
|
23
23
|
"Bash(grep -n \"el\\('p', {}, \\\\[\\\\\"\" webcomponents.js)",
|
|
24
24
|
"Bash(grep -n \"el\\('h[1-5]', {}, \\\\[\\\\\"\" webcomponents.js)",
|
|
25
|
-
"Bash(grep -n \"^const languages\\\\|^EN:\\\\|^FR:\\\\|^HI:\\\\|^ID:\\\\|^\\\\`\\);\" /Users/mitra/git/github_mitra42/frugal-iot-client/webcomponents.js)"
|
|
25
|
+
"Bash(grep -n \"^const languages\\\\|^EN:\\\\|^FR:\\\\|^HI:\\\\|^ID:\\\\|^\\\\`\\);\" /Users/mitra/git/github_mitra42/frugal-iot-client/webcomponents.js)",
|
|
26
|
+
"WebFetch(domain:raw.githubusercontent.com)",
|
|
27
|
+
"Read(//Users/mitra/git/github_mitra42/**)",
|
|
28
|
+
"Read(//Users/mitra/git/github_mitra42/frugal-iot-server/**)"
|
|
26
29
|
]
|
|
27
30
|
}
|
|
28
31
|
}
|
package/package.json
CHANGED
package/webcomponents.js
CHANGED
|
@@ -1541,20 +1541,38 @@ class MqttTopic {
|
|
|
1541
1541
|
}
|
|
1542
1542
|
})
|
|
1543
1543
|
.then(csvData => {
|
|
1544
|
+
// The server appends to these files as readings arrive, so one can end mid-line if the
|
|
1545
|
+
// power was cut while it was being written - a truncated number, a missing column, or an
|
|
1546
|
+
// opening quote with nothing after it. These options make the parser drop whatever is
|
|
1547
|
+
// damaged and return the rest, instead of rejecting the whole file, which would lose a
|
|
1548
|
+
// day of readings over one bad byte at the end.
|
|
1544
1549
|
// noinspection JSCheckFunctionSignatures
|
|
1545
|
-
parse(csvData, (err, newdata) => {
|
|
1550
|
+
parse(csvData, {relax_quotes: true, relax_column_count: true, skip_records_with_error: true}, (err, newdata) => {
|
|
1546
1551
|
if (err) {
|
|
1547
|
-
console.error(
|
|
1548
|
-
|
|
1549
|
-
|
|
1552
|
+
console.error("Could not read", filepath, err.message);
|
|
1553
|
+
this.markNoDataForDay();
|
|
1554
|
+
cb(null); // Not an error to the caller - one unreadable day should not stop the rest
|
|
1550
1555
|
} else {
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1556
|
+
// A record can survive the parse but still be unusable - a torn last line often leaves
|
|
1557
|
+
// just a timestamp, or half of one
|
|
1558
|
+
let newprocdata = newdata
|
|
1559
|
+
.filter(r => (r.length >= 2) && !isNaN(parseInt(r[0])))
|
|
1560
|
+
.map(r => {
|
|
1561
|
+
return {
|
|
1562
|
+
time: parseInt(r[0]),
|
|
1563
|
+
value: this.valueFromText(r[1]) // TODO-72 need function for this as presuming its float
|
|
1564
|
+
};
|
|
1565
|
+
});
|
|
1566
|
+
if (newdata.length !== newprocdata.length) {
|
|
1567
|
+
console.warn(`ignored ${newdata.length - newprocdata.length} damaged record(s) in ${filepath}`);
|
|
1568
|
+
}
|
|
1569
|
+
if (newprocdata.length === 0) {
|
|
1570
|
+
XXX(["No data in", filepath]);
|
|
1571
|
+
this.markNoDataForDay();
|
|
1572
|
+
cb(null); // Nothing to add, but the caller still has to be told this one is finished
|
|
1573
|
+
return;
|
|
1574
|
+
}
|
|
1575
|
+
console.log(`retrieved ${newprocdata.length} records for ${this.topicPath}`);
|
|
1558
1576
|
let olddata = this.data.splice(0, Infinity);
|
|
1559
1577
|
for (let dd of newprocdata) {
|
|
1560
1578
|
this.data.push(dd);
|
|
@@ -1576,18 +1594,25 @@ class MqttTopic {
|
|
|
1576
1594
|
})
|
|
1577
1595
|
.catch(ignored => {
|
|
1578
1596
|
// Did not get any data, draw dotted line from beginning of day to now (and end of prev data to start this day)
|
|
1579
|
-
|
|
1580
|
-
.setUTCHours(0,0,0,0)
|
|
1581
|
-
.valueOf();
|
|
1582
|
-
this.data.splice(0, 0, {
|
|
1583
|
-
time: t,
|
|
1584
|
-
value: null,
|
|
1585
|
-
});
|
|
1597
|
+
this.markNoDataForDay();
|
|
1586
1598
|
//console.error(err); - dont need error - the fetch will also report it, so it is just a repeat.
|
|
1587
1599
|
cb(null); // Dont break caller
|
|
1588
1600
|
}); // May want to report filename here
|
|
1589
1601
|
}
|
|
1590
1602
|
|
|
1603
|
+
// Nothing usable for this day, whether the file was missing, empty or damaged. A null point at
|
|
1604
|
+
// the start of the day makes the graph draw a dotted line across the gap rather than joining the
|
|
1605
|
+
// days either side as though nothing were missing.
|
|
1606
|
+
markNoDataForDay() {
|
|
1607
|
+
let t = new Date(this.graph.state.dateFrom) // Have to explicitly copy it else pointer
|
|
1608
|
+
.setUTCHours(0,0,0,0)
|
|
1609
|
+
.valueOf();
|
|
1610
|
+
this.data.splice(0, 0, {
|
|
1611
|
+
time: t,
|
|
1612
|
+
value: null,
|
|
1613
|
+
});
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1591
1616
|
removeDataBefore(date) { // note date may be null
|
|
1592
1617
|
let i;
|
|
1593
1618
|
if (date) {
|