Presto with Google Sheets

I want to use Preston to display buttons from specific start-ups here, and then have it enter them into the spreadsheet via a Google Sheets API. I don’t have a problem if the whole thing works in regular Python, but IT doesnt Work in using Micro Python. Is there any problem? Does anyone have experience with this or have a script that could help me?

MicroPython feature/presto-wireless-2025 urequests VERBOSE error

I’m now trying to alternatively establish a connection via the post method and a URL: of the sheet. But that also seems problematic. MicroPython feature/presto-wireless-2025 urequests VERBOSE error
It must be possible somehow to get a file or data from a file from the board to a local system. An update via API works from the normal Python environment, but not from the board. I just need the option to read the data from, for example, the file DataID2.json from the board without my main script, which is writing the data, being aborted.

Now, back to what I’m actually planning to do. I have three buttons on the Presto (present, absent, home office). I want the status to be displayed in Sheets when a button is pressed.

more…

Hard to see what is going wrong without code and error trace. Maybe you post your code that works (regular Python), and that does not work (MicroPython) including a full error-trace. GET and POST requests are no problem for MicroPython, so what you want to do seems possible (at this abstract level of course).

I would prefer an API interface. That works perfectly in Python, but there doesn’t seem to be a really functioning API library in Micropython. If that were the case, I would be able to have the script on the Presto send the status information directly to the Sheets table via the API. The POST method also causes problems, possibly because of https, I don’t know. I could now try sending the file with the data to a Pi5 and processing it there via the API. But that also causes problems, because the main script stops when accessing the data file via COM. So if there is a Micropython API, please let me know! Ultimately, I want to use around 50-100 Prestos for the Red Cross to display status information on a screen. If it works, there would be many good applications for it at the Red Cross. I’m open to any good ideas!

Ok, understood. When I enter “google sheets micropython” in my search-engine of choice, I have countless hits (libraries, tutorials). Have you tried any of those?

Try a Lot, also prompting Gemini. I remember a other Project with Pico Incy and Work now ON this solution with Sendung Email. It works and now I try to Work with that in Sheets using a Java Skript. Update: It is working well. Can send now Informations that Set by Press a Button in the Screen to Google Sheets by Email. Can use that also in Google Sites for showing all registrated Users. Great

Can you share code that put the text on the button? I cant seem to pull that off and have to put text next to the button. Thank you

@azsrq13 I don’t know if the example I enclose will help, but it was a bit of a nonsense simple test of buttons I did a while back. It has a couple of buttons with text on the first screen, one of which flashes red when pressed, and the other one changes the display to a second screen with another couple of buttons, both with text on the buttons. I don’t actually use this method but prefer to write to the framebuffer directly, but this short example at least does use the Presto vector graphics to create buttons that can be tapped, so it may help.


from presto import Presto
from picovector import PicoVector, Polygon, Transform, ANTIALIAS_X16
import asyncio
import time

presto = Presto(full_res=True)
display = presto.display

vector = PicoVector(display)
t = Transform()
vector.set_transform(t)
vector.set_antialiasing(ANTIALIAS_X16)
vector.set_font("Roboto-Medium.af", 40)
vector.set_font_letter_spacing(100)
vector.set_font_word_spacing(100)

touch = presto.touch


RED = display.create_pen(200, 0, 0)
BLACK = display.create_pen(0, 0, 0)
GREY = display.create_pen(50, 50, 50)
LIGHTGREY = display.create_pen(100, 100, 100)
WHITE = display.create_pen(255, 255, 255)
SWHITE = display.create_pen(150, 150, 150)
PALEGREEN = display.create_pen(135, 159, 169)
DARKGREY = display.create_pen(10, 40, 50)
GREEN = display.create_pen(14, 60, 76)
PINK = display.create_pen(200,100,100)
BLUE = display.create_pen(0,0,255)
YELLOW = display.create_pen(180,180,0)



class GuiManager:
    def __init__(self):
        self.screens = {}
        self.current_screen = None
        
    def add_screen(self, name, bg_colour):
        self.screens.update({name: {'bg_colour': bg_colour, 'widgets':[]}})
        if self.current_screen is None:
            self.current_screen = name
            
    def set_screen(self, name):
        if name in self.screens:
            self.current_screen = name
        else:
            print('error - screen name not found')
            
    def add_widget(self, screen_name, widget_obj):
        if screen_name in self.screens:
            if widget_obj not in self.screens[screen_name]['widgets']:
                self.screens[screen_name]['widgets'].append(widget_obj)
                widget_obj.gui_manager = self
                widget_obj.assigned_screen = screen_name
        else:
            print('error - screen name not found')
                
    def blank_gui(self):
        display.set_pen(self.screens[self.current_screen]['bg_colour'])
        display.clear()
    
    def draw_gui(self):
        if self.current_screen is None:
            return
        self.blank_gui()
        for widget in self.screens[self.current_screen]['widgets']:
            widget.show()
        presto.update()
        
    def draw_widget(self, widget):
        pass
    
    def process_touch(self,x,y):
        for widget in self.screens[self.current_screen]['widgets']:
            if widget.process_touch(x,y):
                return
            
        
