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