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

Add Advances in notification #117

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/embedded/app/configurator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ configurator =
{
incubator = {},
WiFi = require("wifiinit"),
log = require("log")

}
-------------------------------------------------------------------------------------
Expand All @@ -12,6 +13,9 @@ function configurator:init_module(incubator_object)
configurator.incubator = incubator_object
if config_table ~= nil then
configurator:load_objects_data(config_table)
if config_table.hash then
configurator.log.set_ntfy_url(config_table.hash)
end
end
end

Expand Down Expand Up @@ -52,7 +56,7 @@ function configurator:create_config_file()
tray_two_date = 0,
tray_three_date = 0,
incubation_period = 0,
hash = "1234567890",
hash = "incubator_parameters",
incubator_name = string.format("incubadora-%s",wifi.sta.getmac()),
max_hum = 70,
min_hum = 60
Expand Down Expand Up @@ -103,8 +107,9 @@ function configurator:load_objects_data(new_config_table)
status.tray_three_date = incubator.set_tray_date("three",tonumber(value))
elseif param == "incubation_period" then
status.incubation_period = incubator.set_incubation_period(tonumber(value))
elseif param == "hash" then
elseif param == "hash" then
status.hash = incubator.set_hash(value)
configurator.log.set_ntfy_url(value)
elseif param == "incubator_name" then
status.incubator_name = incubator.set_incubator_name(tostring(value))
elseif param == "max_hum" then
Expand Down
4 changes: 3 additions & 1 deletion src/embedded/app/incubator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ local M = {
tray_two_date = 0,
tray_three_date = 0,
incubation_period = 0,
hash = 1235,
hash = "incubator_parameters",
incubator_name = string.format("incubadora-%s",wifi.sta.getmac()),
rotate_up = true
}
Expand Down Expand Up @@ -458,4 +458,6 @@ function M.set_min_humidity(new_min_hum)
end
end



return M
10 changes: 9 additions & 1 deletion src/embedded/app/incubatorController.lua
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ end -- end function
function read_and_send_data()
temp, hum, pres = incubator.get_values()
send_data_grafana(incubator.temperature, incubator.humidity, incubator.pressure, INICIALES .. "-bme")

if temp >= incubator.max_temp then
log.ntfy("Alerta: La temperatura ah excedido el limite permitido 🔥")
end

if hum >= incubator.max_hum then
log.ntfy("Alerta: La humedad ah excedido el limite permitido 💧")
end
end -- read_and_send_data end

------------------------------------------------------------------------------------
Expand Down Expand Up @@ -190,7 +198,7 @@ incubator.enable_testing(false)
------------------------------------------------------------------------------------
local send_data_timer = tmr.create()
send_data_timer:register(10000, tmr.ALARM_AUTO, read_and_send_data)
--send_data_timer:start()
send_data_timer:start()

local temp_control_timer = tmr.create()
temp_control_timer:register(3000, tmr.ALARM_AUTO, read_and_control)
Expand Down
255 changes: 159 additions & 96 deletions src/embedded/libs/log.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,138 +2,201 @@
-- log.lua
--
-- Copyright (c) 2016 rxi
-- Modified to include NTFY support and Grafana integration
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the MIT license. See LICENSE for details.
--

local log = {
_version = "0.1.0"
_version = "0.1.0"
}

log.usecolor = true
log.outfile = nil
log.grafana = true
log.level = "trace"
log.x86 = false
-- Configuration options
log.usecolor = true -- Enable colored output in console
log.outfile = nil -- File to write logs to (nil for no file output)
log.grafana = true -- Enable sending logs to Grafana
log.ntfy_enabled = true -- Enable sending notifications through ntfy
log.level = "trace" -- Default log level
log.x86 = false -- Platform flag
log.ntfy_url = nil -- NTFY URL to be set dynamically

-- Define log modes with their colors
local modes = {{
name = "trace",
color = "\27[34m"
name = "trace",
color = "\27[34m" -- Blue
}, {
name = "debug",
color = "\27[36m"
name = "debug",
color = "\27[36m" -- Cyan
}, {
name = "info",
color = "\27[32m"
name = "info",
color = "\27[32m" -- Green
}, {
name = "warn",
color = "\27[33m"
name = "warn",
color = "\27[33m" -- Yellow
}, {
name = "error",
color = "\27[31m"
name = "error",
color = "\27[31m" -- Red
}, {
name = "fatal",
color = "\27[35m"
name = "fatal",
color = "\27[35m" -- Magenta
}, {
name = "test",
color = "\27[30m"
name = "test",
color = "\27[30m" -- Black
}}

-- Get file size helper function
local function fsize(file)
local current = file:seek() -- get current position
local size = file:seek("end") -- get file size
file:seek("set", current) -- restore position
return size
local current = file:seek() -- Get current position
local size = file:seek("end") -- Get file size
file:seek("set", current) -- Restore position
return size
end

-- Function to send logs to Grafana
function log.send_to_grafana(message)
-- Construct the log message with device identifier and timestamp
local alert_string = "log,device=" .. INICIALES .. " message=\"" .. message .. "\" " ..
string.format("%.0f", ((time.get()) * 1000000000))

local token_grafana = "token:e98697797a6a592e6c886277041e6b95"
local url = SERVER

local headers = {
["Content-Type"] = "text/plain",
["Authorization"] = "Basic " .. token_grafana
}

-- Send POST request to Grafana
http.post(url, {
headers = headers
}, alert_string, function(code_return, data_return)
if (code_return ~= 204) then
print("Grafana logging error: " .. code_return)
end
end)
end

