Author Topic: Getting memory used in /overlay partition as variable  (Read 552 times)

Offline kwieto

  • Hero Member
  • *****
  • Posts: 579
  • Karma: +27/-14
Getting memory used in /overlay partition as variable
« on: May 30, 2018, 09:35:12 am »
Is there a way to get information about memory used in /overlay partition (where system files are stored) as a variable?
I want to run a scene when my memory will be filled above certain limit. I can see that information via "OScommand" section in Alt UI (df - h), but can make a variable which reads and stores such data?

In AltUI I can see amount of memory and percentage of space filled. In my case it can be any of these parameters, as I can refer to the percentage limit or to kB's used (or left).

Offline akbooer

  • Master Member
  • *******
  • Posts: 6180
  • Karma: +276/-69
  • "Less is more"
Re: Getting memory used in /overlay partition as variable
« Reply #1 on: May 30, 2018, 09:54:05 am »
This will pipe the result into a string that you can parse...

Code: [Select]
local p = io.popen "df -h"
local df = p:read "*a"
p: close()
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline akbooer

  • Master Member
  • *******
  • Posts: 6180
  • Karma: +276/-69
  • "Less is more"
Re: Getting memory used in /overlay partition as variable
« Reply #2 on: May 30, 2018, 10:38:41 am »
So here's a function which does the business:

