1
0

params.wxml 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. <navigation-bar background="{{themeMode === 'dark' ? '#111827' : '#FFF'}}"></navigation-bar>
  2. <view wx:if="{{toastText}}" class="page-toast page-toast--{{toastType}} {{themeClass}}">
  3. {{toastText}}
  4. </view>
  5. <view wx:if="{{activeParamView}}" class="subpage-fixed-header {{activeParamView == 'genericModbus' || activeParamView == 'genericModbusGroup' ? 'subpage-fixed-header--generic' : ''}} {{themeClass}}">
  6. <view class="subpage-page-header">
  7. <view wx:if="{{!(isGenericProtocol && activeParamView == 'genericModbus')}}" class="subpage-back" bindtap="backToParamsHome">
  8. <view class="subpage-back-icon"></view>
  9. </view>
  10. <view class="subpage-page-title">
  11. {{activeParamView == 'driver' ? '驱动器参数' : activeParamView == 'protection' ? '保护' : activeParamView == 'estimator' ? '估算器参数' : activeParamView == 'dq' ? 'DQ轴电流环参数' : activeParamView == 'startup' ? '启动位置管理' : activeParamView == 'speed' ? '速度管理' : activeParamView == 'genericModbus' ? '' : activeParamView == 'genericModbusGroup' ? (activeGenericGroup.name || '寄存器组') : activeParamView == 'status' ? '状态' : ''}}
  12. </view>
  13. <view wx:if="{{activeParamView == 'driver'}}" class="panel-actions subpage-actions">
  14. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" bindtap="readDriverPageParameters">读取</view>
  15. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" bindtap="writeMotorParameters">写入</view>
  16. </view>
  17. <view wx:elif="{{activeParamView == 'protection'}}" class="panel-actions subpage-actions">
  18. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" data-group="protection" bindtap="onGroupRead">读取</view>
  19. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" data-group="protection" bindtap="onGroupWrite">写入</view>
  20. </view>
  21. <view wx:elif="{{activeParamView == 'estimator'}}" class="panel-actions panel-actions--three subpage-actions">
  22. <view class="panel-action-button" bindtap="onEstimatorUpdate">更新</view>
  23. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" data-group="estimator" bindtap="onGroupRead">读取</view>
  24. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" data-group="estimator" bindtap="onGroupWrite">写入</view>
  25. </view>
  26. <view wx:elif="{{activeParamView == 'dq'}}" class="panel-actions subpage-actions">
  27. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" data-group="dq" bindtap="onGroupRead">读取</view>
  28. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" data-group="dq" bindtap="onGroupWrite">写入</view>
  29. </view>
  30. <view wx:elif="{{activeParamView == 'startup'}}" class="panel-actions subpage-actions">
  31. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" bindtap="readStartupManagement">读取</view>
  32. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" bindtap="writeStartupManagement">写入</view>
  33. </view>
  34. <view wx:elif="{{activeParamView == 'speed'}}" class="panel-actions subpage-actions">
  35. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" bindtap="readSpeedManagement">读取</view>
  36. <view class="panel-action-button {{connectedDevice ? '' : 'is-disabled'}}" bindtap="writeSpeedManagement">写入</view>
  37. </view>
  38. <view wx:elif="{{activeParamView == 'genericModbus'}}" class="panel-actions subpage-actions">
  39. <view class="panel-action-button" bindtap="saveGenericModbusJson">保存</view>
  40. <view class="panel-action-button" bindtap="importGenericModbusJson">加载</view>
  41. <view class="panel-action-button panel-action-button--icon" bindtap="openGenericModbusDraft">+</view>
  42. </view>
  43. <view wx:elif="{{activeParamView == 'genericModbusGroup'}}" class="panel-actions subpage-actions">
  44. <view
  45. class="panel-action-button {{connectedDevice && !activeGenericGroup.addressOverflow ? '' : 'is-disabled'}}"
  46. data-group-id="{{activeGenericGroup.id}}"
  47. bindtap="readGenericModbusGroup"
  48. >读取</view>
  49. <view
  50. wx:if="{{activeGenericGroup.writable}}"
  51. class="panel-action-button {{connectedDevice && !activeGenericGroup.addressOverflow ? '' : 'is-disabled'}}"
  52. data-group-id="{{activeGenericGroup.id}}"
  53. bindtap="writeGenericModbusGroup"
  54. >写入</view>
  55. </view>
  56. <view wx:elif="{{activeParamView == 'status'}}" class="panel-actions subpage-actions">
  57. <view class="panel-action-button {{canReadStatus ? '' : 'is-disabled'}}" bindtap="readStatus">读取</view>
  58. </view>
  59. </view>
  60. </view>
  61. <scroll-view class="scrollarea {{themeClass}} {{activeParamView ? 'scrollarea--subpage' : ''}} {{activeParamView == 'genericModbus' || activeParamView == 'genericModbusGroup' ? 'scrollarea--generic' : ''}}" scroll-y type="list">
  62. <view class="page-shell">
  63. <block wx:if="{{activeParamView == 'driver'}}">
  64. <view class="panel driver-summary-panel">
  65. <view class="driver-summary-row driver-summary-row--top">
  66. <text class="driver-summary-chip">{{chipModel || '--'}}</text>
  67. <text class="driver-summary-checksum">{{flashChecksum || '--'}}</text>
  68. </view>
  69. <view class="driver-summary-row driver-summary-row--model">
  70. <text class="driver-summary-model">{{motorModel || '--'}}</text>
  71. </view>
  72. </view>
  73. <view class="panel params-section-panel">
  74. <view class="params-section-title">硬件参数</view>
  75. <view wx:for="{{readonlyParamRegisters}}" wx:key="name" class="param-row">
  76. <view class="param-main">
  77. <view class="param-name">{{item.name}}</view>
  78. <view wx:if="{{!item.hideMeta}}" class="param-meta">{{item.addressDisplay}}</view>
  79. </view>
  80. <view class="param-value">{{item.displayValue || '--'}}{{item.unit ? ' ' + item.unit : ''}}</view>
  81. </view>
  82. </view>
  83. <view class="panel params-section-panel">
  84. <view class="params-section-title">电机参数</view>
  85. <view wx:for="{{motorParameterInputRegisters}}" wx:key="name" class="param-row input-row">
  86. <view class="param-main">
  87. <view class="param-name">{{item.name}}</view>
  88. <view class="param-meta {{item.isDirty ? 'param-meta--dirty' : ''}}">{{item.addressDisplay}} {{item.writeValue || '--'}}</view>
  89. </view>
  90. <view class="input-wrap">
  91. <input
  92. class="value-input value-input--with-unit"
  93. type="{{item.unit ? 'text' : 'digit'}}"
  94. placeholder="--"
  95. value="{{item.inputValue}}"
  96. data-index="{{index}}"
  97. bindinput="onMotorParameterInput"
  98. bindblur="onMotorParameterBlur"
  99. />
  100. </view>
  101. </view>
  102. </view>
  103. </block>
  104. <block wx:elif="{{activeParamView == 'protection'}}">
  105. <view
  106. wx:for="{{protectionSections}}"
  107. wx:for-item="section"
  108. wx:key="key"
  109. class="panel protection-section-panel"
  110. >
  111. <view class="params-section-title">{{section.title}}</view>
  112. <view
  113. wx:for="{{section.rows}}"
  114. wx:for-item="row"
  115. wx:key="key"
  116. class="protection-field-row"
  117. >
  118. <view
  119. wx:for="{{row.fields}}"
  120. wx:for-item="field"
  121. wx:key="name"
  122. class="protection-field protection-field--{{field.kind}}"
  123. >
  124. <view class="protection-field-main">
  125. <view class="param-name">{{field.label}}</view>
  126. <view class="param-meta {{field.isDirty ? 'param-meta--dirty' : ''}}">{{field.addressDisplay}} {{field.metaValue}}</view>
  127. </view>
  128. <switch
  129. wx:if="{{field.kind == 'switch'}}"
  130. checked="{{field.value}}"
  131. color="#0f766e"
  132. disabled="{{!connectedDevice}}"
  133. data-index="{{field.sourceIndex}}"
  134. bindchange="onProtectionSwitchChange"
  135. />
  136. <view wx:else class="input-wrap">
  137. <input
  138. class="value-input {{field.unit ? 'value-input--with-unit' : ''}}"
  139. type="{{field.unit ? 'text' : 'digit'}}"
  140. placeholder="--"
  141. value="{{field.inputValue}}"
  142. data-index="{{field.sourceIndex}}"
  143. data-input-group="protection"
  144. bindinput="onProtectionInputChange"
  145. bindblur="onInputBlur"
  146. />
  147. </view>
  148. </view>
  149. </view>
  150. </view>
  151. </block>
  152. <block wx:elif="{{activeParamView == 'estimator'}}">
  153. <view class="panel params-section-panel">
  154. <view wx:for="{{estimatorCalculatedDisplayRegisters}}" wx:key="name" class="param-row">
  155. <view class="param-main">
  156. <view class="param-name">{{item.name}}</view>
  157. <view class="param-meta {{item.isDirty ? 'param-meta--dirty' : ''}}">{{item.addressDisplay}} {{item.writeValue || '--'}}</view>
  158. </view>
  159. <view class="param-value">{{item.writeValue || '--'}}{{item.unit ? ' ' + item.unit : ''}}</view>
  160. </view>
  161. <view
  162. wx:for="{{atoBandwidthDisplayRegisters}}"
  163. wx:for-item="atoItem"
  164. wx:key="name"
  165. class="param-row input-row"
  166. >
  167. <view class="param-main">
  168. <view class="param-name">{{atoItem.name}}</view>
  169. <view class="param-meta {{atoItem.isDirty ? 'param-meta--dirty' : ''}}">KP 0x{{atoItem.kpAddress}} {{atoItem.kpWriteValue || '--'}} KI 0x{{atoItem.kiAddress}} {{atoItem.kiWriteValue || '--'}}</view>
  170. </view>
  171. <view class="input-wrap">
  172. <input
  173. class="value-input {{atoItem.unit ? 'value-input--with-unit' : ''}}"
  174. type="{{atoItem.unit ? 'text' : 'digit'}}"
  175. placeholder="--"
  176. value="{{atoItem.inputValue}}"
  177. data-index="{{atoItem.sourceIndex}}"
  178. data-input-group="ato"
  179. bindinput="onAtoBandwidthInput"
  180. bindblur="onInputBlur"
  181. />
  182. </view>
  183. </view>
  184. </view>
  185. </block>
  186. <block wx:elif="{{activeParamView == 'dq'}}">
  187. <view class="panel params-section-panel">
  188. <view
  189. wx:for="{{dqGainDisplayRegisters}}"
  190. wx:for-item="dqItem"
  191. wx:key="name"
  192. class="param-row input-row"
  193. >
  194. <view class="param-main">
  195. <view class="param-name">{{dqItem.name}}</view>
  196. <view class="param-meta {{dqItem.isDirty ? 'param-meta--dirty' : ''}}">{{dqItem.addressDisplay}} {{dqItem.writeValue || '--'}}</view>
  197. </view>
  198. <view class="input-wrap">
  199. <input
  200. class="value-input {{dqItem.unit ? 'value-input--with-unit' : ''}}"
  201. type="{{dqItem.unit ? 'text' : 'digit'}}"
  202. placeholder="--"
  203. value="{{dqItem.inputValue}}"
  204. data-index="{{dqItem.sourceIndex}}"
  205. data-input-group="dq"
  206. bindinput="onDqGainInput"
  207. bindblur="onInputBlur"
  208. />
  209. </view>
  210. </view>
  211. </view>
  212. </block>
  213. <block wx:elif="{{activeParamView == 'startup'}}">
  214. <view class="panel params-section-panel">
  215. <view class="params-section-title">顺逆风配置</view>
  216. <view wx:for="{{tailwindControlRegisters}}" wx:key="address" class="param-row">
  217. <view class="param-main">
  218. <view class="param-name">{{item.name}}</view>
  219. <view class="param-meta {{item.isDirty ? 'param-meta--dirty' : ''}}">{{item.addressDisplay}} {{item.writeValue}}</view>
  220. </view>
  221. <switch
  222. checked="{{item.value}}"
  223. color="#0f766e"
  224. disabled="{{!connectedDevice}}"
  225. data-index="{{item.sourceIndex}}"
  226. bindchange="onTailwindSwitchChange"
  227. />
  228. </view>
  229. <view wx:for="{{tailwindCalculatedDisplayRegisters}}" wx:key="name" class="param-row">
  230. <view class="param-main">
  231. <view class="param-name">{{item.name}}</view>
  232. <view class="param-meta {{item.isDirty ? 'param-meta--dirty' : ''}}">{{item.addressDisplay}} {{item.writeValue || '--'}}</view>
  233. </view>
  234. <view class="param-value">{{item.writeValue || '--'}}{{item.unit ? ' ' + item.unit : ''}}</view>
  235. </view>
  236. <view
  237. wx:for="{{tailwindAtoBandwidthDisplayRegisters}}"
  238. wx:for-item="atoItem"
  239. wx:key="name"
  240. class="param-row input-row"
  241. >
  242. <view class="param-main">
  243. <view class="param-name">{{atoItem.name}}</view>
  244. <view class="param-meta {{atoItem.isDirty ? 'param-meta--dirty' : ''}}">KP 0x{{atoItem.kpAddress}} {{atoItem.kpWriteValue || '--'}} KI 0x{{atoItem.kiAddress}} {{atoItem.kiWriteValue || '--'}}</view>
  245. </view>
  246. <view class="input-wrap">
  247. <input
  248. class="value-input {{atoItem.unit ? 'value-input--with-unit' : ''}}"
  249. type="{{atoItem.unit ? 'text' : 'digit'}}"
  250. placeholder="--"
  251. value="{{atoItem.inputValue}}"
  252. data-index="{{atoItem.sourceIndex}}"
  253. data-input-group="ato"
  254. bindinput="onAtoBandwidthInput"
  255. bindblur="onInputBlur"
  256. />
  257. </view>
  258. </view>
  259. </view>
  260. <view class="panel params-section-panel">
  261. <view class="params-section-title">预定位配置</view>
  262. <view wx:for="{{prepositionSwitchRegisters}}" wx:key="address" class="param-row">
  263. <view class="param-main">
  264. <view class="param-name">{{item.name}}</view>
  265. <view class="param-meta {{item.isDirty ? 'param-meta--dirty' : ''}}">{{item.addressDisplay}} {{item.writeValue}}</view>
  266. </view>
  267. <switch
  268. checked="{{item.value}}"
  269. color="#0f766e"
  270. disabled="{{!connectedDevice}}"
  271. data-index="{{item.sourceIndex}}"
  272. bindchange="onTailwindSwitchChange"
  273. />
  274. </view>
  275. <view wx:for="{{prepositionParameterDisplayRegisters}}" wx:key="name" class="param-row input-row">
  276. <view class="param-main">
  277. <view class="param-name">{{item.name}}</view>
  278. <view class="param-meta {{item.isDirty ? 'param-meta--dirty' : ''}}">{{item.addressDisplay}} {{item.writeValue || '--'}}</view>
  279. </view>
  280. <view class="input-wrap">
  281. <input
  282. class="value-input {{item.unit ? 'value-input--with-unit' : ''}}"
  283. type="{{item.unit ? 'text' : 'digit'}}"
  284. placeholder="--"
  285. value="{{item.inputValue}}"
  286. data-index="{{item.sourceIndex}}"
  287. data-input-group="preposition"
  288. bindinput="onPrepositionParameterInput"
  289. bindblur="onInputBlur"
  290. />
  291. </view>
  292. </view>
  293. </view>
  294. </block>
  295. <block wx:elif="{{activeParamView == 'speed'}}">
  296. <view class="panel params-section-panel">
  297. <view class="params-section-title">速度环路</view>
  298. <view wx:for="{{speedLoopInputDisplayRegisters}}" wx:key="name">
  299. <view class="param-row input-row">
  300. <view class="param-main">
  301. <view class="param-name">{{item.name}}</view>
  302. <view class="param-meta {{item.isDirty ? 'param-meta--dirty' : ''}}">{{item.addressDisplay}} {{item.writeValue || '--'}}</view>
  303. </view>
  304. <view class="input-wrap">
  305. <input
  306. class="value-input {{item.unit ? 'value-input--with-unit' : ''}}"
  307. type="{{item.unit ? 'text' : 'digit'}}"
  308. placeholder="--"
  309. value="{{item.inputValue}}"
  310. data-index="{{item.sourceIndex}}"
  311. data-input-group="parameter"
  312. bindinput="onInputChange"
  313. bindblur="onInputBlur"
  314. />
  315. </view>
  316. </view>
  317. </view>
  318. <view wx:for="{{speedLoopExtraDisplayRegisters}}" wx:key="name">
  319. <view class="param-row input-row">
  320. <view class="param-main">
  321. <view class="param-name">{{item.name}}</view>
  322. <view class="param-meta {{item.isDirty ? 'param-meta--dirty' : ''}}">{{item.addressDisplay}} {{item.writeValue || '--'}}</view>
  323. </view>
  324. <view class="input-wrap">
  325. <input
  326. class="value-input {{item.unit ? 'value-input--with-unit' : ''}}"
  327. type="{{item.unit ? 'text' : 'digit'}}"
  328. placeholder="--"
  329. value="{{item.inputValue}}"
  330. data-index="{{item.sourceIndex}}"
  331. data-input-group="speedLoopExtra"
  332. bindinput="onSpeedLoopExtraInput"
  333. bindblur="onInputBlur"
  334. />
  335. </view>
  336. </view>
  337. </view>
  338. </view>
  339. <view class="panel params-section-panel">
  340. <view class="params-section-title">VSP曲线</view>
  341. <view wx:for="{{vspCurveRegisters}}" wx:key="name">
  342. <view class="param-row input-row">
  343. <view class="param-main">
  344. <view class="param-name">{{item.name}}</view>
  345. <view class="param-meta {{item.isDirty ? 'param-meta--dirty' : ''}}">{{item.addressDisplay}} {{item.writeValue || '--'}}{{item.actualText ? ' ' + item.actualText : ''}}</view>
  346. </view>
  347. <view class="input-wrap">
  348. <input
  349. class="value-input {{item.unit ? 'value-input--with-unit' : ''}}"
  350. type="{{item.unit ? 'text' : 'digit'}}"
  351. placeholder="--"
  352. value="{{item.inputValue}}"
  353. data-index="{{item.sourceIndex}}"
  354. data-input-group="parameter"
  355. bindinput="onInputChange"
  356. bindblur="onInputBlur"
  357. />
  358. </view>
  359. </view>
  360. </view>
  361. <view class="param-row">
  362. <view class="param-main">
  363. <view class="param-name">{{speedSlopeRegister.name}}</view>
  364. <view class="param-meta {{speedSlopeRegister.isDirty ? 'param-meta--dirty' : ''}}">{{speedSlopeRegister.addressDisplay}} {{speedSlopeRegister.writeValue || '--'}}</view>
  365. </view>
  366. <view class="param-value">{{speedSlopeRegister.writeValue || '--'}}{{speedSlopeRegister.unit ? ' ' + speedSlopeRegister.unit : ''}}</view>
  367. </view>
  368. </view>
  369. <view class="panel params-section-panel">
  370. <view class="params-section-title">上油参数</view>
  371. <view wx:for="{{oilParameterInputRegisters}}" wx:key="name" class="param-row input-row">
  372. <view class="param-main">
  373. <view class="param-name">{{item.name}}</view>
  374. <view class="param-meta {{item.isDirty ? 'param-meta--dirty' : ''}}">{{item.addressDisplay}} {{item.writeValue || '--'}}</view>
  375. </view>
  376. <view class="input-wrap">
  377. <input
  378. class="value-input {{item.unit ? 'value-input--with-unit' : ''}}"
  379. type="{{item.unit ? 'text' : 'digit'}}"
  380. placeholder="--"
  381. value="{{item.inputValue}}"
  382. data-index="{{index}}"
  383. data-input-group="oil"
  384. bindinput="onOilParameterInput"
  385. bindblur="onInputBlur"
  386. />
  387. </view>
  388. </view>
  389. </view>
  390. </block>
  391. <block wx:elif="{{activeParamView == 'genericModbus'}}">
  392. <view wx:if="{{!genericModbusGroups.length && !genericModbusDialog.visible}}" class="empty-state generic-empty-state">
  393. <view class="empty-title">暂无寄存器组</view>
  394. <view class="empty-text">点击右上角 + 添加,或从聊天记录导入 JSON</view>
  395. </view>
  396. <view
  397. wx:for="{{genericModbusGroups}}"
  398. wx:for-item="group"
  399. wx:key="id"
  400. class="generic-group-shell {{group.deleteVisible ? 'is-delete-visible' : ''}}"
  401. >
  402. <view
  403. wx:if="{{!group.expanded && group.deleteVisible}}"
  404. class="generic-delete-action"
  405. data-group-id="{{group.id}}"
  406. bindtap="deleteGenericModbusGroup"
  407. >
  408. -
  409. </view>
  410. <view
  411. class="panel generic-group-panel {{group.expanded ? '' : 'panel--collapsed'}}"
  412. data-group-id="{{group.id}}"
  413. bindtouchstart="onGenericGroupTouchStart"
  414. bindtouchend="onGenericGroupTouchEnd"
  415. >
  416. <view class="panel-header panel-header--with-actions">
  417. <view
  418. class="panel-heading-toggle"
  419. data-group-id="{{group.id}}"
  420. bindtap="openGenericModbusGroup"
  421. >
  422. <view class="panel-icon icon-terminal"></view>
  423. <view class="generic-group-title-wrap">
  424. <view class="panel-title" data-group-id="{{group.id}}" catchlongpress="openGenericGroupEdit">{{group.name}}</view>
  425. <view class="param-meta generic-group-meta">{{group.addressRangeText}} · {{group.quantity}}/{{group.wordQuantity}}{{group.addressWarningText ? ' · ' + group.addressWarningText : ''}}</view>
  426. </view>
  427. </view>
  428. <view class="panel-actions generic-group-actions">
  429. <view
  430. class="panel-action-button {{connectedDevice && !group.addressOverflow ? '' : 'is-disabled'}}"
  431. data-group-id="{{group.id}}"
  432. bindtap="readGenericModbusGroup"
  433. >
  434. 读取
  435. </view>
  436. <view
  437. wx:if="{{group.writable}}"
  438. class="panel-action-button {{connectedDevice && !group.addressOverflow ? '' : 'is-disabled'}}"
  439. data-group-id="{{group.id}}"
  440. bindtap="writeGenericModbusGroup"
  441. >
  442. 写入
  443. </view>
  444. <view class="entry-chevron"></view>
  445. </view>
  446. </view>
  447. </view>
  448. </view>
  449. </block>
  450. <block wx:elif="{{activeParamView == 'genericModbusGroup'}}">
  451. <view wx:if="{{activeGenericGroup}}" class="panel generic-group-detail-panel">
  452. <view class="generic-group-detail-meta">
  453. {{activeGenericGroup.addressRangeText}} · {{activeGenericGroup.quantity}}/{{activeGenericGroup.wordQuantity}}{{activeGenericGroup.addressWarningText ? ' · ' + activeGenericGroup.addressWarningText : ''}}
  454. </view>
  455. <view
  456. wx:for="{{activeGenericRegisterRows.length ? activeGenericRegisterRows : activeGenericGroup.registers}}"
  457. wx:for-item="register"
  458. wx:for-index="registerIndex"
  459. wx:key="id"
  460. class="generic-register-row {{register.dragClass}}"
  461. style="{{register.dragStyle}}"
  462. >
  463. <view
  464. wx:if="{{!activeGenericGroup.isStructLayout}}"
  465. class="generic-register-drag-handle {{register.dragHandleClass}}"
  466. data-group-id="{{activeGenericGroup.id}}"
  467. data-index="{{register.sourceIndex !== undefined ? register.sourceIndex : registerIndex}}"
  468. catchtouchstart="onGenericRegisterDragStart"
  469. catchtouchmove="onGenericRegisterDragMove"
  470. catchtouchend="onGenericRegisterDragEnd"
  471. catchtouchcancel="onGenericRegisterDragCancel"
  472. >
  473. <view class="generic-register-drag-bar"></view>
  474. <view class="generic-register-drag-bar"></view>
  475. <view class="generic-register-drag-bar"></view>
  476. </view>
  477. <view wx:else class="generic-register-layout-spacer"></view>
  478. <view class="generic-register-main">
  479. <view
  480. class="generic-register-name"
  481. data-group-id="{{activeGenericGroup.id}}"
  482. data-index="{{register.sourceIndex !== undefined ? register.sourceIndex : registerIndex}}"
  483. bindtap="openGenericRegisterInfo"
  484. catchlongpress="openGenericRegisterEdit"
  485. >
  486. {{register.name}}
  487. </view>
  488. <view class="generic-register-meta">
  489. <text>{{register.addressText}} {{register.rawValueText}}</text>
  490. </view>
  491. </view>
  492. <view class="generic-register-input-wrap {{register.showUnit && register.unit ? 'generic-register-input-wrap--unit' : ''}}">
  493. <block wx:if="{{activeGenericGroup.writable}}">
  494. <input
  495. class="value-input generic-register-value {{register.isDirty ? 'value-input--dirty' : ''}}"
  496. placeholder="--"
  497. data-group-id="{{activeGenericGroup.id}}"
  498. data-index="{{register.sourceIndex !== undefined ? register.sourceIndex : registerIndex}}"
  499. value="{{register.inputValue}}"
  500. bindinput="onGenericRegisterValueInput"
  501. bindblur="onGenericRegisterValueBlur"
  502. />
  503. <view wx:if="{{register.showUnit && register.unit}}" class="generic-register-unit">{{register.unit}}</view>
  504. </block>
  505. <view wx:else class="param-value generic-readonly-value">{{register.displayValue || '--'}}{{register.showUnit && register.unit ? ' ' + register.unit : ''}}</view>
  506. </view>
  507. </view>
  508. </view>
  509. </block>
  510. <block wx:elif="{{activeParamView == 'status'}}">
  511. <view wx:for="{{statusRegisterGroups}}" wx:for-item="group" wx:key="key" class="panel params-section-panel">
  512. <view class="params-section-title">{{group.title}}</view>
  513. <view wx:for="{{group.registers}}" wx:for-item="item" wx:key="name" class="param-row">
  514. <view class="param-main">
  515. <view class="param-name">{{item.name}}</view>
  516. <view class="param-meta">{{item.addressDisplay}} {{item.rawValue}}</view>
  517. </view>
  518. <view class="param-value">{{item.displayValue}}{{item.displayUnit ? ' ' + item.displayUnit : ''}}</view>
  519. </view>
  520. </view>
  521. <view wx:if="{{userStatusRegisters.length}}" class="panel params-section-panel">
  522. <view class="params-section-title">用户状态</view>
  523. <view wx:for="{{userStatusRegisters}}" wx:for-item="item" wx:key="name" class="param-row">
  524. <view class="param-main">
  525. <view class="param-name">{{item.name}}</view>
  526. <view class="param-meta">{{item.addressDisplay}} {{item.rawValue}}</view>
  527. </view>
  528. <view class="param-value">{{item.displayValue}}{{item.displayUnit ? ' ' + item.displayUnit : ''}}</view>
  529. </view>
  530. </view>
  531. </block>
  532. <block wx:else>
  533. <view class="panel panel--collapsed param-entry-panel" data-view="driver" bindtap="openParamView">
  534. <view class="panel-header panel-header--with-actions">
  535. <view class="panel-heading-toggle">
  536. <view class="panel-icon icon-chip"></view>
  537. <view class="panel-title">驱动器参数</view>
  538. </view>
  539. <view class="entry-chevron"></view>
  540. </view>
  541. </view>
  542. <view class="panel panel--collapsed param-entry-panel" data-view="estimator" bindtap="openParamView">
  543. <view class="panel-header panel-header--with-actions">
  544. <view class="panel-heading-toggle">
  545. <view class="panel-icon icon-bars"></view>
  546. <view class="panel-title">估算器参数</view>
  547. </view>
  548. <view class="entry-chevron"></view>
  549. </view>
  550. </view>
  551. <view class="panel panel--collapsed param-entry-panel" data-view="dq" bindtap="openParamView">
  552. <view class="panel-header panel-header--with-actions">
  553. <view class="panel-heading-toggle">
  554. <view class="panel-icon icon-tune"></view>
  555. <view class="panel-title">DQ轴电流环参数</view>
  556. </view>
  557. <view class="entry-chevron"></view>
  558. </view>
  559. </view>
  560. <view class="panel panel--collapsed param-entry-panel" data-view="startup" bindtap="openParamView">
  561. <view class="panel-header panel-header--with-actions">
  562. <view class="panel-heading-toggle">
  563. <view class="panel-icon icon-target"></view>
  564. <view class="panel-title">启动位置管理</view>
  565. </view>
  566. <view class="entry-chevron"></view>
  567. </view>
  568. </view>
  569. <view class="panel panel--collapsed param-entry-panel" data-view="speed" bindtap="openParamView">
  570. <view class="panel-header panel-header--with-actions">
  571. <view class="panel-heading-toggle">
  572. <view class="panel-icon icon-speed"></view>
  573. <view class="panel-title">速度管理</view>
  574. </view>
  575. <view class="entry-chevron"></view>
  576. </view>
  577. </view>
  578. <view class="panel panel--collapsed param-entry-panel" data-view="protection" bindtap="openParamView">
  579. <view class="panel-header panel-header--with-actions">
  580. <view class="panel-heading-toggle">
  581. <view class="panel-icon icon-shield-check"></view>
  582. <view class="panel-title">保护</view>
  583. </view>
  584. <view class="entry-chevron"></view>
  585. </view>
  586. </view>
  587. <view class="panel panel--collapsed param-entry-panel" data-view="status" bindtap="openParamView">
  588. <view class="panel-header panel-header--with-actions">
  589. <view class="panel-heading-toggle">
  590. <view class="panel-icon icon-status"></view>
  591. <view class="panel-title">状态</view>
  592. </view>
  593. <view class="entry-chevron"></view>
  594. </view>
  595. </view>
  596. </block>
  597. </view>
  598. </scroll-view>
  599. <view wx:if="{{genericModbusDialog.visible}}" class="generic-dialog-mask {{themeClass}}" bindtap="closeGenericModbusDraft">
  600. <view class="generic-dialog" catchtap="noop">
  601. <view class="generic-dialog-header">
  602. <view class="generic-dialog-title">{{genericModbusDialog.title}}</view>
  603. <view class="generic-dialog-close" bindtap="closeGenericModbusDraft">×</view>
  604. </view>
  605. <block wx:if="{{genericModbusDialog.mode == 'createGroup' || genericModbusDialog.mode == 'editGroup'}}">
  606. <view class="generic-dialog-body">
  607. <view class="generic-config-row">
  608. <view class="param-main">
  609. <view class="param-name">寄存器组名</view>
  610. <view class="param-meta">每组寄存器地址连续</view>
  611. </view>
  612. <input
  613. class="value-input generic-value-input"
  614. data-field="groupName"
  615. value="{{genericModbusDialog.groupName}}"
  616. bindinput="onGenericDraftInput"
  617. />
  618. </view>
  619. <view class="generic-config-row">
  620. <view class="param-main">
  621. <view class="param-name">寄存器类型</view>
  622. <view class="param-meta">决定读取功能码与是否可写</view>
  623. </view>
  624. <picker
  625. mode="selector"
  626. range="{{genericModbusRegisterTypeOptions}}"
  627. range-key="label"
  628. value="{{genericModbusDialog.registerTypeIndex}}"
  629. bindchange="onGenericDraftTypeChange"
  630. >
  631. <view class="generic-picker-value">{{genericModbusDialog.registerTypeText}}</view>
  632. </picker>
  633. </view>
  634. <view class="generic-config-row">
  635. <view class="param-main">
  636. <view class="param-name">寄存器起始地址</view>
  637. <view class="param-meta">16进制,例如 00A0</view>
  638. </view>
  639. <input
  640. class="value-input generic-value-input"
  641. data-field="startAddress"
  642. value="{{genericModbusDialog.startAddress}}"
  643. bindinput="onGenericDraftInput"
  644. />
  645. </view>
  646. <view class="generic-config-row">
  647. <view class="param-main">
  648. <view class="param-name">寄存器数量</view>
  649. <view class="param-meta">{{genericModbusDialog.structParsedSummary || '1 - 256'}}</view>
  650. </view>
  651. <input
  652. class="value-input generic-value-input"
  653. type="number"
  654. data-field="quantity"
  655. value="{{genericModbusDialog.quantity}}"
  656. bindinput="onGenericDraftInput"
  657. />
  658. </view>
  659. <view wx:if="{{genericModbusDialog.mode == 'createGroup'}}" class="generic-struct-section">
  660. <view class="generic-struct-header">
  661. <view class="param-main">
  662. <view class="param-name">结构体定义</view>
  663. <view class="param-meta">支持 typedef struct、typedef 别名与数组</view>
  664. </view>
  665. <view class="panel-action-button" bindtap="parseGenericStructDefinition">解析</view>
  666. </view>
  667. <textarea
  668. class="generic-struct-input"
  669. maxlength="-1"
  670. placeholder="粘贴 C 结构体定义"
  671. data-field="structDefinition"
  672. value="{{genericModbusDialog.structDefinition}}"
  673. bindinput="onGenericDraftInput"
  674. />
  675. </view>
  676. </view>
  677. </block>
  678. <block wx:elif="{{genericModbusDialog.mode == 'editRegister' || genericModbusDialog.mode == 'viewRegister'}}">
  679. <view class="generic-dialog-body">
  680. <view class="generic-info-stack">
  681. <view class="generic-info-row">
  682. <view class="generic-info-label">名称</view>
  683. <view wx:if="{{genericModbusDialog.mode == 'viewRegister'}}" class="generic-info-value">{{genericModbusDialog.name}}</view>
  684. <input wx:else class="value-input generic-value-input" data-field="name" value="{{genericModbusDialog.name}}" bindinput="onGenericDraftInput" />
  685. </view>
  686. <view class="generic-info-row">
  687. <view class="generic-info-label">地址</view>
  688. <view class="generic-info-value">{{genericModbusDialog.addressText}}</view>
  689. </view>
  690. <view wx:if="{{genericModbusDialog.showDataType}}" class="generic-info-row">
  691. <view class="generic-info-label">类型</view>
  692. <view wx:if="{{genericModbusDialog.mode == 'viewRegister'}}" class="generic-info-value">{{genericModbusDialog.dataTypeText}}</view>
  693. <picker wx:else mode="selector" range="{{genericModbusDataTypeOptions}}" range-key="label" value="{{genericModbusDialog.dataTypeIndex}}" bindchange="onGenericDialogDataTypeChange">
  694. <view class="generic-picker-value">{{genericModbusDialog.dataTypeText}}</view>
  695. </picker>
  696. </view>
  697. <view wx:if="{{genericModbusDialog.showTextLength}}" class="generic-info-row">
  698. <view class="generic-info-label">长度</view>
  699. <view wx:if="{{genericModbusDialog.mode == 'viewRegister'}}" class="generic-info-value">{{genericModbusDialog.textByteLength || '--'}}B</view>
  700. <input wx:else class="value-input generic-value-input" type="number" data-field="textByteLength" value="{{genericModbusDialog.textByteLength}}" bindinput="onGenericDraftInput" />
  701. </view>
  702. <view class="generic-info-row">
  703. <view class="generic-info-label">备注</view>
  704. <view wx:if="{{genericModbusDialog.mode == 'viewRegister'}}" class="generic-info-value">{{genericModbusDialog.remark || '--'}}</view>
  705. <input wx:else class="value-input generic-value-input" data-field="remark" value="{{genericModbusDialog.remark}}" bindinput="onGenericDraftInput" />
  706. </view>
  707. <view wx:if="{{genericModbusDialog.showUnit}}" class="generic-info-row">
  708. <view class="generic-info-label">单位</view>
  709. <view wx:if="{{genericModbusDialog.mode == 'viewRegister'}}" class="generic-info-value">{{genericModbusDialog.unit || '--'}}</view>
  710. <input wx:else class="value-input generic-value-input" data-field="unit" value="{{genericModbusDialog.unit}}" bindinput="onGenericDraftInput" />
  711. </view>
  712. <view wx:if="{{genericModbusDialog.mode == 'viewRegister' || genericModbusDialog.showRange}}" class="generic-info-row">
  713. <view class="generic-info-label">最小值</view>
  714. <view wx:if="{{genericModbusDialog.mode == 'viewRegister'}}" class="generic-info-value">{{genericModbusDialog.minValue || '--'}}</view>
  715. <input wx:else class="value-input generic-value-input" data-field="minValue" value="{{genericModbusDialog.minValue}}" bindinput="onGenericDraftInput" />
  716. </view>
  717. <view wx:if="{{genericModbusDialog.mode == 'viewRegister' || genericModbusDialog.showRange}}" class="generic-info-row">
  718. <view class="generic-info-label">最大值</view>
  719. <view wx:if="{{genericModbusDialog.mode == 'viewRegister'}}" class="generic-info-value">{{genericModbusDialog.maxValue || '--'}}</view>
  720. <input wx:else class="value-input generic-value-input" data-field="maxValue" value="{{genericModbusDialog.maxValue}}" bindinput="onGenericDraftInput" />
  721. </view>
  722. </view>
  723. </view>
  724. </block>
  725. <view class="generic-draft-actions">
  726. <view class="panel-action-button" bindtap="closeGenericModbusDraft">{{genericModbusDialog.cancelText}}</view>
  727. <view wx:if="{{genericModbusDialog.confirmText}}" class="panel-action-button is-active" bindtap="confirmGenericModbusDialog">{{genericModbusDialog.confirmText}}</view>
  728. </view>
  729. </view>
  730. </view>