diff --git a/contrib/README b/contrib/README index 7d2d08c..a3a6651 100644 --- a/contrib/README +++ b/contrib/README @@ -28,6 +28,14 @@ could also depend on Lua libraries that are not distributed with the core Lua distribution. Ease of installation and use does not necessarily have to apply to contributed widgets. +vicious.contrib.ati + - provides various info about ATI GPU status + - takes card ID as an argument, i.e. "card0" (and where possible, + uses debugfs to gather data on radeon power management) + - returns a table with string keys: {method}, {dpm_state}, + {dpm_perf_level}, {profile}, {engine_clock mhz}, {engine_clock khz}, + {memory_clock mhz}, {memory_clock khz}, {voltage v}, {voltage mv} + vicious.contrib.batacpi - @@ -54,6 +62,12 @@ vicious.contrib.netcfg vicious.contrib.net - +vicious.contrib.openweather + - provides weather information for a requested city + - takes OpenWeatherMap city ID as an argument, i.e. "1275339" + - returns a table with string keys: {city}, {wind deg}, {wind aim}, + {wind kmh}, {wind mps}, {sky}, {weather}, {temp c}, {humid}, {press} + vicious.contrib.ossvol - diff --git a/contrib/ati.lua b/contrib/ati.lua new file mode 100644 index 0000000..fd9932c --- /dev/null +++ b/contrib/ati.lua @@ -0,0 +1,79 @@ +--------------------------------------------------- +-- Licensed under the GNU General Public License v2 +-- * (c) 2013, NormalRa +--------------------------------------------------- + +-- {{{ Grab environment +local tonumber = tonumber +local io = { open = io.open } +local setmetatable = setmetatable +local helpers = require("vicious.helpers") +local string = { + sub = string.sub, + match = string.match, + gmatch = string.gmatch +} +-- }}} + + +-- ATI: provides various info about ATI GPU status +-- vicious.widgets.ati +local ati = {} + + +-- {{{ Define variables +local _units = { clock = { ["khz"] = 1, ["mhz"] = 1000 }, + voltage = { ["v"] = 1, ["mv"] = 1000 } } +local _reps = { + ["sclk"] = { name = "engine_clock", units = _units.clock, mul = 10 }, + ["mclk"] = { name = "memory_clock", units = _units.clock, mul = 10 }, + ["vddc"] = { name = "voltage", units = _units.voltage }, + ["voltage"] = { name = "voltage", units = _units.voltage }, + ["current engine clock"] = { name = "engine_clock", units = _units.clock }, + ["current memory clock"] = { name = "memory_clock", units = _units.clock } +} +-- }}} + +-- {{{ ATI widget type +local function worker(format, warg) + if not warg then return end + + local pm = helpers.pathtotable("/sys/class/drm/"..warg.."/device") + local _data = {} + + -- Get power info + _data["{method}"] = + pm.power_method and string.sub(pm.power_method, 1, -2) or "N/A" + _data["{dpm_state}"] = + pm.power_dpm_state and string.sub(pm.power_dpm_state, 1, -2) or "N/A" + _data["{dpm_perf_level}"] = + pm.power_dpm_force_performance_level and + string.sub(pm.power_dpm_force_performance_level, 1, -2) or "N/A" + _data["{profile}"] = + pm.power_profile and string.sub(pm.power_profile, 1, -2) or "N/A" + + local f = io.open("/sys/kernel/debug/dri/64/radeon_pm_info", "r") + if f then -- Get ATI info from the debug filesystem + for line in f:lines() do + for k, unit in string.gmatch(line, "(%a+[%a%s]*):[%s]+([%d]+)") do + unit = tonumber(unit) + + _data["{dpm_power_level}"] = -- DPM active? + tonumber(string.match(line, "power level ([%d])")) or "N/A" + + if _reps[k] then + for u, v in pairs(_reps[k].units) do + _data["{".._reps[k].name.." "..u.."}"] = + (unit * (_reps[k].mul or 1)) / v + end + end + end + end + f:close() + end + + return _data +end +-- }}} + +return setmetatable(ati, { __call = function(_, ...) return worker(...) end }) diff --git a/contrib/openweather.lua b/contrib/openweather.lua new file mode 100644 index 0000000..d3d2ffd --- /dev/null +++ b/contrib/openweather.lua @@ -0,0 +1,94 @@ +--------------------------------------------------- +-- Licensed under the GNU General Public License v2 +-- * (c) 2013, NormalRa +--------------------------------------------------- + +-- {{{ Grab environment +local tonumber = tonumber +local io = { popen = io.popen } +local setmetatable = setmetatable +local string = { match = string.match } +local math = { + ceil = math.ceil, + floor = math.floor +} +-- }}} + + +-- Openweather: provides weather information for a requested station +-- vicious.widgets.openweather +local openweather = {} + + +-- Initialize function tables +local _wdirs = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "N" } +local _wdata = { + ["{city}"] = "N/A", + ["{wind deg}"] = "N/A", + ["{wind aim}"] = "N/A", + ["{wind mps}"] = "N/A", + ["{wind kmh}"] = "N/A", + ["{sky}"] = "N/A", + ["{weather}"] = "N/A", + ["{temp c}"] = "N/A", + ["{humid}"] = "N/A", + ["{press}"] = "N/A" +} + +-- {{{ Openweather widget type +local function worker(format, warg) + if not warg then return end + + -- Get weather forceast using the city ID code, from: + -- * OpenWeatherMap.org + local openweather = "http://api.openweathermap.org/data/2.5/weather?id="..warg.."&mode=json&units=metric" + local f = io.popen("curl --connect-timeout 1 -fsm 3 '"..openweather.."'") + local ws = f:read("*all") + f:close() + + -- Check if there was a timeout or a problem with the station + if ws == nil then return _wdata end + + _wdata["{city}"] = -- City name + string.match(ws, '"name":"([%a%s%-]+)"') or _wdata["{city}"] + _wdata["{wind deg}"] = -- Wind degrees + string.match(ws, '"deg":([%d]+)') or _wdata["{wind deg}"] + _wdata["{wind mps}"] = -- Wind speed in meters per second + string.match(ws, '"speed":([%d%.]+)') or _wdata["{wind mps}"] + _wdata["{sky}"] = -- Sky conditions + string.match(ws, '"main":"([%a]+)"') or _wdata["{sky}"] + _wdata["{weather}"] = -- Weather description + string.match(ws, '"description":"([%a%s]+)"') or _wdata["{weather}"] + _wdata["{temp c}"] = -- Temperature in celsius + string.match(ws, '"temp":([%-]?[%d%.]+)') or _wdata["{temp c}"] + _wdata["{humid}"] = -- Relative humidity in percent + string.match(ws, '"humidity":([%d]+)') or _wdata["{humid}"] + _wdata["{press}"] = -- Pressure in hPa + string.match(ws, '"pressure":([%d%.]+)') or _wdata["{press}"] + + -- Wind speed in km/h + if _wdata["{wind mps}"] ~= "N/A" then + _wdata["{wind mps}"] = math.floor(tonumber(_wdata["{wind mps}"]) + .5) + _wdata["{wind kmh}"] = math.ceil(_wdata["{wind mps}"] * 3.6) + end -- Temperature in °C + if _wdata["{temp c}"] ~= "N/A" then + _wdata["{temp c}"] = math.floor(tonumber(_wdata["{temp c}"]) + .5) + end -- Calculate wind direction + if _wdata["{wind deg}"] ~= "N/A" then + _wdata["{wind deg}"] = tonumber(_wdata["{wind deg}"]) + + -- Lua tables start at [1] + if (_wdata["{wind deg}"] / 45)%1 == 0 then + _wdata["{wind aim}"] = _wdirs[_wdata["{wind deg}"] / 45 + 1] + else + _wdata["{wind aim}"] = + _wdirs[math.ceil(_wdata["{wind deg}"] / 45) + 1].. + _wdirs[math.floor(_wdata["{wind deg}"] / 45) + 1] + end + end + + return _wdata +end +-- }}} + +return setmetatable(openweather, { __call = function(_, ...) return worker(...) end })