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