extension-form-mqtt.tpl.html 99.8 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
<!--

    Copyright © 2016-2019 The Thingsboard Authors

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<md-card class="extension-form extension-mqtt">
    <md-card-title name="testValid">
        <md-card-title-text>
            <span translate class="md-headline">extension.configuration</span>
        </md-card-title-text>
    </md-card-title>
    <md-card-content>
        <v-accordion id="mqtt-brokers-accordion" class="vAccordion--default" onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
            <v-pane id="mqtt-brokers-pane" expanded="true">
                <v-pane-header>
                    {{ 'extension.brokers' | translate }}
                </v-pane-header>
                <v-pane-content>
                    <div ng-if="brokers.length > 0">
                        <ol class="list-group">
                            <li class="list-group-item" ng-repeat="(brokerIndex,broker) in brokers">
                                <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeBroker(broker)" ng-hide="brokers.length < 2">
                                    <ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon>
                                    <md-tooltip md-direction="top">
                                        {{ 'action.remove' | translate }}
                                    </md-tooltip>
                                </md-button>
                                <md-card>
                                    <md-card-content>
                                        <section flex layout="row">
                                            <md-input-container flex="40" class="md-block">
                                                <label translate>extension.port</label>
                                                <input required type="number" min="1" max="65535" name="mqttPort_{{brokerIndex}}" ng-model="broker.port">
                                                <div ng-messages="theForm['mqttPort_' + brokerIndex].$error">
                                                    <div translate ng-message="required">extension.field-required</div>
                                                    <div translate ng-message="min">extension.port-range</div>
                                                    <div translate ng-message="max">extension.port-range</div>
                                                </div>
                                            </md-input-container>
                                            <md-input-container flex="60" class="md-block">
                                                <label translate>extension.host</label>
                                                <input required name="mqttHost_{{brokerIndex}}" ng-model="broker.host">
                                                <div ng-messages="theForm['mqttHost_' + brokerIndex].$error">
                                                    <div translate ng-message="required">extension.field-required</div>
                                                </div>
                                            </md-input-container>
                                        </section>
                                        <section flex layout="row">
                                            <md-input-container flex="40" class="md-block">
                                                <label translate>extension.retry-interval</label>
                                                <input required type="number" name="mqttRetryInterval_{{brokerIndex}}" ng-model="broker.retryInterval">
                                                <div ng-messages="theForm['mqttRetryInterval_' + brokerIndex].$error">
                                                    <div translate ng-message="required">extension.field-required</div>
                                                </div>
                                            </md-input-container>
                                            <md-input-container flex="50" class="md-block">
                                                <label translate>extension.credentials</label>
                                                <md-select required name="mqttCredentials_{{brokerIndex}}" ng-model="broker.credentials.type" ng-change="changeCredentials(broker)">
                                                    <md-option ng-repeat="(credentialsType, credentialsValue) in types.mqttCredentialTypes" ng-value="credentialsValue.value">
                                                        {{credentialsValue.name | translate}}
                                                    </md-option>
                                                </md-select>
                                            </md-input-container>
                                            <md-input-container flex="10" class="md-block">
                                                <md-checkbox flex aria-label="{{ 'extension.ssl' | translate }}"
                                                             ng-model="broker.ssl">{{ 'extension.ssl' | translate }}
                                                </md-checkbox>
                                            </md-input-container>
                                        </section>
                                        <section flex layout="row" ng-if='broker.credentials.type == "basic"'>
                                            <md-input-container flex="40" class="md-block" md-is-error="theForm['mqttUsername_' + brokerIndex].$touched && theForm['mqttUsername_' + brokerIndex].$invalid">
                                                <label translate>extension.username</label>
                                                <input required name="mqttUsername_{{brokerIndex}}" ng-model="broker.credentials.username">
                                                <div ng-messages="theForm['mqttUsername_' + brokerIndex].$error">
                                                    <div translate ng-message="required">extension.field-required</div>
                                                </div>
                                            </md-input-container>
                                            <md-input-container flex="60" class="md-block" md-is-error="theForm['mqttPassword_' + brokerIndex].$touched && theForm['mqttPassword_' + brokerIndex].$invalid">
                                                <label translate>extension.password</label>
                                                <input required name="mqttPassword_{{brokerIndex}}" ng-model="broker.credentials.password">
                                                <div ng-messages="theForm['mqttPassword_' + brokerIndex].$error">
                                                    <div translate ng-message="required">extension.field-required</div>
                                                </div>
                                            </md-input-container>
                                        </section>
                                        <section flex layout="column" ng-if='broker.credentials.type == "cert.PEM"' class="dropdown-section">
                                            <div class="tb-container" ng-class="broker.credentials.caCertFileName ? 'ng-valid' : 'ng-invalid'">
                                                <label class="tb-label" translate>extension.ca-cert</label>
                                                <div flow-init="{singleFile:true}" flow-file-added='fileAdded($file, broker, "caCert")' class="tb-file-select-container">
                                                    <div class="tb-file-clear-container">
                                                        <md-button ng-click='clearFile(broker, "caCert")' class="tb-file-clear-btn md-icon-button md-primary" aria-label="{{ 'action.remove' | translate }}">
                                                            <md-tooltip md-direction="top">
                                                                {{ 'action.remove' | translate }}
                                                            </md-tooltip>
                                                            <md-icon aria-label="{{ 'action.remove' | translate }}" class="material-icons">close</md-icon>
                                                        </md-button>
                                                    </div>
                                                    <div class="alert tb-flow-drop" flow-drop>
                                                        <label for="caCertSelect_{{brokerIndex}}" translate>extension.drop-file</label>
                                                        <input class="file-input" flow-btn flow-attrs="{accept:'.pem'}" id="caCertSelect_{{brokerIndex}}">
                                                    </div>
                                                </div>
                                            </div>
                                            <div class="dropdown-messages">
                                                <div ng-if="!broker.credentials.caCertFileName" class="tb-error-message" translate>extension.no-file</div>
                                                <div ng-if="broker.credentials.caCertFileName">{{broker.credentials.caCertFileName}}</div>
                                            </div>
                                            <div class="tb-container" ng-class="broker.credentials.privateKeyFileName ? 'ng-valid' : 'ng-invalid'">
                                                <label class="tb-label" translate>extension.private-key</label>
                                                <div flow-init="{singleFile:true}" flow-file-added='fileAdded($file, broker, "privateKey")' class="tb-file-select-container">
                                                    <div class="tb-file-clear-container">
                                                        <md-button ng-click='clearFile(broker, "privateKey")' class="tb-file-clear-btn md-icon-button md-primary" aria-label="{{ 'action.remove' | translate }}">
                                                            <md-tooltip md-direction="top">
                                                                {{ 'action.remove' | translate }}
                                                            </md-tooltip>
                                                            <md-icon aria-label="{{ 'action.remove' | translate }}" class="material-icons">close</md-icon>
                                                        </md-button>
                                                    </div>
                                                    <div class="alert tb-flow-drop" flow-drop>
                                                        <label for="privateKeySelect_{{brokerIndex}}" translate>extension.drop-file</label>
                                                        <input class="file-input" flow-btn flow-attrs="{accept:'.pem'}" id="privateKeySelect_{{brokerIndex}}">
                                                    </div>
                                                </div>
                                            </div>
                                            <div class="dropdown-messages">
                                                <div ng-if="!broker.credentials.privateKeyFileName" class="tb-error-message" translate>extension.no-file</div>
                                                <div ng-if="broker.credentials.privateKeyFileName">{{broker.credentials.privateKeyFileName}}</div>
                                            </div>
                                            <div class="tb-container" ng-class="broker.credentials.certFileName ? 'ng-valid' : 'ng-invalid'">
                                                <label class="tb-label" translate>extension.cert</label>
                                                <div flow-init="{singleFile:true}" flow-file-added='fileAdded($file, broker, "Cert")' class="tb-file-select-container">
                                                    <div class="tb-file-clear-container">
                                                        <md-button ng-click='clearFile(broker, "Cert")' class="tb-file-clear-btn md-icon-button md-primary" aria-label="{{ 'action.remove' | translate }}">
                                                            <md-tooltip md-direction="top">
                                                                {{ 'action.remove' | translate }}
                                                            </md-tooltip>
                                                            <md-icon aria-label="{{ 'action.remove' | translate }}" class="material-icons">close</md-icon>
                                                        </md-button>
                                                    </div>
                                                    <div class="alert tb-flow-drop" flow-drop>
                                                        <label for="CertSelect_{{brokerIndex}}" translate>extension.drop-file</label>
                                                        <input class="file-input" flow-btn flow-attrs="{accept:'.pem'}" id="CertSelect_{{brokerIndex}}">
                                                    </div>
                                                </div>
                                            </div>
                                            <div class="dropdown-messages">
                                                <div ng-if="!broker.credentials.certFileName" class="tb-error-message" translate>extension.no-file</div>
                                                <div ng-if="broker.credentials.certFileName">{{broker.credentials.certFileName}}</div>
                                            </div>
                                        </section>

                                        <v-accordion id="mqtt-mapping-accordion" class="vAccordion--default" onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
                                            <v-pane id="mqtt-mapping-pane_{{brokerIndex}}">
                                                <v-pane-header>
                                                    {{ 'extension.mapping' | translate }}
                                                </v-pane-header>
                                                <v-pane-content>
                                                    <div ng-if="broker.mapping.length > 0">
                                                        <ol class="list-group">
                                                            <li class="list-group-item" ng-repeat="(mapIndex,map) in broker.mapping">
                                                                <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeMap(map, broker.mapping)">
                                                                    <ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon>
                                                                    <md-tooltip md-direction="top">
                                                                        {{ 'action.remove' | translate }}
                                                                    </md-tooltip>
                                                                </md-button>
                                                                <md-card>
                                                                    <md-card-content>
                                                                        <section flex layout="row">
                                                                            <md-input-container flex="40" class="md-block" md-is-error="theForm['mqttConverterType_' + brokerIndex + mapIndex].$touched && theForm['mqttConverterType_' + brokerIndex + mapIndex].$invalid">
                                                                                <label translate>extension.converter-type</label>
                                                                                <md-select required name="mqttConverterType_{{brokerIndex}}{{mapIndex}}" ng-model="map.converterType" ng-change="changeConverterType(map)">
                                                                                    <md-option ng-repeat="(converterType, value) in types.mqttConverterTypes" ng-value="converterType">
                                                                                        {{value | translate}}
                                                                                    </md-option>
                                                                                </md-select>
                                                                                <div ng-messages="theForm['mqttConverterType_' + brokerIndex + mapIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container flex="60" class="md-block">
                                                                                <label translate>extension.topic-filter</label>
                                                                                <input required name="mqttTopicFilter_{{brokerIndex}}{{mapIndex}}" ng-model="map.topicFilter">
                                                                                <div ng-messages="theForm['mqttTopicFilter_' + brokerIndex + mapIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                        </section>

                                                                        <div ng-if='map.converterType =="json"' ng-init="map.converter.type = 'json'">
                                                                            <section flex layout="row">
                                                                                <md-input-container flex="40" class="md-block" md-is-error="theForm['mqttDeviceNameExpression_' + brokerIndex + mapIndex].$touched && theForm['mqttDeviceNameExpression_' + brokerIndex + mapIndex].$invalid">
                                                                                    <label translate>extension.device-name-expression</label>
                                                                                    <md-select required name="mqttDeviceNameExpression_{{brokerIndex}}{{mapIndex}}" ng-model="map.converter.nameExp" ng-change="changeNameExpression(map.converter)">
                                                                                        <md-option ng-repeat="(key, value) in deviceNameExpressions" ng-value='key'>
                                                                                            {{value | translate}}
                                                                                        </md-option>
                                                                                    </md-select>
                                                                                    <div ng-messages="theForm['mqttDeviceNameExpression_' + brokerIndex + mapIndex].$error">
                                                                                        <div translate ng-message="required">extension.field-required</div>
                                                                                    </div>
                                                                                </md-input-container>
                                                                                <md-input-container ng-if="map.converter.nameExp == 'deviceNameJsonExpression'" flex="60" class="md-block" md-is-error="theForm['mqttJsonNameExp_' + brokerIndex + mapIndex].$touched && theForm['mqttJsonNameExp_' + brokerIndex + mapIndex].$invalid">
                                                                                    <label translate>extension.json-name-expression</label>
                                                                                    <input required name="mqttJsonNameExp_{{brokerIndex}}{{mapIndex}}" ng-model="map.converter.deviceNameJsonExpression">
                                                                                    <div ng-messages="theForm['mqttJsonNameExp_' + brokerIndex + mapIndex].$error">
                                                                                        <div translate ng-message="required">extension.field-required</div>
                                                                                    </div>
                                                                                </md-input-container>
                                                                                <md-input-container ng-if="map.converter.nameExp == 'deviceNameTopicExpression'" flex="60" class="md-block" md-is-error="theForm['mqttTopicNameExp_' + brokerIndex + mapIndex].$touched && theForm['mqttTopicNameExp_' + brokerIndex + mapIndex].$invalid">
                                                                                    <label translate>extension.topic-name-expression</label>
                                                                                    <input required name="mqttTopicNameExp_{{brokerIndex}}{{mapIndex}}" ng-model="map.converter.deviceNameTopicExpression">
                                                                                    <div ng-messages="theForm['mqttTopicNameExp_' + brokerIndex + mapIndex].$error">
                                                                                        <div translate ng-message="required">extension.field-required</div>
                                                                                    </div>
                                                                                </md-input-container>
                                                                            </section>
                                                                            <section flex layout="row">
                                                                                <md-input-container flex="40" class="md-block" md-is-error="theForm['mqttDeviceTypeExpression_' + brokerIndex + mapIndex].$touched && theForm['mqttDeviceTypeExpression_' + brokerIndex + mapIndex].$invalid">
                                                                                    <label translate>extension.device-type-expression</label>
                                                                                    <md-select required name="mqttDeviceTypeExpression_{{brokerIndex}}{{mapIndex}}" ng-model="map.converter.typeExp" ng-change="changeTypeExpression(map.converter)">
                                                                                        <md-option ng-repeat="(key, value) in deviceTypeExpressions" ng-value='key'>
                                                                                            {{value | translate}}
                                                                                        </md-option>
                                                                                    </md-select>
                                                                                    <div ng-messages="theForm['mqttDeviceTypeExpression_' + brokerIndex + mapIndex].$error">
                                                                                        <div translate ng-message="required">extension.field-required</div>
                                                                                    </div>
                                                                                </md-input-container>
                                                                                <md-input-container ng-if="map.converter.typeExp == 'deviceTypeJsonExpression'" flex="60" class="md-block" md-is-error="theForm['mqttJsonTypeExp_' + brokerIndex + mapIndex].$touched && theForm['mqttJsonTypeExp_' + brokerIndex + mapIndex].$invalid">
                                                                                    <label translate>extension.json-type-expression</label>
                                                                                    <input name="mqttJsonTypeExp_{{brokerIndex}}{{mapIndex}}" ng-model="map.converter.deviceTypeJsonExpression">
                                                                                    <div ng-messages="theForm['mqttJsonTypeExp_' + brokerIndex + mapIndex].$error">
                                                                                        <div translate ng-message="required">extension.field-required</div>
                                                                                    </div>
                                                                                </md-input-container>
                                                                                <md-input-container ng-if="map.converter.typeExp == 'deviceTypeTopicExpression'" flex="60" class="md-block" md-is-error="theForm['mqttTopicTypeExp_' + brokerIndex + mapIndex].$touched && theForm['mqttTopicTypeExp_' + brokerIndex + mapIndex].$invalid">
                                                                                    <label translate>extension.topic-type-expression</label>
                                                                                    <input name="mqttTopicTypeExp_{{brokerIndex}}{{mapIndex}}" ng-model="map.converter.deviceTypeTopicExpression">
                                                                                    <div ng-messages="theForm['mqttTopicTypeExp_' + brokerIndex + mapIndex].$error">
                                                                                        <div translate ng-message="required">extension.field-required</div>
                                                                                    </div>
                                                                                </md-input-container>
                                                                            </section>
                                                                            <section flex layout="row">
                                                                                <md-input-container flex="40" class="md-block">
                                                                                    <label translate>extension.timeout</label>
                                                                                    <input type="number" name="mqttTimeout_{{brokerIndex}}{{mapIndex}}" ng-model="map.converter.timeout" parse-to-null>
                                                                                </md-input-container>
                                                                                <md-input-container flex="60" class="md-block" md-is-error="theForm['mqttFilterExpression' + brokerIndex + mapIndex].$touched && theForm['mqttFilterExpression' + brokerIndex + mapIndex].$invalid">
                                                                                    <label translate>extension.filter-expression</label>
                                                                                    <input name="mqttFilterExpression{{brokerIndex}}{{mapIndex}}" ng-model="map.converter.filterExpression">
                                                                                    <div ng-messages="theForm['mqttFilterExpression' + brokerIndex + mapIndex].$error">
                                                                                        <div translate ng-message="required">extension.field-required</div>
                                                                                    </div>
                                                                                </md-input-container>
                                                                            </section>
                                                                        </div>

                                                                        <div ng-if='map.converterType == "custom"'>
                                                                            <div class="md-caption" style="padding-left: 3px; padding-bottom: 10px; color: rgba(0,0,0,0.57);" translate>extension.transformer-json</div>
                                                                            <div flex class="tb-extension-custom-transformer-panel">
                                                                                <div flex class="tb-extension-custom-transformer"
                                                                                     ui-ace="extensionCustomConverterOptions"
                                                                                     ng-model="map.converter"
                                                                                     name="mqttCustomConverter_{{brokerIndex}}{{mapIndex}}"
                                                                                     ng-change='validateCustomConverter(map.converter, "mqttCustomConverter_" + brokerIndex + mapIndex)'
                                                                                     required>
                                                                                </div>
                                                                            </div>
                                                                            <div class="tb-error-messages" ng-messages="theForm['mqttCustomConverter_' + brokerIndex + mapIndex].$error" role="alert">
                                                                                <div ng-message="required" class="tb-error-message" translate>extension.converter-json-required</div>
                                                                                <div ng-message="converterJSON" class="tb-error-message" translate>extension.converter-json-parse</div>
                                                                            </div>
                                                                        </div>

                                                                        <v-accordion ng-if='map.converterType =="json"' id="mqtt-attributes-accordion" class="vAccordion--default" onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
                                                                            <v-pane id="mqtt-attributes-pane_{{brokerIndex}}{{mapIndex}}">
                                                                                <v-pane-header>
                                                                                    {{ 'extension.attributes' | translate }}
                                                                                </v-pane-header>
                                                                                <v-pane-content>
                                                                                    <div ng-if="map.converter.attributes.length > 0">
                                                                                        <ol class="list-group">
                                                                                            <li class="list-group-item" ng-repeat="(attributeIndex, attribute) in map.converter.attributes">
                                                                                                <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeAttribute(attribute, map.converter.attributes)">
                                                                                                    <ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon>
                                                                                                    <md-tooltip md-direction="top">
                                                                                                        {{ 'action.remove' | translate }}
                                                                                                    </md-tooltip>
                                                                                                </md-button>
                                                                                                <md-card>
                                                                                                    <md-card-content>
                                                                                                        <section flex layout="row">
                                                                                                            <md-input-container flex="60" class="md-block" md-is-error="theForm['mqttAttributeKey_' + brokerIndex + mapIndex + attributeIndex].$touched && theForm['mqttAttributeKey_' + brokerIndex + mapIndex + attributeIndex].$invalid">
                                                                                                                <label translate>extension.key</label>
                                                                                                                <input required name="mqttAttributeKey_{{brokerIndex}}{{mapIndex}}{{attributeIndex}}" ng-model="attribute.key">
                                                                                                                <div ng-messages="theForm['mqttAttributeKey_' + brokerIndex + mapIndex + attributeIndex].$error">
                                                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                                                </div>
                                                                                                            </md-input-container>
                                                                                                            <md-input-container flex="40" class="md-block" md-is-error="theForm['mqttAttributeType_' + brokerIndex + mapIndex + attributeIndex].$touched && theForm['mqttAttributeType_' + brokerIndex + mapIndex + attributeIndex].$invalid">
                                                                                                                <label translate>extension.type</label>
                                                                                                                <md-select required name="mqttAttributeType_{{brokerIndex}}{{mapIndex}}{{attributeIndex}}" ng-model="attribute.type">
                                                                                                                    <md-option ng-repeat="(attrType, attrTypeValue) in types.extensionValueType" ng-value="attrType">
                                                                                                                        {{attrTypeValue | translate}}
                                                                                                                    </md-option>
                                                                                                                </md-select>
                                                                                                                <div ng-messages="theForm['mqttAttributeType_' + brokerIndex + mapIndex + attributeIndex].$error">
                                                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                                                </div>
                                                                                                            </md-input-container>
                                                                                                        </section>
                                                                                                        <md-input-container class="md-block" md-is-error="theForm['mqttAttributeValue_' + brokerIndex + mapIndex + attributeIndex].$touched && theForm['mqttAttributeValue_' + brokerIndex + mapIndex + attributeIndex].$invalid">
                                                                                                            <label translate>extension.value</label>
                                                                                                            <input required name="mqttAttributeValue_{{brokerIndex}}{{mapIndex}}{{attributeIndex}}" ng-model="attribute.value">
                                                                                                            <div ng-messages="theForm['mqttAttributeValue_' + brokerIndex + mapIndex + attributeIndex].$error">
                                                                                                                <div translate ng-message="required">extension.field-required</div>
                                                                                                            </div>
                                                                                                        </md-input-container>
                                                                                                    </md-card-content>
                                                                                                </md-card>
                                                                                            </li>
                                                                                        </ol>
                                                                                    </div>
                                                                                    <div flex layout="row" layout-align="start center">
                                                                                        <md-button class="md-primary md-raised"
                                                                                                   ng-click="addAttribute(map.converter.attributes)" aria-label="{{ 'action.add' | translate }}">
                                                                                            <md-icon class="material-icons">add</md-icon>
                                                                                            <span translate>extension.add-attribute</span>
                                                                                        </md-button>
                                                                                    </div>
                                                                                </v-pane-content>
                                                                            </v-pane>
                                                                        </v-accordion>

                                                                        <v-accordion ng-if='map.converterType =="json"' id="mqtt-timeseries-accordion" class="vAccordion--default" onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
                                                                            <v-pane id="mqtt-timeseries-pane_{{brokerIndex}}{{mapIndex}}">
                                                                                <v-pane-header>
                                                                                    {{ 'extension.timeseries' | translate }}
                                                                                </v-pane-header>
                                                                                <v-pane-content>
                                                                                    <div ng-if="map.converter.timeseries.length > 0">
                                                                                        <ol class="list-group">
                                                                                            <li class="list-group-item" ng-repeat="(timeseriesIndex, timeseries) in map.converter.timeseries">
                                                                                                <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeAttribute(timeseries, map.converter.timeseries)">
                                                                                                    <ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon>
                                                                                                    <md-tooltip md-direction="top">
                                                                                                        {{ 'action.remove' | translate }}
                                                                                                    </md-tooltip>
                                                                                                </md-button>
                                                                                                <md-card>
                                                                                                    <md-card-content>
                                                                                                        <section flex layout="row">
                                                                                                            <md-input-container flex="60" class="md-block" md-is-error="theForm['mqttTimeseriesKey_' + brokerIndex + mapIndex + timeseriesIndex].$touched && theForm['mqttTimeseriesKey_' + brokerIndex + mapIndex + timeseriesIndex].$invalid">
                                                                                                                <label translate>extension.key</label>
                                                                                                                <input required name="mqttTimeseriesKey_{{brokerIndex}}{{mapIndex}}{{timeseriesIndex}}" ng-model="timeseries.key">
                                                                                                                <div ng-messages="theForm['mqttTimeseriesKey_' + brokerIndex + mapIndex + timeseriesIndex].$error">
                                                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                                                </div>
                                                                                                            </md-input-container>
                                                                                                            <md-input-container flex="40" class="md-block" md-is-error="theForm['mqttTimeseriesType_' + brokerIndex + mapIndex + timeseriesIndex].$touched && theForm['mqttTimeseriesType_' + brokerIndex + mapIndex + timeseriesIndex].$invalid">
                                                                                                                <label translate>extension.type</label>
                                                                                                                <md-select required name="mqttTimeseriesType_{{brokerIndex}}{{mapIndex}}{{timeseriesIndex}}" ng-model="timeseries.type">
                                                                                                                    <md-option ng-repeat="(attrType, attrTypeValue) in types.extensionValueType" ng-value="attrType">
                                                                                                                        {{attrTypeValue | translate}}
                                                                                                                    </md-option>
                                                                                                                </md-select>
                                                                                                                <div ng-messages="theForm['mqttTimeseriesType_' + brokerIndex + mapIndex + timeseriesIndex].$error">
                                                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                                                </div>
                                                                                                            </md-input-container>
                                                                                                        </section>
                                                                                                        <md-input-container class="md-block" md-is-error="theForm['mqttTimeseriesValue_' + brokerIndex + mapIndex + timeseriesIndex].$touched && theForm['mqttTimeseriesValue_' + brokerIndex + mapIndex + timeseriesIndex].$invalid">
                                                                                                            <label translate>extension.value</label>
                                                                                                            <input required name="mqttTimeseriesValue_{{brokerIndex}}{{mapIndex}}{{timeseriesIndex}}" ng-model="timeseries.value">
                                                                                                            <div ng-messages="theForm['mqttTimeseriesValue_' + brokerIndex + mapIndex + timeseriesIndex].$error">
                                                                                                                <div translate ng-message="required">extension.field-required</div>
                                                                                                            </div>
                                                                                                        </md-input-container>
                                                                                                    </md-card-content>
                                                                                                </md-card>
                                                                                            </li>
                                                                                        </ol>
                                                                                    </div>
                                                                                    <div flex layout="row" layout-align="start center">
                                                                                        <md-button class="md-primary md-raised"
                                                                                                   ng-click="addAttribute(map.converter.timeseries)" aria-label="{{ 'action.add' | translate }}">
                                                                                            <md-icon class="material-icons">add</md-icon>
                                                                                            <span translate>extension.add-timeseries</span>
                                                                                        </md-button>
                                                                                    </div>
                                                                                </v-pane-content>
                                                                            </v-pane>
                                                                        </v-accordion>

                                                                    </md-card-content>
                                                                </md-card>
                                                            </li>
                                                        </ol>
                                                    </div>
                                                    <div flex layout="row" layout-align="start center">
                                                        <md-button class="md-primary md-raised"
                                                                   ng-click="addMap(broker.mapping)" aria-label="{{ 'action.add' | translate }}">
                                                            <md-icon class="material-icons">add</md-icon>
                                                            <span translate>extension.add-map</span>
                                                        </md-button>
                                                    </div>
                                                </v-pane-content>
                                            </v-pane>
                                        </v-accordion>

                                        <v-accordion id="mqtt-connect-requests-accordion" class="vAccordion--default" onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
                                            <v-pane id="mqtt-connect-requests-pane_{{brokerIndex}}">
                                                <v-pane-header>
                                                    {{ 'extension.connect-requests' | translate }}
                                                </v-pane-header>
                                                <v-pane-content>
                                                    <div ng-if="broker.connectRequests.length > 0">
                                                        <ol class="list-group">
                                                            <li class="list-group-item" ng-repeat="(connectRequestIndex, connectRequest) in broker.connectRequests">
                                                                <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeAttribute(connectRequest, broker.connectRequests)">
                                                                    <ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon>
                                                                    <md-tooltip md-direction="top">
                                                                        {{ 'action.remove' | translate }}
                                                                    </md-tooltip>
                                                                </md-button>
                                                                <md-card>
                                                                    <md-card-content>
                                                                        <md-input-container class="md-block">
                                                                            <label translate>extension.topic-filter</label>
                                                                            <input required name="conRequestTopicFilter_{{brokerIndex}}{{connectRequestIndex}}" ng-model="connectRequest.topicFilter">
                                                                            <div ng-messages="theForm['conRequestTopicFilter_' + brokerIndex + connectRequestIndex].$error">
                                                                                <div translate ng-message="required">extension.field-required</div>
                                                                            </div>
                                                                        </md-input-container>
                                                                        <section flex layout="row">
                                                                            <md-input-container flex="40" class="md-block" md-is-error="theForm['connectDeviceNameExpression_' + brokerIndex + connectRequestIndex].$touched && theForm['connectDeviceNameExpression_' + brokerIndex + connectRequestIndex].$invalid">
                                                                                <label translate>extension.device-name-expression</label>
                                                                                <md-select required name="connectDeviceNameExpression_{{brokerIndex}}{{connectRequestIndex}}" ng-model="connectRequest.nameExp" ng-change="changeNameExpression(connectRequest, 'connect')">
                                                                                    <md-option ng-repeat="(key, value) in deviceNameExpressions" ng-value='key'>
                                                                                        {{value | translate}}
                                                                                    </md-option>
                                                                                </md-select>
                                                                                <div ng-messages="theForm['connectDeviceNameExpression_' + brokerIndex + connectRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container ng-if="connectRequest.nameExp == 'deviceNameJsonExpression'" flex="60" class="md-block">
                                                                                <label translate>extension.json-name-expression</label>
                                                                                <input required name="connectJsonNameExp_{{brokerIndex}}{{connectRequestIndex}}" ng-model="connectRequest.deviceNameJsonExpression">
                                                                                <div ng-messages="theForm['connectJsonNameExp_' + brokerIndex + connectRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container ng-if="connectRequest.nameExp == 'deviceNameTopicExpression'" flex="60" class="md-block">
                                                                                <label translate>extension.topic-name-expression</label>
                                                                                <input required name="connectTopicNameExp_{{brokerIndex}}{{connectRequestIndex}}" ng-model="connectRequest.deviceNameTopicExpression">
                                                                                <div ng-messages="theForm['connectTopicNameExp_' + brokerIndex + connectRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                        </section>
                                                                    </md-card-content>
                                                                </md-card>
                                                            </li>
                                                        </ol>
                                                    </div>
                                                    <div flex layout="row" layout-align="start center">
                                                        <md-button class="md-primary md-raised"
                                                                   ng-click='addConnectRequest(broker.connectRequests, "connect")' aria-label="{{ 'action.add' | translate }}">
                                                            <md-icon class="material-icons">add</md-icon>
                                                            <span translate>extension.add-connect-request</span>
                                                        </md-button>
                                                    </div>
                                                </v-pane-content>
                                            </v-pane>
                                        </v-accordion>

                                        <v-accordion id="mqtt-disconnect-requests-accordion" class="vAccordion--default" onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
                                            <v-pane id="mqtt-disconnect-requests-pane_{{brokerIndex}}">
                                                <v-pane-header>
                                                    {{ 'extension.disconnect-requests' | translate }}
                                                </v-pane-header>
                                                <v-pane-content>
                                                    <div ng-if="broker.disconnectRequests.length > 0">
                                                        <ol class="list-group">
                                                            <li class="list-group-item" ng-repeat="(disconnectRequestIndex, disconnectRequest) in broker.disconnectRequests">
                                                                <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeAttribute(disconnectRequest, broker.disconnectRequests)">
                                                                    <ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon>
                                                                    <md-tooltip md-direction="top">
                                                                        {{ 'action.remove' | translate }}
                                                                    </md-tooltip>
                                                                </md-button>
                                                                <md-card>
                                                                    <md-card-content>
                                                                        <md-input-container class="md-block">
                                                                            <label translate>extension.topic-filter</label>
                                                                            <input required name="disconRequestTopicFilter_{{brokerIndex}}{{disconnectRequestIndex}}" ng-model="disconnectRequest.topicFilter">
                                                                            <div ng-messages="theForm['disconRequestTopicFilter_' + brokerIndex + disconnectRequestIndex].$error">
                                                                                <div translate ng-message="required">extension.field-required</div>
                                                                            </div>
                                                                        </md-input-container>
                                                                        <section flex layout="row">
                                                                            <md-input-container flex="40" class="md-block" md-is-error="theForm['disconnectDeviceNameExpression_' + brokerIndex + disconnectRequestIndex].$touched && theForm['disconnectDeviceNameExpression_' + brokerIndex + disconnectRequestIndex].$invalid">
                                                                                <label translate>extension.device-name-expression</label>
                                                                                <md-select required name="disconnectDeviceNameExpression_{{brokerIndex}}{{disconnectRequestIndex}}" ng-model="disconnectRequest.nameExp" ng-change="changeNameExpression(disconnectRequest, 'disconnect')">
                                                                                    <md-option ng-repeat="(key, value) in deviceNameExpressions" ng-value='key'>
                                                                                        {{value | translate}}
                                                                                    </md-option>
                                                                                </md-select>
                                                                                <div ng-messages="theForm['disconnectDeviceNameExpression_' + brokerIndex + disconnectRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container ng-if="disconnectRequest.nameExp == 'deviceNameJsonExpression'" flex="60" class="md-block">
                                                                                <label translate>extension.json-name-expression</label>
                                                                                <input required name="disconnectJsonNameExp_{{brokerIndex}}{{disconnectRequestIndex}}" ng-model="disconnectRequest.deviceNameJsonExpression">
                                                                                <div ng-messages="theForm['disconnectJsonNameExp_' + brokerIndex + disconnectRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container ng-if="disconnectRequest.nameExp == 'deviceNameTopicExpression'" flex="60" class="md-block">
                                                                                <label translate>extension.topic-name-expression</label>
                                                                                <input required name="disconnectTopicNameExp_{{brokerIndex}}{{disconnectRequestIndex}}" ng-model="disconnectRequest.deviceNameTopicExpression">
                                                                                <div ng-messages="theForm['disconnectTopicNameExp_' + brokerIndex + disconnectRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                        </section>
                                                                    </md-card-content>
                                                                </md-card>
                                                            </li>
                                                        </ol>
                                                    </div>
                                                    <div flex layout="row" layout-align="start center">
                                                        <md-button class="md-primary md-raised"
                                                                   ng-click='addConnectRequest(broker.disconnectRequests, "disconnect")' aria-label="{{ 'action.add' | translate }}">
                                                            <md-icon class="material-icons">add</md-icon>
                                                            <span translate>extension.add-disconnect-request</span>
                                                        </md-button>
                                                    </div>
                                                </v-pane-content>
                                            </v-pane>
                                        </v-accordion>

                                        <v-accordion id="mqtt-attribute-requests-accordion" class="vAccordion--default" onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
                                            <v-pane id="mqtt-attribute-requests-pane_{{brokerIndex}}">
                                                <v-pane-header>
                                                    {{ 'extension.attribute-requests' | translate }}
                                                </v-pane-header>
                                                <v-pane-content>
                                                    <div ng-if="broker.attributeRequests.length > 0">
                                                        <ol class="list-group">
                                                            <li class="list-group-item" ng-repeat="(attributeRequestIndex, attributeRequest) in broker.attributeRequests">
                                                                <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeAttribute(attributeRequest, broker.attributeRequests)">
                                                                    <ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon>
                                                                    <md-tooltip md-direction="top">
                                                                        {{ 'action.remove' | translate }}
                                                                    </md-tooltip>
                                                                </md-button>
                                                                <md-card>
                                                                    <md-card-content>
                                                                        <section flex layout="row">
                                                                            <md-input-container flex="80" class="md-block">
                                                                                <label translate>extension.topic-filter</label>
                                                                                <input required name="attributeRequestTopicFilter_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.topicFilter">
                                                                                <div ng-messages="theForm['attributeRequestTopicFilter_' + brokerIndex + attributeRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container flex="20" class="md-block">
                                                                                <md-checkbox flex aria-label="{{ 'extension.client-scope' | translate }}"
                                                                                             ng-model="attributeRequest.clientScope">{{ 'extension.client-scope' | translate }}
                                                                                </md-checkbox>
                                                                            </md-input-container>
                                                                        </section>
                                                                        <section flex layout="row">
                                                                            <md-input-container flex="40" class="md-block" md-is-error="theForm['attrRequestDeviceNameExpression_' + brokerIndex + attributeRequestIndex].$touched && theForm['attrRequestDeviceNameExpression_' + brokerIndex + attributeRequestIndex].$invalid">
                                                                                <label translate>extension.device-name-expression</label>
                                                                                <md-select required name="attrRequestDeviceNameExpression_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.nameExp" ng-change="changeNameExpression(attributeRequest, 'attribute')">
                                                                                    <md-option ng-repeat="(key, value) in deviceNameExpressions" ng-value='key'>
                                                                                        {{value | translate}}
                                                                                    </md-option>
                                                                                </md-select>
                                                                                <div ng-messages="theForm['attrRequestDeviceNameExpression_' + brokerIndex + attributeRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container ng-if="attributeRequest.nameExp == 'deviceNameJsonExpression'" flex="60" class="md-block">
                                                                                <label translate>extension.json-name-expression</label>
                                                                                <input required name="attrRequestJsonNameExp_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.deviceNameJsonExpression">
                                                                                <div ng-messages="theForm['attrRequestJsonNameExp_' + brokerIndex + attributeRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container ng-if="attributeRequest.nameExp == 'deviceNameTopicExpression'" flex="60" class="md-block">
                                                                                <label translate>extension.topic-name-expression</label>
                                                                                <input required name="attrRequestTopicNameExp_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.deviceNameTopicExpression">
                                                                                <div ng-messages="theForm['attrRequestTopicNameExp_' + brokerIndex + attributeRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                        </section>

                                                                        <section flex layout="row">
                                                                            <md-input-container flex="40" class="md-block" md-is-error="theForm['attrRequestAttributeKeyExpression_' + brokerIndex + attributeRequestIndex].$touched && theForm['attrRequestAttributeKeyExpression_' + brokerIndex + attributeRequestIndex].$invalid">
                                                                                <label translate>extension.attribute-key-expression</label>
                                                                                <md-select required name="attrRequestAttributeKeyExpression_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.attrKey" ng-change="changeAttrKeyExpression(attributeRequest)">
                                                                                    <md-option ng-repeat="(key, value) in attributeKeyExpressions" ng-value='key'>
                                                                                        {{value | translate}}
                                                                                    </md-option>
                                                                                </md-select>
                                                                                <div ng-messages="theForm['attrRequestAttributeKeyExpression_' + brokerIndex + attributeRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container ng-if="attributeRequest.attrKey == 'attributeKeyJsonExpression'" flex="60" class="md-block">
                                                                                <label translate>extension.attr-json-key-expression</label>
                                                                                <input required name="attrRequestJsonKeyExp_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.attributeKeyJsonExpression">
                                                                                <div ng-messages="theForm['attrRequestJsonKeyExp_' + brokerIndex + attributeRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container ng-if="attributeRequest.attrKey == 'attributeKeyTopicExpression'" flex="60" class="md-block">
                                                                                <label translate>extension.attr-topic-key-expression</label>
                                                                                <input required name="attrRequestTopicKeyExp_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.attributeKeyTopicExpression">
                                                                                <div ng-messages="theForm['attrRequestTopicKeyExp_' + brokerIndex + attributeRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                        </section>

                                                                        <section flex layout="row">
                                                                            <md-input-container flex="40" class="md-block" md-is-error="theForm['attrRequestIdExpression_' + brokerIndex + attributeRequestIndex].$touched && theForm['attrRequestIdExpression_' + brokerIndex + attributeRequestIndex].$invalid">
                                                                                <label translate>extension.request-id-expression</label>
                                                                                <md-select required name="attrRequestIdExpression_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.requestId" ng-change="changeRequestIdExpression(attributeRequest)">
                                                                                    <md-option ng-repeat="(key, value) in requestIdExpressions" ng-value='key'>
                                                                                        {{value | translate}}
                                                                                    </md-option>
                                                                                </md-select>
                                                                                <div ng-messages="theForm['attrRequestIdExpression_' + brokerIndex + attributeRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container ng-if="attributeRequest.requestId == 'requestIdJsonExpression'" flex="60" class="md-block">
                                                                                <label translate>extension.request-id-json-expression</label>
                                                                                <input required name="attrRequestJsonIdExp_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.requestIdJsonExpression">
                                                                                <div ng-messages="theForm['attrRequestJsonIdExp_' + brokerIndex + attributeRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container ng-if="attributeRequest.requestId == 'requestIdTopicExpression'" flex="60" class="md-block">
                                                                                <label translate>extension.request-id-topic-expression</label>
                                                                                <input required name="attrRequestTopicIdExp_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.requestIdTopicExpression">
                                                                                <div ng-messages="theForm['attrRequestTopicIdExp_' + brokerIndex + attributeRequestIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                        </section>

                                                                        <md-input-container class="md-block">
                                                                            <label translate>extension.response-topic-expression</label>
                                                                            <input required name="attributeRequestResponseTopicExp_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.responseTopicExpression">
                                                                            <div ng-messages="theForm['attributeRequestResponseTopicExp_' + brokerIndex + attributeRequestIndex].$error">
                                                                                <div translate ng-message="required">extension.field-required</div>
                                                                            </div>
                                                                        </md-input-container>
                                                                        <md-input-container class="md-block">
                                                                            <label translate>extension.value-expression</label>
                                                                            <input required name="attributeRequestValueExp_{{brokerIndex}}{{attributeRequestIndex}}" ng-model="attributeRequest.valueExpression">
                                                                            <div ng-messages="theForm['attributeRequestValueExp_' + brokerIndex + attributeRequestIndex].$error">
                                                                                <div translate ng-message="required">extension.field-required</div>
                                                                            </div>
                                                                        </md-input-container>
                                                                    </md-card-content>
                                                                </md-card>
                                                            </li>
                                                        </ol>
                                                    </div>
                                                    <div flex layout="row" layout-align="start center">
                                                        <md-button class="md-primary md-raised"
                                                                   ng-click="addAttributeRequest(broker.attributeRequests)" aria-label="{{ 'action.add' | translate }}">
                                                            <md-icon class="material-icons">add</md-icon>
                                                            <span translate>extension.add-attribute-request</span>
                                                        </md-button>
                                                    </div>
                                                </v-pane-content>
                                            </v-pane>
                                        </v-accordion>

                                        <v-accordion id="mqtt-attribute-updates-accordion" class="vAccordion--default" onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
                                            <v-pane id="mqtt-attribute-updates-pane_{{brokerIndex}}">
                                                <v-pane-header>
                                                    {{ 'extension.attribute-updates' | translate }}
                                                </v-pane-header>
                                                <v-pane-content>
                                                    <div ng-if="broker.attributeUpdates.length > 0">
                                                        <ol class="list-group">
                                                            <li class="list-group-item" ng-repeat="(attributeUpdateIndex, attributeUpdate) in broker.attributeUpdates">
                                                                <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeAttribute(attributeUpdate, broker.attributeUpdates)">
                                                                    <ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon>
                                                                    <md-tooltip md-direction="top">
                                                                        {{ 'action.remove' | translate }}
                                                                    </md-tooltip>
                                                                </md-button>
                                                                <md-card>
                                                                    <md-card-content>
                                                                        <section flex layout="row">
                                                                            <md-input-container flex="50" class="md-block">
                                                                                <label translate>extension.device-name-filter</label>
                                                                                <input required name="attributeUpdateDeviceNameFilter_{{brokerIndex}}{{attributeUpdateIndex}}" ng-model="attributeUpdate.deviceNameFilter">
                                                                                <div ng-messages="theForm['attributeUpdateDeviceNameFilter_' + brokerIndex + attributeUpdateIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container flex="50" class="md-block">
                                                                                <label translate>extension.attribute-filter</label>
                                                                                <input required name="attributeUpdateAttributeFilter_{{brokerIndex}}{{attributeUpdateIndex}}" ng-model="attributeUpdate.attributeFilter">
                                                                                <div ng-messages="theForm['attributeUpdateAttributeFilter_' + brokerIndex + attributeUpdateIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                        </section>
                                                                        <md-input-container class="md-block">
                                                                            <label translate>extension.topic-expression</label>
                                                                            <input required name="attributeUpdateTopicExp_{{brokerIndex}}{{attributeUpdateIndex}}" ng-model="attributeUpdate.topicExpression">
                                                                            <div ng-messages="theForm['attributeUpdateTopicExp_' + brokerIndex + attributeUpdateIndex].$error">
                                                                                <div translate ng-message="required">extension.field-required</div>
                                                                            </div>
                                                                        </md-input-container>
                                                                        <md-input-container class="md-block">
                                                                            <label translate>extension.value-expression</label>
                                                                            <input required name="attributeUpdateValueExp_{{brokerIndex}}{{attributeUpdateIndex}}" ng-model="attributeUpdate.valueExpression">
                                                                            <div ng-messages="theForm['attributeUpdateValueExp_' + brokerIndex + attributeUpdateIndex].$error">
                                                                                <div translate ng-message="required">extension.field-required</div>
                                                                            </div>
                                                                        </md-input-container>
                                                                    </md-card-content>
                                                                </md-card>
                                                            </li>
                                                        </ol>
                                                    </div>
                                                    <div flex layout="row" layout-align="start center">
                                                        <md-button class="md-primary md-raised"
                                                                   ng-click='addAttributeUpdate(broker.attributeUpdates)' aria-label="{{ 'action.add' | translate }}">
                                                            <md-icon class="material-icons">add</md-icon>
                                                            <span translate>extension.add-attribute-update</span>
                                                        </md-button>
                                                    </div>
                                                </v-pane-content>
                                            </v-pane>
                                        </v-accordion>

                                        <v-accordion id="mqtt-server-side-rpc-accordion" class="vAccordion--default" onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
                                            <v-pane id="mqtt-server-side-rpc-pane_{{brokerIndex}}">
                                                <v-pane-header>
                                                    {{ 'extension.server-side-rpc' | translate }}
                                                </v-pane-header>
                                                <v-pane-content>
                                                    <div ng-if="broker.serverSideRpc.length > 0">
                                                        <ol class="list-group">
                                                            <li class="list-group-item" ng-repeat="(rpcIndex, rpc) in broker.serverSideRpc">
                                                                <md-button aria-label="{{ 'action.remove' | translate }}" class="md-icon-button" ng-click="removeAttribute(rpc, broker.serverSideRpc)">
                                                                    <ng-md-icon icon="close" aria-label="{{ 'action.remove' | translate }}"></ng-md-icon>
                                                                    <md-tooltip md-direction="top">
                                                                        {{ 'action.remove' | translate }}
                                                                    </md-tooltip>
                                                                </md-button>
                                                                <md-card>
                                                                    <md-card-content>
                                                                        <section flex layout="row">
                                                                            <md-input-container flex="50" class="md-block">
                                                                                <label translate>extension.device-name-filter</label>
                                                                                <input required name="serverSideRpcDeviceNameFilter_{{brokerIndex}}{{rpcIndex}}" ng-model="rpc.deviceNameFilter">
                                                                                <div ng-messages="theForm['serverSideRpcDeviceNameFilter_' + brokerIndex + rpcIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                            <md-input-container flex="50" class="md-block">
                                                                                <label translate>extension.method-filter</label>
                                                                                <input required name="serverSideRpcMethodFilter_{{brokerIndex}}{{rpcIndex}}" ng-model="rpc.methodFilter">
                                                                                <div ng-messages="theForm['serverSideRpcMethodFilter_' + brokerIndex + rpcIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                        </section>
                                                                        <md-input-container class="md-block">
                                                                            <label translate>extension.request-topic-expression</label>
                                                                            <input required name="serverSideRpcRequestTopicExp_{{brokerIndex}}{{rpcIndex}}" ng-model="rpc.requestTopicExpression">
                                                                            <div ng-messages="theForm['serverSideRpcRequestTopicExp_' + brokerIndex + rpcIndex].$error">
                                                                                <div translate ng-message="required">extension.field-required</div>
                                                                            </div>
                                                                        </md-input-container>
                                                                        <md-input-container class="md-block">
                                                                            <label translate>extension.response-topic-expression</label>
                                                                            <input name="serverSideRpcResponseTopicExp_{{brokerIndex}}{{rpcIndex}}" ng-model="rpc.responseTopicExpression" parse-to-null>
                                                                        </md-input-container>
                                                                        <section flex layout="row">
                                                                            <md-input-container flex="50" class="md-block">
                                                                                <label translate>extension.response-timeout</label>
                                                                                <input type="number" name="serverSideRpcResponseTimeout_{{brokerIndex}}{{rpcIndex}}" ng-model="rpc.responseTimeout" parse-to-null>
                                                                            </md-input-container>
                                                                            <md-input-container flex="50" class="md-block">
                                                                                <label translate>extension.value-expression</label>
                                                                                <input required name="serverSideRpcValueExp_{{brokerIndex}}{{rpcIndex}}" ng-model="rpc.valueExpression">
                                                                                <div ng-messages="theForm['serverSideRpcValueExp_' + brokerIndex + rpcIndex].$error">
                                                                                    <div translate ng-message="required">extension.field-required</div>
                                                                                </div>
                                                                            </md-input-container>
                                                                        </section>
                                                                    </md-card-content>
                                                                </md-card>
                                                            </li>
                                                        </ol>
                                                    </div>
                                                    <div flex layout="row" layout-align="start center">
                                                        <md-button class="md-primary md-raised"
                                                                   ng-click='addServerSideRpc(broker.serverSideRpc)' aria-label="{{ 'action.add' | translate }}">
                                                            <md-icon class="material-icons">add</md-icon>
                                                            <span translate>extension.add-server-side-rpc-request</span>
                                                        </md-button>
                                                    </div>
                                                </v-pane-content>
                                            </v-pane>
                                        </v-accordion>

                                    </md-card-content>
                                </md-card>
                            </li>
                        </ol>
                    </div>

                    <div flex layout="row" layout-align="start center">
                        <md-button class="md-primary md-raised"
                                   ng-click="addBroker()" aria-label="{{ 'action.add' | translate }}">
                            <md-icon class="material-icons">add</md-icon>
                            <span translate>extension.add-broker</span>
                        </md-button>
                    </div>
                </v-pane-content>
            </v-pane>
        </v-accordion>
<!--<pre>
{{config | json}}
</pre>-->
    </md-card-content>
</md-card>