def getDB(self, start, intervall, span): start = int(datetime.datetime.now().timestamp()) intervall = 3600 span = 3600 container = [] container.append( RSCPDTO(tag=RSCPTag.DB_REQ_HISTORY_TIME_START, rscp_type=RSCPType.Uint64, data=start)) container.append( RSCPDTO(tag=RSCPTag.DB_REQ_HISTORY_TIME_INTERVAL, rscp_type=RSCPType.Uint64, data=intervall)) container.append( RSCPDTO(tag=RSCPTag.DB_REQ_HISTORY_TIME_SPAN, rscp_type=RSCPType.Uint64, data=span)) requests = [] requests.append( RSCPDTO(tag=RSCPTag.DB_REQ_HISTORY_DATA_DAY, rscp_type=RSCPType.Container, data=container)) for i in requests: print(i) return requests
def encode_data(self, rscp_dto: RSCPDTO) -> bytes: pack_format = self._DATA_HEADER_FORMAT data_header_length = struct.calcsize(self._DATA_HEADER_FORMAT) if rscp_dto.type == RSCPType.Nil: return struct.pack(self._DATA_HEADER_FORMAT, rscp_dto.tag.value, rscp_dto.type.value, 0) elif rscp_dto.type == RSCPType.Timestamp: timestamp = int(rscp_dto.data / 1000) milliseconds = (rscp_dto.data - timestamp * 1000) * 1e6 high = timestamp >> 32 low = timestamp & 0xffffffff length = struct.calcsize("iii") - data_header_length return struct.pack("iii", rscp_dto.tag.value, rscp_dto.type.value, length, high, low, milliseconds) elif rscp_dto.type == RSCPType.Container: if isinstance(rscp_dto.data, list): new_data = b'' for data_chunk in rscp_dto.data: new_data += self.encode_data(data_chunk) rscp_dto.set_data(new_data) pack_format += str(len(rscp_dto.data)) + rscp_dto.type.mapping elif rscp_dto.type.mapping != "s": pack_format += rscp_dto.type.mapping elif rscp_dto.type.mapping == "s": # We do expect a string object. Make it to bytes array rscp_dto.set_data(bytes(rscp_dto.data, encoding="latin_1")) pack_format += str(len(rscp_dto.data)) + rscp_dto.type.mapping data_length = struct.calcsize(pack_format) - data_header_length logger.debug("pack_format: " + pack_format) logger.debug("data: " + str(rscp_dto.data)) return struct.pack(pack_format, rscp_dto.tag.value, rscp_dto.type.value, data_length, rscp_dto.data)
def getPMData(self, pm_index=0, pm_indexes=None): requests = [] if not pm_indexes: pm_indexes = [pm_index] for pm_index in pm_indexes: r = RSCPDTO(tag=RSCPTag.PM_REQ_DATA) r += RSCPDTO( tag=RSCPTag.PM_INDEX, data=pm_index) # PM INDEX 0 = Leistungsmesser Netzbezug r += RSCPTag.PM_REQ_POWER_L1 r += RSCPTag.PM_REQ_POWER_L2 r += RSCPTag.PM_REQ_POWER_L3 r += RSCPTag.PM_REQ_VOLTAGE_L1 r += RSCPTag.PM_REQ_VOLTAGE_L2 r += RSCPTag.PM_REQ_VOLTAGE_L3 r += RSCPTag.PM_REQ_ENERGY_L1 r += RSCPTag.PM_REQ_ENERGY_L2 r += RSCPTag.PM_REQ_ENERGY_L3 r += RSCPTag.PM_REQ_FIRMWARE_VERSION r += RSCPTag.PM_REQ_ACTIVE_PHASES r += RSCPTag.PM_REQ_MODE r += RSCPTag.PM_REQ_ERROR_CODE r += RSCPTag.PM_REQ_TYPE r += RSCPTag.PM_REQ_DEVICE_ID r += RSCPTag.PM_REQ_COMM_STATE r += RSCPTag.PM_REQ_IS_CAN_SILENCE r += RSCPTag.PM_REQ_DEVICE_STATE requests.append(r) return requests
def getWB(self, index=0): requests = [] r = RSCPDTO(RSCPTag.WB_REQ_DATA, rscp_type=RSCPType.Container) r += RSCPDTO(RSCPTag.WB_INDEX, rscp_type=RSCPType.UChar8, data=index) r += RSCPTag.WB_REQ_STATUS r += RSCPTag.WB_REQ_ENERGY_ALL r += RSCPTag.WB_REQ_ENERGY_SOLAR r += RSCPTag.WB_REQ_SOC r += RSCPTag.WB_REQ_STATUS r += RSCPTag.WB_REQ_ERROR_CODE r += RSCPTag.WB_REQ_MODE r += RSCPTag.WB_REQ_APP_SOFTWARE r += RSCPTag.WB_REQ_BOOTLOADER_SOFTWARE r += RSCPTag.WB_REQ_HW_VERSION r += RSCPTag.WB_REQ_FLASH_VERSION r += RSCPTag.WB_REQ_DEVICE_ID r += RSCPTag.WB_REQ_DEVICE_STATE r += RSCPTag.WB_REQ_PM_POWER_L1 r += RSCPTag.WB_REQ_PM_POWER_L2 r += RSCPTag.WB_REQ_PM_POWER_L3 r += RSCPTag.WB_REQ_PM_ACTIVE_PHASES r += RSCPTag.WB_REQ_PM_MODE r += RSCPTag.WB_REQ_PM_ENERGY_L1 r += RSCPTag.WB_REQ_PM_ENERGY_L2 r += RSCPTag.WB_REQ_PM_ENERGY_L3 r += RSCPTag.WB_REQ_PM_DEVICE_ID r += RSCPTag.WB_REQ_PM_ERROR_CODE r += RSCPTag.WB_REQ_PM_DEVICE_STATE r += RSCPTag.WB_REQ_PM_FIRMWARE_VERSION r += RSCPTag.WB_REQ_DIAG_DEVICE_ID r += RSCPTag.WB_REQ_DIAG_BAT_CAPACITY r += RSCPTag.WB_REQ_DIAG_USER_PARAM r += RSCPTag.WB_REQ_DIAG_MAX_CURRENT r += RSCPTag.WB_REQ_DIAG_PHASE_VOLTAGE r += RSCPTag.WB_REQ_DIAG_DISPLAY_SPEECH r += RSCPTag.WB_REQ_DIAG_DESIGN r += RSCPTag.WB_REQ_DIAG_INFOS r += RSCPTag.WB_REQ_DIAG_WARNINGS r += RSCPTag.WB_REQ_DIAG_ERRORS r += RSCPTag.WB_REQ_DIAG_TEMP_1 r += RSCPTag.WB_REQ_DIAG_TEMP_2 r += RSCPTag.WB_REQ_DIAG_CP_PEGEL r += RSCPTag.WB_REQ_DIAG_PP_IN_A r += RSCPTag.WB_REQ_DIAG_STATUS_DIODE r += RSCPTag.WB_REQ_DIAG_DIG_IN_1 r += RSCPTag.WB_REQ_DIAG_DIG_IN_2 r += RSCPTag.WB_REQ_PM_MAX_PHASE_POWER r += RSCPTag.WB_REQ_DEVICE_NAME r += RSCPTag.WB_REQ_EXTERN_DATA_SUN r += RSCPTag.WB_REQ_EXTERN_DATA_NET r += RSCPTag.WB_REQ_EXTERN_DATA_ALL r += RSCPTag.WB_REQ_EXTERN_DATA_ALG r += RSCPTag.WB_REQ_PARAM_1 r += RSCPTag.WB_REQ_PARAM_2 requests.append(r) return requests
def setChargePower(self, value=None): requests = [] containerData = [] if value: containerData.append(RSCPDTO(tag=RSCPTag.EMS_POWER_LIMITS_USED, data=True)) containerData.append(RSCPDTO(tag=RSCPTag.EMS_MAX_CHARGE_POWER, data=value)) else: containerData.append(RSCPDTO(tag=RSCPTag.EMS_POWER_LIMITS_USED, data=False)) requests.append(RSCPDTO(tag=RSCPTag.EMS_REQ_SET_POWER_SETTINGS, data=containerData)) return requests
def getBatData(self, bat_index=0, bat_indexes=None, dcb_index=0, dcb_indexes=None): requests = [] if not bat_indexes: bat_indexes = [bat_index] if not dcb_indexes and dcb_index: dcb_indexes = [dcb_index] for bat_index in bat_indexes: r = RSCPDTO(tag=RSCPTag.BAT_REQ_DATA) r += RSCPDTO(tag=RSCPTag.BAT_INDEX, data=bat_index) r += RSCPTag.BAT_REQ_USABLE_CAPACITY r += RSCPTag.BAT_REQ_USABLE_REMAINING_CAPACITY r += RSCPTag.BAT_REQ_ASOC r += RSCPTag.BAT_REQ_RSOC_REAL r += RSCPTag.BAT_REQ_MAX_BAT_VOLTAGE r += RSCPTag.BAT_REQ_MAX_CHARGE_CURRENT r += RSCPTag.BAT_REQ_EOD_VOLTAGE r += RSCPTag.BAT_REQ_MAX_DISCHARGE_CURRENT r += RSCPTag.BAT_REQ_CHARGE_CYCLES r += RSCPTag.BAT_REQ_TERMINAL_VOLTAGE r += RSCPTag.BAT_REQ_MAX_DCB_CELL_TEMPERATURE r += RSCPTag.BAT_REQ_MIN_DCB_CELL_TEMPERATURE r += RSCPTag.BAT_REQ_READY_FOR_SHUTDOWN r += RSCPTag.BAT_REQ_TRAINING_MODE r += RSCPTag.BAT_REQ_FCC r += RSCPTag.BAT_REQ_RC r += RSCPTag.BAT_REQ_INFO r += RSCPTag.BAT_REQ_DCB_COUNT r += RSCPTag.BAT_REQ_DEVICE_NAME r += RSCPTag.BAT_REQ_DEVICE_STATE r += RSCPTag.BAT_REQ_SPECIFICATION r += RSCPTag.BAT_REQ_INTERNALS r += RSCPTag.BAT_REQ_TOTAL_USE_TIME r += RSCPTag.BAT_REQ_TOTAL_DISCHARGE_TIME if dcb_indexes: for dcb_index in dcb_indexes: r += RSCPDTO(tag=RSCPTag.BAT_REQ_DCB_ALL_CELL_TEMPERATURES, data=dcb_index) r += RSCPDTO(tag=RSCPTag.BAT_REQ_DCB_ALL_CELL_VOLTAGES, data=dcb_index) r += RSCPDTO(tag=RSCPTag.BAT_REQ_DCB_INFO, data=dcb_index) requests.append(r) return requests
def send_requests2(self, payload: [Union[RSCPDTO, RSCPTag]], waittime=0.0) -> [RSCPDTO]: """ This function will send a list of requests consisting of RSCPDTO's oder RSCPTag's to the e3dc and returns a list of responses. i.e. responses = send_requests([RSCPTag.EMS_REQ_BAT_SOC, RSCPTag.EMS_REQ_POWER_PV, RSCPTag.EMS_REQ_POWER_BAT, RSCPTag.EMS_REQ_POWER_GRID, RSCPTag.EMS_REQ_POWER_WB_ALL]) :param payload: A list of requests :return: A list of responses in form of RSCPDTO's """ dto_list: [RSCPDTO] = [] for payload_element in payload: if isinstance(payload_element, RSCPTag): dto_list.append(RSCPDTO(payload_element)) else: dto_list.append(payload_element) logger.debug("Sending " + str(len(dto_list)) + " requests to " + str(self.ip)) responses: [RSCPDTO] = [] dto: RSCPDTO for dto in dto_list: response = self.send_request(dto, True, waittime=waittime) responses.append(response) return responses
def get_data(self, requests, raw=False, block=True, waittime=0.01): if block: while self.blocked: logger.debug('Warte auf Freigabe der Verbindung') time.sleep(0.05) self.blocked = True responses = [] try: responses = self.e3dc.send_requests(requests, waittime=waittime) except: if block: self.blocked = False raise if block: self.blocked = False if raw: if len(responses) == 1: return responses[0] elif len(responses) > 0: rscp = RSCPDTO(tag=RSCPTag.LIST_TYPE, rscp_type=RSCPType.Container, data=responses) return rscp else: return None else: raise Exception('Deprecated')
def send_request(self, payload: Union[RSCPDTO, RSCPTag], keep_connection_alive: bool = False) -> RSCPDTO: """ This will perform a single request. :param payload: The payload that defines the request :param keep_connection_alive: A flag whether to keep the connection alive or not :return: A response object as RSCPDTO """ if isinstance(payload, RSCPTag): payload = RSCPDTO(payload) if self.socket is None: self._connect() encode_data = self.rscp_utils.encode_data(payload) prepared_data = self.rscp_utils.encode_frame(encode_data) encrypted_data = self.encrypt_decrypt.encrypt(prepared_data) self.socket.send(encrypted_data) response = self._receive() if response.type == RSCPType.Error: logger.error("Error type returned") raise (RSCPCommunicationError(None, logger)) if not keep_connection_alive: self._disconnect() return response
def _connect(self): if self.socket is None: logger.info("Trying to establish connection to " + str(self.ip)) self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.connect((self.ip, self.PORT)) rscp_dto = RSCPDTO( RSCPTag.RSCP_REQ_AUTHENTICATION, RSCPType.Container, [ RSCPDTO(RSCPTag.RSCP_AUTHENTICATION_USER, RSCPType.CString, self.username), RSCPDTO(RSCPTag.RSCP_AUTHENTICATION_PASSWORD, RSCPType.CString, self.password) ], None) result = self.send_request(rscp_dto, True) if result.type == RSCPType.Error: self._disconnect() raise RSCPAuthenticationError("Invalid username or password", logger)
def getBatDcbData(self, bat_index=0, bat_indexes=None): if not bat_indexes: bat_indexes = [bat_index] requests = [] for bat_index in bat_indexes: r = RSCPDTO(tag=RSCPTag.BAT_REQ_DATA) r += RSCPDTO(tag=RSCPTag.BAT_INDEX, data=bat_index) r += RSCPTag.BAT_REQ_DCB_COUNT try: data = self.get_data([r], True) logger.debug('Bat #' + str(bat_index) + ' scheint aktiv zu sein, rufe weitere Daten ab') requests += self.getBatData(bat_index=bat_index, dcb_indexes=range(0, data['BAT_DCB_COUNT'].data)) except: logger.debug('Bat #' + str(bat_index) + ' steht nicht zur Verfügung') return requests
def decode_data(self, data: bytes) -> RSCPDTO: magic_byte = struct.unpack(self._MAGIC_CHECK_FORMAT, data[:struct.calcsize(self._MAGIC_CHECK_FORMAT)])[0] if magic_byte == 0xe3dc: decode_frame_result = self._decode_frame(data) return self.decode_data(decode_frame_result[0]) data_header_size = struct.calcsize(self._DATA_HEADER_FORMAT) data_tag_hex, data_type_hex, data_length = struct.unpack(self._DATA_HEADER_FORMAT, data[:data_header_size]) data_tag = RSCPTag(data_tag_hex) data_type = RSCPType(data_type_hex) # Check the data type name to handle the values accordingly if data_type == RSCPType.Container: container_data = [] current_byte = data_header_size while current_byte < data_header_size + data_length: # inner_data, used_length = self.decode_data(data[current_byte:]) inner_rscp_dto = self.decode_data(data[current_byte:]) current_byte += inner_rscp_dto.size container_data.append(inner_rscp_dto) return RSCPDTO(data_tag, data_type, container_data, current_byte) elif data_type == RSCPType.Timestamp: data_format = "<iii" high, low, ms = struct.unpack(data_format, data[data_header_size:data_header_size + struct.calcsize(data_format)]) timestamp = float(high + low) + (float(ms) * 1e-9) return RSCPDTO(data_tag, data_type, timestamp, data_header_size + struct.calcsize(data_format)) elif data_type.name == "Nil": return RSCPDTO(data_tag, data_type, None, data_header_size) elif data_type.mapping != "s": data_format = "<" + data_type.mapping elif data_type.mapping == "s": data_format = "<" + str(data_length) + data_type.mapping else: raise RSCPDataError("Unknown data type: " + str(data_type_hex), logger) value = struct.unpack(data_format, data[data_header_size:data_header_size + struct.calcsize(data_format)])[0] if data_type.mapping == "s": value = value.decode() return RSCPDTO(data_tag, data_type, value, data_header_size + struct.calcsize(data_format))
def getDCDCData(self, dcdc_index=0, dcdc_indexes=None): requests = [] if not dcdc_indexes: dcdc_indexes = [dcdc_index] for dcdc_index in dcdc_indexes: r = RSCPDTO(tag=RSCPTag.DCDC_REQ_DATA) r += RSCPDTO(tag=RSCPTag.DCDC_INDEX, data=dcdc_index) r += RSCPTag.DCDC_REQ_P_BAT r += RSCPTag.DCDC_REQ_P_DCL r += RSCPTag.DCDC_REQ_U_BAT r += RSCPTag.DCDC_REQ_U_DCL r += RSCPTag.DCDC_REQ_I_BAT r += RSCPTag.DCDC_REQ_I_DCL r += RSCPTag.DCDC_REQ_STATUS_AS_STRING r += RSCPTag.DCDC_REQ_FPGA_FIRMWARE r += RSCPTag.DCDC_REQ_FIRMWARE_VERSION r += RSCPTag.DCDC_REQ_SERIAL_NUMBER r += RSCPTag.DCDC_BOARD_VERSION requests.append(r) return requests
def test_encrypted_frame_can_be_decrypted(): encryptor = RSCPEncryptDecrypt("my_key") rscp_utils = RSCPUtils() encoded_data = rscp_utils.encode_data( RSCPDTO(RSCPTag.RSCP_REQ_AUTHENTICATION, RSCPType.Container, [ RSCPDTO(RSCPTag.RSCP_AUTHENTICATION_USER, RSCPType.CString, 'username'), RSCPDTO(RSCPTag.RSCP_AUTHENTICATION_PASSWORD, RSCPType.CString, 'password') ])) framed_data = rscp_utils.encode_frame(encoded_data) encrypted_data = encryptor.encrypt(framed_data) decrypted_data = encryptor.decrypt(encrypted_data) redecoded_data = rscp_utils.decode_data(decrypted_data) assert redecoded_data.tag == RSCPTag.RSCP_REQ_AUTHENTICATION assert redecoded_data.type == RSCPType.Container assert len(redecoded_data.data) == 2 assert redecoded_data.data[0].tag == RSCPTag.RSCP_AUTHENTICATION_USER assert redecoded_data.data[0].type == RSCPType.CString assert redecoded_data.data[0].data == 'username' assert redecoded_data.data[1].tag == RSCPTag.RSCP_AUTHENTICATION_PASSWORD assert redecoded_data.data[1].type == RSCPType.CString assert redecoded_data.data[1].data == 'password'
def send_request(self, payload: Union[RSCPDTO, RSCPTag, bytes], keep_connection_alive: bool = False, waittime: float = 0.0) -> RSCPDTO: """ This will perform a single request. :param payload: The payload that defines the request :param keep_connection_alive: A flag whether to keep the connection alive or not :return: A response object as RSCPDTO """ if isinstance(payload, RSCPTag): payload = RSCPDTO(payload) if self.socket is None: self._connect() if isinstance(payload, bytes): prepared_data = payload else: encode_data = self.rscp_utils.encode_data(payload) prepared_data = self.rscp_utils.encode_frame(encode_data) #rawdata = binascii.hexlify(prepared_data) #logger.debug('Send RAW: ' + str(rawdata)) logger.debug('Send ' + str(len(prepared_data)) + ' Bytes') encrypted_data = self.encrypt_decrypt.encrypt(prepared_data) try: self.socket.send(encrypted_data) except: self._disconnect() raise wait = self.waittime + waittime if wait > 0.0: time.sleep(wait) response = self._receive() if response.type == RSCPType.Error: logger.debug("Error type returned: " + str(response.data)) raise (RSCPCommunicationError( 'Error type returned: ' + str(response.data), logger, response)) if not keep_connection_alive: self._disconnect() return response
def getWeblogin(self): r = RSCPDTO(RSCPTag.SERVER_REQ_NEW_VIRTUAL_CONNECTION, rscp_type=RSCPType.Container) r += RSCPDTO(RSCPTag.SERVER_USER, RSCPType.CString, self.username) pass_md5 = hashlib.md5() pass_md5.update(self.password.encode('utf-8')) password = pass_md5.hexdigest() r += RSCPDTO(RSCPTag.SERVER_PASSWD, RSCPType.CString, password) r += RSCPDTO(RSCPTag.SERVER_IDENTIFIER, RSCPType.CString, self.identifier) r += RSCPDTO(RSCPTag.SERVER_TYPE, RSCPType.Int32, 4) r += RSCPDTO(RSCPTag.SERVER_HASH_CODE, RSCPType.Int32, 1234567890) return [r]
def send_requests(self, payload: [Union[RSCPDTO, RSCPTag]], waittime=0.0) -> [RSCPDTO]: payload_all = bytes() for payload_element in payload: if isinstance(payload_element, RSCPTag): dto = RSCPDTO(payload_element) else: dto = payload_element payload_all += self.rscp_utils.encode_data(dto) prepared_data = self.rscp_utils.encode_frame(payload_all) response = self.send_request(prepared_data, True, waittime) responses: [RSCPDTO] = [] if response.type == RSCPType.Container: data: RSCPDTO for data in response: responses.append(data) else: responses.append(response) return responses
def getRSCPToServer(self, p): if not isinstance(p, list): p = [p] payload = b'' for payload_element in p: if isinstance(payload_element, RSCPTag): x = RSCPDTO(payload_element) else: x = payload_element payload += self.rscp_utils.encode_data(x) payload = self.rscp_utils.encode_frame(payload) r = RSCPDTO(tag=RSCPTag.SERVER_REQ_RSCP_CMD, rscp_type=RSCPType.Container) r += RSCPDTO(tag=RSCPTag.SERVER_CONNECTION_ID, rscp_type=RSCPType.Int64, data=self.server_connection_id) r += RSCPDTO(tag=RSCPTag.SERVER_AUTH_LEVEL, rscp_type=RSCPType.UChar8, data=self.server_auth_level) r += RSCPDTO(tag=RSCPTag.SERVER_RSCP_DATA_LEN, rscp_type=RSCPType.Int32, data=len(payload)) r += RSCPDTO(tag=RSCPTag.SERVER_RSCP_DATA, rscp_type=RSCPType.ByteArray, data=payload) return r
def interpreter_serverdata(self, data): if not isinstance(data, list): data = [data] requests = [] for res in data: if res.name == 'SERVER_REGISTER_CONNECTION': logger.debug(res.name) self.server_connection_id = res['SERVER_CONNECTION_ID'].data self.server_auth_level = res['SERVER_AUTH_LEVEL'].data self.server_type = res['SERVER_TYPE'].data r = RSCPDTO(tag=RSCPTag.SERVER_CONNECTION_REGISTERED, rscp_type=RSCPType.Container) r += RSCPDTO(tag=RSCPTag.SERVER_CONNECTION_ID, rscp_type=RSCPType.Int64, data=self.server_connection_id) r += RSCPDTO(tag=RSCPTag.SERVER_AUTH_LEVEL, rscp_type=RSCPType.UChar8, data=self.server_auth_level) requests.append(r) if res.name == 'SERVER_UNREGISTER_CONNECTION': logger.debug(res.name) self.server_connection_id = None self.server_auth_level = None r = self.getWeblogin() requests += r elif res.name == 'SERVER_REQ_RSCP_CMD': if res['SERVER_RSCP_DATA']: p = [] rscp_data = res['SERVER_RSCP_DATA'] if self.next_response: if isinstance(rscp_data.data, RSCPDTO): self.next_response_data = rscp_data.data else: self.next_response_data = rscp_data self.next_response = None if 'INFO_SERIAL_NUMBER' in rscp_data: self.info_serial_number = rscp_data['INFO_SERIAL_NUMBER'].data if 'INFO_REQ_IP_ADDRESS' in rscp_data: p.append(RSCPDTO(RSCPTag.INFO_IP_ADDRESS, rscp_type=RSCPType.CString, data='0.0.0.0')) if 'INFO_REQ_SUBNET_MASK' in rscp_data: p.append(RSCPDTO(RSCPTag.INFO_SUBNET_MASK, rscp_type=RSCPType.CString, data='0.0.0.0')) if 'INFO_REQ_GATEWAY' in rscp_data: p.append(RSCPDTO(RSCPTag.INFO_GATEWAY, rscp_type=RSCPType.CString, data='0.0.0.0')) if 'INFO_REQ_DNS' in rscp_data: p.append(RSCPDTO(RSCPTag.INFO_DNS, rscp_type=RSCPType.CString, data='0.0.0.0')) if 'INFO_REQ_DHCP_STATUS' in rscp_data: p.append(RSCPDTO(RSCPTag.INFO_DHCP_STATUS, rscp_type=RSCPType.Bool, data=False)) if 'INFO_REQ_TIME' in rscp_data: # TODO: Zeitstempel korrekt bilden mit Berücksichtigung der Zeitzone current_time = time.time() seconds = math.ceil(current_time) nanoseconds = round((current_time - int(current_time)) * 1000) ts = struct.pack('<QI', seconds, nanoseconds) p.append(RSCPDTO(RSCPTag.INFO_TIME, rscp_type=RSCPType.ByteArray, data=ts)) if 'INFO_REQ_TIME_ZONE' in rscp_data: p.append(RSCPDTO(RSCPTag.INFO_TIME_ZONE, rscp_type=RSCPType.CString, data='GMT+2')) if 'INFO_REQ_UTC_TIME' in rscp_data: current_time = time.time() + 7200 seconds = math.ceil(current_time) nanoseconds = round((current_time - int(current_time)) * 1000) ts = struct.pack('<QI', seconds, nanoseconds) p.append(RSCPDTO(RSCPTag.INFO_UTC_TIME, rscp_type=RSCPType.ByteArray, data=ts)) if 'INFO_REQ_A35_SERIAL_NUMBER' in rscp_data: p.append(RSCPDTO(RSCPTag.INFO_A35_SERIAL_NUMBER, rscp_type=RSCPType.CString, data='123456')) if 'INFO_REQ_INFO' in rscp_data: info = RSCPDTO(RSCPTag.INFO_INFO, rscp_type=RSCPType.Container) hsh = self.username + str(self.server_connection_id) md5 = hashlib.md5(hsh.encode()).hexdigest() info += RSCPDTO(RSCPTag.INFO_SERIAL_NUMBER, rscp_type=RSCPType.CString, data='WEB_' + md5) info += RSCPDTO(RSCPTag.INFO_MAC_ADDRESS, rscp_type=RSCPType.CString, data='00:00:00:00:00:00') p.append(info) if len(p) > 0: requests.append(self.getRSCPToServer(p)) elif res.name == 'SERVER_REQ_PING': logger.debug(res.name) r = RSCPDTO(tag=RSCPTag.SERVER_PING) requests.append(r) return requests
def setIdlePeriod(self, type=0, active=True, day=None, start='01:00', end='23:00'): if not day: day = datetime.datetime.today().weekday() periodData = [] periodData.append( RSCPDTO(tag=RSCPTag.EMS_IDLE_PERIOD_TYPE, data=int(type))) periodData.append( RSCPDTO(tag=RSCPTag.EMS_IDLE_PERIOD_DAY, data=int(day))) periodData.append( RSCPDTO(tag=RSCPTag.EMS_IDLE_PERIOD_ACTIVE, data=active)) timeData = [] timeData.append( RSCPDTO(tag=RSCPTag.EMS_IDLE_PERIOD_HOUR, data=int(start[:2]))) timeData.append( RSCPDTO(tag=RSCPTag.EMS_IDLE_PERIOD_MINUTE, data=int(start[3:]))) periodData.append( RSCPDTO(tag=RSCPTag.EMS_IDLE_PERIOD_START, data=timeData)) timeData = [] timeData.append( RSCPDTO(tag=RSCPTag.EMS_IDLE_PERIOD_HOUR, data=int(end[:2]))) timeData.append( RSCPDTO(tag=RSCPTag.EMS_IDLE_PERIOD_MINUTE, data=int(end[3:]))) periodData.append( RSCPDTO(tag=RSCPTag.EMS_IDLE_PERIOD_END, data=timeData)) data = [] data.append( RSCPDTO(tag=RSCPTag.EMS_IDLE_PERIOD, rscp_type=RSCPType.Container, data=periodData)) containerData = [] containerData.append( RSCPDTO(tag=RSCPTag.EMS_REQ_SET_IDLE_PERIODS, rscp_type=RSCPType.Container, data=data)) return containerData
def getPVIData(self, pvi_index=0, pvi_indexes=None, phase=None, string=None): requests = [] phases = phase if isinstance(phase, list) else [phase] if phase else phase strings = string if isinstance( string, list) else [string] if string else string if not pvi_indexes: pvi_indexes = [pvi_index] for pvi_index in pvi_indexes: r = RSCPDTO(tag=RSCPTag.PVI_REQ_DATA) r += RSCPDTO(tag=RSCPTag.PVI_INDEX, data=pvi_index) r += RSCPTag.PVI_REQ_AC_MAX_PHASE_COUNT r += RSCPTag.PVI_REQ_TEMPERATURE_COUNT r += RSCPTag.PVI_REQ_DC_MAX_STRING_COUNT data = self.get_data([r], True) tempcount = int(data['PVI_TEMPERATURE_COUNT']) if not phases: phases = range(0, int(data['PVI_AC_MAX_PHASE_COUNT'])) if not strings: strings = range(0, int(data['PVI_DC_MAX_STRING_COUNT'])) r = RSCPDTO(tag=RSCPTag.PVI_REQ_DATA) r += RSCPDTO(tag=RSCPTag.PVI_INDEX, data=pvi_index) r += RSCPTag.PVI_REQ_TEMPERATURE_COUNT r += RSCPTag.PVI_REQ_TYPE r += RSCPTag.PVI_REQ_SERIAL_NUMBER r += RSCPTag.PVI_REQ_VERSION r += RSCPTag.PVI_REQ_ON_GRID r += RSCPTag.PVI_REQ_STATE r += RSCPTag.PVI_REQ_LAST_ERROR r += RSCPTag.PVI_REQ_COS_PHI r += RSCPTag.PVI_REQ_VOLTAGE_MONITORING r += RSCPTag.PVI_REQ_POWER_MODE r += RSCPTag.PVI_REQ_SYSTEM_MODE r += RSCPTag.PVI_REQ_FREQUENCY_UNDER_OVER r += RSCPTag.PVI_REQ_AC_MAX_PHASE_COUNT r += RSCPTag.PVI_REQ_MAX_TEMPERATURE r += RSCPTag.PVI_REQ_MIN_TEMPERATURE r += RSCPTag.PVI_REQ_AC_MAX_APPARENTPOWER r += RSCPTag.PVI_REQ_DEVICE_STATE for phase in phases: r += RSCPDTO(tag=RSCPTag.PVI_REQ_AC_POWER, data=phase) r += RSCPDTO(tag=RSCPTag.PVI_REQ_AC_VOLTAGE, data=phase) r += RSCPDTO(tag=RSCPTag.PVI_REQ_AC_CURRENT, data=phase) r += RSCPDTO(tag=RSCPTag.PVI_REQ_AC_APPARENTPOWER, data=phase) r += RSCPDTO(tag=RSCPTag.PVI_REQ_AC_REACTIVEPOWER, data=phase) r += RSCPDTO(tag=RSCPTag.PVI_REQ_AC_ENERGY_ALL, data=phase) r += RSCPDTO(tag=RSCPTag.PVI_REQ_AC_ENERGY_GRID_CONSUMPTION, data=phase) for string in strings: r += RSCPDTO(tag=RSCPTag.PVI_REQ_DC_POWER, data=string) r += RSCPDTO(tag=RSCPTag.PVI_REQ_DC_VOLTAGE, data=string) r += RSCPDTO(tag=RSCPTag.PVI_REQ_DC_CURRENT, data=string) r += RSCPDTO(tag=RSCPTag.PVI_REQ_DC_STRING_ENERGY_ALL, data=string) for temps in range(0, tempcount): r += RSCPDTO(tag=RSCPTag.PVI_REQ_TEMPERATURE, data=temps) requests.append(r) return requests