shake_hand.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import datetime
  4. import logging
  5. import struct
  6. from typing import TYPE_CHECKING
  7. from apps.web.core.accounting import Accounting
  8. from apps.web.device.models import Device
  9. from apps.web.device.timescale import FluentedEngine, OfflineManager
  10. from script.eventer.handlers import Handler
  11. from apps.web.common.event import do_device_event
  12. logger = logging.getLogger(__name__)
  13. if TYPE_CHECKING:
  14. from apps.web.eventer import EventBuilder, Event
  15. class ShakeHandHandler(Handler):
  16. def parse(self):
  17. logger.debug('orginal payload len: {}'.format(len(self.payload)))
  18. payload = struct.pack('<{}s4s'.format(len(self.payload)), self.payload, '0000')
  19. logger.debug('now payload len: {}'.format(len(payload)))
  20. offset = 0
  21. ts = struct.unpack_from('<I', payload, offset = offset)[0]
  22. offset = offset + 4
  23. signal = struct.unpack_from('<B', payload, offset = offset)[0]
  24. offset = offset + 1
  25. logger.debug('ts = {}; signal = {}'.format(ts, signal))
  26. rv = {
  27. 'ts': ts,
  28. 'signal': signal
  29. }
  30. while offset < (len(payload) - 4):
  31. _type = struct.unpack_from('<B', payload, offset = offset)[0]
  32. offset = offset + 1
  33. if _type == 0x01:
  34. # coins: 2
  35. coins = struct.unpack_from('<H', payload, offset = offset)[0]
  36. offset = offset + 2
  37. logger.debug('coins = {}'.format(coins))
  38. rv.update({'today_coins': coins})
  39. elif _type == 0x02:
  40. # start_no:1, end_no:1, used_ports: 1, [port:1, power:2]*
  41. rv.update({'powers': {}})
  42. start_no = struct.unpack_from('<B', payload, offset = offset)[0]
  43. offset = offset + 1
  44. end_no = struct.unpack_from('<B', payload, offset = offset)[0]
  45. offset = offset + 1
  46. used = struct.unpack_from('<B', payload, offset = offset)[0]
  47. offset = offset + 1
  48. logger.debug('start_no = {}; end_no = {}; used ports = {}'.format(start_no, end_no, used))
  49. for i in range(0, used):
  50. port, power = struct.unpack_from('<BH', payload, offset = offset)
  51. offset = offset + 3
  52. logger.debug('port = {}, power = {}'.format(port, power))
  53. rv['powers'][str(port)] = {
  54. 'power': power
  55. # 'voltage': '-',
  56. # 'current': '-'
  57. }
  58. for i in range(start_no, end_no + 1):
  59. if str(i) not in rv['powers']:
  60. rv['powers'][str(i)] = {
  61. 'power': 0
  62. # 'voltage': '-',
  63. # 'current': '-'
  64. }
  65. elif _type == 0x03:
  66. # voltage: 2, start_no:1, end_no:1, used_ports: 1, [port:1, power:2, current:2]*
  67. rv.update({'powers': {}})
  68. voltage = struct.unpack_from('<H', payload, offset = offset)[0]
  69. voltage = str(round(float(voltage) / 10, 2))
  70. offset = offset + 2
  71. logger.debug('voltage = {}'.format(voltage))
  72. start_no = struct.unpack_from('<B', payload, offset = offset)[0]
  73. offset = offset + 1
  74. end_no = struct.unpack_from('<B', payload, offset = offset)[0]
  75. offset = offset + 1
  76. used = struct.unpack_from('<B', payload, offset = offset)[0]
  77. offset = offset + 1
  78. logger.debug('start_no = {}; end_no = {}; used ports = {}'.format(start_no, end_no, used))
  79. for i in range(0, used):
  80. port, power, current = struct.unpack_from('<BHH', payload, offset = offset)
  81. offset = offset + 5
  82. logger.debug('port = {}, power = {}, current = {}'.format(port, power, current))
  83. rv['powers'][str(port)] = {
  84. 'power': power,
  85. 'voltage': voltage,
  86. 'current': current
  87. }
  88. for i in range(start_no, end_no + 1):
  89. if str(i) not in rv['powers']:
  90. rv['powers'][str(i)] = {
  91. 'power': 0,
  92. 'voltage': voltage,
  93. 'current': 0
  94. }
  95. elif _type == 0x05:
  96. # start_no:1, end_no:1, used_ports: 1, [port:1, power:2]*
  97. rv.update({'powers': {}})
  98. start_no = struct.unpack_from('<B', payload, offset = offset)[0]
  99. offset = offset + 1
  100. end_no = struct.unpack_from('<B', payload, offset = offset)[0]
  101. offset = offset + 1
  102. used = struct.unpack_from('<B', payload, offset = offset)[0]
  103. offset = offset + 1
  104. logger.debug('start_no = {}; end_no = {}; used ports = {}'.format(start_no, end_no, used))
  105. for i in range(0, used):
  106. port, power = struct.unpack_from('<BH', payload, offset = offset)
  107. offset = offset + 3
  108. logger.debug('port = {}, power = {}'.format(port, power))
  109. rv['powers'][str(port)] = {
  110. 'power': self.dev.deviceAdapter.format_upload_power(power)
  111. # 'voltage': '-',
  112. # 'current': '-'
  113. }
  114. for i in range(start_no, end_no + 1):
  115. if str(i) not in rv['powers']:
  116. rv['powers'][str(i)] = {
  117. 'power': 0
  118. # 'voltage': '-',
  119. # 'current': '-'
  120. }
  121. if 'powers' in rv and not self.dev.support_power_graph:
  122. Device.get_collection().update({'devNo': self.dev.devNo}, {'$set': {'otherConf.supportPG': True}})
  123. Device.invalid_device_cache(self.dev.devNo)
  124. return rv
  125. def do(self):
  126. rv = self.parse()
  127. OfflineManager.discard_device_offline_notify(devNo = self.dev.devNo)
  128. ts = rv['ts']
  129. signal = rv['signal']
  130. FluentedEngine().in_signal_udp(devNo = self.dev.devNo, ts = ts, signal = signal, cmd = self.cmd)
  131. if 'today_coins' in rv:
  132. Accounting.syncOfflineCoin(self.dev,
  133. datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d'),
  134. int(rv['today_coins']))
  135. for port, item in rv.get('powers', {}).iteritems():
  136. FluentedEngine().in_power_udp(devNo = self.dev.devNo,
  137. port = str(port),
  138. ts = ts,
  139. power = item['power'],
  140. voltage = item.get('voltage', None),
  141. current = item.get('current', None))