|  |  | @ -1,12 +1,18 @@ | 
			
		
	
		
			
				
					|  |  |  | #!/usr/bin/python3 | 
			
		
	
		
			
				
					|  |  |  | # -*- coding: utf-8 -*- | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | """ | 
			
		
	
		
			
				
					|  |  |  | Hoymiles Micro-Inverters decoder library | 
			
		
	
		
			
				
					|  |  |  | """ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | import struct | 
			
		
	
		
			
				
					|  |  |  | import crcmod | 
			
		
	
		
			
				
					|  |  |  | from datetime import datetime, timedelta | 
			
		
	
		
			
				
					|  |  |  | import crcmod | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | f_crc_m = crcmod.predefined.mkPredefinedCrcFun('modbus') | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | class Response: | 
			
		
	
		
			
				
					|  |  |  |     """ All Response Shared methods """ | 
			
		
	
		
			
				
					|  |  |  |     inverter_ser = None | 
			
		
	
		
			
				
					|  |  |  |     inverter_name = None | 
			
		
	
		
			
				
					|  |  |  |     dtu_ser = None | 
			
		
	
	
		
			
				
					|  |  | @ -28,6 +34,7 @@ class Response: | 
			
		
	
		
			
				
					|  |  |  |             self.time_rx = datetime.now() | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     def __dict__(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Base values, availabe in each __dict__ call """ | 
			
		
	
		
			
				
					|  |  |  |         return { | 
			
		
	
		
			
				
					|  |  |  |                 'inverter_ser': self.inverter_ser, | 
			
		
	
		
			
				
					|  |  |  |                 'inverter_name': self.inverter_name, | 
			
		
	
	
		
			
				
					|  |  | @ -36,9 +43,8 @@ class Response: | 
			
		
	
		
			
				
					|  |  |  | class StatusResponse(Response): | 
			
		
	
		
			
				
					|  |  |  |     """Inverter StatusResponse object""" | 
			
		
	
		
			
				
					|  |  |  |     e_keys  = ['voltage','current','power','energy_total','energy_daily','powerfactor'] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
		
			
				
					|  |  |  |         super().__init__(*args, **params) | 
			
		
	
		
			
				
					|  |  |  |     temperature = None | 
			
		
	
		
			
				
					|  |  |  |     frequency = None | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     def unpack(self, fmt, base): | 
			
		
	
		
			
				
					|  |  |  |         """ | 
			
		
	
	
		
			
				
					|  |  | @ -120,9 +126,6 @@ class UnknownResponse(Response): | 
			
		
	
		
			
				
					|  |  |  |     Debugging helper for unknown payload format | 
			
		
	
		
			
				
					|  |  |  |     """ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
		
			
				
					|  |  |  |         super().__init__(*args, **params) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def hex_ascii(self): | 
			
		
	
		
			
				
					|  |  |  |         """ | 
			
		
	
	
		
			
				
					|  |  | @ -131,7 +134,7 @@ class UnknownResponse(Response): | 
			
		
	
		
			
				
					|  |  |  |         :return: hexlifierd byte string | 
			
		
	
		
			
				
					|  |  |  |         :rtype: str | 
			
		
	
		
			
				
					|  |  |  |         """ | 
			
		
	
		
			
				
					|  |  |  |         return ' '.join([f'{b:02x}' for b in self.response]) | 
			
		
	
		
			
				
					|  |  |  |         return ' '.join([f'{byte:02x}' for byte in self.response]) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def valid_crc(self): | 
			
		
	
	
		
			
				
					|  |  | @ -153,13 +156,13 @@ class UnknownResponse(Response): | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         res = self.response | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         r = len(res) % 16 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:r*-1] | 
			
		
	
		
			
				
					|  |  |  |         rem = len(res) % 16 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:rem*-1] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         vals = None | 
			
		
	
		
			
				
					|  |  |  |         if len(res) % 16 == 0: | 
			
		
	
		
			
				
					|  |  |  |             n = len(res)/4 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(n)}L', res) | 
			
		
	
		
			
				
					|  |  |  |             rlen = len(res)/4 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(rlen)}L', res) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         return vals | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -171,13 +174,13 @@ class UnknownResponse(Response): | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         res = self.response[2:] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         r = len(res) % 16 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:r*-1] | 
			
		
	
		
			
				
					|  |  |  |         rem = len(res) % 16 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:rem*-1] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         vals = None | 
			
		
	
		
			
				
					|  |  |  |         if len(res) % 16 == 0: | 
			
		
	
		
			
				
					|  |  |  |             n = len(res)/4 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(n)}L', res) | 
			
		
	
		
			
				
					|  |  |  |             rlen = len(res)/4 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(rlen)}L', res) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         return vals | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -189,13 +192,13 @@ class UnknownResponse(Response): | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         res = self.response[4:] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         r = len(res) % 16 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:r*-1] | 
			
		
	
		
			
				
					|  |  |  |         rem = len(res) % 16 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:rem*-1] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         vals = None | 
			
		
	
		
			
				
					|  |  |  |         if len(res) % 16 == 0: | 
			
		
	
		
			
				
					|  |  |  |             n = len(res)/4 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(n)}L', res) | 
			
		
	
		
			
				
					|  |  |  |             rlen = len(res)/4 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(rlen)}L', res) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         return vals | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -207,13 +210,13 @@ class UnknownResponse(Response): | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         res = self.response[6:] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         r = len(res) % 16 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:r*-1] | 
			
		
	
		
			
				
					|  |  |  |         rem = len(res) % 16 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:rem*-1] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         vals = None | 
			
		
	
		
			
				
					|  |  |  |         if len(res) % 16 == 0: | 
			
		
	
		
			
				
					|  |  |  |             n = len(res)/4 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(n)}L', res) | 
			
		
	
		
			
				
					|  |  |  |             rlen = len(res)/4 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(rlen)}L', res) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         return vals | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -225,13 +228,13 @@ class UnknownResponse(Response): | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         res = self.response | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         r = len(res) % 4 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:r*-1] | 
			
		
	
		
			
				
					|  |  |  |         rem = len(res) % 4 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:rem*-1] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         vals = None | 
			
		
	
		
			
				
					|  |  |  |         if len(res) % 4 == 0: | 
			
		
	
		
			
				
					|  |  |  |             n = len(res)/2 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(n)}H', res) | 
			
		
	
		
			
				
					|  |  |  |             rlen = len(res)/2 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(rlen)}H', res) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         return vals | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -243,17 +246,18 @@ class UnknownResponse(Response): | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         res = self.response[1:] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         r = len(res) % 4 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:r*-1] | 
			
		
	
		
			
				
					|  |  |  |         rem = len(res) % 4 | 
			
		
	
		
			
				
					|  |  |  |         res = res[:rem*-1] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         vals = None | 
			
		
	
		
			
				
					|  |  |  |         if len(res) % 4 == 0: | 
			
		
	
		
			
				
					|  |  |  |             n = len(res)/2 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(n)}H', res) | 
			
		
	
		
			
				
					|  |  |  |             rlen = len(res)/2 | 
			
		
	
		
			
				
					|  |  |  |             vals = struct.unpack(f'>{int(rlen)}H', res) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         return vals | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | class EventsResponse(UnknownResponse): | 
			
		
	
		
			
				
					|  |  |  |     """ Hoymiles micro-inverter event log decode helper """ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     alarm_codes = { | 
			
		
	
		
			
				
					|  |  |  |             1: 'Inverter start', | 
			
		
	
	
		
			
				
					|  |  | @ -337,10 +341,10 @@ class EventsResponse(UnknownResponse): | 
			
		
	
		
			
				
					|  |  |  |         status = self.response[:2] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         chunk_size = 12 | 
			
		
	
		
			
				
					|  |  |  |         for c in range(2, len(self.response), chunk_size): | 
			
		
	
		
			
				
					|  |  |  |             chunk = self.response[c:c+chunk_size] | 
			
		
	
		
			
				
					|  |  |  |         for i_chunk in range(2, len(self.response), chunk_size): | 
			
		
	
		
			
				
					|  |  |  |             chunk = self.response[i_chunk:i_chunk+chunk_size] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             print(' '.join([f'{b:02x}' for b in chunk]) + ': ') | 
			
		
	
		
			
				
					|  |  |  |             print(' '.join([f'{byte:02x}' for byte in chunk]) + ': ') | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             opcode, a_code, a_count, uptime_sec = struct.unpack('>BBHH', chunk[0:6]) | 
			
		
	
		
			
				
					|  |  |  |             a_text = self.alarm_codes.get(a_code, 'N/A') | 
			
		
	
	
		
			
				
					|  |  | @ -351,7 +355,7 @@ class EventsResponse(UnknownResponse): | 
			
		
	
		
			
				
					|  |  |  |                 print(f' {fmt:7}: ' + str(struct.unpack('>' + fmt, chunk))) | 
			
		
	
		
			
				
					|  |  |  |             print(end='', flush=True) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | class DEBUG_DecodeAny(UnknownResponse): | 
			
		
	
		
			
				
					|  |  |  | class DebugDecodeAny(UnknownResponse): | 
			
		
	
		
			
				
					|  |  |  |     """Default decoder""" | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
	
		
			
				
					|  |  | @ -415,206 +419,247 @@ class DEBUG_DecodeAny(UnknownResponse): | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # 1121-Series Intervers, 1 MPPT, 1 Phase | 
			
		
	
		
			
				
					|  |  |  | class HM300_Decode0B(StatusResponse): | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
		
			
				
					|  |  |  |         super().__init__(*args, **params) | 
			
		
	
		
			
				
					|  |  |  | class Hm300Decode0B(StatusResponse): | 
			
		
	
		
			
				
					|  |  |  |     """ 1121-series mirco-inverters status data """ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_voltage_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 VDC """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 2)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_current_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 ampere """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 4)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_power_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 watts """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 6)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_total_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 total energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>L', 8)[0] | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_daily_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 daily energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 12)[0] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def ac_voltage_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Phase 1 VAC """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 14)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def ac_current_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Phase 1 ampere """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 22)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def ac_power_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Phase 1 watts """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 18)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def frequency(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Grid frequency in Hertz """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 16)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def temperature(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Inverter temperature in °C """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 26)[0]/10 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | class HM300_Decode11(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
		
			
				
					|  |  |  |         super().__init__(*args, **params) | 
			
		
	
		
			
				
					|  |  |  | class Hm300Decode11(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     """ Inverter generic events log """ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | class HM300_Decode12(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
		
			
				
					|  |  |  |         super().__init__(*args, **params) | 
			
		
	
		
			
				
					|  |  |  | class Hm300Decode12(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     """ Inverter major events log """ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # 1141-Series Inverters, 2 MPPT, 1 Phase | 
			
		
	
		
			
				
					|  |  |  | class HM600_Decode0B(StatusResponse): | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
		
			
				
					|  |  |  |         super().__init__(*args, **params) | 
			
		
	
		
			
				
					|  |  |  | class Hm600Decode0B(StatusResponse): | 
			
		
	
		
			
				
					|  |  |  |     """ 1141-series mirco-inverters status data """ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_voltage_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 VDC """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 2)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_current_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 ampere """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 4)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_power_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 watts """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 6)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_total_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 total energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>L', 14)[0] | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_daily_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 daily energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 22)[0] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_voltage_1(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 2 VDC """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 8)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_current_1(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 2 ampere """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 10)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_power_1(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 2 watts """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 12)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_total_1(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 2 total energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>L', 18)[0] | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_daily_1(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 2 daily energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 24)[0] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def ac_voltage_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Phase 1 VAC """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 26)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def ac_current_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Phase 1 ampere """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 34)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def ac_power_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Phase 1 watts """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 30)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def frequency(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Grid frequency in Hertz """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 28)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def temperature(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Inverter temperature in °C """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 38)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def alarm_count(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Event counter """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 40)[0] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | class HM600_Decode11(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
		
			
				
					|  |  |  |         super().__init__(*args, **params) | 
			
		
	
		
			
				
					|  |  |  | class Hm600Decode11(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     """ Inverter generic events log """ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | class HM600_Decode12(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
		
			
				
					|  |  |  |         super().__init__(*args, **params) | 
			
		
	
		
			
				
					|  |  |  | class Hm600Decode12(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     """ Inverter major events log """ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # 1161-Series Inverters, 4 MPPT, 1 Phase | 
			
		
	
		
			
				
					|  |  |  | class HM1200_Decode0B(StatusResponse): | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
		
			
				
					|  |  |  |         super().__init__(*args, **params) | 
			
		
	
		
			
				
					|  |  |  | class Hm1200Decode0B(StatusResponse): | 
			
		
	
		
			
				
					|  |  |  |     """ 1161-series mirco-inverters status data """ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_voltage_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 VDC """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 2)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_current_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 ampere """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 4)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_power_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 watts """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 8)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_total_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 total energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>L', 12)[0] | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_daily_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 1 daily energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 20)[0] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_voltage_1(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 2 VDC """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 2)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_current_1(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 2 ampere """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 4)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_power_1(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 2 watts """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 10)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_total_1(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 2 total energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>L', 16)[0] | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_daily_1(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 2 daily energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 22)[0] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_voltage_2(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 3 VDC """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 24)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_current_2(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 3 ampere """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 26)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_power_2(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 3 watts """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 30)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_total_2(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 3 total energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>L', 34)[0] | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_daily_2(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 3 daily energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 42)[0] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_voltage_3(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 4 VDC """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 24)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_current_3(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 4 ampere """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 28)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_power_3(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 4 watts """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 32)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_total_3(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 4 total energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>L', 38)[0] | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def dc_energy_daily_3(self): | 
			
		
	
		
			
				
					|  |  |  |         """ String 4 daily energy in Wh """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 44)[0] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def ac_voltage_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Phase 1 VAC """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 46)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def ac_current_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Phase 1 ampere """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 54)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def ac_power_0(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Phase 1 watts """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 50)[0]/10 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def frequency(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Grid frequency in Hertz """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 48)[0]/100 | 
			
		
	
		
			
				
					|  |  |  |     @property | 
			
		
	
		
			
				
					|  |  |  |     def temperature(self): | 
			
		
	
		
			
				
					|  |  |  |         """ Inverter temperature in °C """ | 
			
		
	
		
			
				
					|  |  |  |         return self.unpack('>H', 58)[0]/10 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | class HM1200_Decode11(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
		
			
				
					|  |  |  |         super().__init__(*args, **params) | 
			
		
	
		
			
				
					|  |  |  | class Hm1200Decode11(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     """ Inverter generic events log """ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | class HM1200_Decode12(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     def __init__(self, *args, **params): | 
			
		
	
		
			
				
					|  |  |  |         super().__init__(*args, **params) | 
			
		
	
		
			
				
					|  |  |  | class Hm1200Decode12(EventsResponse): | 
			
		
	
		
			
				
					|  |  |  |     """ Inverter major events log """ | 
			
		
	
	
		
			
				
					|  |  | 
 |