Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 25, 2020 12:25:47

golubtsov
Зарегистрирован: 2020-12-25
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

вопрос по uio.IOBase и Repl

Доброго времени суток.
Недавно начал программировать на 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
    

Отредактировано golubtsov (Дек. 25, 2020 13:43:45)

Офлайн

#2 Дек. 25, 2020 19:53:28

AD0DE412
Зарегистрирован: 2019-05-12
Сообщения: 1130
Репутация: +  44  -
Профиль   Отправить e-mail  

вопрос по uio.IOBase и Repl

возникает серьёзная ошибка, чип перезагружается.
может это https://pypi.org/project/micropython-logging/
мудрым советам.
эй чяго … зачем вы … не надо так



1. пжлст, форматируйте код, это в панели создания сообщений, выделите код и нажмите что то вроде
2. чтобы вставить изображение залейте его куда нибудь (например), нажмите и вставьте ссылку на его url

есчщо

Отредактировано AD0DE412 (Дек. 25, 2020 20:27:01)

Офлайн

#3 Дек. 26, 2020 02:14:44

golubtsov
Зарегистрирован: 2020-12-25
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

вопрос по uio.IOBase и Repl

эй чяго … зачем вы … не надо так
Надо Федя, надо

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


PS. Сдается мне, что uasyncio блокирует REPL на чтение данных, просто не возвращает ему управление бл.

Отредактировано golubtsov (Дек. 26, 2020 03:54:09)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version