Skip to content

Commit

Permalink
More fixes to plugin management
Browse files Browse the repository at this point in the history
Fixed serialization of sets
  • Loading branch information
chrishamm committed Dec 16, 2022
1 parent 49a9f41 commit fe3c890
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 23 deletions.
17 changes: 17 additions & 0 deletions __tests__/clone.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import ObjectModel, { initObject, Plugin } from "../src";
import { fullModel } from "./update";

test("clone", () => {
const model = new ObjectModel();
model.update(fullModel);
model.plugins.set("Test", initObject(Plugin, { id: "Test", name: "Test Plugin" }));

const serializedFullModel = JSON.stringify(model);
const secondModel = new ObjectModel();
secondModel.update(JSON.parse(serializedFullModel));
expect(JSON.stringify(secondModel)).toBe(serializedFullModel);

expect(secondModel.plugins.size).toBe(1);
expect(secondModel.plugins.get("Test")).toBeInstanceOf(Plugin);
expect(secondModel.plugins.get("Test")?.name).toBe("Test Plugin");
});
43 changes: 23 additions & 20 deletions __tests__/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,9 @@ import { MachineStatus, MessageBox } from "../src/state";
import { LaserFilamentMonitor, RotatingMagnetFilamentMonitor } from "../src/sensors";
import Volume from "../src/volumes";

