Page 1 of 1

Board isn't responding without utime.sleep()

Posted: Fri Jan 03, 2020 8:07 pm
by piechota
Hi,
I want to use ESP8266 to lights up LEDs when I get notification from slack.
Everything seems to work fine when there is utime.sleep() in the main loop, but once it's removed nothing happens.

It looks like loop execute only once, if there is some slack message on start ESP8266 is detecting that.

I have also added some del because I was getting "memory allocation failed"
It takes few seconds to retrieve data from slack and it returns JSON. Depending on the slack workspace it can be quit big.

What can causing this?

Code: Select all

import network
import urllib.urequest
import json
import gc
import utime

slack_api = "https://slack.com/api/"
slack_token = "xoxp-000000000000-000000000000-000000000000-00000000000000000000000000000000"

#get all channels, groups and direct messages
def conversations_list():
  url = slack_api + "conversations.list?token=" + slack_token + "&types=public_channel,private_channel,mpim,im"
  f = urllib.urequest.urlopen(url)
  j = json.loads(f.read())
  f.close()
  del url
  del f
  return j

#get direct messages history  from slack, needed for "unread_count_display"
def im_history(id):
  url = slack_api + "im.history?token=" + slack_token + "&channel=" + id + "&count=1&unreads=1"  
  f = urllib.urequest.urlopen(url)
  j = json.loads(f.read())
  f.close()
  del url
  del f
  return j

#get direct channels info from slack, needed for "unread_count_display"
def channels_info(id):
  url = slack_api + "channels.info?token=" + slack_token + "&channel=" + id  
  f = urllib.urequest.urlopen(url)
  j = json.loads(f.read())
  f.close()
  del url
  del f
  return j

#get direct groups info from slack, needed for "unread_count_display"
def groups_info(id):
  url = slack_api + "groups.info?token=" + slack_token + "&channel=" + id  
  f = urllib.urequest.urlopen(url)
  j = json.loads(f.read())
  f.close()
  del url
  del f
  return j

#connect to WiFi
sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)

sta_if.active(True)
ap_if.active(False)

sta_if.connect('SSID', '*****')


oldState = False
while True:  
  convList = conversations_list()["channels"]
  state = False
  
  #loop that iterates conversations (channels/groups/direct messages) and checks for unread messages
  for conv in convList:
  
    #"is_channel" and "is_group" aren't present in direct message record, so we need to test this first.
    if conv["is_im"] == True:
      info = im_history(conv["id"])        
      if info["unread_count_display"] > 0:
        state = True
        del info
        break
      del info
      continue

    if conv["is_channel"] == True and conv["is_member"] == True:
      info = channels_info(conv["id"])["channel"]      
      if info["is_member"] == True and info["unread_count_display"] > 0:
        state = True
        del info
        break
      del info

    if conv["is_group"] == True:
      info = groups_info(conv["id"])["group"]
      if info["unread_count_display"] > 0:
        state = True
        del info
        break
      del info

  del convList

#check if state changed 
  if state != oldState:
    print("state changed")
    oldState = state  
  
  gc.collect()

Re: Board isn't responding without utime.sleep()

Posted: Mon Jan 06, 2020 2:30 am
by MostlyHarmless
  • This is only half the code. None of the modules you are using has an import statement.
  • None of the globals, referenced in the code, are defined anywhere.
  • The code totally lacks comments. Really bad style.
  • Where did you get this? Was this some sort of homework assignment?

Re: Board isn't responding without utime.sleep()

Posted: Mon Jan 06, 2020 3:23 am
by jimmo
Perhaps without the sleep the slack service is rejecting your request (due to rate limiting). You should definitely be limiting yourself to only sending the query every minute or something. I think your code will raise an exception if it tries to convert an unsuccessful HTTP response into JSON.

Regarding the "del" -- I don't recommend just adding "del" as a way to solve memory issues unless you know that it will help in that specific case. There's more info in this thread: viewtopic.php?f=2&t=7345&start=30#p42423

However, some general advice:
- "del x" at the end of a function won't do anything -- as soon as the function returns it gets cleaned up anyway.
- If you do find a case where "del x" helps (i.e. the scenario described in that thread where you need to do a big allocation to replace an existing variable), then you're better off breaking your code up into functions.

So in this case, if each of the things that the main loop does was a function, then you'd avoid a lot of these problems.

Re: Board isn't responding without utime.sleep()

Posted: Mon Jan 06, 2020 6:35 pm
by piechota
MostlyHarmless wrote:
Mon Jan 06, 2020 2:30 am
This is only half the code. None of the modules you are using has an import statement.
I have updated code with the modules
MostlyHarmless wrote:
Mon Jan 06, 2020 2:30 am
None of the globals, referenced in the code, are defined anywhere.
Added globals, slack_token is sensitive value so it is fake.
MostlyHarmless wrote:
Mon Jan 06, 2020 2:30 am
The code totally lacks comments. Really bad style.
Added some comments, hope it's better now.
MostlyHarmless wrote:
Mon Jan 06, 2020 2:30 am
Where did you get this? Was this some sort of homework assignment?
Just a side project, whole code by me (of course with help of slack documentation/stackOverflow/etc.).
jimmo wrote:
Mon Jan 06, 2020 3:23 am
Perhaps without the sleep the slack service is rejecting your request (due to rate limiting). You should definitely be limiting yourself to only sending the query every minute or something. I think your code will raise an exception if it tries to convert an unsuccessful HTTP response into JSON.
In the end I will check it every minute, that was just a quick test. Just want to know what's going on, don't want it to explode after few hours of working (and also pure curiosity)
If slack is rejecting request, shouldn't this explode? Even if this would parse empty JSON none of the fields that I try to read would exist.
Wouldn't this output some error?
jimmo wrote:
Mon Jan 06, 2020 3:23 am
So in this case, if each of the things that the main loop does was a function, then you'd avoid a lot of these problems.
I will try this

Re: Board isn't responding without utime.sleep()

Posted: Mon Jan 06, 2020 8:20 pm
by jimmo
piechota wrote:
Mon Jan 06, 2020 6:35 pm
If slack is rejecting request, shouldn't this explode? Even if this would parse empty JSON none of the fields that I try to read would exist.
Wouldn't this output some error?
I would imagine it would fail the request, not sure if it would still return valid JSON.

I would recommend adding a try/except around the main loop and if you catch any exceptions then write the details to a file. That way both the program can continue (after a sleep), but you can also inspect the file to see what happened.