Code: [Select]
local function df()
    local format = "(%S+)%s+(%d+)%s+(%d+)%s+(%d+)[^/]+(/%S+)"
    local d = {}
    local p = io.popen "df"
    if p then
        local df = p:read "*a"
        p: close()
        local n = tonumber
        for f,b,u,a,m in df: gmatch(format) do
            d[#d+1] = {file=f, blocks=n(b), used=n(u), available=n(a), mounted=m}
        end
    end
    return d
end

and calling it on one of my Vera's gives a structure line this

Code: [Select]
{
{
available = 0,
blocks = 4608,
file = "/dev/root",
mounted = "/rom",
used = 4608
},{
available = 24904,
blocks = 31240,
file = "tmpfs",
mounted = "/tmp",
used = 6336
},{
available = 512,
blocks = 512,
file = "tmpfs",
mounted = "/dev",
used = 0
},{
available = 7384,
blocks = 11264,
file = "/dev/mtdblock7",
mounted = "/overlay",
used = 3880
},{
available = 0,
blocks = 4480,
file = "/dev/mtdblock8",
mounted = "/mios",
used = 4480
}
}
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline kwieto

  • Hero Member
  • *****
  • Posts: 579
  • Karma: +27/-14
Re: Getting memory used in /overlay partition as variable
« Reply #3 on: June 02, 2018, 05:47:05 pm »
Thanks for the code, but how can I extract some of the results (lets say I want to have "used" value of "file = "/dev/mtdblock7" parameter)?
Is it possible?
Sorry for asking for direct result, but here my "lua programming" skills are definitely too small.

Offline akbooer

  • Master Member
  • *******
  • Posts: 6180
  • Karma: +276/-69
  • "Less is more"
Re: Getting memory used in /overlay partition as variable
« Reply #4 on: June 04, 2018, 01:30:07 pm »
Sorry for asking for direct result, but here my "lua programming" skills are definitely too small.

Hmmm... perhaps you shouldn't be doing this?

Quote
lets say I want to have "used" value of "file = "/dev/mtdblock7" parameter)

Easiest, then, simply to index the data by the "file" parameter and directly access the data:

Code: [Select]
local dfinfo = {}
for _, d in ipairs(df()) do dfinfo[d.file] = d end
local x = dfinfo ["/dev/mtdblock7"]

gives you a table 'x' that looks like this:

Code: [Select]
{
available = 42032,
blocks = 64456,
file = "/dev/mtdblock7",
mounted = "/boot",
used = 22424
}

so the answer you want is in x.used

3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline kwieto

  • Hero Member
  • *****
  • Posts: 579
  • Karma: +27/-14
Re: Getting memory used in /overlay partition as variable
« Reply #5 on: June 04, 2018, 05:22:29 pm »
Hmmm... perhaps you shouldn't be doing this?

Most probably.
Unfortunately dealing with Vera forces me to learn new skills :/

Offline kwieto

  • Hero Member
  • *****
  • Posts: 579
  • Karma: +27/-14
Re: Getting memory used in /overlay partition as variable
« Reply #6 on: June 05, 2018, 03:39:08 am »
Easiest, then, simply to index the data by the "file" parameter and directly access the data:

Code: [Select]
local dfinfo = {}
for _, d in ipairs(df()) do dfinfo[d.file] = d end
local x = dfinfo ["/dev/mtdblock7"]



I've tried to run the code within test lua and got an error. What I'm doing wrong?

Offline akbooer

  • Master Member
  • *******
  • Posts: 6180
  • Karma: +276/-69
  • "Less is more"
Re: Getting memory used in /overlay partition as variable
« Reply #7 on: June 05, 2018, 03:53:43 am »
You also included the code for the function defined earlier?
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline kwieto

  • Hero Member
  • *****
  • Posts: 579
  • Karma: +27/-14
Re: Getting memory used in /overlay partition as variable
« Reply #8 on: June 05, 2018, 04:18:32 am »
No... :(

OK, so the whole structure should be like this?

Code: [Select]
local function df()
    local format = "(%S+)%s+(%d+)%s+(%d+)%s+(%d+)[^/]+(/%S+)"
    local d = {}
    local p = io.popen "df"
    if p then
        local df = p:read "*a"
        p: close()
        local n = tonumber
        for f,b,u,a,m in df: gmatch(format) do
            d[#d+1] = {file=f, blocks=n(b), used=n(u), available=n(a), mounted=m}
        end
    end
    return d
end

local dfinfo = {}
for _, d in ipairs(df()) do dfinfo[d.file] = d end
local x = dfinfo ["/dev/mtdblock7"]

And then I can use variables as x.available or x.used, in a way like:
Code: [Select]
if (tonumber(x.available) < [desired limit of memory]) then....

?

Yes, it is definitely over my knowledge, I just don't want to run clearing code or reboot controller every day, and looking for some smarter solution.


Edit: I've tested it, it works!
Thanks for your help!
« Last Edit: June 05, 2018, 04:59:53 am by kwieto »

Offline therealdb

  • Full Member
  • ***
  • Posts: 175
  • Karma: +2/-0
  • Automate all the things!
Re: Getting memory used in /overlay partition as variable
« Reply #9 on: June 15, 2018, 06:06:41 am »
I modified your code and set to run as part of my daily routine.

local function getOverlayDiskSpace()
   local function df()
         local format = "(%S+)%s+(%d+)%s+(%d+)%s+(%d+)[^/]+(/%S+)"
         local d = {}
         local p = io.popen "df"
         if p then
               local df = p:read "*a"
               p: close()
               local n = tonumber
               for f,b,u,a,m in df: gmatch(format) do
                     d[#d+1] = {file=f, blocks=n(b), used=n(u), available=n(a), mounted=m}
               end
         end
         return d
   end

   local dfinfo = {}
   for _, d in ipairs(df()) do dfinfo[d.mounted] = d end
   local x = dfinfo ["/overlay"]
   return (x.available / (x.available + x.used) * 100)
end

local d = getOverlayDiskSpace()
if (d<30) then -- alert at 30%
  sendAlert("Vera's Overlay partition at " .. tostring(round(d, 2)) .. "%")
end

It will alert you if the partitions is under 30% (we know it's safe at 20% or more). I just changed to check for the /overlay mounted partition, since mine is mounted as /dev/mtdblock6 instead of /dev/mtdblock6, so I guess it may depend on your system, and I'm using a percentage value, since we know it's what matters the most.
sendAlert function is my custom function sending alert to my Telegram bot.
I hope I'd be useful to anyone.
Vera Edge EU, Fibaro FGRM 222 (12), Fibaro FGS 223 (20), Fibaro FGS 222 (5), Fibaro Universal Binary Sensor (2), Fibaro Plug (3), NeoCoolCam Door Sensor (3), NeoCoolCam PIR (2), Nest (3), Home Server running my own integrations, Harmony Hub, OpenSprinkler, Personal Weather Station, Sonoff TH & more