yozik04 / nextion

Nextion serial client
GNU Lesser General Public License v3.0
25 stars 10 forks source link

HelloWorld with the library #24

Closed rocco99 closed 2 years ago

rocco99 commented 2 years ago

I need to use this for a project. I'm only now learning a little Python. I know nothing about asyncio, but i have been reading a lot. I am unable to make sense of it yet. My project is with a nextion 2.4" display. I have only four controls (2 buttons, a slider and a text field). I need to be able to see which of the two buttons has been touched and take appropriate action. for the slider i only need to read and set it's value and for the text field i need only set it's text based on one of the buttons being touched. I have been struggling with this for a couple of days but cannot get it to work. I would be extremely grateful, if you could you send me a simple example of both sending and receiving using this library? I thank you in advance for any help offered.

yozik04 commented 2 years ago

Hey. Example on the main page should work. It has all required code for you.

yozik04 commented 2 years ago

Share what you currently have :)

rocco99 commented 2 years ago

First I would like to thank you for responding. I was not very hopeful that you would. I should say again that I am not a programmer. I am 72 years old, retired and like to tinker with things to keep busy. I got here and now by following a trail down a rabbit hole to solve a problem that I created for myself. My current project (Which is in fact frivolous), is to create a Radio for my desk, using a raspberry pi zero W which plays only BBC radio stations. I could simply use any of the existing streaming service apps available. But where's the fun in that.

So far, I have created the HMI using the nextion 2.4". I am able to connect to it and using your library and determine that a touch event has taken place. I am doing all of this on an intel linux PC. So at this stage, I am not even connected to the raspberry pi. I cannot figure out what to do in order to to have the result of events triggered by the button press flow back into the loop to write to the display. I can't move on until I have figured this out.

I As I stated earlier, I am not a programmer. I am only now trying to learn python as an utter beginner. You say that the example given on the main page should work, I agree and have tried to use it and follow the information provided as well as reading up on Asyncio which I find rather confusing. Still, I have tried. I need to see an example of sending data back to the display. Maybe my understanding of the process is flawed. I am not expecting a tutorial, just a simple example which could help me determine where I am going wrong. Perhaps that way I could learn something new. Thank you again for responding. Happy holidays.

rocco99 commented 2 years ago

By the way. I would be happy to share, but right now I have nothing. I doubt whether you need another "Hello World" app.

yozik04 commented 2 years ago

I decided to make your life easier in version 1.8.0. Will release in couple days. event_handler will be async. Will update example so you won't need to learn all these create_task logic

rocco99 commented 2 years ago

Thank you very much. That will solve the current problem. I shall continue reading and trying to figure out the extent of my misunderstanding. Happy holidays.

yozik04 commented 2 years ago

Please try version 1.8.0

rocco99 commented 2 years ago

I will, as soon as I may. Merry and happy in that order. Thank you again.

rocco99 commented 2 years ago

I have decided to give up on this library. I have not been able to do what should be fairly simple, i.e. press a button on the display and change the value of a text field as a consequence of that event. My understanding was that the library should facilitate this. Maybe I am wrong. I am a novice after all. A new version was made, and I am gratefull. It should help others. It has not helped me. I do not know what crucial concept I am missing. A single example of the library being used would have been most usefull.

If I could use an example as given, then I would know that my setup is good, otherwise I would know that there is something else going on. Right now I have no idea where the problem lies or what I am doing wrong.

rocco99 commented 2 years ago

I would love to hear from anyone who has used this library with a raspberry pi zero w. I hate the thought of having to use an arduino and a different display to do so simple a task.

yozik04 commented 2 years ago

Library fully facilitates this. When you click a button you receive touch event with unique component id. You need to act on that. You can use await client.set("field_name.txt", "abc") to update the value. Without seeing your code I am unable to help. I do not know what components you have in your Nextion project. It does not matter where you use this library on your Linux desktop or a RPI. If it has python interpreter it should work. You can lookup supported Nextion instructions on their website: https://nextion.tech/instruction-set/

rocco99 commented 2 years ago

I can send you my code as it is now. I understand that I'm doing something wrong or do not fully understand how to use the library. I am able to get the stations and their urls (not using the display) which is stored in a folder at location given by 'Path'. Right now I am simply trying to read button 2 (no problem as it is returned correctly as data.component_id 2) and then set the display's text field StationName.txt to the value returned by a function 'get_next_station'. current_station name is a global variable as is current-station_index.

The code below is just one variation of many different attempts I've made to try and get the station name to the display.

-- coding: utf-8 --

import asyncio import logging import random import os from nextion import Nextion, EventType stations=[] urls=[] path = r"/home/rocco/VStudioProjects/Iradio/RadioURLs" current_station_index=0 current_station_name="Give auntie a big hug"

fill the lists with the stationNames and URLs

files = os.listdir(path) for filename in files: fullpath=os.path.join(path,filename) f=open(fullpath) stationurl= f.readline() stationurl = stationurl .replace('\n', "") stations.append(filename) urls.append(stationurl)

class App: def init(self): self.client = Nextion('/dev/ttyUSB0', 9600, self.event_handler)

async def get_next_station():
    ndx=current_station_index
    if ndx==10:
        ndx=0
    else:
        ndx += 1
    current_station_name=stations[ndx]
    current_station_index=ndx
    await asyncio.sleep(1)

