-# Licence: WTFPLv2 <http://www.wtfpl.net/txt/copying/>
+# Licence: GPLv3+ <http://www.gnu.org/licenses/gpl.txt>
# Copyright 2015: Julien Moutinho <julm+air@autogeree.net>
+#
+## GNUmakefile
+###
.SECONDARY:
.SUFFIXES:
MAKEFLAGS += -r
-RRD_CF:=AVERAGE
-SENSORS:= \
- humidity \
+
+uniq=$(if $1,$(call \
+ uniq,$(wordlist 2,$(words $1),$1),$2 $(if \
+ $(filter $(firstword $1),$2),,$(firstword $1))) \
+ ,$2)
+
+views := png html5
+all: $(views)
+
+#
+## Sensors
+###
+
+SENSOR_LABEL_temperature=Température (°C)
+SENSOR_LABEL_humidity=Humidité (%)
+SENSOR_LABEL_particles=Particules
+SENSOR_LABEL_quality=Qualité de l’air
+sensors := \
temperature \
+ humidity \
quality \
particles
-.rrd = $(wildcard rrd/*/*.rrd)
+#
+## Round Robin Database (RRD)
+###
-all: png
+RRD_CF := AVERAGE
+.rrd = $(wildcard rrd/*/*.rrd)
#
## INO
USER_LIB_PATH := $(abspath ./libraries)
+ifeq ($(NO_INO),)
include $(ARDMK_DIR)/Arduino.mk
+endif
ino: $(TARGET_EEP) $(TARGET_HEX)
#
## PNG
###
-.PHONY: png $(addprefix png/,$(SENSORS))
-png: $(addprefix png/,$(SENSORS))
-
-ym=$(patsubst %.rrd,,$(notdir $*))
-month_begin=$(shell date +'%s' -d '$(ym)/01')
-month_end=$(shell date +'%s' -d '$(ym)/01 + 1 month - 1 second')
-month_length=$(shell date +'%d' -d '$(ym)/01 + 1 month - 1 second')
-day_begin=$(shell date +'%s' -d '$(ym)/$(day)')
-day_end=$(shell date +'%s' -d '$(ym)/$(day) + 1 month - 1 second')
-
-define png/sensor
-sensor:=$1
-label:=$2
-png/$$(sensor): \
- $$(patsubst rrd/%.rrd,png/$$(sensor)/%.png,$$(.rrd))
- echo $$@
-
-png/$$(sensor)/%.png: rrd/%.rrd
- mkdir -p png/$$(sensor)/$$*
+
+define view/sensor/png
+endef
+
+define view/sensor/year/png
+view/$(sensor)/$(year)/png:
+endef
+
+define view/sensor/year/month/png
+view/$(sensor)/$(year)/$(month)/png: \
+view/$(sensor)/$(year)/$(month).png
+
+view/$(sensor)/$(year)/$(month).png: \
+rrd/$(year)/$(month).rrd
+ mkdir -p $$(@D)
rrdtool graph $$@ \
-w 785 -h 120 -a PNG \
--slope-mode \
- --start $$(month_begin) --end $$(month_end) \
- --vertical-label '$$(label)' \
+ --start $(month_begin) --end $(month_end) \
+ --vertical-label '$$(SENSOR_LABEL_$(sensor))' \
--x-grid HOUR:8:DAY:1:DAY:1:86400:%d \
- DEF:$$(sensor)=rrd/$$*.rrd:$$(sensor):$$(RRD_CF) \
- LINE1:$$(sensor)'#ff0000':"$$(sensor)"
- for day in $$(shell seq -w $$(month_length)); \
- do \
- day_begin=$$$$(date +'%s' -d "$$(ym)/$$$$day"); \
- day_end=$$$$(date +'%s' -d "$$(ym)/$$$$day + 1 day - 1 second"); \
- rrdtool graph png/$$(sensor)/$$*/$$$$day.png \
- -w 785 -h 120 -a PNG \
- --slope-mode \
- --start $$$$day_begin --end $$$$day_end \
- --vertical-label '$$(label)' \
- --x-grid MINUTE:10:HOUR:1:HOUR:1:0:%H \
- DEF:$$(sensor)=rrd/$$*.rrd:$$(sensor):$$(RRD_CF) \
- LINE1:$$(sensor)'#ff0000':"$$(sensor)"; \
- done
+ DEF:$(sensor)=rrd/$(year)/$(month).rrd:$(sensor):$$(RRD_CF) \
+ LINE1:$(sensor)'#ff0000':"$(sensor)"
+endef
+
+define view/sensor/year/month/day/png
+view/$(sensor)/$(year)/$(month)/$(day)/png: \
+view/$(sensor)/$(year)/$(month)/$(day).png
+
+view/$(sensor)/$(year)/$(month)/$(day).png: \
+rrd/$(year)/$(month).rrd
+ mkdir -p $$(@D)
+ rrdtool graph $$@ \
+ -w 785 -h 120 -a PNG \
+ --slope-mode \
+ --start $(day_begin) --end $(day_end) \
+ --vertical-label '$$(SENSOR_LABEL_$(sensor))' \
+ --x-grid MINUTE:10:HOUR:1:HOUR:1:0:%H \
+ DEF:$(sensor)=rrd/$(year)/$(month).rrd:$(sensor):$$(RRD_CF) \
+ LINE1:$(sensor)'#ff0000':"$(sensor)";
+endef
+
+#
+## HTML5
+###
+
+define view/sensor/html5
+endef
+
+define view/sensor/year/html5
+view/$(sensor)/$(year)/html5:
+endef
+
+define view/sensor/year/month/html5
+view/$(sensor)/$(year)/$(month)/html5: \
+view/$(sensor)/$(year)/$(month).html5
+
+view/$(sensor)/$(year)/$(month).html5: \
+view/$(sensor)/$(year)/$(month)/png
+ printf ' \
+ <report sensor="$(sensor)" year="$(year)" month="$(month)"> \
+ $(foreach day,$(days), \
+ <date \
+ day="$(day)" \
+ day-name="$$(shell date +'%A' -d '$(year)/$(month)/$(day)')"/>) \
+ </report>' | \
+ xsltproc --output $$@ \
+ xsl/sensor/year/month.html5.xsl -
+endef
+define view/year/month/html5
+view/$(year)/$(month)/html5: \
+view/$(year)/$(month).html5
+
+view/$(year)/$(month).html5: \
+$(foreach sensor,$(sensors), view/$(sensor)/$(year)/$(month)/png)
+ mkdir -p $$(@D)
+ printf ' \
+ <report year="$(year)" month="$(month)"> \
+ $(foreach day,$(days), \
+ <date \
+ day="$(day)" \
+ day-name="$$(shell date +'%A' -d '$(year)/$(month)/$(day)')"> \
+ $(foreach sensor,$(sensors), \
+ <sensor name="$(sensor)"/> \
+ ) \
+ </date>) \
+ </report>' | \
+ xsltproc --output $$@ \
+ xsl/year/month.html5.xsl -
+endef
+
+define view/sensor/year/month/day/html5
+#view/$(sensor)/$(year)/$(month)/$(day)/html5: \
+#view/$(sensor)/$(year)/$(month)/$(day).html5
+
+endef
+
+#
+## Dates
+###
+years=$(call uniq,$(foreach rrd,$(.rrd),$(word 2,$(subst /, ,$(rrd)))))
+months=$(foreach rrd,$(filter rrd/$(year)/%,$(.rrd)),$(basename $(word 3,$(subst /, ,$(rrd)))))
+days=$(shell seq -w $$(date +'%d' -d '$(year)/$(month)/01 + 1 month - 1 second'))
+
+month_begin=$(shell date +'%s' -d '$(year)/$(month)/01')
+month_end=$(shell date +'%s' -d '$(year)/$(month)/01 + 1 month - 1 second')
+
+day_begin=$(shell date +'%s' -d '$(year)/$(month)/$(day)')
+day_end=$(shell date +'%s' -d '$(year)/$(month)/$(day) + 1 day - 1 second')
+
+define foreach/sensor
+.PHONY: view/$(sensor)/$(view)
+view/$(view): view/$(sensor)/$(view)
+$(call view/sensor/$(view))
+endef
+
+define foreach/year/sensor/view
+.PHONY: view/$(sensor)/$(year)/$(view)
+view/$(sensor)/$(view): view/$(sensor)/$(year)/$(view)
+$(call view/sensor/year/$(view))
+endef
+
+define foreach/year/month/sensor/view
+.PHONY: view/$(sensor)/$(year)/$(month)/$(view)
+view/$(sensor)/$(year)/$(view): view/$(sensor)/$(year)/$(month)/$(view)
+$(call view/sensor/year/month/$(view))
+endef
+define foreach/year/month/view
+.PHONY: view/$(year)/$(month)/$(view)
+view/$(year)/$(view): view/$(year)/$(month)/$(view)
+$(call view/year/month/$(view))
+endef
+
+define foreach/year/month/day/sensor/view
+.PHONY: view/$(sensor)/$(year)/$(month)/$(day)/$(view)
+view/$(sensor)/$(year)/$(month)/$(view): view/$(sensor)/$(year)/$(month)/$(day)/$(view)
+$(call view/sensor/year/month/day/$(view))
endef
-)=)
-$(eval $(call png/sensor,temperature,Température (°C$)))
-$(eval $(call png/sensor,humidity,Humidité (%$)))
-$(eval $(call png/sensor,particles,Particules))
-$(eval $(call png/sensor,quality,Qualité de l’air))
+$(foreach sensor,$(sensors), \
+ $(foreach view,$(views), \
+ $(eval $(call foreach/sensor)) \
+ ) \
+ )
+$(foreach year,$(years), \
+ $(foreach view,$(views), \
+ $(eval $(call foreach/year/view)) \
+ ) \
+ $(foreach sensor,$(sensors), \
+ $(foreach view,$(views), \
+ $(eval $(call foreach/year/sensor/view)) \
+ ) \
+ ) \
+ $(foreach month,$(months), \
+ $(foreach view,$(views), \
+ $(eval $(call foreach/year/month/view)) \
+ ) \
+ $(foreach sensor,$(sensors), \
+ $(foreach view,$(views), \
+ $(eval $(call foreach/year/month/sensor/view)) \
+ ) \
+ ) \
+ $(foreach day,$(days), \
+ $(foreach view,$(views), \
+ $(eval $(call foreach/year/month/day/view)) \
+ ) \
+ $(foreach sensor,$(sensors), \
+ $(foreach view,$(views), \
+ $(eval $(call foreach/year/month/day/sensor/view)) \
+ ) \
+ ) \
+ ) \
+ ) \
+ )