Sensor.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <template>
  2. <div class="l-flex--col c-device-grid-item o-sensor has-border radius">
  3. <div class="l-flex--row l-flex__none">
  4. <i
  5. class="l-flex__none c-sibling-item o-icon"
  6. :class="sensorType"
  7. />
  8. <span class="l-flex__fill c-sibling-item near u-color--info u-ellipsis">{{ title }}</span>
  9. <i
  10. v-if="enough"
  11. class="l-flex__none c-sibling-item u-font-size--md u-color--blue el-icon-s-operation has-active"
  12. @click="onShowAll"
  13. />
  14. </div>
  15. <div class="l-flex__fill l-flex--row center u-font-size--md u-color--black u-bold">
  16. <div
  17. class="u-text--center"
  18. :style="{ color }"
  19. >
  20. <template v-if="sensor">
  21. {{ tip }}
  22. <div class="o-sensor__current">
  23. {{ sensor }}
  24. </div>
  25. </template>
  26. <i
  27. v-else-if="loading"
  28. class="el-icon-loading"
  29. />
  30. <template v-else>
  31. 未知
  32. </template>
  33. </div>
  34. </div>
  35. <div
  36. v-for="item in more"
  37. :key="item.port"
  38. class="l-flex__none l-flex--row o-sensor__more"
  39. >
  40. <div class="l-flex__none">{{ item.time }}</div>
  41. <div class="l-flex__none o-sensor__name">传感器{{ item.port }}</div>
  42. <div class="l-flex__fill u-text--right">{{ item.info }}</div>
  43. </div>
  44. <table-dialog
  45. ref="tableDialog"
  46. :title="listTitle"
  47. :schema="schema"
  48. />
  49. </div>
  50. </template>
  51. <script>
  52. import {
  53. ThirdPartyDevice,
  54. ThirdPartyDeviceInfo
  55. } from '@/constant'
  56. import { parseTime } from '@/utils'
  57. import { getSensorRecords } from '@/api/external'
  58. export default {
  59. name: 'Sensor',
  60. props: {
  61. type: {
  62. type: Number,
  63. required: true
  64. },
  65. title: {
  66. type: String,
  67. default: ''
  68. },
  69. color: {
  70. type: String,
  71. default: ''
  72. },
  73. deviceId: {
  74. type: String,
  75. required: true
  76. }
  77. },
  78. data () {
  79. return {
  80. loading: false,
  81. list: [],
  82. schema: {
  83. nonPagination: true,
  84. list: this.getSensors,
  85. cols: [
  86. { prop: 'port', label: '端口' },
  87. { prop: 'info', label: '数据' },
  88. { prop: 'time', label: '采集时间' }
  89. ]
  90. }
  91. }
  92. },
  93. computed: {
  94. listTitle () {
  95. return ThirdPartyDeviceInfo[this.type]
  96. },
  97. sorted () {
  98. if (this.type === ThirdPartyDevice.TRANSLOCATION_SENSOR) {
  99. return this.list
  100. }
  101. return this.list.slice().sort((a, b) => Number(a.value) < Number(b.value) ? 1 : -1)
  102. },
  103. sensorType () {
  104. return `sensor_${this.type}`
  105. },
  106. tip () {
  107. return this.sorted.length ? this.sorted[0].info : null
  108. },
  109. sensor () {
  110. const length = this.sorted.length
  111. return length
  112. ? length === 1
  113. ? this.sorted[0].time
  114. : `${this.sorted[0].time} 传感器${this.sorted[0].port}`
  115. : null
  116. },
  117. more () {
  118. return this.list.length > 1 ? this.sorted.slice(1, 3) : []
  119. },
  120. enough () {
  121. return this.list.length > 3
  122. }
  123. },
  124. created () {
  125. this.$running = true
  126. this.$timer = -1
  127. this.startRun()
  128. },
  129. beforeDestroy () {
  130. this.$running = false
  131. clearTimeout(this.$timer)
  132. },
  133. methods: {
  134. startRun () {
  135. if (!this.$running) {
  136. return
  137. }
  138. const now = Date.now()
  139. this.loading = true
  140. getSensorRecords({
  141. deviceId: this.deviceId,
  142. sensorType: this.type,
  143. startTime: now - 10000,
  144. endTime: now
  145. }, { custom: true }).then(({ data }) => {
  146. this.list = this.transfromData(data)
  147. this.$refs.tableDialog?.getTable()?.pageTo()
  148. }).finally(() => {
  149. this.loading = false
  150. if (this.$running) {
  151. this.$timer = setTimeout(this.startRun, 10000)
  152. }
  153. })
  154. },
  155. transfromData (data) {
  156. const map = {}
  157. const arr = []
  158. data.forEach(sensor => {
  159. if (!map[sensor.port]) {
  160. map[sensor.port] = 1
  161. arr.push(this.transformSensorData(sensor))
  162. }
  163. })
  164. return arr
  165. },
  166. transformSensorData (data) {
  167. const { port, type, value, time } = data
  168. return {
  169. port, value,
  170. time: parseTime(time, '{y}-{m}-{d} {h}:{i}:{s}'),
  171. info: this.transformValue(type, value, data)
  172. }
  173. },
  174. transformValue (type, value, data) {
  175. switch (type) {
  176. case ThirdPartyDevice.SMOKE_SENSOR:
  177. return `${value}ppm`
  178. case ThirdPartyDevice.TEMPERATURE_SENSOR:
  179. return `${value}℃`
  180. case ThirdPartyDevice.LIGHT_SENSOR:
  181. return `${value}Lux`
  182. case ThirdPartyDevice.FLOODING_SENSOR:
  183. return value ? '是' : '否'
  184. case ThirdPartyDevice.TRANSLOCATION_SENSOR:
  185. console.log(data)
  186. return `x ${data.xvalue?.toFixed(3)} y ${data.yvalue?.toFixed(3)} z ${data.zvalue?.toFixed(3)}`
  187. default:
  188. return value
  189. }
  190. },
  191. getSensors () {
  192. return Promise.resolve({ data: this.list })
  193. },
  194. onShowAll () {
  195. this.$refs.tableDialog.show()
  196. }
  197. }
  198. }
  199. </script>
  200. <style lang="scss" scoped>
  201. .o-icon {
  202. &.sensor_9 {
  203. background-image: url("~@/assets/icon_smoke.png");
  204. }
  205. &.sensor_10 {
  206. background-image: url("~@/assets/icon_temperature.png");
  207. }
  208. &.sensor_11 {
  209. background-image: url("~@/assets/icon_light.png");
  210. }
  211. &.sensor_12 {
  212. background-image: url("~@/assets/icon_flooding.png");
  213. }
  214. &.sensor_13 {
  215. background-image: url("~@/assets/icon_shift.png");
  216. }
  217. }
  218. .o-sensor {
  219. &__current {
  220. margin-top: 6px;
  221. color: $info;
  222. font-size: 12px;
  223. }
  224. &__more {
  225. padding: 8px 0;
  226. color: $info--dark;
  227. font-size: 14px;
  228. border-bottom: 1px solid $border;
  229. }
  230. &__name {
  231. margin: 0 16px 0 24px;
  232. }
  233. }
  234. </style>