Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Merge in the scared.lua scripts for the latest blog post. |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
26b540b3274a662fb0375299ed555008 |
| User & Date: | rberteig 2015-05-22 23:23:49.108 |
Context
|
2015-06-16
| ||
| 22:18 | Merged to trunk for next blog post release. This has the nominally working email when startled script that can be configured to either email a plot of SPL or an MP3 of the room audio around the event. check-in: 8d8ccc7f52 user: rberteig tags: blog-splear09, trunk | |
|
2015-05-22
| ||
| 23:23 | Merge in the scared.lua scripts for the latest blog post. check-in: 26b540b327 user: rberteig tags: trunk | |
| 22:25 | Fix published email address. check-in: 31ad4ca9c2 user: rberteig tags: scared | |
|
2015-04-17
| ||
| 22:06 | Caught a typo, and renamed readme.txt to readme.md in most folders. check-in: 3b4f54236e user: rberteig tags: trunk | |
Changes
Added Scared/plotspl.lua.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
--[[
Lua module to plot SPL data with gnuplot.
Uses temp files to hold the data and plotting script, with the
script written from a template in this module. Produces a plot
with labeled axes, a title, and annotations for the trigger time,
mean and 1 sigma range about the mean.
]]
-- miminal Lua 5.x module setup, M is the module's table.
local M = {
_NAME=(...) or "plotspl",
_DESCRIPTION="Plot SPL data with gnuplot",
_VERSION="0.001",
}
package.loaded[M._NAME] = M
-- write the data array to a temp file
local function prepdata(data)
local datfile = "tmp-SPL.data"
f = assert(io.open(datfile,"w"))
f:write(data)
f:close()
return datfile
end
-- write out a gnuplot script to plot the data file
-- to the named pngfile, with an offset to the trigger
-- time and the specified title.
local function prepscript(datafile, pngfile, trigger, title)
assert(datafile)
pngfile = pngfile or "tmp-SPL.png"
trigger = trigger or 2.6
title = title or "Scaredy Cat"
local plotfile = "tmp-SPL.plot"
f = assert(io.open(plotfile, "w"))
f:write('# Configuration\n',
'trigger=', trigger, '\n',
'datafile="', datafile, '"\n',
'outfile="', pngfile, '"\n',
'titletext="', title, '"\n',
'\n')
f:write[===[
set terminal push
# Graph Title, Axis labels, key and grid
set title titletext
set xlabel "seconds"
set ylabel "SPL, dB"
set key off
set grid xtics ytics
# Compute mean and sd by cheating with a constant function fit to the
# data.
f(x) = mean_y
fit f(x) datafile via mean_y
stddev_y = sqrt(FIT_WSSR / (FIT_NDF + 1 ))
set terminal png
set output outfile
# label a vertical line at trigger time, which will be at x=0 after
# transformations
set label 1 "Trigger" at 0, graph 0 offset character 0.25,0.5
set arrow 1 from 0, graph 0 to 0, graph 1 nohead linewidth 5 lc rgb "#ccccff"
# plot with stddev bounds and mean, scaling and offsetting x to
# seconds with x=0 at the trigger
plot datafile using ($1 - trigger):2 with lines linewidth 2.5, \
mean_y with lines lc rgb "#00dd00", \
mean_y-stddev_y with lines lc rgb "#dd0000", \
mean_y+stddev_y with lines lc rgb "#dd0000"
set output
set terminal pop
]===]
f:close()
return plotfile
end
-- plot the given data string to the named png file.
function M.plot(data, pngfile, trigger, title)
local datafile = prepdata(data)
local plotfile = prepscript(datafile, pngfile, trigger, title)
local cmd = "gnuplot " .. plotfile .. " >" .. plotfile .. ".log 2>&1"
print(cmd)
os.execute(cmd)
end
-- return the module table
return M
|
Added Scared/scared.lua.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
#! lua
local plot = require "plotspl"
address = "user@example.com"
-- today's date in (almost) ISO-8601 format
local function isodate()
return os.date"%Y-%m-%d %H:%M:%S"
end
-- make its argument be a single string
function flatten(s)
if type(s)=="string" then return '"'..s..'"' end
if type(s)~="table" then return nil end
return '"'..table.concat(s, '" "')..'"'
end
-- Send an email to addr with subject and body. If body
-- is nil then just repeat the subject. This assumes that
-- a "mail" command is available with the usual options.
local function email(addr, subj, body)
body = body or subj
local mail = ("mail -s '%q' %s"):format(subj,addr)
local b = assert(io.popen(mail, "w"))
b:write([[I heard a noise on ]], isodate(), "\r\n\r\n")
b:write(body, "\r\n\r\n")
b:write"(This an automated message.)\r\n"
b:close()
end
-- Send a MIME packed email containing an image of the
-- event to a recipient with a subject
-- mpack(address, eek, "scared.png")
local function mpack(address, subject, pngfile)
assert(address)
assert(subject)
assert(pngfile)
local cmd = ("mpack -a -s %q %q %s"):format(subject, pngfile, address)
print(cmd)
os.execute(cmd)
end
-- Implement a buffer of samples. For simplicity, let the
-- index increment without bound. Note that this will have
-- a problem after 2^53 samples, which is about 30 million
-- years at 10 samples per second.
local recent = {
depth=200,
n=1,
add=function(self,spl)
local n = self.n
self[n] = spl
self[n-self.depth] = nil
self.n = n + 1
end,
text=function(self)
local t = {"0.1s, dB"}
local offset = self.n-self.depth-1
for i=1,self.depth do
if self[i+offset] then
t[#t+1] = ("%0.1f, %s"):format(i/10,self[i+offset])
end
end
return table.concat(t,"\n")
end
}
-- Quick and dirty way to force the UART to have the
-- tty driver settings we need for clean raw access
-- to the port.
os.execute("stty -F /dev/ttyAMA0 115200"
.." pass8 raw -iexten"
.." -echo -echoe -echok -echoke -echoctl")
-- Open the UART for both reading and writing, and send
-- the SPLear command to go into raw SPL sample mode. The
-- output must be unbuffered because the current SPLear
-- firmware would revert to 0.5 Hz summary mode if it
-- receives a newline.
local port = assert(io.open('/dev/ttyAMA0','r+'))
port:setvbuf"no" -- no output buffer at all
port:write"S" -- so this write is immediate
-- Loop reading the SPL samples and watching for loud
-- noises, keeping a log of recent samples as we go.
-- When a loud noise is heard, keep logging for a bit
-- before sending email. Include the log in the email.
local spl, spl0
local triggered = false
local eek = ""
local addr = flatten(address)
print("Notifying "..addr)
while true do
local line = port:read"*l" -- read a single line
spl = tonumber(line)
if spl then
spl = 0.75 * spl
io.write("SPL "..(triggered and "TRG " or " "), spl, "\r")
recent:add(spl)
-- Watch for the trigger condition: 12 dB louder
if not triggered and spl0 and (spl - spl0 > 12.) then
triggered = math.floor(recent.depth * 2. / 3.)
eek = "EEK! "..spl.." dB"
end
if triggered then
triggered = triggered - 1
if triggered == 0 then
triggered = false
local data = recent:text()
local pngfile = "startled-plot.png"
plot.plot(data,
pngfile,
recent.depth/30., -- 1/3 trigger pos, 1/10 for time scale
"Startled at "..isodate())
local body = eek.."\n"..data
print("email " .. addr, eek, isodate())
mpack(addr, eek, pngfile)
end
end
spl0 = spl
end
end
|