Skip to content

Commit

Permalink
chore(binding-mbus): enable strict type checking
Browse files Browse the repository at this point in the history
Co-authored-by: Jan Romann <[email protected]>
  • Loading branch information
danielpeintner and JKRhb authored Sep 6, 2023
1 parent ecddb7f commit d1d2abd
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 23 deletions.
14 changes: 12 additions & 2 deletions packages/binding-mbus/src/mbus-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ export default class MBusClient implements ProtocolClient {
new MBusConnection(host, port, { connectionTimeout: form["mbus:timeout"] || DEFAULT_TIMEOUT })
);
connection = this._connections.get(hostAndPort);
if (!connection) {
debug(`MbusConnection undefined`);
throw new Error("MbusConnection undefined");
}
} else {
debug(`Reusing MbusConnection for ${hostAndPort}`);
}
Expand All @@ -124,8 +128,14 @@ export default class MBusClient implements ProtocolClient {
const query = parsed.searchParams;

input["mbus:unitID"] = parseInt(pathComp[1], 10) || input["mbus:unitID"];
input["mbus:offset"] = parseInt(query.get("offset"), 10) || input["mbus:offset"];
input["mbus:timeout"] = parseInt(query.get("timeout"), 10) || input["mbus:timeout"];
const stringOffset = query.get("offset");
if (stringOffset !== null) {
input["mbus:offset"] = parseInt(stringOffset, 10);
}
const stringTimeout = query.get("timeout");
if (stringTimeout !== null) {
input["mbus:timeout"] = parseInt(stringTimeout, 10);
}
}

private validateAndFillDefaultForm(form: MBusForm): MBusForm {
Expand Down
50 changes: 33 additions & 17 deletions packages/binding-mbus/src/mbus-connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ export class MBusConnection {
client: any; // MBusClient.IMBusRTU
connecting: boolean;
connected: boolean;
timer: NodeJS.Timer; // connection idle timer
currentTransaction: MBusTransaction; // transaction currently in progress or null
timer?: NodeJS.Timer; // connection idle timer
currentTransaction?: MBusTransaction; // transaction currently in progress or undefined
queue: Array<MBusTransaction>; // queue of further transactions
config: {
connectionTimeout?: number;
operationTimeout?: number;
connectionRetryTime?: number;
maxRetries?: number;
maxRetries: number;
};

constructor(
Expand All @@ -92,8 +92,8 @@ export class MBusConnection {
});
this.connecting = false;
this.connected = false;
this.timer = null;
this.currentTransaction = null;
this.timer = undefined;
this.currentTransaction = undefined;
this.queue = new Array<MBusTransaction>();

this.config = Object.assign(configDefaults, config);
Expand Down Expand Up @@ -156,7 +156,7 @@ export class MBusConnection {
}
}

async execute(op: PropertyOperation): Promise<Content | PromiseLike<Content>> {
async execute(op: PropertyOperation): Promise<Content | PromiseLike<Content> | undefined> {
this.trigger();
return op.execute();
}
Expand All @@ -182,20 +182,25 @@ export class MBusConnection {
// inform all the operations that the connection cannot be recovered
this.queue.forEach((transaction) => {
transaction.operations.forEach((op) => {
op.failed(error);
op.failed(error instanceof Error ? error : new Error(JSON.stringify(error)));
});
});
}
} else if (this.connected && this.currentTransaction == null && this.queue.length > 0) {
// take next transaction from queue and execute
this.currentTransaction = this.queue.shift();
if (!this.currentTransaction) {
warn(`Current transaction is undefined -> transaction not executed`);
return;
}

try {
await this.executeTransaction(this.currentTransaction);
this.currentTransaction = null;
this.currentTransaction = undefined;
this.trigger();
} catch (err) {
warn(`Transaction failed: ${err}`);
this.currentTransaction = null;
this.currentTransaction = undefined;
this.trigger();
}
}
Expand All @@ -211,7 +216,9 @@ export class MBusConnection {
} catch (err) {
warn(`Read operation failed on unit ${transaction.unitId}. ${err}.`);
// inform all operations and the invoker
transaction.operations.forEach((op) => op.failed(err));
transaction.operations.forEach((op) =>
op.failed(error instanceof Error ? error : new Error(JSON.stringify(error)))
);
throw err;
}
}
Expand Down Expand Up @@ -249,7 +256,7 @@ export class MBusConnection {
}
});
clearInterval(this.timer);
this.timer = null;
this.timer = undefined;
}
}

Expand All @@ -259,19 +266,22 @@ export class MBusConnection {
export class PropertyOperation {
unitId: number;
base: number;
resolve: (value?: Content | PromiseLike<Content>) => void;
reject: (reason?: Error) => void;
resolve?: (value?: Content | PromiseLike<Content>) => void;
reject?: (reason?: Error) => void;

constructor(form: MBusForm) {
this.unitId = form["mbus:unitID"];
if (form["mbus:offset"] === undefined) {
throw new Error("form['mbus:offset'] is undefined");
}
this.base = form["mbus:offset"];
}

/**
* Trigger execution of this operation.
*
*/
async execute(): Promise<Content | PromiseLike<Content>> {
async execute(): Promise<(Content | PromiseLike<Content>) | undefined> {
return new Promise(
(resolve: (value?: Content | PromiseLike<Content>) => void, reject: (reason?: Error) => void) => {
this.resolve = resolve;
Expand Down Expand Up @@ -310,6 +320,9 @@ export class PropertyOperation {

const resp = new Content("application/json", Readable.from(JSON.stringify(payload)));

if (!this.resolve) {
throw new Error("Function 'done' was invoked before executing the Mbus operation");
}
// resolve the Promise given to the invoking script
this.resolve(resp);
}
Expand All @@ -319,9 +332,12 @@ export class PropertyOperation {
*
* @param reason Reason of failure
*/
failed(reason: string): void {
warn("Operation failed:", reason);
failed(reason: Error): void {
warn(`Operation failed: ${reason}`);
if (!this.reject) {
throw new Error("Function 'failed' was invoked before executing the Mbus operation");
}
// reject the Promise given to the invoking script
this.reject(new Error(reason));
this.reject(reason);
}
}
14 changes: 11 additions & 3 deletions packages/binding-mbus/test/mbus-client-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*
* SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
********************************************************************************/
import { should } from "chai";
import { expect, should } from "chai";
import * as chai from "chai";
import MBusClient from "../src/mbus-client";
import { MBusForm } from "../src/mbus";
Expand Down Expand Up @@ -56,8 +56,16 @@ describe("mbus client test", () => {
// eslint-disable-next-line dot-notation
client["overrideFormFromURLPath"](form);
form["mbus:unitID"].should.be.equal(2, "Form value not overridden");
form["mbus:offset"].should.be.equal(2, "Form value not overridden");
form["mbus:timeout"].should.be.equal(5, "Form value not overridden");
if (form["mbus:offset"]) {
form["mbus:offset"].should.be.equal(2, "Form value not overridden");
} else {
expect.fail("mbus:offset undefined");
}
if (form["mbus:timeout"]) {
form["mbus:timeout"].should.be.equal(5, "Form value not overridden");
} else {
expect.fail("mbus:timeout undefined");
}
});

describe("read resource", () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/binding-mbus/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
"rootDir": "src",
"strict": true
},
"include": ["src/**/*"],
"references": [{ "path": "../td-tools" }, { "path": "../core" }]
Expand Down

0 comments on commit d1d2abd

Please sign in to comment.