@meta2d/core 1.1.14 → 1.1.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meta2d/core",
3
- "version": "1.1.14",
3
+ "version": "1.1.15",
4
4
  "description": "@meta2d/core: Powerful, Beautiful, Simple, Open - Web-Based 2D At Its Best .",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
package/src/core.d.ts CHANGED
@@ -260,17 +260,27 @@ export declare class Meta2d {
260
260
  reconnectNetwork(index: number): void;
261
261
  iotMqttClient: MqttClient;
262
262
  iotTimer: any;
263
- iotWebsocketClient: WebSocket;
264
263
  connectIot(): Promise<void>;
264
+ iotAggregateBuild(item: any): {
265
+ token: string;
266
+ deviceId: any;
267
+ key: any;
268
+ name: string;
269
+ };
270
+ iotAggregatePublish(item: any): void;
265
271
  closeIot(): void;
266
272
  connectSqls(): void;
267
273
  connectSSE(net: Network): void;
268
274
  closeSSE(): void;
269
275
  connectNetMqtt(net: Network): void;
270
276
  connectNetWebSocket(net: Network): void;
271
- getMqttUrl(): Promise<string>;
272
- getIotToken(devices: any, type: number): Promise<any>;
273
- unsubscribeIot(token: string): Promise<any>;
277
+ getMqttUrl(): Promise<{
278
+ username: any;
279
+ password: any;
280
+ url: string;
281
+ }>;
282
+ getIotToken(devices: any, type: number, room?: string): Promise<any>;
283
+ unsubscribeIot(token: string, room?: string): Promise<any>;
274
284
  doSqlCode(sql: Sql): Promise<void>;
275
285
  randomString(e: number): string;
276
286
  mockValue(data: any): any;
package/src/core.js CHANGED
@@ -740,7 +740,48 @@ export class Meta2d {
740
740
  delete network.data;
741
741
  }
742
742
  if (network.protocol === 'iot') {
743
- this.iotMqttClient && this.iotMqttClient.publish(`le5le-iot/property/set/${this.store.data.iot?.token}`, JSON.stringify(value));
743
+ if (this.store.data.iot.room) {
744
+ let payload = {
745
+ token: this.store.data.iot.token,
746
+ data: value,
747
+ };
748
+ if (value.name) {
749
+ const keys = Object.keys(value).filter((key) => value[key] === 'aggregate');
750
+ if (keys.length) {
751
+ const _value = deepClone(value);
752
+ keys.forEach((key) => {
753
+ delete _value[key];
754
+ });
755
+ delete _value.name;
756
+ if (_value.start && typeof _value.start === 'string') {
757
+ _value.start = Math.floor(new Date(_value.start).getTime() / 1000);
758
+ }
759
+ if (_value.end && typeof _value.end === 'string') {
760
+ _value.end = Math.floor(new Date(_value.end).getTime() / 1000);
761
+ }
762
+ let payload = [];
763
+ keys.forEach((key) => {
764
+ let arr = key.split('#');
765
+ payload.push({
766
+ token: this.store.data.iot.token,
767
+ deviceId: arr[0],
768
+ key: arr[1],
769
+ name: arr[1] + '_' + value.name,
770
+ ..._value,
771
+ });
772
+ });
773
+ this.iotMqttClient &&
774
+ this.iotMqttClient.publish(`le5le-iot/${this.store.data.iot.room}/property/aggregate`, JSON.stringify(payload));
775
+ return;
776
+ }
777
+ }
778
+ this.iotMqttClient &&
779
+ this.iotMqttClient.publish(`le5le-iot/${this.store.data.iot.room}/properties/set`, JSON.stringify(payload));
780
+ }
781
+ else {
782
+ this.iotMqttClient &&
783
+ this.iotMqttClient.publish(`le5le-iot/property/set/${this.store.data.iot?.token}`, JSON.stringify(value));
784
+ }
744
785
  return;
745
786
  }
746
787
  if (!network.url) {
@@ -1194,6 +1235,7 @@ export class Meta2d {
1194
1235
  this.store.bind = {};
1195
1236
  const devices = [];
1196
1237
  const properties = [];
1238
+ const computes = [];
1197
1239
  this.store.data.pens.forEach((pen) => {
1198
1240
  pen.realTimes?.forEach((realTime) => {
1199
1241
  if (realTime.bind && realTime.bind.id) {
@@ -1262,26 +1304,47 @@ export class Meta2d {
1262
1304
  }
1263
1305
  }
1264
1306
  if (realTime.bind.class === 'iot') {
1265
- let bind = realTime.bind.id.split('#');
1266
- let idx = devices.findIndex((item) => item.deviceId === bind[0]);
1267
- if (idx > -1) {
1268
- if (!devices[idx].properties.includes(bind[1])) {
1269
- devices[idx].properties.push(bind[1]);
1307
+ if (realTime.bind.compute_name) {
1308
+ let c_idx = computes.findIndex((item) => item.id === realTime.bind.id);
1309
+ if (c_idx === -1) {
1310
+ computes.push(deepClone(realTime.bind));
1311
+ }
1312
+ let idx = devices.findIndex((item) => item.deviceId === realTime.bind.deviceId);
1313
+ if (idx > -1) {
1314
+ if (!devices[idx].properties.includes(realTime.bind.key)) {
1315
+ devices[idx].properties.push(realTime.bind.key);
1316
+ }
1317
+ }
1318
+ else {
1319
+ devices.push({
1320
+ deviceId: realTime.bind.deviceId,
1321
+ properties: [realTime.bind.key],
1322
+ token: realTime.bind.token
1323
+ });
1270
1324
  }
1271
1325
  }
1272
1326
  else {
1273
- devices.push({
1274
- deviceId: bind[0],
1275
- properties: [bind[1]],
1276
- token: realTime.bind.token
1277
- });
1278
- }
1279
- let index = properties.findIndex((item) => item.key === realTime.bind.id);
1280
- if (index === -1) {
1281
- properties.push({
1282
- key: realTime.bind.id,
1283
- label: realTime.bind.label,
1284
- });
1327
+ let bind = realTime.bind.id.split('#');
1328
+ let idx = devices.findIndex((item) => item.deviceId === bind[0]);
1329
+ if (idx > -1) {
1330
+ if (!devices[idx].properties.includes(bind[1])) {
1331
+ devices[idx].properties.push(bind[1]);
1332
+ }
1333
+ }
1334
+ else {
1335
+ devices.push({
1336
+ deviceId: bind[0],
1337
+ properties: [bind[1]],
1338
+ token: realTime.bind.token
1339
+ });
1340
+ }
1341
+ let index = properties.findIndex((item) => item.key === realTime.bind.id);
1342
+ if (index === -1) {
1343
+ properties.push({
1344
+ key: realTime.bind.id,
1345
+ label: realTime.bind.label,
1346
+ });
1347
+ }
1285
1348
  }
1286
1349
  }
1287
1350
  else if (realTime.bind.class === 'sql') {
@@ -1339,6 +1402,9 @@ export class Meta2d {
1339
1402
  else {
1340
1403
  delete this.store.data.iot.list;
1341
1404
  }
1405
+ if (computes.length) {
1406
+ this.store.data.iot.computes = computes;
1407
+ }
1342
1408
  }
1343
1409
  connectSocket() {
1344
1410
  this.connectWebsocket();
@@ -2464,23 +2530,39 @@ export class Meta2d {
2464
2530
  }
2465
2531
  iotMqttClient;
2466
2532
  iotTimer;
2467
- iotWebsocketClient;
2468
2533
  async connectIot() {
2469
2534
  const { iot } = this.store.data;
2470
2535
  if (!(iot && iot?.devices?.length) || (iot && iot.enable === false)) {
2471
2536
  return;
2472
2537
  }
2473
- const url = globalThis.iotUrl || await this.getMqttUrl();
2538
+ let { url, password, username } = await this.getMqttUrl();
2539
+ if (!url) {
2540
+ url = globalThis.iotUrl;
2541
+ }
2474
2542
  if (!url) {
2475
2543
  console.warn('iot Request address error');
2476
2544
  return;
2477
2545
  }
2478
- const token = await this.getIotToken(iot.devices, iot.protocol === 'websocket' ? 1 : undefined);
2546
+ const { token, room, data } = await this.getIotToken(iot.devices, iot.protocol === 'websocket' ? 1 : undefined, iot.room);
2547
+ if (data) {
2548
+ // 初始数据
2549
+ this.socketCallback(JSON.stringify(data), {
2550
+ type: 'iot',
2551
+ url,
2552
+ method: 'mqtt'
2553
+ });
2554
+ }
2555
+ if (room) {
2556
+ iot.room = room;
2557
+ }
2479
2558
  iot.token = token;
2480
2559
  //物联网设备
2481
- // if(iot.protocol === 'mqtt'){
2482
- // const url ='ws://192.168.110.148:8083/mqtt'; //`${location.protocol === 'https:'?'wss':'ws'}://${iot.host}:${location.protocol === 'https:'?'8084':'8083'}/mqtt`
2483
- this.iotMqttClient = mqtt.connect(url);
2560
+ const options = {
2561
+ username,
2562
+ password,
2563
+ clientId: 'client-' + Math.random().toString(16).slice(2, 8),
2564
+ };
2565
+ this.iotMqttClient = mqtt.connect(url, options);
2484
2566
  this.iotMqttClient.on('message', (topic, message) => {
2485
2567
  this.socketCallback(message.toString(), {
2486
2568
  topic: `le5le-iot/properties/${token}`,
@@ -2492,29 +2574,87 @@ export class Meta2d {
2492
2574
  this.iotMqttClient.on('error', (error) => {
2493
2575
  this.store.emitter.emit('error', { type: 'mqtt', error });
2494
2576
  });
2495
- this.iotMqttClient.subscribe(`le5le-iot/properties/${token}`);
2577
+ if (iot.room) {
2578
+ this.iotMqttClient.subscribe(`le5le-iot/${iot.room}/properties/get`);
2579
+ }
2580
+ else {
2581
+ this.iotMqttClient.subscribe(`le5le-iot/properties/${token}`);
2582
+ }
2496
2583
  this.iotTimer = setInterval(() => {
2497
- this.iotMqttClient && this.iotMqttClient.publish(`le5le-iot/subscribe/ping`, token);
2584
+ if (iot.room) {
2585
+ this.iotMqttClient && this.iotMqttClient.publish(`le5le-iot/subscribe/ping`, iot.room);
2586
+ }
2587
+ else {
2588
+ this.iotMqttClient && this.iotMqttClient.publish(`le5le-iot/subscribe/ping`, token);
2589
+ }
2498
2590
  }, 300000);
2499
- // }else if(iot.protocol === 'websocket'){
2500
- // const url = 'ws://192.168.110.6/api/ws/iot/properties'// `${location.protocol === 'https:'?'wss':'ws'}://${location.host}/api/ws/iot/properties`
2501
- // this.iotWebsocketClient = new WebSocket(
2502
- // url,
2503
- // token
2504
- // );
2505
- // this.iotWebsocketClient.onmessage = (e) => {
2506
- // this.socketCallback(e.data, { type: 'iot', method: 'websocket' });
2507
- // };
2508
- // this.iotWebsocketClient.onerror = (error) => {
2509
- // this.store.emitter.emit('error', { type: 'websocket', error });
2510
- // };
2511
- // }
2591
+ if (this.store.data.iot.computes?.length) {
2592
+ let flag = false;
2593
+ this.store.data.iot.computes.forEach((item) => {
2594
+ if (item.times > 0) {
2595
+ flag = true;
2596
+ }
2597
+ });
2598
+ this.iotAggregatePublish(this.store.data.iot.computes);
2599
+ iot.times = 0;
2600
+ if (flag) {
2601
+ iot.interval = setInterval(() => {
2602
+ iot.times += 1;
2603
+ let arr = this.store.data.iot.computes.filter((item) => item.times && iot.times % item.times === 0);
2604
+ if (arr.length) {
2605
+ this.iotAggregatePublish(arr);
2606
+ }
2607
+ }, 1000);
2608
+ }
2609
+ }
2610
+ }
2611
+ iotAggregateBuild(item) {
2612
+ let data = {
2613
+ token: this.store.data.iot.token,
2614
+ deviceId: item.deviceId,
2615
+ key: item.key,
2616
+ name: item.key + '_' + item.compute_name //item.id
2617
+ };
2618
+ ['aggregate', 'start', 'end', 'groupBy', 'limit', 'recent'].forEach((key) => {
2619
+ if (item[key]) {
2620
+ if (item[key].indexOf('${') > -1) {
2621
+ let keys = item[key].match(/(?<=\$\{).*?(?=\})/g);
2622
+ data[key] = this.getDynamicParam(keys[0]);
2623
+ }
2624
+ else {
2625
+ if (key === 'start' || key === 'end') {
2626
+ if (typeof item[key] === 'string') {
2627
+ data[key] = Math.floor(new Date(item[key]).getTime() / 1000);
2628
+ }
2629
+ else {
2630
+ data[key] = item[key];
2631
+ }
2632
+ }
2633
+ else {
2634
+ data[key] = item[key];
2635
+ }
2636
+ }
2637
+ }
2638
+ });
2639
+ return data;
2640
+ }
2641
+ iotAggregatePublish(item) {
2642
+ if (this.iotMqttClient) {
2643
+ let data = item.map((_item) => {
2644
+ return this.iotAggregateBuild(_item);
2645
+ });
2646
+ this.iotMqttClient.publish(`le5le-iot/${this.store.data.iot.room}/property/aggregate`, JSON.stringify(data));
2647
+ }
2512
2648
  }
2513
2649
  closeIot() {
2514
2650
  if (this.iotMqttClient) {
2515
2651
  const { iot } = this.store.data;
2652
+ if (iot.interval) {
2653
+ clearInterval(iot.interval);
2654
+ iot.interval = undefined;
2655
+ }
2516
2656
  if (iot?.token) {
2517
- this.unsubscribeIot(iot.token);
2657
+ this.unsubscribeIot(iot.token, iot.room);
2518
2658
  }
2519
2659
  this.iotMqttClient.end();
2520
2660
  this.iotMqttClient = undefined;
@@ -2722,29 +2862,32 @@ export class Meta2d {
2722
2862
  if (!port) {
2723
2863
  return;
2724
2864
  }
2725
- return `${location.protocol === 'https:' ? 'wss' : 'ws'}://${results.host}:${location.protocol === 'https:' ? results.wssPort : results.wsPort}${results.path}`;
2865
+ return {
2866
+ username: results.username,
2867
+ password: results.password,
2868
+ url: `${location.protocol === 'https:' ? 'wss' : 'ws'}://${results.host}:${location.protocol === 'https:' ? results.wssPort : results.wsPort}${results.path}`
2869
+ };
2726
2870
  }
2727
2871
  }
2728
- async getIotToken(devices, type) {
2872
+ async getIotToken(devices, type, room) {
2729
2873
  const res = await fetch('/api/iot/subscribe/properties', {
2730
2874
  method: 'POST',
2731
2875
  headers: {
2732
2876
  Authorization: getToken(),
2733
2877
  },
2734
- body: JSON.stringify({ devices: devices, type }),
2878
+ body: JSON.stringify({ devices: devices, type, room }),
2735
2879
  });
2736
2880
  if (res.ok) {
2737
- const data = await res.text();
2738
- return JSON.parse(data).token;
2881
+ return await res.json();
2739
2882
  }
2740
2883
  }
2741
- async unsubscribeIot(token) {
2884
+ async unsubscribeIot(token, room) {
2742
2885
  const ret = await fetch(`/api/iot/unsubscribe/properties`, {
2743
2886
  method: 'POST',
2744
2887
  headers: {
2745
2888
  Authorization: getToken(),
2746
2889
  },
2747
- body: JSON.stringify({ token }),
2890
+ body: JSON.stringify({ token, room }),
2748
2891
  });
2749
2892
  return ret;
2750
2893
  }
@@ -3192,17 +3335,6 @@ export class Meta2d {
3192
3335
  _sqlTimer = undefined;
3193
3336
  });
3194
3337
  this.closeIot();
3195
- // if(this.iotMqttClient){
3196
- // this.iotMqttClient.end();
3197
- // this.iotMqttClient = undefined;
3198
- // }
3199
- // clearInterval(this.iotTimer);
3200
- // this.iotTimer = undefined;
3201
- // if(this.iotWebsocketClient){
3202
- // this.iotWebsocketClient.onclose = undefined;
3203
- // this.iotWebsocketClient.close();
3204
- // this.iotWebsocketClient = undefined;
3205
- // }
3206
3338
  closeJetLinks(this);
3207
3339
  this.closeSSE();
3208
3340
  }
@@ -5294,6 +5426,7 @@ export class Meta2d {
5294
5426
  calcInView(pen);
5295
5427
  pen.onMove?.(pen);
5296
5428
  }
5429
+ this.canvas.canvasTemplate.init();
5297
5430
  this.canvas.canvasImage.init();
5298
5431
  this.canvas.canvasImageBottom.init();
5299
5432
  this.render();