Найти - Пользователи
Полная версия: вопрос по uio.IOBase и Repl
Начало » Python для новичков » вопрос по uio.IOBase и Repl
1
golubtsov
Доброго времени суток.
Недавно начал программировать на Python, а точнее сразу на MicroPython для ESP32/8266.
Вообще, очень сложно было, я на уровне любителя программировал для WEB, с трудом понял асинхронное программирование, ещё все было усложнено не правильной работой uasyncio с сокетами на этих платформах, написал свою реализацию uasyncio+socket всё прекрасно работает, пока изучал язык и платформу, с ужасом смотрел в сторону буферов и потоков(stream), думал потом разберусь. Не тут-то было, уперся в собственную реализацию websocket<->repl, стандартная реализация webrepl во-первых не входит в рамки проекта, во-вторых просто не работает из-за каких-то проблем платформы (асинхронные потоки просто виснут).
В принципе все просто, переключаешь REPL на собственный поток, реализующий интерфейс uio.IOBase, и все заработает, см https://docs.micropython.org/en/latest/library/uos.html#uos.dupterm, не пойму как реализовать класс. REPL переключается, сообщения не видно, возникает серьёзная ошибка, чип перезагружается.
Буду рад мудрым советам.

 import uasyncio, uio, machine, sys, uos
import webnode.webmodule as webmodule
from webnode.utils import *
class Stream( uio.IOBase ):
    def __init__( self, wm ):
        self.wm = wm
        
    # запись
    def write( self, d ):
        # потом эти данные будут отправлятся в сокет
        self.wm.wdata.append( d )
    
    def read( self, n = -1 ):
        if not self.wm.rdata: return None
        if n >= 0 and n < len( self.wm.rdata ):
            d = self.wm.rdata[:n]
            self.wm.rdata = self.wm.rdata[n:]
            return d
        d = self.wm.rdata
        self.wm.rdata= '';
        return d
    
    def readline( self ):
        if not self.wm.rdata: return None
        i = self.wm.rdata.find('\r\n')
        return self.read( i )
    
    def readinto( self,  buf ):
        if self.wm.rdata:
            d = self.wm.rdata
            self.wm.rdata = ''
            buf.write( d )
        
    
class WebModule( webmodule.WebModule ):
    
    name = 'Repl'
   
    async def onText( self, frame ):
        self._log('appendData', frame['body'] )
        self.rdata += frame['body']
    
    async def onLoop( self ):
        if self.wdata:
            d = self.wdata.pop(0)
            await self.asocket.asendWS( d )
    
    def onConnect( self, headers ):
        
        self.wdata = []
        self.rdata = ''
        
        await self.asocket.asendWS( data='Прювет из модуля '+self.name )
        self.stream = Stream( self )
        uos.dupterm( self.stream, 1)
    
    def onSocketError( self, msg = 'socket error' ):
        self._log( msg )
        self.disconnect()
        return False
    
    def disconnect( self ):
        self._log('disconnect')
        uart = machine.UART(0, 115200)
        uos.dupterm(uart, 1)
        del self.stream.wm
        del self.stream
        del self.asocket
    
AD0DE412
возникает серьёзная ошибка, чип перезагружается.
может это https://pypi.org/project/micropython-logging/
мудрым советам.
эй чяго … зачем вы … не надо так
golubtsov
эй чяго … зачем вы … не надо так
Надо Федя, надо

Ну с выводом сообщений как-то решил вопрос, просто взял тот самый uart, который отсоединил и “врайтил” сообщения туда, подсмотрел код тут https://github.com/dmazzella/uble/blob/master/examples/api/api_repl.py, человек реализовал 2 метода по документации, повторил. Write работает как надо, причем туда данные скидываются маленькими кусочками, но быстро, так что цикл модуля отправлял клиенту уже целое сообщение. А вот readinto даже не вызывается из uos , как-то сообщать надо uos, что есть данные чтоли, не пойму пока


PS. Сдается мне, что uasyncio блокирует REPL на чтение данных, просто не возвращает ему управление бл.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB