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