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, 0 added, 57 removed)
- 1730702565889-204.png
- 1730702622551-808.png
- 1730702656725-496.png
- 1730702688377-367.png
- 1730702814435-805.png
- 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,6 +4,3 @@ 1 - 2 - 3 - 4 4 = 1. About this demo = 5 5 6 6 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. ... ... @@ -17,1058 +17,101 @@ 17 17 The rest of this chapter will provide the introduction for how to set up similiar solution. 18 18 19 19 20 -= 2. Basic configurationinstructions=17 += 2. Set up a similiar dashboard = 21 21 22 -When you start a complex IoT project, you first need to learn some basic configuration methods for ThingsEye. 23 23 24 - Herearesomeinstructionsyouneedtoknow:20 +== 2.1 Creat the dashboard and add branch == 25 25 26 - Dashboardcreation and some basic configurations:[[https:~~/~~/wiki.thingseye.io/xwiki/bin/view/Main/How%20to%20import%20and%20use%20the%20dashboard%3F/#H3.2.2.1CreatA0alarm>>https://wiki.thingseye.io/xwiki/bin/view/Main/How%20to%20import%20and%20use%20the%20dashboard%3F/#H3.2.2.1CreatA0alarm]]22 +=== 2.1.1 Create Dashboard === 27 27 28 - Rule chain creation:[[https:~~/~~/wiki.thingseye.io/xwiki/bin/view/Main/Basic%20configuration%20of%20rule%20chains>>https://wiki.thingseye.io/xwiki/bin/view/Main/Basic%20configuration%20of%20rule%20chains/]]24 +[[image:1730340927404-430.png]] 29 29 30 -Devices connected to thingseye:[[https:~~/~~/wiki.thingseye.io/xwiki/bin/view/Main/How%20to%20connect%20my%20devices%20to%20ThingsEye%3F/>>https://wiki.thingseye.io/xwiki/bin/view/Main/How%20to%20connect%20my%20devices%20to%20ThingsEye%3F/]] 31 31 32 - = 3.overview =27 +[[image:1730340927412-610.png]] 33 33 34 - == 3.1 MHierarchicalarchitectureorefeatures ==29 +Assigning users and groups is not necessary and can be done uniformly after completing the overall project creation 35 35 36 - Beforewestart a project, we first needto understandthe organizationalstructure of the project. Only withaclear outlinecan our project construction process be smoother31 +== 2.2 Add a branch == 37 37 38 -**Assets:**Dragino Office 、Dragino Factory 39 39 40 -**Devices:** 41 41 42 - Dragino Factory:temperatureand humidity measurement×7、Gateway×135 +[[image:1730341060305-544.png]] 43 43 44 - DraginoOffice:temperature and humiditymeasurement×2、Airqualitymeasurement×437 +How many interfaces do you need to display, and how many statuses you need to create. 45 45 46 - == 3.2 Dashboard architecture ==39 +[[image:1730341060308-892.png]] 47 47 48 - Inthisdemo,thedashboard isdividedintothree layers,namely:home page,asset, and device.41 +After creating the branch, you can add widgets into your dashboard and decorate it. 49 49 50 - **home page:**It includes threeparts: map, asset list, and all alarm. From this interface, you can see how many factories, offices, and so on there are43 +[[image:1730341060310-449.png]] 51 51 52 - **asset:**Itincludes three parts: asset map, device list, and asset alarm.From this interface,you can see how manysensorsare deployed in the office or project, where they are located, and their alarm status45 +== 2.3 Connect Sensors == 53 53 54 - **device:**Thissectiondisplaysthe specific informationcollected by the device, and different typesf sensorshave different display interfaces47 +=== 2.3.1 Add LoRaWAN Sensors === 55 55 56 - [[image:屏幕截图2024-11-04134645.png]]49 +=== 2.3.2 Add NB-IoT Sensors === 57 57 58 - Firstfloor:51 +== 2.4 Creat group and add device == 59 59 60 -[[image:1730 702565889-204.png||height="771" width="1445"]]53 +[[image:1730341200415-449.png]] 61 61 62 - Second floor:55 +[[image:1730341200420-412.png]] 63 63 64 -[[image:1730 702622551-808.png||height="756" width="1450"]]57 +[[image:1730341200421-190.png]] 65 65 66 - Third floor:59 +[[image:1730341200424-882.png]] 67 67 68 - [[image:1730702656725-496.png||height="775"width="1455"]]61 +== 2.5 Creat entity alias and connect == 69 69 70 - [[image:1730702814435-805.png||height="797"width="1458"]]63 +=== 2.5.1 Creat entity alias === 71 71 65 +[[image:1730341268104-527.png]] 72 72 73 -[[image:1730 702688377-367.png||height="770" width="1462"]]67 +[[image:1730341268106-565.png]] 74 74 75 -* How many types of devices do you need, how many layers of third level dashboards you need to create. 76 76 77 -== 3.3 Alarmrules==70 +=== 2.5.2 Connect entity === 78 78 79 - High Temperature、Low Temperature、High humidity、Low humidity、Low voltage、Device Disconnected72 +[[image:1730341268108-632.png]] 80 80 81 - [[image:屏幕截图2024-11-04 135045.png]]74 +== 2.6 Creat actions == 82 82 83 - =4.configuration details =76 +[[image:1730341395062-192.png]] 84 84 85 - After understanding thearchitecture and layeringof thecomplete project, we canstart configuring it78 +[[image:1730341395069-644.png]] 86 86 87 -= =4.1 Dashboard configuration details==80 += 3.Set up Alarm = 88 88 89 -== =4.1.1.Datasource(Entity aliases)===82 +== 3.1 Creat device profiles == 90 90 91 - detail:Obtain data based ondashboardstatus84 +[[image:1730341507235-819.png||height="636" width="1260"]] 92 92 93 - [[image:1730709424998-915.png||height="729"width="1436"]]86 +== 3.2 Set up Alarm == 94 94 95 - Alarm:Obtainalarminformation88 +[[image:1730341543316-750.png||height="629" width="1260"]] 96 96 97 -[[image:1730 709479828-595.png||height="696" width="1435"]]90 +[[image:1730341543319-574.png]] 98 98 99 -Dragino&GXHL,Ltd:Obtain data through asset types 100 100 101 - [[image:1730709511861-439.png||height="714"width="1435"]]93 +== 3.3 replace device profile == 102 102 103 - Selected Supermarket:Retrievedevices bydevicetype95 +[[image:1730341567947-831.png||height="629" width="1266"]] 104 104 105 - [[image:1730709527720-418.png||height="751"width="1433"]]97 += 4. create rule chain = 106 106 107 - SupermarketDevices:Obtain datathrough devicetype99 +== 4.1 creat rule chain == 108 108 109 -[[image:1730 709555797-383.png||height="726" width="1434"]]101 += [[image:1730341620059-499.png||height="621" width="1263"]] = 110 110 111 - LHT65NDevice:Obtain data based ondevicetype103 += [[image:1730341620061-922.png||height="612" width="1263"]] = 112 112 113 - [[image:1730857191863-514.png||height="725"width="1433"]]105 +Regarding the rule chain, you can see the relevant explanation below: 114 114 115 -=== 4.1.2.Page Configuration === 116 116 117 -== ==4.1.2.1、Configurethe interfaceof the thirdlayerDavies.====108 +== 4.2 replace rule chain == 118 118 119 - ====4.1.2.2、Configure thenterfaceof the secondlayer asset===110 +[[image:1730341620064-656.png||height="628" width="1265"]] 120 120 121 -= ====4.1.2.2.1Equipmentdistribution diagram:=====112 += 5. More features = 122 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 - 676 -== 4.2 Alarm configuration details == 677 - 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 - 738 -== 4.3 Rule chain configuration details == 739 - 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]] 114 +
- 1730702565889-204.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -786.9 KB - Content
- 1730702622551-808.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -258.2 KB - Content
- 1730702656725-496.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -522.8 KB - Content
- 1730702688377-367.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -92.0 KB - Content
- 1730702814435-805.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -74.0 KB - Content
- 1730709382428-730.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -480.8 KB - Content
- 1730709409941-536.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -451.5 KB - Content
- 1730709424998-915.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -443.4 KB - Content
- 1730709442773-502.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -448.3 KB - Content
- 1730709461297-207.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -458.2 KB - Content
- 1730709479828-595.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -450.7 KB - Content
- 1730709511861-439.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -470.0 KB - Content
- 1730709527720-418.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -475.8 KB - Content
- 1730709542597-321.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -474.8 KB - Content
- 1730709555797-383.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -463.2 KB - Content
- 1730710271230-716.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -1.5 MB - Content
- 1730710395303-672.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -1.6 MB - Content
- 1730710693066-349.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -94.4 KB - Content
- 1730710850458-781.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -1.5 MB - Content
- 1730710875401-848.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -1.0 MB - Content
- 1730710949358-671.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -1.0 MB - Content
- 1730710990334-601.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -1.0 MB - Content
- 1730712335338-750.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -77.1 KB - Content
- 1730712473941-913.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -135.9 KB - Content
- 1730712539209-554.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -131.0 KB - Content
- 1730770392454-317.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -195.6 KB - Content
- 1730770636230-829.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -290.6 KB - Content
- 1730770875793-351.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -305.2 KB - Content
- 1730771103096-522.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -197.9 KB - Content
- 1730771199343-553.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -108.5 KB - Content
- 1730771228766-212.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -46.8 KB - Content
- 1730771256045-238.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -69.1 KB - Content
- 1730771318657-502.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -60.4 KB - Content
- 1730771386258-676.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -46.4 KB - Content
- 1730771441589-122.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -57.6 KB - Content
- 1730771504586-433.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -151.2 KB - Content
- 1730857191863-514.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -354.7 KB - Content
- 1730857537965-184.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -455.1 KB - Content
- 1730857750749-240.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -285.9 KB - Content
- 1730862483514-101.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -195.8 KB - Content
- 1730862584519-902.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -191.1 KB - Content
- 1730863708259-750.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -220.1 KB - Content
- 1730863750414-979.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -210.6 KB - Content
- 1730864045747-876.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -208.9 KB - Content
- 1730864077395-395.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -201.4 KB - Content
- 1730864117808-484.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -203.0 KB - Content
- 1730864159071-895.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -226.6 KB - Content
- 1730864207037-477.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -215.3 KB - Content
- 1730864250506-111.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -209.5 KB - Content
- 1730864293216-991.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -138.5 KB - Content
- 1730864331859-740.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -134.4 KB - Content
- 1730864460314-611.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -256.7 KB - Content
- 1730864617480-221.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -260.8 KB - Content
- 1730864676542-406.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -227.7 KB - Content
- 1730864784118-474.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -148.8 KB - Content
- 1730865053380-293.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -46.7 KB - Content
- 屏幕截图 2024-11-04 135045.png
-
- Author
-
... ... @@ -1,1 +1,0 @@ 1 -XWiki.hera - Size
-
... ... @@ -1,1 +1,0 @@ 1 -29.4 KB - Content