Changes for page Demo for Smart Office, Factory
Last modified by Hera Guo on 2024/11/11 17:08
Summary
-
Page properties (1 modified, 0 added, 0 removed)
-
Attachments (0 modified, 52 added, 0 removed)
- 1730709382428-730.png
- 1730709409941-536.png
- 1730709424998-915.png
- 1730709442773-502.png
- 1730709461297-207.png
- 1730709479828-595.png
- 1730709511861-439.png
- 1730709527720-418.png
- 1730709542597-321.png
- 1730709555797-383.png
- 1730710271230-716.png
- 1730710395303-672.png
- 1730710693066-349.png
- 1730710850458-781.png
- 1730710875401-848.png
- 1730710949358-671.png
- 1730710990334-601.png
- 1730712335338-750.png
- 1730712473941-913.png
- 1730712539209-554.png
- 1730770392454-317.png
- 1730770636230-829.png
- 1730770875793-351.png
- 1730771103096-522.png
- 1730771199343-553.png
- 1730771228766-212.png
- 1730771256045-238.png
- 1730771318657-502.png
- 1730771386258-676.png
- 1730771441589-122.png
- 1730771504586-433.png
- 1730857191863-514.png
- 1730857537965-184.png
- 1730857750749-240.png
- 1730862483514-101.png
- 1730862584519-902.png
- 1730863708259-750.png
- 1730863750414-979.png
- 1730864045747-876.png
- 1730864077395-395.png
- 1730864117808-484.png
- 1730864159071-895.png
- 1730864207037-477.png
- 1730864250506-111.png
- 1730864293216-991.png
- 1730864331859-740.png
- 1730864460314-611.png
- 1730864617480-221.png
- 1730864676542-406.png
- 1730864784118-474.png
- 1730865053380-293.png
- 屏幕截图 2024-11-04 135045.png
Details
- Page properties
-
- Content
-
... ... @@ -1,10 +2,6 @@ 1 -**Table of Contents:** 2 2 3 -{{toc/}} 4 4 5 5 6 - 7 - 8 8 = 1. About this demo = 9 9 10 10 This demo is to show the installation for various sensors in Dragino Office, Dragino Facotry & ThingsEye Office. It covers various types of sensors such as Temperature, Humidity, CO2, Water Flow, Vibration & many many. ... ... @@ -57,7 +57,7 @@ 57 57 58 58 **device:**This section displays the specific information collected by the device, and different types of sensors have different display interfaces 59 59 60 -[[image: 1730699212334-960.png]]56 +[[image:屏幕截图 2024-11-04 134645.png]] 61 61 62 62 First floor: 63 63 ... ... @@ -82,7 +82,7 @@ 82 82 83 83 High Temperature、Low Temperature、High humidity、Low humidity、Low voltage、Device Disconnected 84 84 85 -[[image:1 730699566023-958.png]]81 +[[image:屏幕截图 2024-11-04 135045.png]] 86 86 87 87 = 4.configuration details = 88 88 ... ... @@ -90,17 +90,989 @@ 90 90 91 91 == 4.1 Dashboard configuration details == 92 92 93 -1 、Configurethe interface of the third layerDavies.89 +=== 4.1.1.Data source (Entity aliases) === 94 94 91 +detail:Obtain data based on dashboard status 95 95 96 - 2、Configurethenterfaceof the secondlayer asset93 +[[image:1730709424998-915.png||height="729" width="1436"]] 97 97 95 +Alarm:Obtain alarm information 98 98 99 - 3、Configurethefirstlayer menuinterface97 +[[image:1730709479828-595.png||height="696" width="1435"]] 100 100 99 +Dragino&GXHL,Ltd:Obtain data through asset types 101 101 101 +[[image:1730709511861-439.png||height="714" width="1435"]] 102 + 103 +Selected Supermarket:Retrieve devices by device type 104 + 105 +[[image:1730709527720-418.png||height="751" width="1433"]] 106 + 107 +Supermarket Devices:Obtain data through device type 108 + 109 +[[image:1730709555797-383.png||height="726" width="1434"]] 110 + 111 +LHT65N Device:Obtain data based on device type 112 + 113 +[[image:1730857191863-514.png||height="725" width="1433"]] 114 + 115 +=== 4.1.2.Page Configuration === 116 + 117 +==== 4.1.2.1、Configure the interface of the third layer Davies. ==== 118 + 119 +==== 4.1.2.2、Configure the interface of the second layer asset ==== 120 + 121 +===== 4.1.2.2.1 Equipment distribution diagram: ===== 122 + 123 +**Data:** 124 + 125 +[[image:1730770392454-317.png||height="745" width="1439"]] 126 + 127 +**Appearannce:**In this module, we need to arrange our devices in the corresponding positions and use icons to display our devices. Therefore, in the Appearance interface, we need to configure them 128 + 129 +**Tooltip function:**This module displays the current information of the device 130 + 131 +[[image:1730857537965-184.png]] 132 + 133 +{{code language="none"}} 134 +var msg = data 135 +if(msg.Label=="gateway" && msg.type == "gateway"){ 136 + var stauts 137 + if (msg.gatewaystauts=="true"){ 138 + stauts = "Connect" 139 + } 140 + else{ 141 + stauts = "Disconnected" 142 + } 143 + var str = "<b>"+msg.entityName+"</b><br/><b>"+stauts+"</b><br/>" 144 + return str 145 +} 146 +else if(msg.type=="gxhl01" && msg.Label!="gateway"){ 147 + var str = "<b>"+msg.entityName+"</b><br/><b>"+msg.Label+"</b><br/><b>Bat:</b>"+msg.BatV+"V<br/><b>Temperature:</b>"+ msg.TempC_SHT+ "°C<br/><b>Humidity:</b>"+msg.Hum_SHT+"%" 148 + return str 149 +} 150 +else{ 151 + var str = "<b>"+msg.entityName+"</b><br/><b>"+msg.Label+"</b><br/><b>Bat:</b>"+msg.BatV+"V<br/><b>Temperature:</b>"+ msg.temperature+ "°C<br/><b>Humidity:"+msg.humidity+"%"+"</b><br/>"+ 152 + "<b>Co2:"+msg.co2+"</b></br><b>Air_Pressure:"+msg.air_pressure 153 + 154 + return str 155 +} 156 +{{/code}} 157 + 158 +(% class="wikigeneratedid" id="HMarkerimagefunctionFF1A" %) 159 +**Marker image function:**This module can display different icons based on different types of sensors and their status to achieve its functionality 160 + 161 +(% class="wikigeneratedid" %) 162 +[[image:1730857750749-240.png]] 163 + 164 +{{code language="none"}} 165 +var res 166 +var msg = data 167 +if(msg.Label=="gateway" && msg.type=="gateway"){ 168 + if (msg.gatewaystauts == "true"){ 169 + res = { 170 + url: images[3], 171 + size: 40 172 +} 173 +} 174 +else{ 175 + res = { 176 + url: images[2], 177 + size: 40 178 +} 179 +}} 180 +else if(msg.Label!="gateway" && msg.type=="gxhl01" ){ 181 + if (msg.active=="false"){ 182 + res = { 183 + url: images[1], 184 + size: 40 185 +}} 186 +else{ 187 + res = { 188 + url: images[0], 189 + size: 40 190 +} 191 +} 192 +} 193 +else if(msg.type=="LWL02"){ 194 + if (msg.WATER_LEAK_STATUS=="0"){ 195 + res = { 196 + url: images[6], 197 + size: 40 198 +}} 199 +else{ 200 + res = { 201 + url: images[7], 202 + size: 40 203 +} 204 +} 205 +} 206 +else if(msg.type=="LDS02"){ 207 + if (msg.DOOR_OPEN_STATUS=="0"){ 208 + res = { 209 + url: images[5], 210 + size: 40 211 +}} 212 +else{ 213 + res = { 214 + url: images[8], 215 + size: 40 216 +} 217 +} 218 +} 219 +else if(msg.type=="LDS12"){ 220 + res = { 221 + url: images[10], 222 + size: 40 223 +}} 224 +else if(msg.type=="SE01"){ 225 + res = { 226 + url: images[9], 227 + size: 40 228 +}} 229 +else if(msg.type=="PB01"){ 230 + res = { 231 + url: images[11], 232 + size: 40 233 +}} 234 +else if(msg.type=="S31b"){ 235 + res = { 236 + url: images[12], 237 + size: 40 238 +}} 239 +else if(msg.type=="LHT65N"){ 240 + res = { 241 + url: images[13], 242 + size: 40 243 +}} 244 +else{ 245 + res = { 246 + url: images[4], 247 + size: 40 248 +} 249 +} 250 +return res; 251 +{{/code}} 252 + 253 +(% class="wikigeneratedid" %) 254 +[[image:1730770875793-351.png]] 255 + 256 +(% class="wikigeneratedid" %) 257 +**Actions:**We need to implement the function of entering the details interface through the corresponding device icon, so in this module, we need to add actions to achieve redirection 258 + 259 +{{code language="none"}} 260 +var entitySubType; 261 +var $injector = widgetContext.$scope.$injector; 262 +$injector.get(widgetContext.servicesMap.get('entityService')).getEntity(entityId.entityType, entityId.id) 263 + .subscribe(function(data) { 264 + entitySubType = data.type; 265 + console.log(entitySubType) 266 + if (entitySubType == 'gateway') { 267 + openDashboardStates('gateway_detail'); 268 + } else if (entitySubType == 'gxhl01') { 269 + openDashboardStates('detail'); 270 + } 271 + else if(entitySubType == 'AQS01-dragino-office'){ 272 + openDashboardStates("aqs01_detail") 273 + } 274 + else if (entitySubType == 'LDS12') { 275 + openDashboardStates('lds12_detail'); 276 + } 277 + else if (entitySubType == 'LDS02') { 278 + openDashboardStates('lds02_detail'); 279 + } 280 + else if (entitySubType == 'SE01') { 281 + openDashboardStates('se01_detail'); 282 + } 283 + else if (entitySubType == 'PB01') { 284 + openDashboardStates('pb01_detail'); 285 + } 286 + else if (entitySubType == 'LWL02') { 287 + openDashboardStates('lwl02_detail'); 288 + } 289 + else if (entitySubType == 'LPS8N') { 290 + openDashboardStates('lps8n_detail'); 291 + } 292 + else if (entitySubType == 'LHT65N') { 293 + openDashboardStates('lht65n_detail'); 294 + } 295 + else if (entitySubType == 'S31b') { 296 + openDashboardStates('s31b_detail'); 297 + } 298 + }); 299 + 300 +function openDashboardStates(statedId) { 301 + var stateParams = widgetContext.stateController.getStateParams(); 302 + var params = { 303 + entityId: entityId, 304 + entityName: entityName 305 + }; 306 + 307 + if (stateParams.city) { 308 + params.city = stateParams.city; 309 + } 310 + 311 + widgetContext.stateController.openState(statedId, params, false); 312 +} 313 + 314 +{{/code}} 315 + 316 +[[image:1730771103096-522.png]] 317 + 318 +===== 4.1.2.2.2 Device List ===== 319 + 320 +(% class="wikigeneratedid" id="HDataFF1A" %) 321 +**Data:** 322 + 323 +[[image:1730771199343-553.png]] 324 + 325 +**Actions:**Equipment distribution diagram: In this module, functions need to be implemented such as adding devices, editing devices, deleting devices, and jumping to the device details page. Therefore, the following actions need to be added: 326 + 327 +[[image:1730771228766-212.png]] 328 + 329 +(% class="wikigeneratedid" id="HEditdeviceFF1A" %) 330 +**Edit device:**Implementation function: Device editing 331 + 332 +[[image:1730771256045-238.png]] 333 + 334 +{{code language="none"}} 335 +let $injector = widgetContext.$scope.$injector; 336 +let customDialog = $injector.get(widgetContext.servicesMap.get('customDialog')); 337 +let deviceService = $injector.get(widgetContext.servicesMap.get('deviceService')); 338 +let attributeService = $injector.get(widgetContext.servicesMap.get('attributeService')); 339 + 340 +openEditDeviceDialog(); 341 + 342 +function openEditDeviceDialog() { 343 + customDialog.customDialog(htmlTemplate, EditDeviceDialogController).subscribe(); 344 +} 345 + 346 +function EditDeviceDialogController(instance) { 347 + let vm = instance; 348 + 349 + vm.device = null; 350 + vm.attributes = {}; 351 + 352 + vm.editDeviceFormGroup = vm.fb.group({ 353 + deviceName: ['', [vm.validators.required]], 354 + deviceType: ['', [vm.validators.required]], 355 + deviceLabel: [''], 356 + attributes: vm.fb.group({ 357 + latitude: [null], 358 + longitude: [null] 359 + }) 360 + }); 361 + 362 + vm.cancel = function() { 363 + vm.dialogRef.close(null); 364 + }; 365 + 366 + vm.save = function() { 367 + vm.editDeviceFormGroup.markAsPristine(); 368 + if (vm.editDeviceFormGroup.get('deviceType').value !== vm.device.type) { 369 + delete vm.device.deviceProfileId; 370 + } 371 + vm.device.name = vm.editDeviceFormGroup.get('deviceName').value, 372 + vm.device.type = vm.editDeviceFormGroup.get('deviceType').value, 373 + vm.device.label = vm.editDeviceFormGroup.get('deviceLabel').value 374 + deviceService.saveDevice(vm.device).subscribe( 375 + function () { 376 + saveAttributes().subscribe( 377 + function () { 378 + widgetContext.updateAliases(); 379 + vm.dialogRef.close(null); 380 + } 381 + ); 382 + } 383 + ); 384 + }; 385 + 386 + getEntityInfo(); 387 + 388 + function getEntityInfo() { 389 + deviceService.getDevice(entityId.id).subscribe( 390 + function (device) { 391 + attributeService.getEntityAttributes(entityId, 'SERVER_SCOPE', 392 + ['latitude', 'longitude']).subscribe( 393 + function (attributes) { 394 + for (let i = 0; i < attributes.length; i++) { 395 + vm.attributes[attributes[i].key] = attributes[i].value; 396 + } 397 + vm.device = device; 398 + vm.editDeviceFormGroup.patchValue( 399 + { 400 + deviceName: vm.device.name, 401 + deviceType: vm.device.type, 402 + deviceLabel: vm.device.label, 403 + attributes: { 404 + latitude: vm.attributes.latitude, 405 + longitude: vm.attributes.longitude 406 + } 407 + }, {emitEvent: false} 408 + ); 409 + } 410 + ); 411 + } 412 + ); 413 + } 414 + 415 + function saveAttributes() { 416 + let attributes = vm.editDeviceFormGroup.get('attributes').value; 417 + let attributesArray = []; 418 + for (let key in attributes) { 419 + attributesArray.push({key: key, value: attributes[key]}); 420 + } 421 + if (attributesArray.length > 0) { 422 + return attributeService.saveEntityAttributes(entityId, 'SERVER_SCOPE', attributesArray); 423 + } else { 424 + return widgetContext.rxjs.of([]); 425 + } 426 + } 427 +} 428 +{{/code}} 429 + 430 +**Delete device:**Implementation function: Device deletion 431 + 432 +[[image:1730771318657-502.png]] 433 + 434 +{{code language="none"}} 435 +let $injector = widgetContext.$scope.$injector; 436 +let dialogs = $injector.get(widgetContext.servicesMap.get('dialogs')); 437 +let deviceService = $injector.get(widgetContext.servicesMap.get('deviceService')); 438 + 439 +openDeleteDeviceDialog(); 440 + 441 +function openDeleteDeviceDialog() { 442 + let title = "Are you sure you want to delete the device " + entityName + "?"; 443 + let content = "Be careful, after the confirmation, the device and all related data will become unrecoverable!"; 444 + dialogs.confirm(title, content, 'Cancel', 'Delete').subscribe( 445 + function (result) { 446 + if (result) { 447 + deleteDevice(); 448 + } 449 + } 450 + ); 451 +} 452 + 453 +function deleteDevice() { 454 + deviceService.deleteDevice(entityId.id).subscribe( 455 + function () { 456 + widgetContext.updateAliases(); 457 + } 458 + ); 459 +} 460 + 461 +{{/code}} 462 + 463 +**jump:I**mplementation function: Jump to the device details page 464 + 465 +[[image:1730771386258-676.png]] 466 + 467 +{{code language="none"}} 468 +console.log(entityName) 469 +var entitySubType; 470 +var $injector = widgetContext.$scope.$injector; 471 +//console.log($injector) 472 +$injector.get(widgetContext.servicesMap.get('entityService')).getEntity(entityId.entityType, entityId.id) 473 + .subscribe(function(data) { 474 + console.log(data) 475 + entitySubType = data.type; 476 + console.log(entitySubType) 477 + if (entitySubType == 'AQS01-dragino-office') { 478 + openDashboardStates('aqs01_detail'); 479 + }else if (entitySubType == 'gateway') { 480 + openDashboardStates('gateway_detail'); 481 + } else if (entitySubType == 'gxhl01') { 482 + openDashboardStates('detail'); 483 + 484 + } else if (entitySubType == 'tank-type1') { 485 + openDashboardStates('test1'); 486 + } 487 + else if (entitySubType == 'LDS12') { 488 + openDashboardStates('lds12_detail'); 489 + } 490 + else if (entitySubType == 'LDS02') { 491 + openDashboardStates('lds02_detail'); 492 + } 493 + else if (entitySubType == 'SE01') { 494 + openDashboardStates('se01_detail'); 495 + } 496 + else if (entitySubType == 'PB01') { 497 + openDashboardStates('pb01_detail'); 498 + } 499 + else if (entitySubType == 'LWL02') { 500 + openDashboardStates('lwl02_detail'); 501 + } 502 + else if (entitySubType == 'LPS8N') { 503 + openDashboardStates('lps8n_detail'); 504 + } 505 + else if (entitySubType == 'LHT65N') { 506 + openDashboardStates('lht65n_detail'); 507 + } 508 + else if (entitySubType == 'S31b') { 509 + openDashboardStates('s31b_detail'); 510 + } 511 + }); 512 + 513 +function openDashboardStates(statedId) { 514 + var stateParams = widgetContext.stateController.getStateParams(); 515 + //console.log(stateParams) 516 + var params = { 517 + entityId: entityId, 518 + entityName: entityName 519 + }; 520 + widgetContext.stateController.updateState(statedId, params, false); 521 +} 522 +{{/code}} 523 + 524 +(% class="wikigeneratedid" id="H-1" %) 525 +**Add device:**Implementation function: Add device 526 + 527 +[[image:1730771441589-122.png]] 528 + 529 +{{code language="none"}} 530 +let $injector = widgetContext.$scope.$injector; 531 +let customDialog = $injector.get(widgetContext.servicesMap.get('customDialog')); 532 +let deviceService = $injector.get(widgetContext.servicesMap.get('deviceService')); 533 +let attributeService = $injector.get(widgetContext.servicesMap.get('attributeService')); 534 + 535 +openAddDeviceDialog(); 536 + 537 +function openAddDeviceDialog() { 538 + customDialog.customDialog(htmlTemplate, AddDeviceDialogController).subscribe(); 539 +} 540 + 541 +function AddDeviceDialogController(instance) { 542 + let vm = instance; 543 + 544 + vm.addDeviceFormGroup = vm.fb.group({ 545 + deviceName: ['', [vm.validators.required]], 546 + deviceType: ['', [vm.validators.required]], 547 + deviceLabel: [''], 548 + attributes: vm.fb.group({ 549 + latitude: [null], 550 + longitude: [null] 551 + }) 552 + }); 553 + 554 + vm.cancel = function() { 555 + vm.dialogRef.close(null); 556 + }; 557 + 558 + vm.save = function() { 559 + vm.addDeviceFormGroup.markAsPristine(); 560 + let device = { 561 + name: vm.addDeviceFormGroup.get('deviceName').value, 562 + type: vm.addDeviceFormGroup.get('deviceType').value, 563 + label: vm.addDeviceFormGroup.get('deviceLabel').value 564 + }; 565 + deviceService.saveDevice(device).subscribe( 566 + function (device) { 567 + saveAttributes(device.id).subscribe( 568 + function () { 569 + widgetContext.updateAliases(); 570 + vm.dialogRef.close(null); 571 + } 572 + ); 573 + } 574 + ); 575 + }; 576 + 577 + function saveAttributes(entityId) { 578 + let attributes = vm.addDeviceFormGroup.get('attributes').value; 579 + let attributesArray = []; 580 + for (let key in attributes) { 581 + attributesArray.push({key: key, value: attributes[key]}); 582 + } 583 + if (attributesArray.length > 0) { 584 + return attributeService.saveEntityAttributes(entityId, "SERVER_SCOPE", attributesArray); 585 + } else { 586 + return widgetContext.rxjs.of([]); 587 + } 588 + } 589 +} 590 +{{/code}} 591 + 592 +==== ==== 593 + 594 +===== 4.1.2.2.3 Asset Alarm: ===== 595 + 596 +**Data:** 597 + 598 +[[image:1730771504586-433.png]] 599 + 600 +==== 4.1.2.3、Configure the first layer menu interface ==== 601 + 602 +===== 4.1.2.3.1 Map: ===== 603 + 604 +**Data:** 605 + 606 +===== ===== 607 + 608 +[[image:1730710271230-716.png||height="729" width="1427"]] 609 + 610 +**Actions**:The map interface has two actions, among which Select supermarket can refresh the device list and related alarms on the right side to enter the location, and Supermarket_detail can jump to the second level physical interface to view the details of the location based on the selected location 611 + 612 +[[image:1730710850458-781.png||height="770" width="1429"]] 613 + 614 +**Select supermarket:**Implementation function: Refresh the side page 615 + 616 +{{code language="none"}} 617 +var params = widgetContext.stateController.getStateParams(); 618 +var selectedSupermarket = params['selectedSupermarket']; 619 +if (selectedSupermarket && selectedSupermarket.entityId.id === entityId.id) { 620 + params['selectedSupermarket'] = null; 621 +} else { 622 + params['selectedSupermarket'] = { entityId: entityId, entityName: entityName, entityLabel: entityLabel }; 623 +} 624 +widgetContext.stateController.updateState(null, params); 625 +{{/code}} 626 + 627 +[[image:1730710875401-848.png||height="767" width="1429"]] 628 + 629 +**Supermarket_detail:**Implementation function: Jump to the asset details page 630 + 631 +{{code language="none"}} 632 +var params = JSON.parse(JSON.stringify(widgetContext.stateController.getStateParams())); 633 +params['selectedSupermarket'] = { 634 + entityId: entityId, 635 + entityName: entityName, 636 + entityLabel: entityLabel, 637 +}; 638 +params['targetEntityParamName'] = 'selectedSupermarket'; 639 +params['selectedDevice'] = null; 640 + 641 +widgetContext.stateController.openState('svgmap', params); 642 +{{/code}} 643 + 644 +[[image:1730710990334-601.png||height="772" width="1433"]] 645 + 646 +* ((( 647 +In this demo, exclusive map icons were set as follows: 648 +))) 649 + 650 +{{code language="none"}} 651 +var res = { 652 + url: images[0], 653 + size: 66 654 +}; 655 +return res; 656 +{{/code}} 657 + 658 +[[image:1730710395303-672.png||height="771" width="1438"]] 659 + 660 +===== 4.1.2.3.1 Asset List: ===== 661 + 662 +**Data:** 663 + 664 +[[image:1730710693066-349.png||height="772" width="1439"]] 665 + 666 +**Actions:**The Assets List interface has an action, which is the same as the Supermarket_details in the Map. You can jump to the second level entity interface to view the details of the selected location based on its location 667 + 668 +[[image:1730712335338-750.png||height="751" width="1423"]] 669 + 670 +[[image:1730712473941-913.png||height="781" width="1422"]] 671 + 672 +All Alarms: 673 + 674 +[[image:1730712539209-554.png||height="764" width="1424"]] 675 + 102 102 == 4.2 Alarm configuration details == 103 103 678 +=== 4.2.1 High temperature === 679 + 680 +Creat: 681 + 682 +[[image:1730862483514-101.png||height="750" width="1407"]] 683 + 684 +Clear: 685 + 686 +[[image:1730862584519-902.png||height="758" width="1404"]] 687 + 688 +=== 4.2.2 Low Temperature === 689 + 690 +Creat: 691 + 692 +[[image:1730863708259-750.png||height="752" width="1403"]] 693 + 694 +Clear: 695 + 696 +[[image:1730863750414-979.png||height="746" width="1403"]] 697 + 698 +=== 4.2.3 High humidity === 699 + 700 +Creat: 701 + 702 +[[image:1730864045747-876.png||height="752" width="1396"]] 703 + 704 +Clear: 705 + 706 +[[image:1730864077395-395.png||height="735" width="1393"]] 707 + 708 +=== 4.2.4 Low humidity === 709 + 710 +Creat: 711 + 712 +[[image:1730864117808-484.png||height="741" width="1392"]] 713 + 714 +Clear: 715 + 716 +[[image:1730864159071-895.png||height="745" width="1392"]] 717 + 718 +=== 4.2.5 Low voltage === 719 + 720 +Creat: 721 + 722 +[[image:1730864207037-477.png||height="740" width="1388"]] 723 + 724 +Clear: 725 + 726 +[[image:1730864250506-111.png||height="735" width="1389"]] 727 + 728 +=== 4.2.6 Device Disconnected === 729 + 730 +Creat: 731 + 732 +[[image:1730864293216-991.png||height="739" width="1387"]] 733 + 734 +Clear: 735 + 736 +[[image:1730864331859-740.png||height="735" width="1385"]] 737 + 104 104 == 4.3 Rule chain configuration details == 105 105 106 -= 5. = 740 +[[image:1730864784118-474.png]] 741 + 742 +**Script:**Email configuration for sending device alarm information 743 + 744 +[[image:1730864676542-406.png||height="732" width="1384"]] 745 + 746 +{{code language="none"}} 747 +function locatime(timenumber){ 748 + var date = new Date(timenumber) 749 + return date.toLocaleDateString() + ' ' + date.toLocaleTimeString() 750 +} 751 +var name = msg.name 752 +var devicename = msg.originatorName 753 +var label = msg.originatorLabel 754 +var status = msg.status 755 +var detaildata =JSON.parse(msg.details.data) 756 +var tempswitch 757 + 758 +if (name != "Device Disconnected") { 759 + //detaildata=JSON.parse(msg.details.data) 760 + if (detaildata.Temperature_alarm_switch == true) { 761 + tempswitch = "open" 762 + } else { 763 + tempswitch = "close" 764 + } 765 + var humswitch 766 + if (detaildata.Humidity_alarm_switch == true) { 767 + humswitch = "open" 768 + } else { 769 + humswitch = "close" 770 + } 771 + var batswitch 772 + if (detaildata.Voltage_alarm_switch == true) { 773 + batswitch = "open" 774 + } else { 775 + batswitch = "close" 776 + } 777 + var str2 = "<p>-- Temperature alarm switch status: " + 778 + tempswitch + "</p>" + 779 + "<p>-- Humidity alarm switch status: " + humswitch + 780 + "</p>" + 781 + "<p>-- Voltage alarm switch status: " + batswitch 782 +} 783 + 784 +if (name == "High Temperature" && status == 785 + "ACTIVE_UNACK") { 786 + var emailstr = 787 + "<div><p><span style='color: black; font-weight: bold'>" + 788 + "Device " + label + " has alarm:</span></p>" + 789 + "<p><span style='color: red; font-weight: bold'>-- High Temperature Alarm</span></p>" + 790 + "<p>-- Current Temperature : " + detaildata 791 + .TempC_SHT + "</p><br>" + 792 + "<p>Device Configure:</p>" + 793 + "<p>-- Temperature Threshold : min: " + detaildata 794 + .Low_temperature_alarm + ", max: " + detaildata 795 + .High_temperature_alarm + "</p>" + 796 + "<p>-- Humidity Threshold: min: " + detaildata 797 + .Low_humidity_alarm + ", max:" + detaildata 798 + .High_humidity_alarm + "</p>" + 799 + "<p>-- Battery threshold: min: " + detaildata 800 + .Low_voltage_alarm + "</p>" + str2 + "</div>" 801 + return { 802 + msg: { 803 + "data": emailstr 804 + }, 805 + metadata: metadata, 806 + msgType: msgType 807 + }; 808 +} else if (name == "Low Temperature" && status == 809 + "ACTIVE_UNACK") { 810 + var emailstr = 811 + "<div><p><span style='color: black; font-weight: bold'>" + 812 + "Device " + label + " has alarm:</span></p>" + 813 + "<p><span style='color: red; font-weight: bold'>-- Low Temperature Alarm</span></p>" + 814 + "<p>-- Current Temperature : " + detaildata 815 + .TempC_SHT + "</p><br>" + 816 + "<p>Device Configure:</p>" + 817 + "<p>-- Temperature Threshold : min: " + detaildata 818 + .Low_temperature_alarm + ", max: " + detaildata 819 + .High_temperature_alarm + "</p>" + 820 + "<p>-- Humidity Threshold: min: " + detaildata 821 + .Low_humidity_alarm + ", max:" + detaildata 822 + .High_humidity_alarm + "</p>" + 823 + "<p>-- Battery threshold: min: " + detaildata 824 + .Low_voltage_alarm + "</p>" + str2 + "</div>" 825 + 826 + return { 827 + msg: { 828 + "data": emailstr 829 + }, 830 + metadata: metadata, 831 + msgType: msgType 832 + }; 833 + 834 +} else if (name == "Device Disconnected" && status == 835 + "ACTIVE_UNACK") { 836 + var time1 = locatime(Number(detaildata.lastActivityTime)) 837 + //var time1 = detaildata.lastActivityTime 838 + // var chazhi = parseInt((detaildata.inactivityAlarmTime-detaildata.lastActivityTime)/1000/60) 839 + // var emailstr = 840 + // "<div><p><span style='color: red; font-weight: bold'>" + 841 + // "Device " + label + " has Alarm</span></p><p>Last activity time: "+time1+"</p><p>Last Uplink: 21"+"minutes ago</p></div>" 842 + 843 + var emailstr ="Device " + label + " has Alarm##Last activity time: "+time1+"##Last Uplink: 21minutes ago" 844 + var newType = "POST_TELEMETRY_REQUEST" 845 + return { 846 + msg:emailstr, 847 + metadata: metadata, 848 + msgType: newType 849 + } 850 +} else if (name == "High humidity" && status == 851 + "ACTIVE_UNACK") { 852 + var emailstr = 853 + "<div><p><span style='color: black; font-weight: bold'>" + 854 + "Device " + label + " has alarm:</span></p>" + 855 + "<p><span style='color: red; font-weight: bold'>-- High Humidity Alarm</span></p>" + 856 + "<p>-- Current Temperature : " + detaildata 857 + .Hum_SHT + "</p><br>" + 858 + "<p>Device Configure:</p>" + 859 + "<p>-- Temperature Threshold : min: " + detaildata 860 + .Low_temperature_alarm + ", max: " + detaildata 861 + .High_temperature_alarm + "</p>" + 862 + "<p>-- Humidity Threshold: min: " + detaildata 863 + .Low_humidity_alarm + ", max:" + detaildata 864 + .High_humidity_alarm + "</p>" + 865 + "<p>-- Battery threshold: min: " + detaildata 866 + .Low_voltage_alarm + "</p>" + str2 + "</div>" 867 + 868 + return { 869 + msg: { 870 + "data": emailstr 871 + }, 872 + metadata: metadata, 873 + msgType: msgType 874 + }; 875 +} else if (name == "Low humidity" && status == 876 + "ACTIVE_UNACK") { 877 + var emailstr = 878 + "<div><p><span style='color: black; font-weight: bold'>" + 879 + "Device " + label + " has alarm:</span></p>" + 880 + "<p><span style='color: red; font-weight: bold'>-- Low Humidity Alarm</span></p>" + 881 + "<p>-- Current Temperature : " + detaildata 882 + .Hum_SHT + "</p><br>" + 883 + "<p>Device Configure:</p>" + 884 + "<p>-- Temperature Threshold : min: " + detaildata 885 + .Low_temperature_alarm + ", max: " + detaildata 886 + .High_temperature_alarm + "</p>" + 887 + "<p>-- Humidity Threshold: min: " + detaildata 888 + .Low_humidity_alarm + ", max:" + detaildata 889 + .High_humidity_alarm + "</p>" + 890 + "<p>-- Battery threshold: min: " + detaildata 891 + .Low_voltage_alarm + "</p>" + str2 + "</div>" 892 + 893 + return { 894 + msg: { 895 + "data": emailstr 896 + }, 897 + metadata: metadata, 898 + msgType: msgType 899 + }; 900 +} else if (name == "Low voltage" && status == 901 + "ACTIVE_UNACK") { 902 + var emailstr = 903 + "<div><p><span style='color: black; font-weight: bold'>" + 904 + "Device " + label + " has alarm:</span></p>" + 905 + "<p><span style='color: red; font-weight: bold'>-- Low Voltage Alarm</span></p>" + 906 + "<p>-- Current Temperature : " + detaildata.BatV + 907 + "</p><br>" + 908 + "<p>Device Configure:</p>" + 909 + "<p>-- Temperature Threshold : min: " + detaildata 910 + .Low_temperature_alarm + ", max: " + detaildata 911 + .High_temperature_alarm + "</p>" + 912 + "<p>-- Humidity Threshold: min: " + detaildata 913 + .Low_humidity_alarm + ", max:" + detaildata 914 + .High_humidity_alarm + "</p>" + 915 + "<p>-- Battery threshold: min: " + detaildata 916 + .Low_voltage_alarm + "</p>" + str2 + "</div>" 917 + 918 + return { 919 + msg: { 920 + "data": emailstr 921 + }, 922 + metadata: metadata, 923 + msgType: msgType 924 + }; 925 +} else if (name == "High Temperature" && status == 926 + "CLEARED_UNACK") { 927 + var emailstr = 928 + "<div><p><span style='color: green; font-weight: bold'>Device " + 929 + label + 930 + " High Temperature Alarm Cleared</span></p>" + 931 + "<p>-- Current Temperature : " + detaildata 932 + .TempC_SHT + "</p><br>" + 933 + "<p>Device Configure:</p>" + 934 + "<p>-- Temperature Threshold : min: " + detaildata 935 + .Low_temperature_alarm + ", max: " + detaildata 936 + .High_temperature_alarm + "</p>" + 937 + "<p>-- Humidity Threshold: min: " + detaildata 938 + .Low_humidity_alarm + ", max:" + detaildata 939 + .High_humidity_alarm + "</p>" + 940 + "<p>-- Battery threshold: min: " + detaildata 941 + .Low_voltage_alarm + "</p>" + str2 + "</div>" 942 + 943 + return { 944 + msg: { 945 + "data": emailstr 946 + }, 947 + metadata: metadata, 948 + msgType: msgType 949 + }; 950 +} else if (name == "Low Temperature" && status == 951 + "CLEARED_UNACK") { 952 + var emailstr = 953 + "<div><p><span style='color: green; font-weight: bold'>Device " + 954 + label + 955 + " Low Temperature Alarm Cleared</span></p>" + 956 + "<p>-- Current Temperature : " + detaildata 957 + .TempC_SHT + "</p><br>" + 958 + "<p>Device Configure:</p>" + 959 + "<p>-- Temperature Threshold : min: " + detaildata 960 + .Low_temperature_alarm + ", max: " + detaildata 961 + .High_temperature_alarm + "</p>" + 962 + "<p>-- Humidity Threshold: min: " + detaildata 963 + .Low_humidity_alarm + ", max:" + detaildata 964 + .High_humidity_alarm + "</p>" + 965 + "<p>-- Battery threshold: min: " + detaildata 966 + .Low_voltage_alarm + "</p>" + str2 + "</div>" 967 + 968 + return { 969 + msg: { 970 + "data": emailstr 971 + }, 972 + metadata: metadata, 973 + msgType: msgType 974 + }; 975 +} else if (name == "High humidity" && status == 976 + "CLEARED_UNACK") { 977 + var emailstr = 978 + "<div><p><span style='color: green; font-weight: bold'>Device " + 979 + label + " High Humidity Alarm Cleared</span></p>" + 980 + "<p>-- Current Temperature : " + detaildata 981 + .Hum_SHT + "</p><br>" + 982 + "<p>Device Configure:</p>" + 983 + "<p>-- Temperature Threshold : min: " + detaildata 984 + .Low_temperature_alarm + ", max: " + detaildata 985 + .High_temperature_alarm + "</p>" + 986 + "<p>-- Humidity Threshold: min: " + detaildata 987 + .Low_humidity_alarm + ", max:" + detaildata 988 + .High_humidity_alarm + "</p>" + 989 + "<p>-- Battery threshold: min: " + detaildata 990 + .Low_voltage_alarm + "</p>" + str2 + "</div>" 991 + 992 + return { 993 + msg: { 994 + "data": emailstr 995 + }, 996 + metadata: metadata, 997 + msgType: msgType 998 + }; 999 +} else if (name == "Low humidity" && status == 1000 + "CLEARED_UNACK") { 1001 + var emailstr = 1002 + "<div><p><span style='color: green; font-weight: bold'>Device " + 1003 + label + " Low Humidity Alarm Cleared</span></p>" + 1004 + "<p>-- Current Temperature : " + detaildata 1005 + .Hum_SHT + "</p><br>" + 1006 + "<p>Device Configure:</p>" + 1007 + "<p>-- Temperature Threshold : min: " + detaildata 1008 + .Low_temperature_alarm + ", max: " + detaildata 1009 + .High_temperature_alarm + "</p>" + 1010 + "<p>-- Humidity Threshold: min: " + detaildata 1011 + .Low_humidity_alarm + ", max:" + detaildata 1012 + .High_humidity_alarm + "</p>" + 1013 + "<p>-- Battery threshold: min: " + detaildata 1014 + .Low_voltage_alarm + "</p>" + str2 + "</div>" 1015 + return { 1016 + msg: { 1017 + "data": emailstr 1018 + }, 1019 + metadata: metadata, 1020 + msgType: msgType 1021 + }; 1022 +} else if (name == "Low voltage" && status == 1023 + "CLEARED_UNACK") { 1024 + 1025 + var emailstr = 1026 + "<div><p><span style='color: green; font-weight: bold'>Device " + 1027 + label + " Low Voltage Alarm Cleared</span></p>" + 1028 + "<p>-- Current Temperature : " + detaildata.BatV + 1029 + "</p><br><br>" + 1030 + "<p>Device Configure:</p>" + 1031 + "<p>-- Temperature Threshold : min: " + detaildata 1032 + .Low_temperature_alarm + ", max: " + detaildata 1033 + .High_temperature_alarm + "</p>" + 1034 + "<p>-- Humidity Threshold: min: " + detaildata 1035 + .Low_humidity_alarm + ", max:" + detaildata 1036 + .High_humidity_alarm + "</p>" + 1037 + "<p>-- Battery threshold: min: " + detaildata 1038 + .Low_voltage_alarm + "</p>" + str2 + "</div>" 1039 + 1040 + return { 1041 + msg: { 1042 + "data": emailstr 1043 + }, 1044 + metadata: metadata, 1045 + msgType: msgType 1046 + }; 1047 +} else if (name == "Device Disconnected" && status == 1048 + "CLEARED_UNACK") { 1049 + var time1 = locatime(Number(detaildata.lastActivityTime)) 1050 + //var time1 = detaildata.lastActivityTime 1051 + // var chazhi = parseInt((detaildata.inactivityAlarmTime-detaildata.lastActivityTime)/1000/60) 1052 + // var emailstr = 1053 + // "<div><p><span style='color: green; font-weight: bold'>" + 1054 + // "Device " + label + " has Alarm Cleared</span></p><p>Last activity time: "+time1+"</p></div>" 1055 + var emailstr ="Device " + label + " has Alarm Cleared##Last activity time: "+time1 1056 + var newType = "POST_TELEMETRY_REQUEST" 1057 + return { 1058 + msg: emailstr, 1059 + metadata: metadata, 1060 + msgType: newType 1061 + } 1062 +} 1063 +{{/code}} 1064 + 1065 +(% class="wikigeneratedid" %) 1066 +**Generate Report:** 1067 + 1068 +(% class="wikigeneratedid" %) 1069 +[[image:1730865053380-293.png]] 1070 + 1071 += 5.other = 1072 + 1073 +* If you want to create a similar dashboard, after understanding the case, you can download and import the dashboard, device profiles, rule chains, etc. of the case on GitHub, and make modifications based on them. 1074 +* GitHub address:[[https:~~/~~/github.com/ThingsEye-io/te-platform/tree/main/case/Dragino%20Office%20%26%20Factory>>https://github.com/ThingsEye-io/te-platform/tree/main/case/Dragino%20Office%20%26%20Factory]]
- 1730709382428-730.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +480.8 KB - Content
- 1730709409941-536.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +451.5 KB - Content
- 1730709424998-915.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +443.4 KB - Content
- 1730709442773-502.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +448.3 KB - Content
- 1730709461297-207.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +458.2 KB - Content
- 1730709479828-595.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +450.7 KB - Content
- 1730709511861-439.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +470.0 KB - Content
- 1730709527720-418.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +475.8 KB - Content
- 1730709542597-321.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +474.8 KB - Content
- 1730709555797-383.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +463.2 KB - Content
- 1730710271230-716.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.5 MB - Content
- 1730710395303-672.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.6 MB - Content
- 1730710693066-349.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +94.4 KB - Content
- 1730710850458-781.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.5 MB - Content
- 1730710875401-848.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.0 MB - Content
- 1730710949358-671.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.0 MB - Content
- 1730710990334-601.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.0 MB - Content
- 1730712335338-750.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +77.1 KB - Content
- 1730712473941-913.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +135.9 KB - Content
- 1730712539209-554.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +131.0 KB - Content
- 1730770392454-317.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +195.6 KB - Content
- 1730770636230-829.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +290.6 KB - Content
- 1730770875793-351.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +305.2 KB - Content
- 1730771103096-522.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +197.9 KB - Content
- 1730771199343-553.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +108.5 KB - Content
- 1730771228766-212.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +46.8 KB - Content
- 1730771256045-238.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +69.1 KB - Content
- 1730771318657-502.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +60.4 KB - Content
- 1730771386258-676.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +46.4 KB - Content
- 1730771441589-122.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +57.6 KB - Content
- 1730771504586-433.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +151.2 KB - Content
- 1730857191863-514.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +354.7 KB - Content
- 1730857537965-184.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +455.1 KB - Content
- 1730857750749-240.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +285.9 KB - Content
- 1730862483514-101.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +195.8 KB - Content
- 1730862584519-902.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +191.1 KB - Content
- 1730863708259-750.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +220.1 KB - Content
- 1730863750414-979.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +210.6 KB - Content
- 1730864045747-876.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +208.9 KB - Content
- 1730864077395-395.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +201.4 KB - Content
- 1730864117808-484.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +203.0 KB - Content
- 1730864159071-895.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +226.6 KB - Content
- 1730864207037-477.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +215.3 KB - Content
- 1730864250506-111.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +209.5 KB - Content
- 1730864293216-991.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +138.5 KB - Content
- 1730864331859-740.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +134.4 KB - Content
- 1730864460314-611.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +256.7 KB - Content
- 1730864617480-221.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +260.8 KB - Content
- 1730864676542-406.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +227.7 KB - Content
- 1730864784118-474.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +148.8 KB - Content
- 1730865053380-293.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +46.7 KB - Content
- 屏幕截图 2024-11-04 135045.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +29.4 KB - Content