summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/context/scripts/mkiv/mtx-youless.html56
-rw-r--r--doc/context/scripts/mkiv/mtx-youless.man42
-rw-r--r--doc/context/scripts/mkiv/mtx-youless.xml29
-rw-r--r--scripts/context/lua/mtx-youless.lua270
-rw-r--r--tex/context/base/cont-new.mkiv2
-rw-r--r--tex/context/base/context-version.pdfbin4112 -> 4107 bytes
-rw-r--r--tex/context/base/context.mkiv2
-rw-r--r--tex/context/base/core-con.lua2
-rw-r--r--tex/context/base/core-con.mkiv14
-rw-r--r--tex/context/base/s-youless.mkiv201
-rw-r--r--tex/context/base/status-files.pdfbin24519 -> 24516 bytes
-rw-r--r--tex/context/base/status-lua.pdfbin222448 -> 222369 bytes
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
13 files changed, 609 insertions, 11 deletions
diff --git a/doc/context/scripts/mkiv/mtx-youless.html b/doc/context/scripts/mkiv/mtx-youless.html
new file mode 100644
index 000000000..1889367d0
--- /dev/null
+++ b/doc/context/scripts/mkiv/mtx-youless.html
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>youless Fetcher</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">youless Fetcher </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--collect</th><td></td><td>collect data from device</td></tr>
+ <tr><th>--nobackup</th><td></td><td>don't backup old datafile</td></tr>
+ <tr><th>--nofile</th><td></td><td>don't write data to file (for checking)</td></tr>
+ <tr><th>--kwh</th><td></td><td>summative kwk data</td></tr>
+ <tr><th>--watt</th><td></td><td>collected watt data</td></tr>
+ <tr><th>--host</th><td></td><td>ip address of device</td></tr>
+ </table>
+<br/>
+<h1>Example</h1>
+<tt>mtxrun --script youless --collect --host=192.168.2.50 --kwk</tt>
+<br/><tt>mtxrun --script youless --collect --host=192.168.2.50 --watt somefile.lua</tt>
+<br/><br/> </div>
+ </div>
+ </body>
+ </html>
diff --git a/doc/context/scripts/mkiv/mtx-youless.man b/doc/context/scripts/mkiv/mtx-youless.man
new file mode 100644
index 000000000..bce5219c3
--- /dev/null
+++ b/doc/context/scripts/mkiv/mtx-youless.man
@@ -0,0 +1,42 @@
+.TH "mtx-youless" "1" "01-01-2013" "version 1.00" "youless Fetcher"
+.SH NAME
+.B mtx-youless
+.SH SYNOPSIS
+.B mtxrun --script youless [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B youless Fetcher
+.SH OPTIONS
+.TP
+.B --collect
+collect data from device
+.TP
+.B --nobackup
+don't backup old datafile
+.TP
+.B --nofile
+don't write data to file (for checking)
+.TP
+.B --kwh
+summative kwk data
+.TP
+.B --watt
+collected watt data
+.TP
+.B --host
+ip address of device
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/doc/context/scripts/mkiv/mtx-youless.xml b/doc/context/scripts/mkiv/mtx-youless.xml
new file mode 100644
index 000000000..9a34efce5
--- /dev/null
+++ b/doc/context/scripts/mkiv/mtx-youless.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-youless</entry>
+ <entry name="detail">youless Fetcher</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="collect"><short>collect data from device</short></flag>
+ <flag name="nobackup"><short>don't backup old datafile</short></flag>
+ <flag name="nofile"><short>don't write data to file (for checking)</short></flag>
+ <flag name="kwh"><short>summative kwk data</short></flag>
+ <flag name="watt"><short>collected watt data</short></flag>
+ <flag name="host"><short>ip address of device</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+ <examples>
+ <category>
+ <title>Example</title>
+ <subcategory>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --kwk</command></example>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --watt somefile.lua</command></example>
+ </subcategory>
+ </category>
+ </examples>
+</application>
diff --git a/scripts/context/lua/mtx-youless.lua b/scripts/context/lua/mtx-youless.lua
new file mode 100644
index 000000000..18304571b
--- /dev/null
+++ b/scripts/context/lua/mtx-youless.lua
@@ -0,0 +1,270 @@
+if not modules then modules = { } end modules ['mtx-youless'] = {
+ version = 1.002,
+ comment = "script tp fetch data from kwk meter polling device",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE",
+ license = "see context related readme files"
+}
+
+-- This script can fetch data from a youless device (http://www.youless.nl/) where data
+-- is merged into a file. The data concerns energy consumption (current wattage as well
+-- as kwh usage). There is an accompanying module to generate graphics.
+
+require("util-jsn")
+
+-- the library variant:
+
+local youless = { }
+utilities.youless = youless
+
+local lpegmatch = lpeg.match
+local formatters = string.formatters
+
+local http = socket.http
+
+-- maybe just a special parser but who cares about speed here
+
+local function fetch(url,what,i)
+ local url = formatters["http://%s/V?%s=%i&f=j"](url,what,i)
+ local data = http.request(url)
+ local result = data and utilities.json.tolua(data)
+ return result
+end
+
+-- "123" " 1,234"
+
+local tovalue = lpeg.Cs((lpeg.R("09") + lpeg.P(1)/"")^1) / tonumber
+
+-- "2013-11-12T06:40:00"
+
+local totime = (lpeg.C(4) / tonumber) * lpeg.P("-")
+ * (lpeg.C(2) / tonumber) * lpeg.P("-")
+ * (lpeg.C(2) / tonumber) * lpeg.P("T")
+ * (lpeg.C(2) / tonumber) * lpeg.P(":")
+ * (lpeg.C(2) / tonumber) * lpeg.P(":")
+ * (lpeg.C(2) / tonumber)
+
+local function get(url,what,i,data,average)
+ if not data then
+ data = { }
+ end
+ while true do
+ local d = fetch(url,what,i)
+ if d and next(d) then
+ local c_year, c_month, c_day, c_hour, c_minute, c_seconds = lpegmatch(totime,d.tm)
+ if c_year and c_seconds then
+ local delta = tonumber(d.dt)
+ local tnum = os.time { year = c_year, month = c_month, day = c_day, hour = c_hour, minute = c_minute }
+ local v = d.val
+ for i=1,#v do
+ local newvalue = lpegmatch(tovalue,v[i])
+ if newvalue then
+ local t = tnum + (i-1)*delta
+ local current = os.date("%Y-%m-%dT%H:%M:%S",t)
+ local c_year, c_month, c_day, c_hour, c_minute, c_seconds = lpegmatch(totime,current)
+ if c_year and c_seconds then
+ local years = data.years if not years then years = { } data.years = years end
+ local d_year = years[c_year] if not d_year then d_year = { } years[c_year] = d_year end
+ local months = d_year.months if not months then months = { } d_year.months = months end
+ local d_month = months[c_month] if not d_month then d_month = { } months[c_month] = d_month end
+ local days = d_month.days if not days then days = { } d_month.days = days end
+ local d_day = days[c_day] if not d_day then d_day = { } days[c_day] = d_day end
+ if average then
+ d_day.average = newvalue
+ else
+ local hours = d_day.hours if not hours then hours = { } d_day.hours = hours end
+ local d_hour = hours[c_hour] if not d_hour then d_hour = { } hours[c_hour] = d_hour end
+ d_hour[c_minute] = newvalue
+ end
+ end
+ end
+ end
+ end
+ else
+ return data
+ end
+ i = i + 1
+ end
+ return data
+end
+
+-- day of month (kwh)
+-- url = http://192.168.1.14/V?m=2
+-- m = the number of month (jan = 1, feb = 2, ..., dec = 12)
+
+-- hour of day (watt)
+-- url = http://192.168.1.14/V?d=1
+-- d = the number of days ago (today = 0, yesterday = 1, etc.)
+
+-- 10 minutes (watt)
+-- url = http://192.168.1.14/V?w=1
+-- w = 1 for the interval now till 8 hours ago.
+-- w = 2 for the interval 8 till 16 hours ago.
+-- w = 3 for the interval 16 till 24 hours ago.
+
+-- 1 minute (watt)
+-- url = http://192.168.1.14/V?h=1
+-- h = 1 for the interval now till 30 minutes ago.
+-- h = 2 for the interval 30 till 60 minutes ago
+
+function youless.collect(specification)
+ if type(specification) ~= "table" then
+ return
+ end
+ local host = specification.host or ""
+ local data = specification.data or { }
+ local filename = specification.filename or ""
+ local variant = specification.variant or "kwh"
+ local detail = specification.detail or false
+ local nobackup = specification.nobackup or false
+ if host == "" then
+ return
+ end
+ if name then
+ data = table.load(name) or data
+ end
+ if variant == "kwh" then
+ get(host,"m",1,data,true)
+ elseif variant == "watt" then
+ get(host,"d",0,data,true)
+ get(host,"w",1,data)
+ if detail then
+ get(host,"h",1,data)
+ end
+ end
+ if filename == "" then
+ return
+ end
+ local path = file.dirname(filename)
+ local base = file.basename(filename)
+ if nobackup then
+ -- saved but with checking
+ local tempname = file.join(path,"youless.tmp")
+ table.save(tempname,data)
+ local check = table.load(tempname)
+ if type(check) == "table" then
+ local keepname = file.replacesuffix(filename,"old")
+ os.remove(keepname)
+ if not lfs.isfile(keepname) then
+ os.rename(filename,keepname)
+ os.rename(tempname,filename)
+ end
+ end
+ else
+ local keepname = file.join(path,formatters["%s-%s"](os.date("%Y-%m-%d-%H-%M-%S",os.time()),base))
+ os.rename(filename,keepname)
+ if not lfs.isfile(filename) then
+ table.save(filename,data)
+ end
+ end
+ return data
+end
+
+-- local data = youless.collect {
+-- host = "192.168.2.50",
+-- variant = "watt",
+-- filename = "youless-watt.lua"
+-- }
+
+-- inspect(data)
+
+-- local data = youless.collect {
+-- host = "192.168.2.50",
+-- variant = "kwh",
+-- filename = "youless-kwh.lua"
+-- }
+
+-- inspect(data)
+
+-- the script
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-youless</entry>
+ <entry name="detail">youless Fetcher</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="collect"><short>collect data from device</short></flag>
+ <flag name="nobackup"><short>don't backup old datafile</short></flag>
+ <flag name="nofile"><short>don't write data to file (for checking)</short></flag>
+ <flag name="kwh"><short>summative kwk data</short></flag>
+ <flag name="watt"><short>collected watt data</short></flag>
+ <flag name="host"><short>ip address of device</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+ <examples>
+ <category>
+ <title>Example</title>
+ <subcategory>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --kwk</command></example>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --watt somefile.lua</command></example>
+ </subcategory>
+ </category>
+ </examples>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-youless",
+ banner = "youless Fetcher",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.youless = scripts.youless or { }
+
+function scripts.youless.collect()
+ local host = environment.arguments.host
+ local variant = environment.arguments.kwh and "kwh" or environment.arguments.watt and "watt"
+ local nobackup = environment.arguments.nobackup
+ local nofile = environment.arguments.nofile
+ local filename = environment.files[1]
+ if not variant then
+ report("provide variant --kwh or --watt")
+ return
+ else
+ report("using variant %a",variant)
+ end
+ if not host then
+ host = "192.168.2.50"
+ report("using default host %a",host)
+ else
+ report("using host %a",host)
+ end
+ if nobackup then
+ report("not backing up data file")
+ end
+ if not filename and not nofile then
+ filename = formatters["youless-%s.lua"](variant)
+ end
+ if filename ~= "" then
+ report("using file %a",filename)
+ end
+ local data = youless.collect {
+ filename = filename,
+ host = host,
+ variant = variant,
+ nobackup = nobackup,
+ }
+ if type(data) ~= "table" then
+ report("no data collected")
+ elseif filename == "" then
+ report("data collected but not saved")
+ end
+end
+
+if environment.argument("collect") then
+ scripts.youless.collect()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index 0506dce5d..f535e1628 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2013.11.13 12:28}
+\newcontextversion{2013.11.13 16:21}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index 853950cd3..10a349799 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index f945319dd..355879aa1 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -25,7 +25,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2013.11.13 12:28}
+\edef\contextversion{2013.11.13 16:21}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/core-con.lua b/tex/context/base/core-con.lua
index 315a34f39..dad24a7d4 100644
--- a/tex/context/base/core-con.lua
+++ b/tex/context/base/core-con.lua
@@ -971,7 +971,7 @@ local days = { -- not variables.sunday
"saturday",
}
-local months = { -- not variables.januari
+local months = { -- not variables.january
"january",
"february",
"march",
diff --git a/tex/context/base/core-con.mkiv b/tex/context/base/core-con.mkiv
index 375d77072..a43473ced 100644
--- a/tex/context/base/core-con.mkiv
+++ b/tex/context/base/core-con.mkiv
@@ -206,8 +206,8 @@
%D
%D Anyhow, the conversion looks like:
-\def\monthlong #1{\ctxcommand{monthname(#1)}}
-\def\monthshort#1{\ctxcommand{monthmnem(#1)}}
+\unexpanded\def\monthlong #1{\ctxcommand{monthname(#1)}}
+\unexpanded\def\monthshort#1{\ctxcommand{monthmnem(#1)}}
\let\convertmonth\monthlong % for old times sake
@@ -218,9 +218,9 @@
\let\month \monthlong
-\def\MONTH #1{\WORD{\month {#1}}}
-\def\MONTHLONG #1{\WORD{\monthlong {#1}}}
-\def\MONTHSHORT#1{\WORD{\monthshort{#1}}}
+\unexpanded\def\MONTH #1{\WORD{\month {#1}}}
+\unexpanded\def\MONTHLONG #1{\WORD{\monthlong {#1}}}
+\unexpanded\def\MONTHSHORT#1{\WORD{\monthshort{#1}}}
%D We never explicitly needed this, but Tobias Burnus pointed out that it would be
%D handy to convert to the day of the week. In doing so, we have to calculate the
@@ -240,8 +240,8 @@
%D \showsetup{weekday}
%D \showsetup{WEEKDAY}
-\def\weekday#1{\ctxcommand{day(#1)}}
-\def\WEEKDAY#1{\WORD{\weekday{#1}}}
+\unexpanded\def\weekday#1{\ctxcommand{day(#1)}}
+\unexpanded\def\WEEKDAY#1{\WORD{\weekday{#1}}}
%D \macros
%D {getdayoftheweek, dayoftheweek}
diff --git a/tex/context/base/s-youless.mkiv b/tex/context/base/s-youless.mkiv
new file mode 100644
index 000000000..fbc60ba47
--- /dev/null
+++ b/tex/context/base/s-youless.mkiv
@@ -0,0 +1,201 @@
+%D \module
+%D [ file=s-youless,
+%D version=2013.11.12,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Youless Graphics,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is experimental code. When I have collected enough data I will make the
+%D graphics nicer and provide some more.
+%D
+%D The Jouless can serve web pages but there is not much detail in them. They also are
+%D somewhat bad \HTML, like unquoted attributes and so. We don't need this anyway as we
+%D can also fetch data directly. The data is collected using a dedicated helper script
+%D (of course we could just call it as module too). The data is fetched from the Jouless
+%D device using queries (currently we use json, but a more direct parsing of data might
+%D be more efficient). The data is converted into a proper \LUA\ table and saved (merged).
+
+% mtxrun --script youless --collect --kwk
+% mtxrun --script youless --collect --watt
+
+\startluacode
+
+ moduledata.youless = { }
+
+ function moduledata.youless.enhance(data)
+ if data.years then
+ for y, year in next, data.years do
+ if year.months then
+ local a_year, n_year, m_year = 0, 0, 0
+ for m, month in next, year.months do
+ if month.days then
+ n_year = n_year + 1
+ local a_month, n_month = 0, 0
+ for d, day in next, month.days do
+ if day.hours then
+ n_month = n_month + 1
+ local a_day, n_day = 0, 0
+ for h, hour in next, day.hours do
+ local a_hour, n_hour, m_hour = 0, 0, 0
+ for k, v in next, hour do
+ if type(k) == "number" then
+ a_hour = a_hour + v
+ n_hour = n_hour + 1
+ if v > m_hour then
+ m_hour = v
+ end
+ end
+ end
+ n_day = n_day + n_hour
+ a_day = a_day + a_hour
+ hour.maxwatt = m_hour
+ hour.watt = a_hour / n_hour
+ if m_hour > m_year then
+ m_year = m_hour
+ end
+ end
+ if n_day > 0 then
+ a_month = a_month + a_day
+ n_month = n_month + n_day
+ day.watt = a_day / n_day
+ else
+ day.watt = 0
+ end
+ end
+ end
+ if n_month > 0 then
+ a_year = a_year + a_month
+ n_year = n_year + n_month
+ month.watt = a_month / n_month
+ else
+ month.watt = 0
+ end
+ end
+ end
+ if n_year > 0 then
+ year.watt = a_year / n_year
+ year.maxwatt = m_year
+ else
+ year.watt = 0
+ year.maxwatt = 0
+ end
+ end
+ end
+ end
+ end
+
+ function moduledata.youless.kwh(specification)
+ -- todo
+ end
+
+ function moduledata.youless.watt(specification)
+
+ local y = tonumber(specification.year) or os.today().year
+ local data = table.load(specification.filename or "youless-watt.lua")
+
+ if not data then
+ return
+ end
+
+ moduledata.youless.enhance(data)
+
+ local year = data.years[y]
+ local scale = 10
+
+ for m=1,12 do
+ local month = year.months[m]
+ if month then
+ context.startMPpage { offset = "10pt" }
+ context("linecap := butt; pickup pencircle scaled .5")
+
+ for i=0,(math.div(year.maxwatt,1000)+1)*1000,100 do
+ context("draw (%s,%s) -- (%s,%s) withcolor .6white ;",0,i/scale,31 * 24,i/scale)
+ end
+
+ context("draw (0,%s) -- (31 * 24,%s) dashed dashpattern(on 3 off 3) withcolor darkgreen withpen pencircle scaled 1 ;",year.watt /scale,year.watt /scale)
+ context("draw (0,%s) -- (31 * 24,%s) dashed dashpattern(off 3 on 3) withcolor darkred withpen pencircle scaled 1 ;",month.watt/scale,month.watt/scale)
+
+ local days = month.days
+ if days then
+ local nd = os.nofdays(y,m)
+ for d=1,nd do
+ local day = days[d]
+ local xoffset = (d-1) * 24
+ local wd = os.weekday(d,m,y)
+ local weekend = wd == 1 or wd == 2 or wd == 7
+ if weekend then
+ context("draw (%s,%s) -- (%s,%s); ",xoffset,-12,xoffset,weekend and -30)
+ context("draw (%s,%s) -- (%s,%s); ",xoffset+24,-12,xoffset+24,weekend and -30)
+ end
+ context([[draw textext("%s") shifted (%s,%s) ; ]],d,xoffset + 12,-20)
+ if day then
+ for h=0,23 do
+ local hours = day.hours
+ if hours then
+ local hour = hours[h]
+ if hour then
+ local dx = xoffset + h
+ local dy = hour.watt/scale
+ local dm = hour.maxwatt/scale
+ context("draw (%s,%s) -- (%s,%s) withcolor darkblue ; ",dx,0,dx,dy)
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",dx,dy,dx,dm)
+ end
+ end
+ end
+ end
+ end
+ for d=1,31 do
+ local xoffset = d * 24
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset,0,xoffset,-10)
+ end
+ end
+
+ local max = (math.div(year.maxwatt,1000)+1)
+
+ for i=0,max*1000,1000 do
+ context([[draw textext.lft("%s") shifted (%s,%s) ; ]],i,-10,i/scale)
+ context("draw (%s,%s) -- (%s,%s) withcolor .2white ;",0,i/scale,31 * 24,i/scale)
+ end
+
+ context([[draw textext("\strut\month{%s}\enspace%s") shifted (%s,%s) ; ]],m, y, 31 * 24 / 2, -50)
+ context([[draw textext("watt") rotated 90 shifted (%s,%s) ; ]],-15,50)
+
+ context.stopMPpage()
+ else
+ -- maybe placeholder
+ end
+ end
+
+ end
+
+\stopluacode
+
+\continueifinputfile{s-youless.mkiv}
+
+\setupbodyfont[dejavu]
+
+% printer (oce) : > 3000 W startup (900 W idle, 2000 W printing)
+% coffeemaker : 1500 W when heating
+
+% baseline day : 2250 W (servers, airco, workstations, routers, switches, heating, etc)
+% baseline night : 1750 W
+
+\starttext
+
+ \startluacode
+
+ os.execute([[mtxrun --script youless --collect --watt "c:/data/system/youless/data/youless-watt.lua"]])
+
+ -- os.execute([[mtxrun --script youless --collect --watt --nobackup "c:/data/system/youless/data/youless-watt.lua"]])
+
+ moduledata.youless.watt { year = 2013, filename = "c:/data/system/youless/data/youless-watt.lua" }
+
+ \stopluacode
+
+\stoptext
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index ce269173a..34d4875da 100644
--- a/tex/context/base/status-files.pdf
+++ b/tex/context/base/status-files.pdf
Binary files differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
index 3ac4ca292..9eb5052cc 100644
--- a/tex/context/base/status-lua.pdf
+++ b/tex/context/base/status-lua.pdf
Binary files differ
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index f6e95a000..202c24994 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 11/13/13 12:28:55
+-- merge date : 11/13/13 16:21:08
do -- begin closure to overcome local limits and interference