local alert_string = "log,device=" .. INICIALES .. " message=\"" .. message .. "\" " ..
string.format("%.0f", ((time.get()) * 1000000000))

local token_grafana = "token:e98697797a6a592e6c886277041e6b95"
local url = SERVER

local headers = {
["Content-Type"] = "text/plain",
["Authorization"] = "Basic " .. token_grafana
}
-- Function to send notification through NTFY
function log.ntfy(alert)
-- Check if NTFY is properly configured
if not log.ntfy_enabled or not log.ntfy_url then
print("NTFY not enabled or URL not set")
return
end

local headers = {
["Content-Type"] = "text/plain"
}

-- Send POST request to NTFY
http.post(log.ntfy_url, {
headers = headers
}, alert, function(code_return, _)
if code_return ~= 200 then
log.trace("Failed to send notification: " .. code_return)
else
log.trace("Notification sent successfully")
end
end)
end

http.post(url, {
headers = headers
}, alert_string, function(code_return, data_return)
if (code_return ~= 204) then
print("error de loggg " .. code_return)
end
end) -- * post function end
end -- * send_data_grafana end
-- Function to set the NTFY URL with a given hash
function log.set_ntfy_url(hash)
if hash then
log.ntfy_url = "http://ntfy.sh/" .. hash
print("NTFY URL set to: " .. log.ntfy_url)
else
log.ntfy_url = nil
print("NTFY URL is nil")
end
end

-- Build log level lookup table
local levels = {}
for i, v in ipairs(modes) do
levels[v.name] = i
levels[v.name] = i
end

-- Rounding function for numbers in log messages
local round = function(x, increment)
increment = increment or 1
x = x / increment
return (x > 0 and math.floor(x + .5) or math.ceil(x - .5)) * increment
increment = increment or 1
x = x / increment
return (x > 0 and math.floor(x + .5) or math.ceil(x - .5)) * increment
end

-- Store original tostring
local _tostring = tostring

-- Override tostring to handle number rounding
local tostring = function(...)
local t = {}
for i = 1, select('#', ...) do
local x = select(i, ...)
if type(x) == "number" then
x = round(x, .01)
end
t[#t + 1] = _tostring(x)
end
return table.concat(t, " ")
local t = {}
for i = 1, select('#', ...) do
local x = select(i, ...)
if type(x) == "number" then
x = round(x, .01)
end
t[#t + 1] = _tostring(x)
end
return table.concat(t, " ")
end

-- Create log methods for each mode
for i, x in ipairs(modes) do
local nameupper = x.name:upper()
log[x.name] = function(...)

-- Return early if we're below the log level
if i < levels[log.level] then
return
end

local msg = tostring(...)
local strtime = " "
local lineinfo = " "
if log.x86 then
local info = debug.getinfo(2, "Sl")
lineinfo = info.short_src .. ":" .. info.currentline
strtime = os.date("%H:%M:%S")
else
lineinfo = " "
local thismoment = time.getlocal()
strtime = string.format("%04d-%02d-%02d %02d:%02d:%02d DST:%d", thismoment["year"], thismoment["mon"], thismoment["day"],
thismoment["hour"], thismoment["min"], thismoment["sec"], thismoment["dst"])
end

-- Output to console
print(string.format("%s[%-6s%s]%s %s: %s", log.usecolor and x.color or "", nameupper, strtime,
log.usecolor and "\27[0m" or "", lineinfo, msg))

-- Output to grafana
if log.grafana and nameupper == "ERROR" then
log.send_to_grafana(string.format("[%-6s%s] %s: %s\n", nameupper, strtime, lineinfo, msg))
end

-- Output to log file
if log.outfile then
local fp = io.open(log.outfile, "a")
local str = string.format("[%-6s%s] %s: %s\n", nameupper, strtime, lineinfo, msg)
fp:write(str)
fp:close()
end

end
local nameupper = x.name:upper()
log[x.name] = function(...)
-- Return early if we're below the log level
if i < levels[log.level] then
return
end

local msg = tostring(...)
local strtime = " "
local lineinfo = " "

-- Get debug info and time based on platform
if log.x86 then
local info = debug.getinfo(2, "Sl")
lineinfo = info.short_src .. ":" .. info.currentline
strtime = os.date("%H:%M:%S")
else
lineinfo = " "
local thismoment = time.getlocal()
strtime = string.format("%04d-%02d-%02d %02d:%02d:%02d DST:%d",
thismoment["year"], thismoment["mon"], thismoment["day"],
thismoment["hour"], thismoment["min"], thismoment["sec"],
thismoment["dst"])
end

-- Output to console with color if enabled
print(string.format("%s[%-6s%s]%s %s: %s",
log.usecolor and x.color or "",
nameupper, strtime,
log.usecolor and "\27[0m" or "",
lineinfo,
msg))

-- Send error logs to Grafana if enabled
if log.grafana and nameupper == "ERROR" then
log.send_to_grafana(string.format("[%-6s%s] %s: %s\n",
nameupper, strtime, lineinfo, msg))
end

-- Send error logs to NTFY if enabled
if log.ntfy_enabled and log.ntfy_url and nameupper == "ERROR" then
log.ntfy(string.format("[%-6s%s] %s: %s\n",
nameupper, strtime, lineinfo, msg))
end

-- Write to log file if enabled
if log.outfile then
local fp = io.open(log.outfile, "a")
local str = string.format("[%-6s%s] %s: %s\n",
nameupper, strtime, lineinfo, msg)
fp:write(str)
fp:close()
end
end
end

return log
return log