home.wxml 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <navigation-bar background="#FFF"></navigation-bar>
  2. <view wx:if="{{toastText}}" class="page-toast page-toast--{{toastType}}">
  3. {{toastText}}
  4. </view>
  5. <scroll-view class="scrollarea" scroll-y type="list">
  6. <view class="page-shell">
  7. <view class="connected-panel">
  8. <view class="panel-header panel-header--with-actions">
  9. <view class="panel-icon icon-bluetooth"></view>
  10. <view class="panel-title">连接状态</view>
  11. <view class="panel-actions connection-actions">
  12. <view
  13. class="panel-action-button {{canSyncRegisters ? '' : 'is-disabled'}}"
  14. bindtap="syncRegisters"
  15. >
  16. 同步
  17. </view>
  18. <view
  19. class="panel-action-button {{canStartScan ? '' : 'is-disabled'}}"
  20. bindtap="startScan"
  21. >
  22. {{scanButtonText}}
  23. </view>
  24. <view
  25. class="panel-action-button {{canClearDevices ? '' : 'is-disabled'}}"
  26. bindtap="clearDevices"
  27. >
  28. 清空
  29. </view>
  30. <view
  31. class="panel-action-button {{canDisconnectDevice ? '' : 'is-disabled'}}"
  32. bindtap="disconnectDevice"
  33. >
  34. 断开
  35. </view>
  36. </view>
  37. </view>
  38. <view class="connected-summary">
  39. <view class="connected-name">
  40. {{connectionName}}
  41. </view>
  42. </view>
  43. <view class="device-badges connection-badges">
  44. <view class="connect-state {{connectedDevice ? 'connected' : ''}}">{{connectionStatusText}}</view>
  45. <view class="rssi">{{connectionSignalText}}</view>
  46. <view class="traffic-badge">{{txCount}} / {{rxCount}} bytes</view>
  47. </view>
  48. <view class="meta-grid">
  49. <view class="meta-item">
  50. <text class="meta-label">设备 ID</text>
  51. <text class="meta-value">{{connectionDeviceId}}</text>
  52. </view>
  53. <view class="meta-item">
  54. <text class="meta-label">服务数</text>
  55. <text class="meta-value">{{connectionServiceCount}}</text>
  56. </view>
  57. <view class="meta-item">
  58. <text class="meta-label">特征值</text>
  59. <text class="meta-value">{{connectionCharacteristicText}}</text>
  60. </view>
  61. </view>
  62. </view>
  63. <view wx:if="{{showDeviceSection}}" class="device-section">
  64. <view class="panel-header outside-header">
  65. <view class="panel-icon icon-radar"></view>
  66. <view class="panel-title">附近设备 {{deviceCountText}}</view>
  67. <view class="device-filter">
  68. <view
  69. wx:for="{{deviceFilterOptions}}"
  70. wx:key="key"
  71. class="device-filter-item {{deviceFilterMode === item.key ? 'is-active' : ''}}"
  72. data-filter="{{item.key}}"
  73. bindtap="onDeviceFilterTap"
  74. >
  75. {{item.label}}
  76. </view>
  77. </view>
  78. </view>
  79. <scroll-view class="device-scroll" scroll-y type="list">
  80. <view wx:if="{{!devices.length}}" class="empty-state">
  81. <view class="empty-title">{{emptyDeviceTitle}}</view>
  82. <view class="empty-text">{{emptyDeviceText}}</view>
  83. </view>
  84. <view
  85. wx:for="{{devices}}"
  86. wx:key="deviceId"
  87. class="device-card {{connectedDevice && connectedDevice.deviceId === item.deviceId ? 'device-card--connected' : ''}}"
  88. data-device-id="{{item.deviceId}}"
  89. bindtap="connectDevice"
  90. >
  91. <view class="device-info">
  92. <view class="device-main-row">
  93. <view class="device-name">{{item.displayName}}</view>
  94. <view class="device-badges">
  95. <view class="rssi">{{item.signalText}}</view>
  96. <view wx:if="{{connectingDeviceId === item.deviceId}}" class="connect-state">连接中</view>
  97. <view wx:elif="{{connectedDevice && connectedDevice.deviceId === item.deviceId}}" class="connect-state connected">已连接</view>
  98. <view wx:else class="connect-state">连接</view>
  99. </view>
  100. </view>
  101. <view class="device-id">{{item.deviceId}}</view>
  102. <view class="device-meta-row">
  103. <view class="device-service">{{item.serviceText}}</view>
  104. <view wx:if="{{item.targetText}}" class="device-target">{{item.targetText}}</view>
  105. </view>
  106. </view>
  107. </view>
  108. </scroll-view>
  109. </view>
  110. <view class="panel">
  111. <view class="panel-header panel-header--with-actions">
  112. <view class="panel-icon icon-terminal"></view>
  113. <view class="panel-title">Modbus RTU 指令</view>
  114. <view class="panel-actions">
  115. <view
  116. class="panel-action-button {{!connectedDevice || !generatedHex ? 'is-disabled' : ''}}"
  117. bindtap="sendGeneratedFrame"
  118. >
  119. 下发
  120. </view>
  121. </view>
  122. </view>
  123. <view class="protocol-form">
  124. <view class="protocol-row">
  125. <text class="protocol-label">功能码</text>
  126. <picker
  127. class="protocol-picker"
  128. mode="selector"
  129. range="{{protocolCommands}}"
  130. range-key="label"
  131. value="{{commandIndex}}"
  132. bindchange="onCommandChange"
  133. >
  134. <view class="picker-value">{{protocolCommands[commandIndex].label}}</view>
  135. </picker>
  136. </view>
  137. <view class="protocol-row protocol-field-row">
  138. <text class="protocol-label">从站地址</text>
  139. <input
  140. class="protocol-input protocol-row-input"
  141. type="text"
  142. maxlength="2"
  143. value="{{slaveAddress}}"
  144. bindinput="onSlaveAddressInput"
  145. />
  146. </view>
  147. <view class="protocol-row protocol-field-row">
  148. <text class="protocol-label">协议寄存器</text>
  149. <input
  150. class="protocol-input protocol-row-input"
  151. type="text"
  152. maxlength="4"
  153. value="{{registerAddress}}"
  154. bindinput="onRegisterAddressInput"
  155. />
  156. </view>
  157. <view wx:if="{{showCommandValue}}" class="protocol-row protocol-field-row">
  158. <text class="protocol-label">{{commandValueLabel}}</text>
  159. <input
  160. class="protocol-input protocol-row-input"
  161. type="text"
  162. value="{{commandValue}}"
  163. bindinput="onCommandValueInput"
  164. />
  165. </view>
  166. <view wx:if="{{showCoilValue}}" class="protocol-row coil-row">
  167. <text class="protocol-label">线圈值</text>
  168. <view class="coil-control">
  169. <text>{{coilEnabled ? 'ON' : 'OFF'}}</text>
  170. <switch checked="{{coilEnabled}}" color="#0f766e" bindchange="onCoilValueChange" />
  171. </view>
  172. </view>
  173. <view class="generated-frame">
  174. <view class="generated-title">生成帧</view>
  175. <view class="generated-value">{{generatedHex || '--'}}</view>
  176. <view wx:if="{{protocolErrorText}}" class="protocol-error">{{protocolErrorText}}</view>
  177. </view>
  178. </view>
  179. </view>
  180. <view class="panel">
  181. <view class="panel-header panel-header--with-actions">
  182. <view class="panel-icon icon-send"></view>
  183. <view class="panel-title">发送</view>
  184. <view class="panel-actions">
  185. <view class="panel-action-button" bindtap="clearInput">清空</view>
  186. <view
  187. class="panel-action-button {{!connectedDevice ? 'is-disabled' : ''}}"
  188. bindtap="sendHexFrame"
  189. >
  190. 发送
  191. </view>
  192. </view>
  193. </view>
  194. <textarea
  195. class="hex-input"
  196. maxlength="-1"
  197. auto-height
  198. placeholder="例如:01 03 00 00 00 01 84 0A"
  199. value="{{sendHex}}"
  200. bindinput="onHexInput"
  201. />
  202. </view>
  203. <view class="panel">
  204. <view class="panel-header panel-header--with-actions log-header">
  205. <view class="panel-icon icon-history"></view>
  206. <view class="panel-title">收发日志 {{logs.length ? '(' + logs.length + ')' : ''}}</view>
  207. <view class="panel-actions">
  208. <view class="panel-action-button" bindtap="clearLogs">清空</view>
  209. </view>
  210. </view>
  211. <scroll-view
  212. class="log-scroll"
  213. scroll-y
  214. scroll-with-animation
  215. scroll-into-view="{{logScrollTarget}}"
  216. type="list"
  217. >
  218. <view wx:if="{{!logs.length}}" class="empty-log">暂无收发数据</view>
  219. <view
  220. wx:for="{{logs}}"
  221. wx:key="id"
  222. id="{{item.id}}"
  223. class="log-row log-row--{{item.direction}}"
  224. >
  225. <view class="log-meta">
  226. <view class="log-tags">
  227. <text class="log-direction">{{item.direction}}</text>
  228. <text wx:if="{{item.note}}" class="log-note">{{item.note}}</text>
  229. </view>
  230. <text class="log-time">{{item.time}}</text>
  231. </view>
  232. <view class="log-payload">{{item.payload}}</view>
  233. </view>
  234. </scroll-view>
  235. </view>
  236. </view>
  237. </scroll-view>