123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import logging
- import struct
- from typing import TYPE_CHECKING
- from apps.web.core.accounting import Accounting
- from apps.web.device.models import Device
- from apps.web.device.timescale import FluentedEngine, OfflineManager
- from script.eventer.handlers import Handler
- from apps.web.common.event import do_device_event
- logger = logging.getLogger(__name__)
- if TYPE_CHECKING:
- from apps.web.eventer import EventBuilder, Event
- class ShakeHandHandler(Handler):
- def parse(self):
- logger.debug('orginal payload len: {}'.format(len(self.payload)))
- payload = struct.pack('<{}s4s'.format(len(self.payload)), self.payload, '0000')
- logger.debug('now payload len: {}'.format(len(payload)))
- offset = 0
- ts = struct.unpack_from('<I', payload, offset = offset)[0]
- offset = offset + 4
- signal = struct.unpack_from('<B', payload, offset = offset)[0]
- offset = offset + 1
- logger.debug('ts = {}; signal = {}'.format(ts, signal))
- rv = {
- 'ts': ts,
- 'signal': signal
- }
- while offset < (len(payload) - 4):
- _type = struct.unpack_from('<B', payload, offset = offset)[0]
- offset = offset + 1
- if _type == 0x01:
- # coins: 2
- coins = struct.unpack_from('<H', payload, offset = offset)[0]
- offset = offset + 2
- logger.debug('coins = {}'.format(coins))
- rv.update({'today_coins': coins})
- elif _type == 0x02:
- # start_no:1, end_no:1, used_ports: 1, [port:1, power:2]*
- rv.update({'powers': {}})
- start_no = struct.unpack_from('<B', payload, offset = offset)[0]
- offset = offset + 1
- end_no = struct.unpack_from('<B', payload, offset = offset)[0]
- offset = offset + 1
- used = struct.unpack_from('<B', payload, offset = offset)[0]
- offset = offset + 1
- logger.debug('start_no = {}; end_no = {}; used ports = {}'.format(start_no, end_no, used))
- for i in range(0, used):
- port, power = struct.unpack_from('<BH', payload, offset = offset)
- offset = offset + 3
- logger.debug('port = {}, power = {}'.format(port, power))
- rv['powers'][str(port)] = {
- 'power': power
- # 'voltage': '-',
- # 'current': '-'
- }
- for i in range(start_no, end_no + 1):
- if str(i) not in rv['powers']:
- rv['powers'][str(i)] = {
- 'power': 0
- # 'voltage': '-',
- # 'current': '-'
- }
- elif _type == 0x03:
- # voltage: 2, start_no:1, end_no:1, used_ports: 1, [port:1, power:2, current:2]*
- rv.update({'powers': {}})
- voltage = struct.unpack_from('<H', payload, offset = offset)[0]
- voltage = str(round(float(voltage) / 10, 2))
- offset = offset + 2
- logger.debug('voltage = {}'.format(voltage))
- start_no = struct.unpack_from('<B', payload, offset = offset)[0]
- offset = offset + 1
- end_no = struct.unpack_from('<B', payload, offset = offset)[0]
- offset = offset + 1
- used = struct.unpack_from('<B', payload, offset = offset)[0]
- offset = offset + 1
- logger.debug('start_no = {}; end_no = {}; used ports = {}'.format(start_no, end_no, used))
- for i in range(0, used):
- port, power, current = struct.unpack_from('<BHH', payload, offset = offset)
- offset = offset + 5
- logger.debug('port = {}, power = {}, current = {}'.format(port, power, current))
- rv['powers'][str(port)] = {
- 'power': power,
- 'voltage': voltage,
- 'current': current
- }
- for i in range(start_no, end_no + 1):
- if str(i) not in rv['powers']:
- rv['powers'][str(i)] = {
- 'power': 0,
- 'voltage': voltage,
- 'current': 0
- }
- elif _type == 0x05:
- # start_no:1, end_no:1, used_ports: 1, [port:1, power:2]*
- rv.update({'powers': {}})
- start_no = struct.unpack_from('<B', payload, offset = offset)[0]
- offset = offset + 1
- end_no = struct.unpack_from('<B', payload, offset = offset)[0]
- offset = offset + 1
- used = struct.unpack_from('<B', payload, offset = offset)[0]
- offset = offset + 1
- logger.debug('start_no = {}; end_no = {}; used ports = {}'.format(start_no, end_no, used))
- for i in range(0, used):
- port, power = struct.unpack_from('<BH', payload, offset = offset)
- offset = offset + 3
- logger.debug('port = {}, power = {}'.format(port, power))
- rv['powers'][str(port)] = {
- 'power': self.dev.deviceAdapter.format_upload_power(power)
- # 'voltage': '-',
- # 'current': '-'
- }
- for i in range(start_no, end_no + 1):
- if str(i) not in rv['powers']:
- rv['powers'][str(i)] = {
- 'power': 0
- # 'voltage': '-',
- # 'current': '-'
- }
- if 'powers' in rv and not self.dev.support_power_graph:
- Device.get_collection().update({'devNo': self.dev.devNo}, {'$set': {'otherConf.supportPG': True}})
- Device.invalid_device_cache(self.dev.devNo)
- return rv
- def do(self):
- rv = self.parse()
- OfflineManager.discard_device_offline_notify(devNo = self.dev.devNo)
- ts = rv['ts']
- signal = rv['signal']
- FluentedEngine().in_signal_udp(devNo = self.dev.devNo, ts = ts, signal = signal, cmd = self.cmd)
- if 'today_coins' in rv:
- Accounting.syncOfflineCoin(self.dev,
- datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d'),
- int(rv['today_coins']))
- for port, item in rv.get('powers', {}).iteritems():
- FluentedEngine().in_power_udp(devNo = self.dev.devNo,
- port = str(port),
- ts = ts,
- power = item['power'],
- voltage = item.get('voltage', None),
- current = item.get('current', None))
|