aes70 1.5.0 → 1.5.2
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 +9 -0
- package/dist/AES70.es5.js +1 -1
- package/package.json +2 -2
- package/src/controller/remote_device.js +1 -76
- package/src/controller/tree_to_rolemap.js +77 -0
- package/src/index.default.d.ts +4 -2
- package/tests/connect.js +0 -93
- package/tests/device/check_tree.js +0 -101
- package/tests/device/custom_class.js +0 -61
- package/tests/device/keepalive.js +0 -50
- package/tests/device/locking.js +0 -52
- package/tests/device/method_callback.js +0 -24
- package/tests/device/property_changes.js +0 -113
- package/tests/device/test.js +0 -185
- package/tests/device.js +0 -313
- package/tests/helpers.js +0 -108
- package/tests/ocp1.js +0 -285
|
@@ -16,6 +16,7 @@ import { OcaTaskManager } from './ControlClasses/OcaTaskManager.js';
|
|
|
16
16
|
import { OcaCodingManager } from './ControlClasses/OcaCodingManager.js';
|
|
17
17
|
import { OcaDiagnosticManager } from './ControlClasses/OcaDiagnosticManager.js';
|
|
18
18
|
import { OcaBlock } from './ControlClasses/OcaBlock.js';
|
|
19
|
+
import tree_to_rolemap from './tree_to_rolemap.js';
|
|
19
20
|
|
|
20
21
|
import * as RemoteControlClasses from './ControlClasses.js';
|
|
21
22
|
|
|
@@ -29,82 +30,6 @@ function eventToKey(event) {
|
|
|
29
30
|
return [ono, id.DefLevel, id.EventIndex].join(',');
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
function tree_to_rolemap(tree, s) {
|
|
33
|
-
const roles = new Map();
|
|
34
|
-
if (!s) s = '/';
|
|
35
|
-
|
|
36
|
-
const tasks = [];
|
|
37
|
-
|
|
38
|
-
const fetch_role = (o) => {
|
|
39
|
-
if (Array.isArray(o)) {
|
|
40
|
-
o.forEach(fetch_role);
|
|
41
|
-
} else {
|
|
42
|
-
tasks.push(
|
|
43
|
-
o.GetRole().then((role) => {
|
|
44
|
-
roles.set(o, role);
|
|
45
|
-
})
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
tree.forEach(fetch_role);
|
|
51
|
-
|
|
52
|
-
return Promise.all(tasks).then(function () {
|
|
53
|
-
const rolemap = new Map();
|
|
54
|
-
|
|
55
|
-
const build_paths = (a, prefix) => {
|
|
56
|
-
const p = prefix != null ? prefix + s : '';
|
|
57
|
-
const local_roles = new Map();
|
|
58
|
-
|
|
59
|
-
a.forEach(function (o, i) {
|
|
60
|
-
if (Array.isArray(o)) return;
|
|
61
|
-
|
|
62
|
-
const role = roles.get(o);
|
|
63
|
-
|
|
64
|
-
if (local_roles.has(role)) {
|
|
65
|
-
const tmp = local_roles.get(role);
|
|
66
|
-
|
|
67
|
-
if (Array.isArray(tmp)) tmp.push(o);
|
|
68
|
-
else local_roles.set(role, [tmp, o]);
|
|
69
|
-
} else {
|
|
70
|
-
local_roles.set(role, o);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
local_roles.forEach(function (o, role) {
|
|
75
|
-
if (Array.isArray(o)) {
|
|
76
|
-
let n = 1;
|
|
77
|
-
for (let i = 0; i < o.length; i++) {
|
|
78
|
-
const nrole = role + n;
|
|
79
|
-
while (local_roles.has(nrole)) {
|
|
80
|
-
n++;
|
|
81
|
-
}
|
|
82
|
-
local_roles.set(nrole, o[i]);
|
|
83
|
-
local_roles.set(o[i], nrole);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
local_roles.delete(role);
|
|
87
|
-
} else {
|
|
88
|
-
local_roles.set(o, role);
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
a.forEach((o, i) => {
|
|
93
|
-
if (Array.isArray(o)) {
|
|
94
|
-
build_paths(o, p + local_roles.get(a[i - 1]));
|
|
95
|
-
} else {
|
|
96
|
-
const path = p + local_roles.get(o);
|
|
97
|
-
rolemap.set(path, o);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
build_paths(tree, null);
|
|
103
|
-
|
|
104
|
-
return rolemap;
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
33
|
const subscriberMethod = {
|
|
109
34
|
ONo: 1055,
|
|
110
35
|
MethodID: {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
function tree_to_rolemap(tree, s) {
|
|
2
|
+
const roles = new Map();
|
|
3
|
+
if (!s) s = '/';
|
|
4
|
+
|
|
5
|
+
const tasks = [];
|
|
6
|
+
|
|
7
|
+
const fetch_role = (o) => {
|
|
8
|
+
if (Array.isArray(o)) {
|
|
9
|
+
o.forEach(fetch_role);
|
|
10
|
+
} else {
|
|
11
|
+
tasks.push(
|
|
12
|
+
o.GetRole().then((role) => {
|
|
13
|
+
roles.set(o, role);
|
|
14
|
+
})
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
tree.forEach(fetch_role);
|
|
20
|
+
|
|
21
|
+
return Promise.all(tasks).then(function () {
|
|
22
|
+
const rolemap = new Map();
|
|
23
|
+
|
|
24
|
+
const build_paths = (a, prefix) => {
|
|
25
|
+
const p = prefix != null ? prefix + s : '';
|
|
26
|
+
const local_roles = new Map();
|
|
27
|
+
|
|
28
|
+
a.forEach(function (o, i) {
|
|
29
|
+
if (Array.isArray(o)) return;
|
|
30
|
+
|
|
31
|
+
const role = roles.get(o);
|
|
32
|
+
|
|
33
|
+
if (local_roles.has(role)) {
|
|
34
|
+
const tmp = local_roles.get(role);
|
|
35
|
+
|
|
36
|
+
if (Array.isArray(tmp)) tmp.push(o);
|
|
37
|
+
else local_roles.set(role, [tmp, o]);
|
|
38
|
+
} else {
|
|
39
|
+
local_roles.set(role, o);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
local_roles.forEach(function (o, role) {
|
|
44
|
+
if (Array.isArray(o)) {
|
|
45
|
+
let n = 1;
|
|
46
|
+
for (let i = 0; i < o.length; i++) {
|
|
47
|
+
let nrole;
|
|
48
|
+
while (local_roles.has((nrole = role + n))) {
|
|
49
|
+
n++;
|
|
50
|
+
}
|
|
51
|
+
local_roles.set(nrole, o[i]);
|
|
52
|
+
local_roles.set(o[i], nrole);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
local_roles.delete(role);
|
|
56
|
+
} else {
|
|
57
|
+
local_roles.set(o, role);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
a.forEach((o, i) => {
|
|
62
|
+
if (Array.isArray(o)) {
|
|
63
|
+
build_paths(o, p + local_roles.get(a[i - 1]));
|
|
64
|
+
} else {
|
|
65
|
+
const path = p + local_roles.get(o);
|
|
66
|
+
rolemap.set(path, o);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
build_paths(tree, null);
|
|
72
|
+
|
|
73
|
+
return rolemap;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export default tree_to_rolemap;
|
package/src/index.default.d.ts
CHANGED
|
@@ -14,5 +14,7 @@ export * from './controller/remote_device';
|
|
|
14
14
|
export * from './controller/define_custom_class';
|
|
15
15
|
export * from './controller/abstract_udp_connection';
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
import * as RemoteControlClasses from './controller/ControlClasses';
|
|
18
|
+
import * as Types from './types';
|
|
19
|
+
|
|
20
|
+
export { RemoteControlClasses, Types };
|
package/tests/connect.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
const process = require('process');
|
|
2
|
-
const RemoteDevice = require('../lib/Controller').RemoteDevice;
|
|
3
|
-
const TCPConnection = require('../lib/controller/TCP').TCPConnection;
|
|
4
|
-
const OCC = require('../lib/controller/ControlClasses');
|
|
5
|
-
|
|
6
|
-
if (process.argv.length < 4)
|
|
7
|
-
{
|
|
8
|
-
console.log('Usage: node connect.js <ip> <port>');
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const host = process.argv[2];
|
|
13
|
-
const port = parseInt(process.argv[3]);
|
|
14
|
-
|
|
15
|
-
TCPConnection.connect({
|
|
16
|
-
host: host,
|
|
17
|
-
port: port,
|
|
18
|
-
})
|
|
19
|
-
.then(function(connection) {
|
|
20
|
-
return new RemoteDevice(connection);
|
|
21
|
-
})
|
|
22
|
-
.then(printDeviceTree);
|
|
23
|
-
|
|
24
|
-
function delay(n)
|
|
25
|
-
{
|
|
26
|
-
return new Promise(function(resolve, reject) {
|
|
27
|
-
setTimeout(resolve, n);
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async function microblink(objects)
|
|
32
|
-
{
|
|
33
|
-
let found = false;
|
|
34
|
-
|
|
35
|
-
do
|
|
36
|
-
{
|
|
37
|
-
for (let i = 0; i < objects.length; i++)
|
|
38
|
-
{
|
|
39
|
-
const o = objects[i];
|
|
40
|
-
|
|
41
|
-
if (o instanceof OCC.OcaBitstringActuator)
|
|
42
|
-
{
|
|
43
|
-
const N = await o.GetNrBits();
|
|
44
|
-
|
|
45
|
-
const n = 0 | (Math.random() * N);
|
|
46
|
-
const v = Math.random() > 0.5;
|
|
47
|
-
|
|
48
|
-
await o.SetBit(n, v);
|
|
49
|
-
await delay(10);
|
|
50
|
-
|
|
51
|
-
found = true;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
} while (found);
|
|
55
|
-
|
|
56
|
-
process.exit(0);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function printDeviceTree(device)
|
|
60
|
-
{
|
|
61
|
-
var print = function(objects, i) {
|
|
62
|
-
var o = objects[i];
|
|
63
|
-
var a = [];
|
|
64
|
-
|
|
65
|
-
if (!o) {
|
|
66
|
-
microblink(objects);
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
a.push(o.GetRole().then((role) => console.log("Role:", role)));
|
|
71
|
-
o.get_properties().forEach((p) => {
|
|
72
|
-
const getter = p.getter(o);
|
|
73
|
-
if (!getter) return;
|
|
74
|
-
a.push(getter().then((val) => console.log(" %s: %o ", p.name, val)));
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
Promise.all(a)
|
|
78
|
-
.then(
|
|
79
|
-
() => print(objects, i+1),
|
|
80
|
-
(err) => {
|
|
81
|
-
console.error(err);
|
|
82
|
-
print(objects, i+1)
|
|
83
|
-
});
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
device.discover_all().then(
|
|
87
|
-
function(o) {
|
|
88
|
-
print(o, 0);
|
|
89
|
-
},
|
|
90
|
-
function(err) {
|
|
91
|
-
console.error(err);
|
|
92
|
-
});
|
|
93
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { ObjectTest } from './test.js';
|
|
2
|
-
|
|
3
|
-
class CheckTree extends ObjectTest {
|
|
4
|
-
async check_object(o, parent, i) {
|
|
5
|
-
if (Array.isArray(o))
|
|
6
|
-
{
|
|
7
|
-
this.check(i > 0, "Children follow their parent object.");
|
|
8
|
-
await check_children(children[i-1], o);
|
|
9
|
-
}
|
|
10
|
-
else
|
|
11
|
-
{
|
|
12
|
-
try {
|
|
13
|
-
const ono = await o.GetOwner();
|
|
14
|
-
|
|
15
|
-
this.check(ono === parent.ObjectNumber, "object %O has owner property %o (should be %o)",
|
|
16
|
-
o.ObjectNumber, ono, parent.ObjectNumber);
|
|
17
|
-
} catch (e) {
|
|
18
|
-
this.fail('GetOwner is not implemented in object %o.', o.ObjectNumber);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
this.check(o.ObjectNumber >= 4096, "object has reserved ObjectNumber ( below 4096 )");
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
const id = await o.GetClassIdentification();
|
|
25
|
-
const class_version = o.ClassVersion;
|
|
26
|
-
const class_id = o.ClassID;
|
|
27
|
-
|
|
28
|
-
this.check(id.ClassID.startsWith(o.ClassID), "ClassID does not match in object %o (%o vs. %o)",
|
|
29
|
-
o.ObjectNumber, id.ClassID, o.ClassID);
|
|
30
|
-
} catch (e) {
|
|
31
|
-
this.fail('GetOwner is not implemented in object %o.', o.ObjectNumber);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
class CheckPath extends ObjectTest {
|
|
38
|
-
constructor(device)
|
|
39
|
-
{
|
|
40
|
-
super(device);
|
|
41
|
-
this.roles = new Map();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
get_roles_for(o)
|
|
45
|
-
{
|
|
46
|
-
if (!this.roles.has(o))
|
|
47
|
-
{
|
|
48
|
-
this.roles.set(o, new Set());
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return this.roles.get(o);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async check_object(o, parent, i)
|
|
55
|
-
{
|
|
56
|
-
const roles = this.get_roles_for(parent);
|
|
57
|
-
|
|
58
|
-
const role = await o.GetRole();
|
|
59
|
-
|
|
60
|
-
this.check(role.length, "Role name is empty.");
|
|
61
|
-
|
|
62
|
-
this.check(!roles.has(role), "Role name collision with object %d (role: %o)", o.ono, role);
|
|
63
|
-
|
|
64
|
-
roles.add(role);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
class CheckRoleMap extends ObjectTest {
|
|
69
|
-
constructor(get_device)
|
|
70
|
-
{
|
|
71
|
-
super(get_device);
|
|
72
|
-
this.rolemap = null;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async prepare()
|
|
76
|
-
{
|
|
77
|
-
await super.prepare();
|
|
78
|
-
this.rolemap = await this.device.get_role_map();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
async check_object(o, parent, i)
|
|
82
|
-
{
|
|
83
|
-
let found = false;
|
|
84
|
-
|
|
85
|
-
const role = await o.GetRole();
|
|
86
|
-
|
|
87
|
-
this.rolemap.forEach((tmp, path) => {
|
|
88
|
-
if (o === tmp)
|
|
89
|
-
{
|
|
90
|
-
this.check(!found, "Found object %o in role map twice.", o.ono);
|
|
91
|
-
this.check(path.split("/").pop().startsWith(role), "Role names do not match.");
|
|
92
|
-
|
|
93
|
-
found = true;
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
this.check(found, "Could not find object %o in role map.", o.ono);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export default [ CheckTree, CheckPath, CheckRoleMap ];
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
const RemoteControlClasses = require('../../lib').RemoteControlClasses;
|
|
2
|
-
const Types = require('../../lib').Types;
|
|
3
|
-
const define_custom_class = require('../../lib').controller.define_custom_class;
|
|
4
|
-
const Test = require('./test').Test;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const SimpleBlock = define_custom_class(
|
|
8
|
-
"SimpleBlock",
|
|
9
|
-
3,
|
|
10
|
-
"1.1.3",
|
|
11
|
-
2,
|
|
12
|
-
"OcaWorker",
|
|
13
|
-
[
|
|
14
|
-
[ "GetMembers", 3, 5, [ ], [ [ 'LIST', Types.OcaObjectIdentification ] ] ],
|
|
15
|
-
[ "GetMembersRecursive", 3, 6, [ ], [ [ 'LIST', Types.OcaBlockMember ] ] ],
|
|
16
|
-
],
|
|
17
|
-
[
|
|
18
|
-
],
|
|
19
|
-
[ ]
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
class CustomBlock extends Test
|
|
23
|
-
{
|
|
24
|
-
async prepare()
|
|
25
|
-
{
|
|
26
|
-
await super.prepare();
|
|
27
|
-
this.device2 = await this.get_device();
|
|
28
|
-
this.device2.add_control_classes([ SimpleBlock ]);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async run()
|
|
32
|
-
{
|
|
33
|
-
this.check(SimpleBlock.ClassID === "\u0001\u0001\u0003",
|
|
34
|
-
'SimpleBlock class id is wrong: %o', SimpleBlock.ClassID);
|
|
35
|
-
const rolemap1 = await this.device.get_role_map();
|
|
36
|
-
const rolemap2 = await this.device2.get_role_map();
|
|
37
|
-
|
|
38
|
-
this.check(rolemap1.size == rolemap2.size, "Different number of objects.");
|
|
39
|
-
this.check(
|
|
40
|
-
JSON.stringify(Array.from(rolemap1.keys())) ===
|
|
41
|
-
JSON.stringify(Array.from(rolemap2.keys())), "Same role map.");
|
|
42
|
-
|
|
43
|
-
rolemap2.forEach((o) => {
|
|
44
|
-
if (o.ClassID === SimpleBlock.ClassID)
|
|
45
|
-
this.check(o instanceof SimpleBlock,
|
|
46
|
-
"Custom class was not used.");
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
cleanup()
|
|
51
|
-
{
|
|
52
|
-
super.cleanup();
|
|
53
|
-
if (this.device2 !== null)
|
|
54
|
-
{
|
|
55
|
-
this.device2.close();
|
|
56
|
-
this.device2 = null;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
module.exports = [ CustomBlock ];
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Test } from './test.js';
|
|
2
|
-
import { UDPConnection } from '../../src/controller/udp_connection.js';
|
|
3
|
-
|
|
4
|
-
function wait(n)
|
|
5
|
-
{
|
|
6
|
-
return new Promise(function(resolve, reject)
|
|
7
|
-
{
|
|
8
|
-
setTimeout(resolve, n*1000);
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
class IdleTime extends Test {
|
|
13
|
-
async run()
|
|
14
|
-
{
|
|
15
|
-
this.device.set_keepalive_interval(1);
|
|
16
|
-
|
|
17
|
-
await wait(2);
|
|
18
|
-
|
|
19
|
-
const connection = this.device.connection;
|
|
20
|
-
|
|
21
|
-
this.check(connection.tx_idle_time() < 1500, "TX Idle time too big: %o", connection.tx_idle_time());
|
|
22
|
-
this.check(connection.rx_idle_time() < 1500, "RX Idle time too big: %o", connection.rx_idle_time());
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
class RemoteClose extends Test {
|
|
27
|
-
run()
|
|
28
|
-
{
|
|
29
|
-
// we cannot detect this properly
|
|
30
|
-
if (this.device.connection instanceof UDPConnection)
|
|
31
|
-
return Promise.resolve(true);
|
|
32
|
-
|
|
33
|
-
return new Promise((resolve, reject) => {
|
|
34
|
-
this.device.set_keepalive_interval(1);
|
|
35
|
-
const connection = this.device.connection;
|
|
36
|
-
|
|
37
|
-
// we manually remove the keepalive interval
|
|
38
|
-
// out connection will be silent from now on
|
|
39
|
-
clearInterval(connection.keepalive_interval);
|
|
40
|
-
|
|
41
|
-
// we expect a close
|
|
42
|
-
connection.on('close', resolve);
|
|
43
|
-
setTimeout(function() {
|
|
44
|
-
reject(new Error("Connection not closed by remote side."));
|
|
45
|
-
}, 1000 * 4);
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export default [ IdleTime, RemoteClose ];
|
package/tests/device/locking.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { ObjectTest } from './test.js';
|
|
2
|
-
import { OcaStatus } from '../../src/types/OcaStatus.js';
|
|
3
|
-
|
|
4
|
-
class Locking extends ObjectTest
|
|
5
|
-
{
|
|
6
|
-
async prepare()
|
|
7
|
-
{
|
|
8
|
-
await super.prepare();
|
|
9
|
-
this.other_device = await this.get_device();
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
async check_object(o)
|
|
13
|
-
{
|
|
14
|
-
try {
|
|
15
|
-
if (!await o.GetLockable()) return;
|
|
16
|
-
} catch (e) {
|
|
17
|
-
if (e.status == OcaStatus.NotImplemented) return;
|
|
18
|
-
throw e;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const o2 = this.other_device.allocate(o.constructor, o.ono);
|
|
22
|
-
|
|
23
|
-
this.check(await o2.GetRole() == await o.GetRole(),
|
|
24
|
-
"Role names do not match.");
|
|
25
|
-
|
|
26
|
-
await o.LockTotal();
|
|
27
|
-
|
|
28
|
-
await o.GetRole();
|
|
29
|
-
|
|
30
|
-
try {
|
|
31
|
-
await o2.GetRole();
|
|
32
|
-
this.check(false, "Object should be locked for other clients now.");
|
|
33
|
-
} catch (e) {
|
|
34
|
-
this.check(e.status == OcaStatus.Locked,
|
|
35
|
-
"Calling methods as a second client should return OcaStatus::Locked.");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
await o.Unlock();
|
|
39
|
-
|
|
40
|
-
this.check(await o2.GetRole() == await o.GetRole(),
|
|
41
|
-
"Role names do not match.");
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
cleanup()
|
|
45
|
-
{
|
|
46
|
-
super.cleanup();
|
|
47
|
-
this.close_device(this.other_device);
|
|
48
|
-
this.other_device = null;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export default [ Locking ];
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Test } from './test.js';
|
|
2
|
-
|
|
3
|
-
class CheckCallbackMethod extends Test {
|
|
4
|
-
async run() {
|
|
5
|
-
const root = this.device.Root;
|
|
6
|
-
|
|
7
|
-
const result = await root.GetMembers();
|
|
8
|
-
|
|
9
|
-
const result2 = await new Promise((resolve, reject) => {
|
|
10
|
-
const tmp = root.GetMembers((ok, result) => {
|
|
11
|
-
(ok ? resolve : reject)(result);
|
|
12
|
-
});
|
|
13
|
-
if (tmp) {
|
|
14
|
-
console.error('got %o', tmp);
|
|
15
|
-
throw new Error('Unexpected return value.');
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
if (result.length !== result2.length)
|
|
20
|
-
throw new Error('Result mismatch.');
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export default [ CheckCallbackMethod ];
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { ObjectTest } from './test.js';
|
|
2
|
-
import { Arguments } from '../../src/controller/arguments.js';
|
|
3
|
-
import { OcaStatus } from '../../src/types/OcaStatus.js';
|
|
4
|
-
import { OcaPropertyChangeType } from '../../src/types/OcaPropertyChangeType.js';
|
|
5
|
-
|
|
6
|
-
function isEqual(a, b) {
|
|
7
|
-
if (a === b) return true;
|
|
8
|
-
|
|
9
|
-
if (Array.isArray(a)) {
|
|
10
|
-
if (!Array.isArray(b)) return false;
|
|
11
|
-
if (a.length !== b.length) return false;
|
|
12
|
-
|
|
13
|
-
return a.every((element, i) => isEqual(element, b[i]));
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (typeof a === 'object') {
|
|
17
|
-
if (typeof b !== 'object') return false;
|
|
18
|
-
if (a.constructor !== b.constructor) return false;
|
|
19
|
-
|
|
20
|
-
for (const name in a) {
|
|
21
|
-
if (a[name] !== b[name]) return false;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
class PropertyChanges extends ObjectTest
|
|
31
|
-
{
|
|
32
|
-
async check_object(o)
|
|
33
|
-
{
|
|
34
|
-
const sync = o.GetPropertySync();
|
|
35
|
-
await sync.sync();
|
|
36
|
-
|
|
37
|
-
sync.forEach((value, name) => {
|
|
38
|
-
this.check(sync[name] === value, "PropertySync Getters are broken: %o vs. %o", sync[name], value);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
await Promise.all(o.get_properties().forEach(async (prop) => {
|
|
42
|
-
const name = prop.name;
|
|
43
|
-
const setter = prop.setter(o);
|
|
44
|
-
const getter = prop.getter(o);
|
|
45
|
-
const event = prop.event(o);
|
|
46
|
-
|
|
47
|
-
if (!setter || !getter) return;
|
|
48
|
-
|
|
49
|
-
let a;
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
a = await getter();
|
|
53
|
-
} catch (e) {
|
|
54
|
-
if (e.status === OcaStatus.NotImplemented) return;
|
|
55
|
-
throw e;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (!(a instanceof Arguments)) return;
|
|
59
|
-
|
|
60
|
-
const val = a.item(0);
|
|
61
|
-
const min = a.item(1);
|
|
62
|
-
const max = a.item(2);
|
|
63
|
-
|
|
64
|
-
// this happens with GetThreshold() in OcaDynamics
|
|
65
|
-
if (typeof val !== typeof min || typeof val !== typeof max) return;
|
|
66
|
-
|
|
67
|
-
this.check(isEqual(sync[name], val),
|
|
68
|
-
"Property Sync value '%s' is not equal to current: %o vs. %o", name, sync[name], val);
|
|
69
|
-
|
|
70
|
-
const test_set = async (to) => {
|
|
71
|
-
let called = false;
|
|
72
|
-
|
|
73
|
-
const cb = (value, changeType) => {
|
|
74
|
-
if (changeType !== OcaPropertyChangeType.CurrentChanged)
|
|
75
|
-
return;
|
|
76
|
-
|
|
77
|
-
this.check(isEqual(value, to), "Received event for different value change: %o vs. %o", to, value);
|
|
78
|
-
|
|
79
|
-
called = true;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
await event.subscribe(cb);
|
|
83
|
-
|
|
84
|
-
try {
|
|
85
|
-
await setter(to);
|
|
86
|
-
} catch (e) {
|
|
87
|
-
if (e.status === OcaStatus.NotImplemented) return;
|
|
88
|
-
throw e;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const tmp = (await getter()).item(0);
|
|
92
|
-
|
|
93
|
-
await event.unsubscribe(cb);
|
|
94
|
-
|
|
95
|
-
this.check(called, "PropertyChanged event was not received for '%s'", name);
|
|
96
|
-
|
|
97
|
-
this.check(isEqual(to, tmp),
|
|
98
|
-
"Property '%s' set to %o succeeded but get returned %o", name, to, tmp);
|
|
99
|
-
this.check(isEqual(to, sync[name]),
|
|
100
|
-
"Property '%s' set to %o succeeded but sync contains %o", name, to, sync[name]);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// set to min first
|
|
104
|
-
await test_set(min);
|
|
105
|
-
await test_set(max);
|
|
106
|
-
await test_set(val);
|
|
107
|
-
}));
|
|
108
|
-
|
|
109
|
-
sync.Dispose();
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export default [ PropertyChanges ];
|