Read data from a table. If successful, all of the data from the
		requested table will be returned.

		:param int tableid: The table number to read from (0x0000 <= tableid <= 0xffff)
		:param int octetcount: Limit the amount of data read, only works if
		  the meter supports this type of reading.
		:param int offset: The offset at which to start to read the data from.

def get_table_data(self, tableid, octetcount=None, offset=None):
		"""
		Read data from a table. If successful, all of the data from the
		requested table will be returned.

		:param int tableid: The table number to read from (0x0000 <= tableid <= 0xffff)
		:param int octetcount: Limit the amount of data read, only works if
		  the meter supports this type of reading.
		:param int offset: The offset at which to start to read the data from.
		"""
		if self.caching_enabled and tableid in self._cacheable_tables and tableid in self._table_cache.keys():
			self.logger.info('returning cached table #' + str(tableid))
			return self._table_cache[tableid]
		self.send(C1218ReadRequest(tableid, offset, octetcount))
		data = self.recv()
		status = data[0]
		if status != 0x00:
			status = status
			details = (C1218_RESPONSE_CODES.get(status) or 'unknown response code')
			self.logger.error('could not read table id: ' + str(tableid) + ', error: ' + details)
			raise C1218ReadTableError('could not read table id: ' + str(tableid) + ', error: ' + details, status)
		if len(data) < 4:
			if len(data) == 0:
				self.logger.error('could not read table id: ' + str(tableid) + ', error: no data was returned')
				raise C1218ReadTableError('could not read table id: ' + str(tableid) + ', error: no data was returned')
			self.logger.error('could not read table id: ' + str(tableid) + ', error: data read was corrupt, invalid length (less than 4)')
			raise C1218ReadTableError('could not read table id: ' + str(tableid) + ', error: data read was corrupt, invalid length (less than 4)')
		length = struct.unpack('>H', data[1:3])[0]
		chksum = data[-1]
		data = data[3:-1]
		if len(data) != length:
			self.logger.error('could not read table id: ' + str(tableid) + ', error: data read was corrupt, invalid length')
			raise C1218ReadTableError('could not read table id: ' + str(tableid) + ', error: data read was corrupt, invalid length')
		if not check_data_checksum(data, chksum):
			self.logger.error('could not read table id: ' + str(tableid) + ', error: data read was corrupt, invalid check sum')
			raise C1218ReadTableError('could not read table id: ' + str(tableid) + ', error: data read was corrupt, invalid checksum')

		if self.caching_enabled and tableid in self._cacheable_tables and not tableid in self._table_cache.keys():
			self.logger.info('caching table #' + str(tableid))
			self._table_cache[tableid] = data
		return data