const fullModel = {"boards":[],"directories":{"filaments":"0:/filaments","firmware":"0:/firmware","gCodes":"0:/gcodes","macros":"0:/macros","menu":"0:/menu","scans":"0:/scans","system":"0:/sys","web":"0:/www"},"fans":[],"global":{},"heat":{"bedHeaters":[],"chamberHeaters":[],"coldExtrudeTemperature":160,"coldRetractTemperature":90,"heaters":[]},"httpEndpoints":[],"inputs":[{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"HTTP","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false},{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"Telnet","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false},{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"File","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false},{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"USB","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false},{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"Aux","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false},{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"Trigger","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false},{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"Queue","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false},{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"LCD","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false},{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"SBC","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false},{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"Daemon","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false},{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"Autopause","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false},{"axesRelative":false,"compatibility":"RepRapFirmware","distanceUnit":"mm","drivesRelative":true,"feedRate":50,"inMacro":false,"macroRestartable":false,"name":"Unknown","stackDepth":0,"state":"idle","lineNumber":0,"volumetric":false}],"job":{"build":null,"duration":null,"file":{"filament":[],"fileName":null,"firstLayerHeight":0,"generatedBy":null,"height":0,"lastModified":null,"layerHeight":0,"numLayers":0,"printTime":null,"simulatedTime":null,"size":0,"thumbnails":[]},"filePosition":null,"lastDuration":null,"lastFileName":null,"lastFileAborted":false,"lastFileCancelled":false,"lastFileSimulated":false,"layer":null,"layers":[],"layerTime":null,"pauseDuration":null,"rawExtrusion":null,"timesLeft":{"filament":null,"file":null,"slicer":null},"warmUpDuration":null},"limits":{"axes":null,"axesPlusExtruders":null,"bedHeaters":null,"boards":null,"chamberHeaters":null,"drivers":null,"driversPerAxis":null,"extruders":null,"extrudersPerTool":null,"fans":null,"gpInPorts":null,"gpOutPorts":null,"heaters":null,"heatersPerTool":null,"monitorsPerHeater":null,"restorePoints":null,"sensors":null,"spindles":null,"tools":null,"trackedObjects":null,"triggers":null,"volumes":null,"workplaces":null,"zProbeProgramBytes":null,"zProbes":null},"messages":[],"move":{"axes":[],"calibration":{"final":{"deviation":0,"mean":0},"initial":{"deviation":0,"mean":0},"numFactors":0},"compensation":{"fadeHeight":0,"file":null,"liveGrid":null,"meshDeviation":null,"probeGrid":{"axes":["X","Y"],"maxs":[-1,-1],"mins":[0,0],"radius":0,"spacings":[0,0]},"skew":{"compensateXY":true,"tanXY":0,"tanXZ":0,"tanYZ":0},"type":"none"},"currentMove":{"acceleration":0,"deceleration":0,"laserPwm":null,"requestedSpeed":0,"topSpeed":0},"extruders":[],"idle":{"factor":0.3,"timeout":30},"kinematics":{"name":"unknown","segmentation":null},"printingAcceleration":10000,"queue":[],"rotation":{"angle":0,"centre":[0,0]},"shaping":{"amplitudes":[],"damping":0.2,"durations":[],"frequency":0,"minAcceleration":10,"type":"none"},"speedFactor":1,"travelAcceleration":10000,"virtualEPos":0,"workplaceNumber":0},"network":{"corsSite":null,"hostname":"test","interfaces":[{"activeProtocols":[],"actualIP":"192.168.1.122","configuredIP":"192.168.1.122","dnsServer":null,"firmwareVersion":null,"gateway":"192.168.1.254","mac":"DC:A6:32:04:59:E3","numReconnects":null,"signal":null,"speed":null,"subnet":"255.255.255.0","type":"wifi"}],"name":"My Duet"},"plugins":{},"scanner":{"progress":0,"status":"D"},"sensors":{"analog":[],"endstops":[],"filamentMonitors":[],"gpIn":[],"probes":[]},"spindles":[],"state":{"atxPower":null,"atxPowerPort":null,"beep":null,"currentTool":-1,"displayMessage":"","dsfVersion":"1.2.5.0","dsfPluginSupport":false,"dsfRootPluginSupport":false,"gpOut":[],"laserPwm":-1,"logFile":null,"logLevel":"off","messageBox":{"axisControls":0,"message":"message","mode":2,"seq":-1,"timeout":0,"title":"title"},"machineMode":"FFF","macroRestarted":false,"msUpTime":0,"nextTool":-1,"pluginsStarted":false,"powerFailScript":"","previousTool":-1,"restorePoints":[],"status":"idle","time":null,"upTime":0},"tools":[],"userSessions":[],"volumes":[{"capacity":58851373056,"freeSpace":55021527040,"mounted":true,"name":null,"openFiles":null,"path":"/","speed":null},{"capacity":2143281152,"freeSpace":2087972864,"mounted":true,"name":null,"openFiles":null,"path":"/boot","speed":null}]};
export const fullModel = { "boards": [], "directories": { "filaments": "0:/filaments", "firmware": "0:/firmware", "gCodes": "0:/gcodes", "macros": "0:/macros", "menu": "0:/menu", "scans": "0:/scans", "system": "0:/sys", "web": "0:/www" }, "fans": [], "global": {}, "heat": { "bedHeaters": [], "chamberHeaters": [], "coldExtrudeTemperature": 160, "coldRetractTemperature": 90, "heaters": [] }, "httpEndpoints": [], "inputs": [{ "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "HTTP", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }, { "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "Telnet", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }, { "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "File", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }, { "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "USB", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }, { "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "Aux", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }, { "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "Trigger", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }, { "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "Queue", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }, { "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "LCD", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }, { "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "SBC", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }, { "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "Daemon", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }, { "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "Autopause", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }, { "axesRelative": false, "compatibility": "RepRapFirmware", "distanceUnit": "mm", "drivesRelative": true, "feedRate": 50, "inMacro": false, "macroRestartable": false, "name": "Unknown", "stackDepth": 0, "state": "idle", "lineNumber": 0, "volumetric": false }], "job": { "build": null, "duration": null, "file": { "filament": [], "fileName": null, "firstLayerHeight": 0, "generatedBy": null, "height": 0, "lastModified": null, "layerHeight": 0, "numLayers": 0, "printTime": null, "simulatedTime": null, "size": 0, "thumbnails": [] }, "filePosition": null, "lastDuration": null, "lastFileName": null, "lastFileAborted": false, "lastFileCancelled": false, "lastFileSimulated": false, "layer": null, "layers": [], "layerTime": null, "pauseDuration": null, "rawExtrusion": null, "timesLeft": { "filament": null, "file": null, "slicer": null }, "warmUpDuration": null }, "limits": { "axes": null, "axesPlusExtruders": null, "bedHeaters": null, "boards": null, "chamberHeaters": null, "drivers": null, "driversPerAxis": null, "extruders": null, "extrudersPerTool": null, "fans": null, "gpInPorts": null, "gpOutPorts": null, "heaters": null, "heatersPerTool": null, "monitorsPerHeater": null, "restorePoints": null, "sensors": null, "spindles": null, "tools": null, "trackedObjects": null, "triggers": null, "volumes": null, "workplaces": null, "zProbeProgramBytes": null, "zProbes": null }, "messages": [], "move": { "axes": [], "calibration": { "final": { "deviation": 0, "mean": 0 }, "initial": { "deviation": 0, "mean": 0 }, "numFactors": 0 }, "compensation": { "fadeHeight": 0, "file": null, "liveGrid": null, "meshDeviation": null, "probeGrid": { "axes": ["X", "Y"], "maxs": [-1, -1], "mins": [0, 0], "radius": 0, "spacings": [0, 0] }, "skew": { "compensateXY": true, "tanXY": 0, "tanXZ": 0, "tanYZ": 0 }, "type": "none" }, "currentMove": { "acceleration": 0, "deceleration": 0, "laserPwm": null, "requestedSpeed": 0, "topSpeed": 0 }, "extruders": [], "idle": { "factor": 0.3, "timeout": 30 }, "kinematics": { "name": "unknown", "segmentation": null }, "printingAcceleration": 10000, "queue": [], "rotation": { "angle": 0, "centre": [0, 0] }, "shaping": { "amplitudes": [], "damping": 0.2, "durations": [], "frequency": 0, "minAcceleration": 10, "type": "none" }, "speedFactor": 1, "travelAcceleration": 10000, "virtualEPos": 0, "workplaceNumber": 0 }, "network": { "corsSite": null, "hostname": "test", "interfaces": [{ "activeProtocols": [], "actualIP": "192.168.1.122", "configuredIP": "192.168.1.122", "dnsServer": null, "firmwareVersion": null, "gateway": "192.168.1.254", "mac": "DC:A6:32:04:59:E3", "numReconnects": null, "signal": null, "speed": null, "subnet": "255.255.255.0", "type": "wifi" }], "name": "My Duet" }, "plugins": {}, "scanner": { "progress": 0, "status": "D" }, "sensors": { "analog": [], "endstops": [], "filamentMonitors": [], "gpIn": [], "probes": [] }, "spindles": [], "state": { "atxPower": null, "atxPowerPort": null, "beep": null, "currentTool": -1, "displayMessage": "", "dsfVersion": "1.2.5.0", "dsfPluginSupport": false, "dsfRootPluginSupport": false, "gpOut": [], "laserPwm": -1, "logFile": null, "logLevel": "off", "messageBox": { "axisControls": 0, "message": "message", "mode": 2, "seq": -1, "timeout": 0, "title": "title" }, "machineMode": "FFF", "macroRestarted": false, "msUpTime": 0, "nextTool": -1, "pluginsStarted": false, "powerFailScript": "", "previousTool": -1, "restorePoints": [], "status": "idle", "time": null, "upTime": 0 }, "tools": [], "userSessions": [], "volumes": [{ "capacity": 58851373056, "freeSpace": 55021527040, "mounted": true, "name": null, "openFiles": null, "path": "/", "speed": null }, { "capacity": 2143281152, "freeSpace": 2087972864, "mounted": true, "name": null, "openFiles": null, "path": "/boot", "speed": null }] };

test("fullModel", () => {
const model = new ObjectModel();
model.update(fullModel);
expect(model.volumes.length).toBe(2);
expect(model.volumes[0]).toBeInstanceOf(Volume);
});

const patch = {
export const patch = {
"boards": [
{
"firmwareFileName": "Test"
Expand Down Expand Up @@ -50,6 +43,13 @@ const patch = {
}
};

test("fullModel", () => {
const model = new ObjectModel();
model.update(fullModel);
expect(model.volumes.length).toBe(2);
expect(model.volumes[0]).toBeInstanceOf(Volume);
});

test("patch", () => {
const model = new ObjectModel();
model.update(fullModel);
Expand Down Expand Up @@ -154,17 +154,20 @@ test("updateKinematics", () => {
expect(model.move.kinematics.name).toBe(KinematicsName.delta);
});

test("clone", () => {
test("updatePlugin", () => {
const model = new ObjectModel();
model.update(fullModel);
model.plugins.set("Test", initObject(Plugin, { id: "Test", name: "Test Plugin" }));

const serializedFullModel = JSON.stringify(model);
const secondModel = new ObjectModel();
secondModel.update(JSON.parse(serializedFullModel));
expect(JSON.stringify(secondModel)).toBe(serializedFullModel);
model.plugins.set("foobar", initObject(Plugin, { id: "foobar", name: "foo bar" }));

const updateData = {
plugins: {
foobar: {
pid: 123
}
}
};
model.update(updateData);

expect(secondModel.plugins.size).toBe(1);
expect(secondModel.plugins.get("Test")).toBeInstanceOf(Plugin);
expect(secondModel.plugins.get("Test")?.name).toBe("Test Plugin");
expect(model.plugins.get("foobar")?.id).toBe("foobar");
expect(model.plugins.get("foobar")?.name).toBe("foo bar");
expect(model.plugins.get("foobar")?.pid).toBe(123);
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@duet3d/objectmodel",
"version": "3.5.0-beta.15",
"version": "3.5.0-beta.16",
"description": "TypeScript implementation of the Duet3D Object Model",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
1 change: 1 addition & 0 deletions src/ModelDictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export class ModelDictionary<T> extends Map<string, T | null> implements IModelO
if (currentItem !== newItem) {
return super.set(key, value);
}
return this;
}
return super.set(key, value);
}
Expand Down
10 changes: 10 additions & 0 deletions src/ModelSet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Wrapper around a standard set to make sure it serializes to an array
*/
export default class ModelSet<T> extends Set<T> {
/**
* Convert this object to JSON
* @returns JSON object
*/
toJSON() { return Array.from(this); }
}
3 changes: 2 additions & 1 deletion src/network/NetworkInterface.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ModelObject from "../ModelObject";
import ModelSet from "../ModelSet";

export enum NetworkProtocol {
HTTP = "http",
Expand Down Expand Up @@ -27,7 +28,7 @@ export enum NetworkInterfaceType {
}

export class NetworkInterface extends ModelObject {
activeProtocols: Set<NetworkProtocol> = new Set<NetworkProtocol>();
activeProtocols: ModelSet<NetworkProtocol> = new ModelSet<NetworkProtocol>();
actualIP: string | null = null;
configuredIP: string | null = null;
dnsServer: string | null = null;
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/PluginManifest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ModelObject from "../ModelObject";
import ModelSet from "../ModelSet";

export enum SbcPermission {
none = "none",
Expand Down Expand Up @@ -91,7 +92,7 @@ export class PluginManifest extends ModelObject {
sbcExecutableArguments: string | null = null;
sbcExtraExecutables: Array<string> = [];
sbcOutputRedirected: boolean = true;
sbcPermissions: Set<SbcPermission> = new Set<SbcPermission>();
sbcPermissions: ModelSet<SbcPermission> = new ModelSet<SbcPermission>();
sbcPackageDependencies: Array<string> = [];
sbcPluginDependencies: Array<string> = [];
sbcPythonDependencies: Array<string> = [];
Expand Down

0 comments on commit fe3c890

Please sign in to comment.