简体   繁体   中英

embed synchronous python code with Asyncio

This script below is some example code from the open leader project that uses iohttp and asyncio for a client server XML based web protocol communication process for the utility industry.

Newbie question here, is it possible to embed synchronous code with asynchronous code? For example this code here which is embeded into the main.py below I know is definitely synchronous. Its BACnet communication library with BAC0 .

bacnet = BAC0.lite()


async def collect_report_value():
    #read temp sensor from BACnet device
    T1 = bacnet.read('12345:2 analogInput 2 presentValue')
    return T1

The main.py script works (shown below) I can #read temp sensor from BACnet device from the async function collect_report_value I am just worried that I could possibly be making the entire process synchronous. Would anyone have any advice?

import asyncio
from datetime import timedelta
from openleadr import OpenADRClient, enable_default_logging
import BAC0



bacnet = BAC0.lite()


async def collect_report_value():
    #read temp sensor from BACnet device
    T1 = bacnet.read('12345:2 analogInput 2 presentValue')
    return T1

async def handle_event(event):
    # This callback receives an Event dict.
    # You should include code here that sends control signals to your resources.
    return 'optIn'

# Create the client object
client = OpenADRClient(ven_name='ven123',
                       vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b')

# Add the report capability to the client
client.add_report(callback=collect_report_value,
                  resource_id='device001',
                  measurement='temperature',
                  sampling_rate=timedelta(seconds=60))

# Add event handling capability to the client
client.add_handler('on_event', handle_event)

# Run the client in the Python AsyncIO Event Loop
loop = asyncio.get_event_loop()
loop.create_task(client.run())
loop.run_forever()

EDIT final script that appears to work

import asyncio
from datetime import timedelta
from openleadr import OpenADRClient, enable_default_logging
import BAC0
import concurrent.futures

enable_default_logging()


#apprently runs on its own thread
bacnet = BAC0.lite()


def blocking_io():
    #read temp sensor from BACnet device
    try:
         sensor_value = bacnet.read('12345:2 analogInput 2 presentValue')
         return sensor_value
    except:
         return np.nan


async def collect_report_value():
    # 1. Run in the default loop's executor:
    result = await loop.run_in_executor(None, blocking_io)
    return result



async def handle_event(event):
    # This callback receives an Event dict.
    # You should include code here that sends control signals to your resources.
    return 'optIn'

# Create the client object
client = OpenADRClient(ven_name='ven123',
                       vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b')

# Add the report capability to the client
client.add_report(callback=collect_report_value,
                  resource_id='device001',
                  measurement='temperature',
                  sampling_rate=timedelta(seconds=60))

# Add event handling capability to the client
client.add_handler('on_event', handle_event)

# Run the client in the Python AsyncIO Event Loop
loop = asyncio.get_event_loop()
loop.create_task(client.run())
loop.run_forever()

This worked

import asyncio
from datetime import timedelta
from openleadr import OpenADRClient, enable_default_logging
import BAC0
import concurrent.futures

enable_default_logging()


#apprently runs on its own thread
bacnet = BAC0.lite()


def blocking_io():
    #read temp sensor from BACnet device
    sensor_value = bacnet.read('12345:2 analogInput 2 presentValue')
    return sensor_value


async def collect_report_value():
    # 1. Run in the default loop's executor:
    result = await loop.run_in_executor(None, blocking_io)
    return result



async def handle_event(event):
    # This callback receives an Event dict.
    # You should include code here that sends control signals to your resources.
    return 'optIn'

# Create the client object
client = OpenADRClient(ven_name='ven123',
                       vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM