Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bat_now.status is nil #451

Closed
bitwombat opened this issue Apr 11, 2020 · 15 comments
Closed

bat_now.status is nil #451

bitwombat opened this issue Apr 11, 2020 · 15 comments

Comments

@bitwombat
Copy link

  • output of awesome -v and lua -v

awesome v4.2 (Human after all)
lua not on path

  • expected behavior and actual behavior
    Expecting bat_now.status to have a value as defined in the wiki

Actual: bat_now.status is nil
without bat_now.status, the below config works.

  • steps to reproduce the problem
local theme                                     = {}
theme.font                                      = "Terminus 10.5"

local lain  = require("lain")
local markup     = lain.util.markup
local separators = lain.util.separators
local gray       = "#9E9C9A"

local bat = lain.widget.bat({
    settings = function()
        bat_header = " Bat "
        bat_p      = bat_now.perc .. "% "
        bat_t      = bat_now.time .. " "
        bat_s      = bat_now.status .. " "
        widget:set_markup(markup.font(theme.font, markup(gray, bat_header) .. bat_p .. bat_t .. bat_s))
    end
})
  • X error log
Apr 11 22:25:43 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: stack traceback:
Apr 11 22:25:43 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: #011/home/gbell2/.config/awesome/rc.lua:154: in upvalue 'settings'
Apr 11 22:25:43 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: #011/home/gbell2/.config/awesome/lain/widget/bat.lua:185: in local 'func'
Apr 11 22:25:43 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: #011/usr/share/awesome/lib/gears/object.lua:143: in function 'gears.object.emit_signal'
Apr 11 22:25:43 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: #011/home/gbell2/.config/awesome/lain/helpers.lua:97: in function 'lain.helpers.newtimer'
Apr 11 22:25:43 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: #011/home/gbell2/.config/awesome/lain/widget/bat.lua:212: in function 'lain.widget.bat'
Apr 11 22:25:43 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: #011/home/gbell2/.config/awesome/rc.lua:149: in main chunk
Apr 11 22:25:43 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: error: /home/gbell2/.config/awesome/rc.lua:154: attempt to concatenate a nil value (field 'status')
Apr 11 22:25:49 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: 2020-04-11 22:25:49 E: Error opening directory '/usr/share/awesome/applications': No such file or directory
Apr 11 22:25:49 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: 2020-04-11 22:25:49 E: Error opening directory '/usr/local/share/applications': No such file or directory
Apr 11 22:25:49 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: 2020-04-11 22:25:49 E: Error opening directory '/home/gbell2/.nix-profile/share/applications': No such file or directory
Apr 11 22:25:49 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: 2020-04-11 22:25:49 E: Error opening directory '/usr/share/awesome/applications': No such file or directory
Apr 11 22:25:49 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: 2020-04-11 22:25:49 E: Error opening directory '/usr/local/share/applications': No such file or directory
Apr 11 22:25:49 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: 2020-04-11 22:25:49 E: Error opening directory '/home/gbell2/.nix-profile/share/applications': No such file or directory
Apr 11 22:25:50 thinkpad /usr/lib/gdm3/gdm-x-session[1402]: 2020-04-11 22:25:50 W: awesome: a_glib_poll:432: Last main loop iteration took 0.619277 seconds! Increasing limit for this warning to that value.
@bitwombat
Copy link
Author

Looking at bat.lua, I see that it sets bat_now.status to bat_now.n_status[1], which is null because "battery" isn't set.

This wasn't autodetected. It's BAT0 on my system. Setting arg.battery solves the problem, but I'm wondering if this should be considered a bug?

@lcpz
Copy link
Owner

lcpz commented Apr 11, 2020

lua not on path

What does this mean?

Do you have the directory /sys/class/power_supply/?

Try the following in a Lua shell (spawn it in a terminal by typing lua):

io.popen("ls -1 /sys/class/power_supply/"):read("*all"):match("BAT%w+")

Tell me if it outputs "BAT0".

Also, if you have a ThinkPad, consider trying this widget instead.

@bitwombat
Copy link
Author

What does this mean?

The lua binary is not on my shell's path, as defined by the PATH environment variable...

It doesn't seem to be installed anywhere. Awesome seems to use liblua5.3-0, and not require a lua CLI?

Anyway...

Do you have the directory /sys/class/power_supply/?

Yep, which is why everything works when I define arg.battery.

Tell me if it outputs "BAT0".

Yep, which is why everything works when I define arg.battery.

@lcpz
Copy link
Owner

lcpz commented Apr 14, 2020

Yep, which is why everything works when I define arg.battery.
Yep, which is why everything works when I define arg.battery.

I know that you have the file. What I asked you is to run a command in the Lua command-line interpreter that does exactly what the widget does in this function, to see what is the output and fix it.

Both Awesome and Lain depend on Lua.

I understand that liblua5.3.-0 installs it, even though you say you do not have it in your PATH variable.

Hence, from what you say I do not understand what you have done.

Can I assume that you added Lua to your user path and ran the command as I asked?

Otherwise, do it.

And if you want my further attention, avoid pointless and childish copy-pasting.

@bitwombat
Copy link
Author

Sorry, I didn't realize copy-pasting could be construed as childish. I was simply answering two different questions with the same answer.

There is no lua binary on this system, yet Awesome works fine. The package liblua5.3.-0 only has some .so files in it. The lua binary seems to be in lua5.2, which is not installed on this system.

Just some confusion, that's all. I've installed lua5.2, just to run your test. Outputs BAT0, no problem.

The problem is in here somewhere.

lain/widget/bat.lua

Lines 39 to 48 in 33c0e0c

function bat.get_batteries()
helpers.line_callback("ls -1 " .. pspath, function(line)
local bstr = string.match(line, "BAT%w+")
if bstr then
batteries[#batteries + 1] = bstr
else
ac = string.match(line, "A%w+") or "AC0"
end
end)
end

It's not pspath - that's correct. Hmm... I'll let you know what I figure out.

@lcpz
Copy link
Owner

lcpz commented Apr 15, 2020

I was simply answering two different questions with the same answer.

Just be nice and not redundant. It's my honest advice.

I'll let you know what I figure out.F

You say that the string matching works. Let's debug the function integrity.

Change this:

if #batteries == 0 then bat.get_batteries() end

To this:

bat.get_batteries()

If it doesn't work, put after here the following line:

naughty.notify{ timeout = 0, text = bstr .. " " .. tostring(batteries[1]) .. " " .. ac }

@bitwombat
Copy link
Author

You say that the string matching works. Let's debug the function integrity.

I'm a few steps ahead of that. Believe it or not, it's actually something to do with Gio.UnixInputStream. Easiest way to demonstrate it is that

helpers.line_callback("ls -1 /" ...

Works, but

helpers.line_callback("ls -1 " .. pspath, ...

doesn't work, even though pspath is correct. It either has something to do with the nature of /sys, or with the fact that BAT0 is a symlink in there.

@lcpz
Copy link
Owner

lcpz commented Apr 15, 2020

Is pspath somehow nil in that scope?

Did you try constructing the argument before?

if pspath == nil then naughty.notify { text = "nil", timeout = 0 } end
local cmd_str = string.format("ls -1 %s", pspath)
helpers.line_callback(cmd_str, function(line)
    -- [...]
end)

@bitwombat
Copy link
Author

bitwombat commented Apr 16, 2020

Is pspath somehow nil in that scope?

No, believe it or not! Which is why I'm down in the pits looking at Gio.UnixInputStream

I should have been clearer and said:

helpers.line_callback("ls -1 /" ...

gives results, while

helpers.line_callback("ls -1 /sys/class/power_supply" ...

returns nothing, even though from the shell ls -1 /sys/class/power_supply returns two lines. So it's something in spawn or with Gio.UnixInputStream

@lcpz
Copy link
Owner

lcpz commented Apr 16, 2020

If this is not a bug of mine, I can only speculate:

  1. Maybe GLib2 does not have access permission to /sys/class/power_supply.
  2. Maybe you need Glib2 > 2.53 for some reason.

EDIT: The net widget also uses helpers.line_callback. Do you have issues with that as well?

@bitwombat
Copy link
Author

Is line_callback non-blocking?

Because I can't make sense of the trace.

I sprinkled some notifies in. It is finding BAT0.

    function bat.get_batteries()
        naughty.notify { timeout = 0, text = 'Autodetecting'}
        helpers.line_callback("ls -1 " .. pspath, function(line)
            local bstr =  string.match(line, "BAT%w+")
            naughty.notify { timeout = 0, text = bstr }
            if bstr then
                batteries[#batteries + 1] = bstr
                naughty.notify { timeout = 0, text = 'is now' .. #batteries }
            else
                ac = string.match(line, "A%w+") or "AC0"
            end
        naughty.notify { timeout = 0, text = 'at the inner end is' .. #batteries }
        end)
        naughty.notify { timeout = 0, text = 'at the end is' .. #batteries }
    end

    if #batteries == 0 then bat.get_batteries() end
    naughty.notify { timeout = 0, text = 'later is' .. #batteries }

What I get is

Autodetecting
at the end is 0
later is 0
at the inner end is 0
BAT0
is now 1
at the inner end is 1

Besides the weird order ("later is" where it is), it looks like the callback's getting called twice?

@lcpz
Copy link
Owner

lcpz commented Apr 17, 2020

line_callback is asynchronous, hence non-blocking.

Your log makes perfect sense:

  1. The If condition is true; get_batteries is spawned.
  2. 'Autodetecting' is printed; line_callback is spawned, it will be executed on the nex Awesome cycle.
  3. 'at the end is' is printed; get_batteries terminates.
  4. The line after the If is executed: 'later is' is printed.
  5. Next Awesome cycle: line_callback starts; the command cmd = "ls -1 ..." is spawned; the callback function(line) ... end is executed on each line returned by cmd.
  6. First line does not match "BAT%w+"; #batteries = 0, hence "at the inner end is 0" is printed.
  7. Second line matches; #batteries = 1, hence printing of bstr, "is now 1" and "at the inner end is 1".
  8. There are no more lines: line_callback terminates.

As a result, the widget is perfectly working, the problem is that you are trying to get the information before this is retrieved.

The solution is to use defensive programming:

local bat = lain.widget.bat {
    settings = function()
        bat_header = " Bat "
        bat_p      = (bat_now.perc or "N/A") .. "% "
        bat_t      = (bat_now.time or "N/A") .. " "
        bat_s      = (bat_now.status or "N/A/") .. " "
        widget:set_markup(markup.font(theme.font, markup(gray, bat_header) .. bat_p .. bat_t .. bat_s))
    end
}

The reason behind is that my widgets are asynchronous. However, this style of programming is also useful for detecting system changes (e.g., battery removed or added) or failures (e.g., battery failing!).

Sorry, I should have detected this immediately from your code. Anyway, I believe this thread is a contribution to new users. I will add a link to the main wiki page.

In the future, check how I configure widgets in my themes for reference. You have different examples there.

Also, as I wrote before, you can check tp_smapi if you're using a ThinkPad, or also my upower recipe.

@bitwombat
Copy link
Author

bitwombat commented Apr 17, 2020

Because of operator precedence, the fix actually needs to be:

local bat = lain.widget.bat {
    settings = function()
        bat_header = " Bat "
        bat_p      = bat_now.perc .. "% "
        bat_t      = bat_now.time .. " "
        bat_s      = (bat_now.status or "N/A/ ") .. " "
        widget:set_markup(markup.font(theme.font, markup(gray, bat_header) .. bat_p .. bat_t .. bat_s))
    end
}

Also, I've added the guard to just bat_s because only bat_now.status comes back nil.

So, you could probably fix it for all users at:
https://github.com/lcpz/lain/blob/master/widget/bat.lua#L139

If I'm not mistaken, the widget updates every 30 seconds, not asynchronously?

@lcpz
Copy link
Owner

lcpz commented Apr 18, 2020

I will add the fix, thanks.

If I'm not mistaken, the widget updates every 30 seconds, not asynchronously?

That's the update frequency, but the update itself is asynchronous, as you have seen.

@lcpz lcpz closed this as completed in af125b3 Apr 18, 2020
@bitwombat
Copy link
Author

Cool, after a rough start, I knew we'd be friends Luca.
Thanks for talking through that with me, and for the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants