Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inherited timestamps sometimes being in seconds since epoch #347

Merged
merged 1 commit into from
Oct 1, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 45 additions & 6 deletions acs-edge/lib/helpers/typeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as jsonpointer from 'jsonpointer';
import * as Long from "long";
import {MessageSecurityMode, SecurityPolicy} from "node-opcua";
import {Address} from "@amrc-factoryplus/utilities";
import {log, logf} from "./log.js";
import {log} from "./log.js";

export enum serialisationType {
ignored = "Defined by Protocol",
Expand Down Expand Up @@ -250,7 +250,8 @@ export class Metrics {
const metric = this.#array[i];
this.#nameIndex[metric.name || ""] = i;
// this.#aliasIndex[metric.alias as number] = i;
if (metric.properties != null && metric.properties.address != null && metric.properties.path != null && (metric.properties.method.value as string).search(/^GET/g) > -1) {
if (metric.properties != null && metric.properties.address != null && metric.properties.path != null && (metric.properties.method.value as string).search(
/^GET/g) > -1) {
const addr = metric.properties.address.value as string;
if (!this.#addrIndex[addr]) {
this.#addrIndex[addr] = [];
Expand Down Expand Up @@ -382,8 +383,11 @@ export function parseValueFromPayload(msg: any, metric: sparkplugMetric, payload
if (path) {
/* Work around a bug in the JSONPath library */
let newVal = path === "$" && payload === false
? [ false ]
: JSONPath({path: path, json: payload});
? [false]
: JSONPath({
path: path,
json: payload
});
if (payload === 0 || !Array.isArray(newVal)) {
return 0;
} else {
Expand Down Expand Up @@ -467,14 +471,49 @@ export function parseTimeStampFromPayload(msg: any, metric: sparkplugMetric, pay
}

const timestamp = JSONPath({
path: '$.timestamp', json: payload
path: '$.timestamp',
json: payload
});
return Array.isArray(timestamp) ? timestamp[0] : undefined;

const extractedTimestamp = Array.isArray(timestamp) ? timestamp[0] : undefined;

// The timestamp will be a unix timestamp in milliseconds or
// seconds, however upstream Factory+ expects it to be in
// milliseconds. Here, we detect if the timestamp is in seconds
// and convert it to milliseconds if necessary.

if (extractedTimestamp) {
if (isTimestampInMilliseconds(extractedTimestamp)) {
return extractedTimestamp;
}

return extractedTimestamp * 1000;
}

return undefined;

default:
return undefined;
}
}

function isTimestampInMilliseconds(timestamp: number) {
// Convert the timestamp to a number (in case it's a string)
timestamp = Number(timestamp);

// Check if the timestamp is in milliseconds or seconds
if (timestamp > 1e12) {
// If it's larger than 1e12 (approximately 13 digits), it's in milliseconds
return true;
} else if (timestamp > 1e9 && timestamp <= 1e12) {
// If it's between 1e9 and 1e12 (approximately 10 digits), it's in seconds
return false;
}

// Return false by default if the timestamp is outside expected ranges
return false;
}

function parseTypeFromString(type: string, val: any) {

// Pass straight through if not a string
Expand Down
Loading