extension-form-modbus.tpl.html
<!--
Copyright © 2016-2018 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-modbus">
<md-card-title>
<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="modbus-server-configs-accordion" class="vAccordion--default" onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
<v-pane id="modbus-servers-pane" expanded="true">
<v-pane-header>
{{ 'extension.modbus-server' | translate }}
</v-pane-header>
<v-pane-content>
<div ng-if="configuration.servers.length === 0">
<span translate layout-align="center center" class="tb-prompt">extension.modbus-add-server-prompt</span>
</div>
<div ng-if="configuration.servers.length > 0">
<ol class="list-group">
<li class="list-group-item" ng-repeat="(serverIndex, server) in configuration.servers">
<md-button aria-label="{{ 'action.remove' | translate }}"
class="md-icon-button"
ng-click="removeItem(server, configuration.servers)"
ng-hide="configuration.servers.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>
<div layout="row">
<md-input-container flex="50" class="md-block tb-container-for-select">
<label translate>extension.modbus-transport</label>
<md-select required
name="transportType_{{serverIndex}}"
ng-model="server.transport.type"
ng-change="onTransportChanged(server)"
>
<md-option ng-value="transportType"
ng-repeat="(transportType, transportValue) in types.extensionModbusTransports"
><span ng-bind="transportValue"></span></md-option>
</md-select>
<div ng-messages="theForm['transportType_' + serverIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
</div>
</md-input-container>
</div>
<div layout="row" ng-if="server.transport.type == 'tcp' || server.transport.type == 'udp'">
<md-input-container flex="33" class="md-block">
<label translate>extension.host</label>
<input required name="transportHost_{{serverIndex}}" ng-model="server.transport.host">
<div ng-messages="theForm['transportHost_' + serverIndex].$error">
<div translate ng-message="required">extension.field-required</div>
</div>
</md-input-container>
<md-input-container flex="33" class="md-block">
<label translate>extension.port</label>
<input type="number"
required
name="transportPort_{{serverIndex}}"
ng-model="server.transport.port"
min="1"
max="65535"
>
<div ng-messages="theForm['transportPort_' + serverIndex].$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="33" class="md-block">
<label translate>extension.timeout</label>
<input type="number"
required name="transportTimeout_{{serverIndex}}"
ng-model="server.transport.timeout"
>
<div ng-messages="theForm['transportTimeout_' + serverIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
</div>
</md-input-container>
</div>
<div ng-if="server.transport.type == 'rtu'">
<div layout="row">
<md-input-container flex="70" class="md-block">
<label translate>extension.modbus-port-name</label>
<input required name="transportPortName_{{serverIndex}}" ng-model="server.transport.portName">
<div ng-messages="theForm['transportPortName_' + serverIndex].$error">
<div translate ng-message="required">extension.field-required</div>
</div>
</md-input-container>
<md-input-container flex="30" class="md-block">
<label translate>extension.timeout</label>
<input type="number"
required name="transportTimeout_{{serverIndex}}"
ng-model="server.transport.timeout"
>
<div ng-messages="theForm['transportTimeout_' + serverIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
</div>
</md-input-container>
</div>
<div layout="row">
<md-input-container flex="50" class="md-block tb-container-for-select">
<label translate>extension.modbus-encoding</label>
<md-select required
name="transportEncoding_{{serverIndex}}"
ng-model="server.transport.encoding"
>
<md-option ng-value="encodingType"
ng-repeat="(encodingType, encodingValue) in types.extensionModbusRtuEncodings"
><span ng-bind="encodingValue"></span></md-option>
</md-select>
<div ng-messages="theForm['transportEncoding_' + serverIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
</div>
</md-input-container>
<md-input-container flex="50" class="md-block tb-container-for-select">
<label translate>extension.modbus-parity</label>
<md-select name="transportParity_{{serverIndex}}" ng-model="server.transport.parity">
<md-option ng-repeat="(parityKey, parityValue) in types.extensionModbusRtuParities"
ng-value="parityValue"
>
{{parityValue}}
</md-option>
</md-select>
<div ng-messages="theForm['transportParity_' + serverIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
</div>
</md-input-container>
</div>
<div layout="row">
<md-input-container flex="33" class="md-block">
<label translate>extension.modbus-baudrate</label>
<input type="number"
required name="transportBaudRate_{{serverIndex}}"
ng-model="server.transport.baudRate"
>
<div ng-messages="theForm['transportBaudRate_' + serverIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
</div>
</md-input-container>
<md-input-container flex="33" class="md-block">
<label translate>extension.modbus-databits</label>
<input type="number"
required
name="transportDataBits_{{serverIndex}}"
ng-model="server.transport.dataBits"
min="7"
max="8"
>
<div ng-messages="theForm['transportDataBits_' + serverIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
<div translate
ng-message="min"
>extension.modbus-databits-range</div>
<div translate
ng-message="max"
>extension.modbus-databits-range</div>
</div>
</md-input-container>
<md-input-container flex="33" class="md-block">
<label translate>extension.modbus-stopbits</label>
<input type="number"
required
name="transportStopBits_{{serverIndex}}"
ng-model="server.transport.stopBits"
min="1"
max="2"
>
<div ng-messages="theForm['transportStopBits_' + serverIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
<div translate
ng-message="min"
>extension.modbus-stopbits-range</div>
<div translate
ng-message="max"
>extension.modbus-stopbits-range</div>
</div>
</md-input-container>
</div>
</div>
<v-accordion id="modbus-mapping-accordion"
class="vAccordion--default"
onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
<v-pane id="modbus-mapping-pane_{{serverIndex}}">
<v-pane-header>
{{ 'extension.mapping' | translate }}
</v-pane-header>
<v-pane-content>
<div ng-if="server.devices.length > 0">
<ol class="list-group">
<li class="list-group-item"
ng-repeat="(deviceIndex, device) in server.devices"
>
<md-button aria-label="{{ 'action.remove' | translate }}"
class="md-icon-button"
ng-click="removeItem(device, server.devices)"
>
<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>
<div flex layout="row">
<md-input-container flex="80" class="md-block">
<label translate>extension.modbus-device-name</label>
<input required
name="deviceName_{{serverIndex}}{{deviceIndex}}"
ng-model="device.deviceName"
>
<div ng-messages="theForm['deviceName_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
</div>
</md-input-container>
<md-input-container flex="20" class="md-block">
<label translate>extension.modbus-unit-id</label>
<input type="number"
required
name="unitId_{{serverIndex}}{{deviceIndex}}"
ng-model="device.unitId"
min="1"
max="247"
>
<div ng-messages="theForm['unitId_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
<div translate
ng-message="min"
>extension.modbus-unit-id-range</div>
<div translate
ng-message="max"
>extension.modbus-unit-id-range</div>
</div>
</md-input-container>
</div>
<div flex layout="row">
<md-input-container flex="50" class="md-block">
<label translate>extension.modbus-attributes-poll-period</label>
<input type="number"
required
name="attributesPollPeriod_{{serverIndex}}{{deviceIndex}}"
ng-model="device.attributesPollPeriod"
min="1"
>
<div ng-messages="theForm['attributesPollPeriod_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
<div translate
ng-message="min"
>extension.modbus-poll-period-range</div>
</div>
</md-input-container>
<md-input-container flex="50" class="md-block">
<label translate>extension.modbus-timeseries-poll-period</label>
<input type="number"
required
name="timeseriesPollPeriod_{{serverIndex}}{{deviceIndex}}"
ng-model="device.timeseriesPollPeriod"
min="1"
>
<div ng-messages="theForm['timeseriesPollPeriod_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
<div translate
ng-message="min"
>extension.modbus-poll-period-range</div>
</div>
</md-input-container>
</div>
<v-accordion id="modbus-attributes-accordion"
class="vAccordion--default"
onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
<v-pane id="modbus-attributes-pane_{{serverIndex}}{{deviceIndex}}">
<v-pane-header>
{{ 'extension.attributes' | translate }}
</v-pane-header>
<v-pane-content>
<div ng-show="device.attributes.length > 0">
<ol class="list-group">
<li class="list-group-item"
ng-repeat="(attributeIndex, attribute) in device.attributes"
>
<md-button aria-label="{{ 'action.remove' | translate }}"
class="md-icon-button"
ng-click="removeItem(attribute, device.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="50" class="md-block">
<label translate>extension.modbus-tag</label>
<input required
name="modbusAttributeTag_{{serverIndex}}{{deviceIndex}}{{attributeIndex}}"
ng-model="attribute.tag"
>
<div ng-messages="theForm['modbusAttributeTag_' + serverIndex + deviceIndex + attributeIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
</div>
</md-input-container>
<md-input-container flex="30" class="md-block tb-container-for-select">
<label translate>extension.type</label>
<md-select required name="modbusAttributeType_{{serverIndex}}{{deviceIndex}}{{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['modbusAttributeType_' + serverIndex + deviceIndex + attributeIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
</div>
</md-input-container>
<md-input-container flex="20" class="md-block">
<label translate>extension.modbus-poll-period</label>
<input type="number"
name="pollPeriod_{{serverIndex}}{{deviceIndex}}"
ng-model="attribute.pollPeriod"
min="1"
>
<div ng-messages="theForm['pollPeriod_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="min"
>extension.modbus-poll-period-range</div>
</div>
</md-input-container>
</section>
<section flex layout="row">
<md-input-container flex="50" class="md-block tb-container-for-select">
<label translate>extension.type</label>
<md-select required name="modbusAttributeFunctionCode_{{serverIndex}}{{deviceIndex}}{{attributeIndex}}"
ng-model="attribute.functionCode"
>
<md-option ng-repeat="(functionCode, functionName) in types.extensionModbusFunctionCodes"
ng-value="functionCode"
>
{{functionName}}
</md-option>
</md-select>
<div ng-messages="theForm['modbusAttributeFunctionCode_' + serverIndex + deviceIndex + attributeIndex].$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.modbus-register-address</label>
<input type="number"
required
name="address_{{serverIndex}}{{deviceIndex}}"
ng-model="attribute.address"
min="0"
max="65535"
>
<div ng-messages="theForm['address_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
<div translate
ng-message="min"
>extension.modbus-register-address-range</div>
<div translate
ng-message="max"
>extension.modbus-register-address-range</div>
</div>
</md-input-container>
</section>
<section flex layout="row">
<md-input-container flex="50" class="md-block" ng-if="attribute.type != 'boolean'">
<label translate>extension.modbus-register-count</label>
<input type="number"
name="registerCount_{{serverIndex}}{{deviceIndex}}"
ng-model="attribute.registerCount"
min="1"
>
<div ng-messages="theForm['registerCount_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="min"
>extension.modbus-register-count-range</div>
</div>
</md-input-container>
<md-input-container flex="50" class="md-block" ng-if="attribute.type == 'boolean' && attribute.functionCode >= 3">
<label translate>extension.modbus-register-bit-index</label>
<input type="number"
required
name="bit_{{serverIndex}}{{deviceIndex}}"
ng-model="attribute.bit"
min="0"
max="15"
>
<div ng-messages="theForm['bit_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
<div translate
ng-message="min"
>extension.modbus-register-bit-index-range</div>
<div translate
ng-message="max"
>extension.modbus-register-bit-index-range</div>
</div>
</md-input-container>
</section>
<section flex layout="row">
<md-input-container flex="100" class="md-block" ng-if="attribute.functionCode >= 3">
<label translate>extension.modbus-byte-order</label>
<input required
name="modbusByteOrder_{{serverIndex}}{{deviceIndex}}{{attributeIndex}}"
ng-model="attribute.byteOrder"
>
<div ng-messages="theForm['modbusByteOrder_' + serverIndex + deviceIndex + attributeIndex].$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="addNewAttribute(device)"
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 id="modbus-timeseries-accordion" class="vAccordion--default" onexpand="expandValidation(index, id)" oncollapse="collapseValidation(index, id)">
<v-pane id="modbus-timeseries-pane_{{serverIndex}}{{deviceIndex}}">
<v-pane-header>
{{ 'extension.timeseries' | translate }}
</v-pane-header>
<v-pane-content>
<div ng-show="device.timeseries.length > 0">
<ol class="list-group">
<li class="list-group-item"
ng-repeat="(timeseriesIndex, timeserie) in device.timeseries"
>
<md-button aria-label="{{ 'action.remove' | translate }}"
class="md-icon-button"
ng-click="removeItem(timeserie, device.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="50" class="md-block">
<label translate>extension.modbus-tag</label>
<input required
name="modbusTimeserieTag_{{serverIndex}}{{deviceIndex}}{{timeseriesIndex}}"
ng-model="timeserie.tag"
>
<div ng-messages="theForm['modbusTimeserieTag_' + serverIndex + deviceIndex + timeseriesIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
</div>
</md-input-container>
<md-input-container flex="30" class="md-block tb-container-for-select">
<label translate>extension.type</label>
<md-select required name="modbusTimeserieType_{{serverIndex}}{{deviceIndex}}{{timeseriesIndex}}"
ng-model="timeserie.type"
>
<md-option ng-repeat="(attrType, attrTypeValue) in types.extensionValueType"
ng-value="attrType"
>
{{attrTypeValue | translate}}
</md-option>
</md-select>
<div ng-messages="theForm['modbusTimeserieType_' + serverIndex + deviceIndex + timeseriesIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
</div>
</md-input-container>
<md-input-container flex="20" class="md-block">
<label translate>extension.modbus-poll-period</label>
<input type="number"
name="pollPeriod_{{serverIndex}}{{deviceIndex}}"
ng-model="timeserie.pollPeriod"
min="1"
>
<div ng-messages="theForm['pollPeriod_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="min"
>extension.modbus-poll-period-range</div>
</div>
</md-input-container>
</section>
<section flex layout="row">
<md-input-container flex="50" class="md-block tb-container-for-select">
<label translate>extension.type</label>
<md-select required name="modbusTimeserieFunctionCode_{{serverIndex}}{{deviceIndex}}{{timeseriesIndex}}"
ng-model="timeserie.functionCode"
>
<md-option ng-repeat="(functionCode, functionName) in types.extensionModbusFunctionCodes"
ng-value="functionCode"
>
{{functionName}}
</md-option>
</md-select>
<div ng-messages="theForm['modbusTimeserieFunctionCode_' + serverIndex + deviceIndex + timeseriesIndex].$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.modbus-register-address</label>
<input type="number"
required
name="address_{{serverIndex}}{{deviceIndex}}"
ng-model="timeserie.address"
min="0"
max="65535"
>
<div ng-messages="theForm['address_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
<div translate
ng-message="min"
>extension.modbus-register-address-range</div>
<div translate
ng-message="max"
>extension.modbus-register-address-range</div>
</div>
</md-input-container>
</section>
<section flex layout="row">
<md-input-container flex="50" class="md-block" ng-if="timeserie.type != 'boolean'">
<label translate>extension.modbus-register-count</label>
<input type="number"
name="registerCount_{{serverIndex}}{{deviceIndex}}"
ng-model="timeserie.registerCount"
min="1"
>
<div ng-messages="theForm['registerCount_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="min"
>extension.modbus-register-count-range</div>
</div>
</md-input-container>
<md-input-container flex="50" class="md-block" ng-if="timeserie.type == 'boolean' && timeserie.functionCode >= 3">
<label translate>extension.modbus-register-bit-index</label>
<input type="number"
required
name="bit_{{serverIndex}}{{deviceIndex}}"
ng-model="timeserie.bit"
min="0"
max="15"
>
<div ng-messages="theForm['bit_' + serverIndex + deviceIndex].$error">
<div translate
ng-message="required"
>extension.field-required</div>
<div translate
ng-message="min"
>extension.modbus-register-bit-index-range</div>
<div translate
ng-message="max"
>extension.modbus-register-bit-index-range</div>
</div>
</md-input-container>
</section>
<section flex layout="row">
<md-input-container flex="100" class="md-block" ng-if="timeserie.functionCode >= 3">
<label translate>extension.modbus-byte-order</label>
<input required
name="modbusByteOrder_{{serverIndex}}{{deviceIndex}}{{timeseriesIndex}}"
ng-model="timeserie.byteOrder"
>
<div ng-messages="theForm['modbusByteOrder_' + serverIndex + deviceIndex + timeseriesIndex].$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="addNewTimeseries(device)"
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="addDevice(server.devices)"
aria-label="{{ 'action.add' | translate }}"
>
<md-icon class="material-icons">add</md-icon>
<span translate>extension.add-device</span>
</md-button>
</div>
</v-pane-content>
</v-pane>
</v-accordion>
</md-card-content>
</md-card>
</li>
</ol>
<div flex
layout="row"
layout-align="start center"
>
<md-button class="md-primary md-raised"
ng-click="addServer(configuration.servers)"
aria-label="{{ 'action.add' | translate }}"
>
<md-icon class="material-icons">add</md-icon>
<span translate>extension.modbus-add-server</span>
</md-button>
</div>
</div>
</v-pane-content>
</v-pane>
</v-accordion>
<!--{{config}}-->
</md-card-content>
</md-card>