extension-form-mqtt.tpl.html 48.1 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
<!--

    Copyright © 2016-2017 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">
            <v-pane id="mqtt-brokers-pane" expanded="isAdd">
                <v-pane-header>
                    {{ 'extension.brokers' | translate }}
                </v-pane-header>
                <v-pane-content>
                    <div ng-if="brokers.length === 0">
                        <span translate layout-align="center center" class="tb-prompt">extension.add-broker-prompt</span>
                    </div>
                    <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-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.port-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.host-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.retry-interval-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 t-right">
                                                <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">
                                                <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.username-required</div>
                                                </div>
                                            </md-input-container>
                                            <md-input-container flex="60" class="md-block">
                                                <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.password-required</div>
                                                </div>
                                            </md-input-container>
                                        </section>
                                        <section flex layout="column" ng-if='broker.credentials.type == "cert.PEM"'>
                                            <div class="tb-container">
                                                <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">
                                                <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">
                                            <v-pane id="mqtt-mapping-pane">
                                                <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">
                                                                                <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.converter-type-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.topic-filter-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">
                                                                                    <label translate>extension.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 nameExpressions" ng-value='key'>
                                                                                            {{value | translate}}
                                                                                        </md-option>
                                                                                    </md-select>
                                                                                </md-input-container>
                                                                                <md-input-container ng-if="map.converter.nameExp == 'deviceNameJsonExpression'" flex="60" class="md-block">
                                                                                    <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.json-name-expression-required</div>
                                                                                    </div>
                                                                                </md-input-container>
                                                                                <md-input-container ng-if="map.converter.nameExp == 'deviceNameTopicExpression'" flex="60" class="md-block">
                                                                                    <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.topic-name-expression-required</div>
                                                                                    </div>
                                                                                </md-input-container>
                                                                            </section>
                                                                            <section flex layout="row">
                                                                                <md-input-container flex="40" class="md-block">
                                                                                    <label translate>extension.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 typeExpressions" ng-value='key'>
                                                                                            {{value | translate}}
                                                                                        </md-option>
                                                                                    </md-select>
                                                                                </md-input-container>
                                                                                <md-input-container ng-if="map.converter.typeExp == 'deviceTypeJsonExpression'" flex="60" class="md-block">
                                                                                    <label translate>extension.json-type-expression</label>
                                                                                    <input required name="mqttJsonTypeExp_{{brokerIndex}}{{mapIndex}}" ng-model="map.converter.deviceTypeJsonExpression">
                                                                                    <div ng-messages="theForm['mqttJsonTypeExp_' + brokerIndex + mapIndex].$error">
                                                                                        <div translate ng-message="required">extension.json-type-expression-required</div>
                                                                                    </div>
                                                                                </md-input-container>
                                                                                <md-input-container ng-if="map.converter.typeExp == 'deviceTypeTopicExpression'" flex="60" class="md-block">
                                                                                    <label translate>extension.topic-type-expression</label>
                                                                                    <input required name="mqttTopicTypeExp_{{brokerIndex}}{{mapIndex}}" ng-model="map.converter.deviceTypeTopicExpression">
                                                                                    <div ng-messages="theForm['mqttTopicTypeExp_' + brokerIndex + mapIndex].$error">
                                                                                        <div translate ng-message="required">extension.topic-type-expression-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">
                                                                                    <label translate>extension.filter-expression</label>
                                                                                    <input required name="mqttFilterExpression{{brokerIndex}}{{mapIndex}}" ng-model="map.converter.filterExpression">
                                                                                    <div ng-messages="theForm['mqttFilterExpression' + brokerIndex + mapIndex].$error">
                                                                                        <div translate ng-message="required">extension.filter-expression-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">
                                                                            <v-pane id="mqtt-attributes-pane">
                                                                                <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">
                                                                                                                <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.required-key</div>
                                                                                                                </div>
                                                                                                            </md-input-container>
                                                                                                            <md-input-container flex="40" class="md-block">
                                                                                                                <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.required-type</div>
                                                                                                                </div>
                                                                                                            </md-input-container>
                                                                                                        </section>
                                                                                                        <md-input-container class="md-block">
                                                                                                            <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.required-value</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-tooltip md-direction="top">
                                                                                                {{ 'extension.add-attribute' | translate }}
                                                                                            </md-tooltip>
                                                                                            <md-icon class="material-icons">add</md-icon>
                                                                                            <span translate>action.add</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">
                                                                            <v-pane id="mqtt-timeseries-pane">
                                                                                <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">
                                                                                                                <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.required-key</div>
                                                                                                                </div>
                                                                                                            </md-input-container>
                                                                                                            <md-input-container flex="40" class="md-block">
                                                                                                                <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.required-type</div>
                                                                                                                </div>
                                                                                                            </md-input-container>
                                                                                                        </section>
                                                                                                        <md-input-container class="md-block">
                                                                                                            <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.required-value</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-tooltip md-direction="top">
                                                                                                {{ 'extension.add-timeseries' | translate }}
                                                                                            </md-tooltip>
                                                                                            <md-icon class="material-icons">add</md-icon>
                                                                                            <span translate>action.add</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-tooltip md-direction="top">
                                                                {{ 'extension.add-map' | translate }}
                                                            </md-tooltip>
                                                            <md-icon class="material-icons">add</md-icon>
                                                            <span translate>action.add</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-tooltip md-direction="top">
                                {{ 'extension.add-broker' | translate }}
                            </md-tooltip>
                            <md-icon class="material-icons">add</md-icon>
                            <span translate>action.add</span>
                        </md-button>
                    </div>
                </v-pane-content>
            </v-pane>
        </v-accordion>
<pre>
{{config | json}}
</pre>
    </md-card-content>
</md-card>