How to end infinite while loop from uplink

Hello,

i am doing a chicken coop automatic door project and having an issue with my automatic mode.

I created an automatic mode using a while True loop, this automatic function calls my open_door and close_door functions. The automatic mode function opens the door at sunrise and close the door at sunset.

I am simply trying to add a button where it stops the automatic mode function (while True loop). I tried a background function with the .kill attribute on another function without success.

Is there an easy way to do that?

Hi @jnvachon1 and welcome to the forum.

It’d be great to see some code snippets and or a clone link to your app.

Have you considered using scheduled tasks instead of an infinite loop?
https://anvil.works/docs/background-tasks/scheduled-tasks

If you’re using uplink perhaps you could add a global flag in the server module.

automatic_mode = True

You could check this flag at each iteration and this would kill the loop if the flag was False.
You then have a button that calls a function that sets this global flag.

1 Like

Hello stucork,

Thanks for the quick reply.

Here is the automatic mode code (i used a threading function to access all of my project functions so the anvil server connection is made on another page):

def coop_door_automatic_mode():
    #import librairies
    import RPi.GPIO as GPIO
    import time
    from get_addresses import get_addresses
    from datetime import datetime
    from datetime import date
    from datetime import timedelta
    from sunraise_sunset_hatley import sunraise_sunset_hatley
    from open_coop_door import open_coop_door
    from close_coop_door import close_coop_door

    #set GPIO numbering mode
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)

    while True:
        #set variables
        date_now= date.today() #current date
        time_now= datetime.now().strftime("%H:%M") #current time
        today_sr, today_ss= sunraise_sunset_hatley()#today sunrise and sunset time
        today_sr = datetime.strptime(today_sr, "%H:%M")
        today_ss = datetime.strptime(today_ss, "%H:%M")
        today_sr= today_sr.strftime("%H:%M")
        time_open_door= today_sr
        time_close_door= today_ss + timedelta(minutes=30)
        today_ss=today_ss.strftime("%H:%M")
        time_close_door= time_close_door.strftime("%H:%M")
        
        #open door at sunrise
        print('auto mode')
        time.sleep(1)
        if time_now == time_open_door:
            open_coop_door()
            
        #close door at sunset
        if time_now == time_close_door:
            close_coop_door()
            door_status='closed'

    #cleaning
    GPIO.cleanup()

Here is the button that calls the function:
image

Questions:
-How can i use a variable that is triggered (auto_mode = True) in my UpLink code? I simply use a global in the server module?

This thread might be useful

The solution involved running the raspberry pi logic in a separate thread so that anvil server calls would be able to interrupt the execution with global flags.

I think the same type of solution will work here.

Edit: I missed that you already mentioned you were using threading.

Thanks for the reply! i am not sure to fully understand, sorry i am a new programmer (and programming for fun).

Here is my main uplink code, i am not sure how to include the thread and call it on anvil server module.

image

That calls the open or close function as shown below (i also included open and close button on my anvil server, this i why i have separate functions):

image

Again, my idea is to be able to stop the auto mode, maybe the infinite loop is not the best way? The auto mode simply opens or closes the door at sunraise/sunset.

In addition, i want to modify a text label using data binding. I tried to create a data table in my anvil server that is modified with the door_status variable.
1- how can i modify the door_status value in my table? do i need to add a row each time>
2- how to have the door_status value displayed as my text label (text label will change depending on door_status value)?

here’s some pseudo code that might help

## uplink code
AUTO_MODE = True

def run_auto_mode():
    while AUTO_MODE:
        # your logic above 


@anvil.server.callable
def coop_auto_mode():
    global AUTO_MODE
    AUTO_MODE = True
    # run auto mode
    coop = threading.Thread(target=run_auto_mode)
    coop.start()

@anvil.server.callable
def stop_auto_mode():
    global AUTO_MODE
    AUTO_MODE = False

You might also explore other ways to stop threads
example article https://www.geeksforgeeks.org/python-different-ways-to-kill-a-thread/

side note: it’s best to present code snippets using back ticks (for code formatting) rather than screen shots.

```python
def say_hello(name):
   print("Hello, %s" % name)
```

Let’s focus on this part for now - it’s good to split questions so perhaps create a new topic about your databindings question so as not to muddle the conversation. Remember to follow the guide lines form

How to ask a good question

2 Likes

Hello stucork,

thank you so much for your help it worked perfectly. I will also look at safer way to kill threads.

I will certainly continue reading and learning about python programming and Anvil that is such a great and user-friendly platform.

Regards,
Jean-Nicolas

2 Likes