Merge pull request #63 from mjkl-gh/master
Improve documentation asyncio
This commit is contained in:
		
						commit
						7f35cd3c73
					
				
							
								
								
									
										173
									
								
								README.rst
									
									
									
									
									
								
							
							
						
						
									
										173
									
								
								README.rst
									
									
									
									
									
								
							| @ -39,10 +39,6 @@ process because the code is blocking (not asynchronous): | ||||
|      for telegram in serial_reader.read(): | ||||
|          print(telegram)  # see 'Telegram object' docs below | ||||
| 
 | ||||
| **AsyncIO client** | ||||
| 
 | ||||
| To be documented. | ||||
| 
 | ||||
| **Socket client** | ||||
| 
 | ||||
| Read a remote serial port (for example using ser2net) and work with the parsed telegrams. | ||||
| @ -62,6 +58,115 @@ It should be run in a separate process because the code is blocking (not asynchr | ||||
|      for telegram in socket_reader.read(): | ||||
|          print(telegram)  # see 'Telegram object' docs below | ||||
| 
 | ||||
| **AsyncIO client** | ||||
| 
 | ||||
| For a test run using a tcp server (lasting 20 seconds) use the following example: | ||||
| 
 | ||||
| .. code-block:: python | ||||
|     import asyncio | ||||
|     import logging | ||||
|     from dsmr_parser import obis_references | ||||
|     from dsmr_parser.clients.protocol import create_dsmr_reader, create_tcp_dsmr_reader | ||||
| 
 | ||||
|     logging.basicConfig(level=logging.INFO, format='%(message)s') | ||||
| 
 | ||||
|     HOST = MY_HOST | ||||
|     PORT = MY_PORT | ||||
|     DSMR_VERSION = MY_DSMR_VERSION | ||||
| 
 | ||||
|     logger = logging.getLogger('tcpclient') | ||||
|     logger.debug("Logger created") | ||||
| 
 | ||||
|     def printTelegram(telegram): | ||||
|         logger.info(telegram) | ||||
| 
 | ||||
| 
 | ||||
|     async def main(): | ||||
|         try: | ||||
|             logger.debug("Getting loop") | ||||
|             loop = asyncio.get_event_loop() | ||||
|             logger.debug("Creating reader") | ||||
|             await 	create_tcp_dsmr_reader( | ||||
|                                 HOST, | ||||
|                                 PORT, | ||||
|                                 DSMR_VERSION, | ||||
|                                 printTelegram, | ||||
|                                 loop | ||||
|                                 ) | ||||
|             logger.debug("Reader created going to sleep now")					 | ||||
|             await asyncio.sleep(20) | ||||
|             logger.info('Finished run')					 | ||||
|         except Exception as e: | ||||
|             logger.error("Unexpected error: "+ e) | ||||
| 
 | ||||
|     asyncio.run(main()) | ||||
| 
 | ||||
| Note the creation of a callback function to call when a telegram is received. In this case `printTelegram`. Normally the used loop is the one running. | ||||
| 
 | ||||
| Currently the asyncio implementation does not support returning telegram objects directly as a `read_as_object()` for async tcp is currently not implemented. | ||||
| Moreover, the telegram passed to `telegram_callback(telegram)` is already parsed. Therefore we can't feed it into the telegram constructor directly as that expects unparsed telegrams | ||||
| 
 | ||||
| However, if we construct a mock TelegramParser that just returns the already parsed object we can work around this. An example is below: | ||||
| 
 | ||||
| .. code-block:: python | ||||
|     import asyncio | ||||
|     import logging | ||||
|     #from dsmr_parser import obis_references | ||||
|     #from dsmr_parser import telegram_specifications | ||||
|     #from dsmr_parser.clients.protocol import create_dsmr_reader, create_tcp_dsmr_reader | ||||
|     #from dsmr_parser.objects import Telegram | ||||
| 
 | ||||
|     logging.basicConfig(level=logging.INFO, format='%(message)s') | ||||
| 
 | ||||
|     HOST = MY_HOST | ||||
|     PORT = MY_PORT | ||||
|     DSMR_VERSION = MY_DSMR_VERSION | ||||
| 
 | ||||
|     logger = logging.getLogger('tcpclient') | ||||
|     logger.debug("Logger created") | ||||
| 
 | ||||
|     class mockTelegramParser(object): | ||||
| 
 | ||||
|         def parse(self, telegram): | ||||
|             return telegram | ||||
| 
 | ||||
|     telegram_parser = mockTelegramParser() | ||||
| 
 | ||||
|     def printTelegram(telegram): | ||||
|         try: | ||||
|             logger.info(Telegram(telegram, telegram_parser, telegram_specifications.V4)) | ||||
|         except InvalidChecksumError as e: | ||||
|             logger.warning(str(e)) | ||||
|         except ParseError as e: | ||||
|             logger.error('Failed to parse telegram: %s', e) | ||||
| 
 | ||||
| 
 | ||||
|     async def main(): | ||||
|         try: | ||||
|             logger.debug("Getting loop") | ||||
|             loop = asyncio.get_event_loop() | ||||
|             logger.debug("Creating reader") | ||||
|             await 	create_tcp_dsmr_reader( | ||||
|                                 HOST, | ||||
|                                 PORT, | ||||
|                                 DSMR_VERSION, | ||||
|                                 printTelegram, | ||||
|                                 loop | ||||
|                                 ) | ||||
|             logger.debug("Reader created going to sleep now")					 | ||||
|             while True: | ||||
|                 await asyncio.sleep(1) | ||||
|         except Exception as e: | ||||
|             logger.error("Unexpected error: "+ e) | ||||
|             raise | ||||
| 
 | ||||
|     if __name__ == '__main__': | ||||
|         try: | ||||
|             asyncio.run(main()) | ||||
|         except (KeyboardInterrupt, SystemExit): | ||||
|             logger.info('Closing down...')					 | ||||
|         except Exception as e: | ||||
|             logger.error("Unexpected error: "+ e) | ||||
| 
 | ||||
| Parsing module usage | ||||
| -------------------- | ||||
| @ -70,39 +175,39 @@ into a dictionary. | ||||
| 
 | ||||
| .. code-block:: python | ||||
| 
 | ||||
|      from dsmr_parser import telegram_specifications | ||||
|      from dsmr_parser.parsers import TelegramParser | ||||
|     from dsmr_parser import telegram_specifications | ||||
|     from dsmr_parser.parsers import TelegramParser | ||||
| 
 | ||||
|      # String is formatted in separate lines for readability. | ||||
|      telegram_str = ( | ||||
|          '/ISk5\\2MT382-1000\r\n' | ||||
|          '\r\n' | ||||
|          '0-0:96.1.1(4B384547303034303436333935353037)\r\n' | ||||
|          '1-0:1.8.1(12345.678*kWh)\r\n' | ||||
|          '1-0:1.8.2(12345.678*kWh)\r\n' | ||||
|          '1-0:2.8.1(12345.678*kWh)\r\n' | ||||
|          '1-0:2.8.2(12345.678*kWh)\r\n' | ||||
|          '0-0:96.14.0(0002)\r\n' | ||||
|          '1-0:1.7.0(001.19*kW)\r\n' | ||||
|          '1-0:2.7.0(000.00*kW)\r\n' | ||||
|          '0-0:17.0.0(016*A)\r\n' | ||||
|          '0-0:96.3.10(1)\r\n' | ||||
|          '0-0:96.13.1(303132333435363738)\r\n' | ||||
|          '0-0:96.13.0(303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E' | ||||
|          '3F303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F30313233' | ||||
|          '3435363738393A3B3C3D3E3F)\r\n' | ||||
|          '0-1:96.1.0(3232323241424344313233343536373839)\r\n' | ||||
|          '0-1:24.1.0(03)\r\n' | ||||
|          '0-1:24.3.0(090212160000)(00)(60)(1)(0-1:24.2.1)(m3)\r\n' | ||||
|          '(00001.001)\r\n' | ||||
|          '0-1:24.4.0(1)\r\n' | ||||
|          '!\r\n' | ||||
|      ) | ||||
|     # String is formatted in separate lines for readability. | ||||
|     telegram_str = ( | ||||
|         '/ISk5\\2MT382-1000\r\n' | ||||
|         '\r\n' | ||||
|         '0-0:96.1.1(4B384547303034303436333935353037)\r\n' | ||||
|         '1-0:1.8.1(12345.678*kWh)\r\n' | ||||
|         '1-0:1.8.2(12345.678*kWh)\r\n' | ||||
|         '1-0:2.8.1(12345.678*kWh)\r\n' | ||||
|         '1-0:2.8.2(12345.678*kWh)\r\n' | ||||
|         '0-0:96.14.0(0002)\r\n' | ||||
|         '1-0:1.7.0(001.19*kW)\r\n' | ||||
|         '1-0:2.7.0(000.00*kW)\r\n' | ||||
|         '0-0:17.0.0(016*A)\r\n' | ||||
|         '0-0:96.3.10(1)\r\n' | ||||
|         '0-0:96.13.1(303132333435363738)\r\n' | ||||
|         '0-0:96.13.0(303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E' | ||||
|         '3F303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F30313233' | ||||
|         '3435363738393A3B3C3D3E3F)\r\n' | ||||
|         '0-1:96.1.0(3232323241424344313233343536373839)\r\n' | ||||
|         '0-1:24.1.0(03)\r\n' | ||||
|         '0-1:24.3.0(090212160000)(00)(60)(1)(0-1:24.2.1)(m3)\r\n' | ||||
|         '(00001.001)\r\n' | ||||
|         '0-1:24.4.0(1)\r\n' | ||||
|         '!\r\n' | ||||
|     ) | ||||
| 
 | ||||
|      parser = TelegramParser(telegram_specifications.V3) | ||||
|     parser = TelegramParser(telegram_specifications.V3) | ||||
| 
 | ||||
|      telegram = parser.parse(telegram_str) | ||||
|      print(telegram)  # see 'Telegram object' docs below | ||||
|     telegram = parser.parse(telegram_str) | ||||
|     print(telegram)  # see 'Telegram object' docs below | ||||
| 
 | ||||
| Telegram dictionary | ||||
| ------------------- | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user