class GuiWidget:
    def __init__(self, x, y, w = None, h = None, fg_colour=WHITE, bg_colour=BLACK):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.fg_colour = fg_colour
        self.bg_colour = bg_colour
        self.gui_manager = None
        self.poly = Polygon()
        self.poly_exists = False
        self.assigned_screen = None
    
    def show(self):
        pass
    
    def within_bounds(self, x, y, w=None, h=None, pad=10):
        """Check if (x,y) is within padded bounds of this control."""
        w = w or self.w
        h = h or self.h
        pad = pad 
        return (self.x - pad <= x < self.x + w + pad) and (self.y - pad <= y < self.y + h + pad)
    
    def process_touch(self,x,y):
        return False
           
 
class GuiButton(GuiWidget):
    def __init__(self, x, y, w, h, fg_colour, bg_colour=WHITE, text=None,
                 text_colour=BLACK, flash_colour=None,font="Roboto-Medium.af", font_size=40, r_corners=False, callback=None):
        super().__init__(x, y, w, h, fg_colour, bg_colour)
        self.text = text
        self.text_colour = text_colour
        self.flash_colour = flash_colour
        self.font = font
        self.font_size = font_size
        self.r_corners = r_corners
        self.callback = callback

    def show(self):
        display.set_pen(self.fg_colour)
        if self.poly_exists == False:
            if self.r_corners is True:
                self.poly.rectangle(self.x, self.y, self.w, self.h, corners=(10,10,10,10))
            else:
                self.poly.rectangle(self.x, self.y, self.w, self.h)
            self.poly_exists=True
        vector.draw(self.poly)
        # put text on the button    
        if self.text is not None:
            vector.set_font(self.font, self.font_size)
            display.set_pen(self.text_colour)
            vector.text(self.text, self.x + 30, self.y + 30)          
    
    async def flash(self):
        if self.flash_colour:
            button_colour=self.fg_colour
            self.fg_colour=self.flash_colour
            self.show()
            presto.update()
            await asyncio.sleep(0.25)
            self.fg_colour=button_colour
            self.show()
            presto.update()
    
    
    def process_touch(self,x,y):
        if self.within_bounds(x,y):
            asyncio.create_task(self.flash())
            if self.callback:
                self.callback(self.gui_manager)
            return True


class GuiLabel(GuiWidget):
    def __init__(self, x, y, w=None, h=None, fg_colour=None, bg_colour=None, text='', text_colour=WHITE,
                 font="Roboto-Medium.af", font_size=40):
        super().__init__(x, y, w, h, fg_colour, bg_colour)
        self.text = text
        self.text_colour = text_colour
        self.font = font
        self.font_size = font_size
    
        
    def show(self):
        vector.set_font(self.font, self.font_size)
        display.set_pen(self.text_colour)
        vector.text(self.text, self.x, self.y)


    def set_text(self,new_text):
        self.text = new_text
        if self.gui_manager.current_screen == self.assigned_screen:
            self.gui_manager.draw_gui()

            
# functions to run on button presses        
def b1_callback(mgr):
    mgr.set_screen('screen2')
    mgr.draw_gui()

def b2_callback(mgr):
    mgr.set_screen('screen1')
    mgr.draw_gui()

def b3_callback(mgr):
    l_3.set_text('Now the label is ??')

def b4_callback(mgr):
    l_3.set_text('Another change!!')


    
# an async task to get touch events and pass coordinates to gui_manager
async def get_touch(mgr):
    while True:
        touch.poll()
        if touch.state:
            mgr.process_touch(touch.x, touch.y)
            await asyncio.sleep(0.5)  # adjust as required to avoid multiple touch events for one press
        await asyncio.sleep_ms(100)


async def main(mgr): 
    # create the touch task
    asyncio.create_task(get_touch(mgr))
    
    # display the nominated current screen
    mgr.draw_gui()
    
    while True:
        await asyncio.sleep(0)


#create a gui manager
mgr = GuiManager()

# create screens
mgr.add_screen('screen1',BLUE)
mgr.add_screen('screen2',BLACK)
    
# create widgets
b_1 = GuiButton(10,400,300,40,PINK,text='Goto Screen 2',text_colour=BLACK, r_corners=True, callback=b1_callback)
b_2 = GuiButton(10,400,300,40,PINK,text='Goto Screen 1',text_colour=BLACK,  r_corners=True, callback=b2_callback)    
b_3 = GuiButton(10,200,350,40,PALEGREEN,text='Change Text on S1',text_colour=BLACK, flash_colour=RED, r_corners=True, callback=b3_callback)
b_4 = GuiButton(10,300,250,40,PALEGREEN,text='Change Text',text_colour=BLACK,flash_colour=RED, r_corners=True, callback=b4_callback)

l_1 = GuiLabel(130,75, text='Screen 1')
l_2 = GuiLabel(130,75, text='Screen 2')
l_3 = GuiLabel(100,200, text='test label')


# add widgets to screens
mgr.add_widget('screen1', b_1)
mgr.add_widget('screen1', l_1)
mgr.add_widget('screen1', l_3)
mgr.add_widget('screen1', b_4)

mgr.add_widget('screen2', b_2)
mgr.add_widget('screen2', l_2)
mgr.add_widget('screen2', b_3)



# set the current screen
mgr.set_screen('screen1')


try:
    asyncio.run(main(mgr))
except KeyboardInterrupt:
    print('Ctl C')
finally:
    print('finally is being actioned')
    asyncio.new_event_loop()