# Note: async event_handler can be used only in versions 1.8.0+ (versions 1.8.0+ supports both sync and async versions)
async def event_handler(self, type_, data):
    if type_ == EventType.STARTUP:
        print('We have booted up!')
    elif type_ == EventType.TOUCH:
        if data.component_id==2: 
            get_next_station()

        print('A button (id: %d) was touched on page %d' % (data.component_id, data.page_id))

    logging.info('Event %s data: %s', type, str(data))

async def run(self):
    await self.client.connect()
    print(await self.client.get('sleep'))
    await get_next_station()
    await self.client.set('StationName.txt', current_station_name)
    await asyncio.sleep(1)
    print('finished')

if name == 'main': logging.basicConfig( format='%(asctime)s - %(levelname)s - %(message)s', level=logging.DEBUG, handlers=[ logging.StreamHandler() ]) loop = asyncio.get_event_loop() app = App() asyncio.ensure_future(app.run()) loop.run_forever()

rocco99 commented 2 years ago

here is the current console display after i connect and then touch a button.

rocco@LinuxMint:~/VStudioProjects/Iradio$ cd /home/rocco/VStudioProjects/Iradio ; /usr/bin/env /usr/bin/python3 /home/rocco/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/launcher 44971 -- /home/rocco/VStudioProjects/Iradio/NextionInterface.py 2021-12-27 15:58:41,931 - INFO - Connecting: /dev/ttyUSB0, baud: 9600 2021-12-27 15:58:41,932 - INFO - Connected to serial 2021-12-27 15:58:41,932 - DEBUG - sent: b'DRAKJHSUYDGBNCJHGJKSHBDN' 2021-12-27 15:58:41,966 - DEBUG - received: b'1a' 2021-12-27 15:58:42,102 - DEBUG - sent: b'connect' 2021-12-27 15:58:42,190 - DEBUG - received: b'636f6d6f6b20312c33303630312d302c4e5833323234543032345f303131522c3136332c36313438382c444536383743353735333732353032332c34313934333034' 2021-12-27 15:58:42,190 - INFO - Address: 30601-0 2021-12-27 15:58:42,190 - INFO - Detected model: NX3224T024_011R 2021-12-27 15:58:42,190 - INFO - Firmware version: 163 2021-12-27 15:58:42,191 - INFO - Serial number: DE687C5753725023 2021-12-27 15:58:42,191 - INFO - Flash size: 4194304 2021-12-27 15:58:42,191 - DEBUG - sent: b'bkcmd=3' 2021-12-27 15:58:42,222 - DEBUG - received: b'01' 2021-12-27 15:58:42,222 - DEBUG - sent: b'get sleep' 2021-12-27 15:58:42,254 - DEBUG - received: b'7100000000' 2021-12-27 15:58:42,254 - INFO - Successfully connected to the device 2021-12-27 15:58:42,254 - DEBUG - sent: b'get sleep' 2021-12-27 15:58:42,286 - DEBUG - received: b'7100000000' 0 2021-12-27 15:58:42,286 - ERROR - Task exception was never retrieved future: <Task finished name='Task-1' coro=<App.run() done, defined at /home/rocco/VStudioProjects/Iradio/NextionInterface.py:53> exception=NameError("name 'get_next_station' is not defined")> Traceback (most recent call last): File "/home/rocco/VStudioProjects/Iradio/NextionInterface.py", line 56, in run await get_next_station() NameError: name 'get_next_station' is not defined 2021-12-27 15:58:46,540 - DEBUG - received: b'65000201' 2021-12-27 15:58:46,541 - DEBUG - Handle event: b'e\x00\x02\x01' 2021-12-27 15:58:46,541 - ERROR - Task exception was never retrieved future: <Task finished name='Task-7' coro=<App.event_handler() done, defined at /home/rocco/VStudioProjects/Iradio/NextionInterface.py:41> exception=NameError("name 'get_next_station' is not defined")> Traceback (most recent call last): File "/home/rocco/VStudioProjects/Iradio/NextionInterface.py", line 46, in event_handler get_next_station() NameError: name 'get_next_station' is not defined

yozik04 commented 2 years ago

NameError: name 'get_next_station' is not defined

Change: get_next_station() to self.get_next_station()

It is not about library problem it is about misunderstanding what is class method vs regular function.

rocco99 commented 2 years ago

I changed to:----> self.get_next_station() with no arguments The error I now get is:--->

2021-12-28 07:53:12,162 - DEBUG - received: b'65000201' 2021-12-28 07:53:12,162 - DEBUG - Handle event: b'e\x00\x02\x01' 2021-12-28 07:53:12,163 - ERROR - Task exception was never retrieved future: <Task finished name='Task-8' coro=<App.event_handler() done, defined at /home/rocco/VStudioProjects/Iradio/NextionInterface.py:41> exception=TypeError('get_next_station() takes 0 positional arguments but 1 was given')> Traceback (most recent call last): File "/home/rocco/VStudioProjects/Iradio/NextionInterface.py", line 46, in event_handler self.get_next_station() TypeError: get_next_station() takes 0 positional arguments but 1 was given

yozik04 commented 2 years ago

Please watch some Python courses. I can still help you with library problems but you need to learn core language principles yourself.

first argument needs to be self.

async def get_next_station(self):
# then you will be able to use that "self" inside the function

# Function call
await self.get_next_station()
# as you are calling instance method here. "self" will be auto populated for you.
rocco99 commented 2 years ago

thank you, i will follow all your suggestions. I have started a python course in the meantime.