Merge pull request #63 from mjkl-gh/master
Improve documentation asyncio
This commit is contained in:
		
						commit
						7f35cd3c73
					
				
							
								
								
									
										175
									
								
								README.rst
									
									
									
									
									
								
							
							
						
						
									
										175
									
								
								README.rst
									
									
									
									
									
								
							| @ -39,10 +39,6 @@ process because the code is blocking (not asynchronous): | |||||||
|      for telegram in serial_reader.read(): |      for telegram in serial_reader.read(): | ||||||
|          print(telegram)  # see 'Telegram object' docs below |          print(telegram)  # see 'Telegram object' docs below | ||||||
| 
 | 
 | ||||||
| **AsyncIO client** |  | ||||||
| 
 |  | ||||||
| To be documented. |  | ||||||
| 
 |  | ||||||
| **Socket client** | **Socket client** | ||||||
| 
 | 
 | ||||||
| Read a remote serial port (for example using ser2net) and work with the parsed telegrams. | 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(): |      for telegram in socket_reader.read(): | ||||||
|          print(telegram)  # see 'Telegram object' docs below |          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 | Parsing module usage | ||||||
| -------------------- | -------------------- | ||||||
| @ -70,39 +175,39 @@ into a dictionary. | |||||||
| 
 | 
 | ||||||
| .. code-block:: python | .. code-block:: python | ||||||
| 
 | 
 | ||||||
|      from dsmr_parser import telegram_specifications |     from dsmr_parser import telegram_specifications | ||||||
|      from dsmr_parser.parsers import TelegramParser |     from dsmr_parser.parsers import TelegramParser | ||||||
| 
 | 
 | ||||||
|      # String is formatted in separate lines for readability. |     # String is formatted in separate lines for readability. | ||||||
|      telegram_str = ( |     telegram_str = ( | ||||||
|          '/ISk5\\2MT382-1000\r\n' |         '/ISk5\\2MT382-1000\r\n' | ||||||
|          '\r\n' |         '\r\n' | ||||||
|          '0-0:96.1.1(4B384547303034303436333935353037)\r\n' |         '0-0:96.1.1(4B384547303034303436333935353037)\r\n' | ||||||
|          '1-0:1.8.1(12345.678*kWh)\r\n' |         '1-0:1.8.1(12345.678*kWh)\r\n' | ||||||
|          '1-0:1.8.2(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.1(12345.678*kWh)\r\n' | ||||||
|          '1-0:2.8.2(12345.678*kWh)\r\n' |         '1-0:2.8.2(12345.678*kWh)\r\n' | ||||||
|          '0-0:96.14.0(0002)\r\n' |         '0-0:96.14.0(0002)\r\n' | ||||||
|          '1-0:1.7.0(001.19*kW)\r\n' |         '1-0:1.7.0(001.19*kW)\r\n' | ||||||
|          '1-0:2.7.0(000.00*kW)\r\n' |         '1-0:2.7.0(000.00*kW)\r\n' | ||||||
|          '0-0:17.0.0(016*A)\r\n' |         '0-0:17.0.0(016*A)\r\n' | ||||||
|          '0-0:96.3.10(1)\r\n' |         '0-0:96.3.10(1)\r\n' | ||||||
|          '0-0:96.13.1(303132333435363738)\r\n' |         '0-0:96.13.1(303132333435363738)\r\n' | ||||||
|          '0-0:96.13.0(303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E' |         '0-0:96.13.0(303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E' | ||||||
|          '3F303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F30313233' |         '3F303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F30313233' | ||||||
|          '3435363738393A3B3C3D3E3F)\r\n' |         '3435363738393A3B3C3D3E3F)\r\n' | ||||||
|          '0-1:96.1.0(3232323241424344313233343536373839)\r\n' |         '0-1:96.1.0(3232323241424344313233343536373839)\r\n' | ||||||
|          '0-1:24.1.0(03)\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' |         '0-1:24.3.0(090212160000)(00)(60)(1)(0-1:24.2.1)(m3)\r\n' | ||||||
|          '(00001.001)\r\n' |         '(00001.001)\r\n' | ||||||
|          '0-1:24.4.0(1)\r\n' |         '0-1:24.4.0(1)\r\n' | ||||||
|          '!\r\n' |         '!\r\n' | ||||||
|      ) |     ) | ||||||
| 
 | 
 | ||||||
|      parser = TelegramParser(telegram_specifications.V3) |     parser = TelegramParser(telegram_specifications.V3) | ||||||
|      | 
 | ||||||
|      telegram = parser.parse(telegram_str) |     telegram = parser.parse(telegram_str) | ||||||
|      print(telegram)  # see 'Telegram object' docs below |     print(telegram)  # see 'Telegram object' docs below | ||||||
| 
 | 
 | ||||||
| Telegram dictionary | Telegram dictionary | ||||||
| ------------------- | ------------------- | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user