-
Notifications
You must be signed in to change notification settings - Fork 0
/
ppm_norns.lua
168 lines (145 loc) · 4.03 KB
/
ppm_norns.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
-- ppm_norns
-- v1.00 @duncangeere
-- https://llllllll.co/t/XXXX
--
-- a single sine tone that
-- reflects the concentration
-- of CO2 in the atmosphere.
--
-- there are no controls.
--
-- to change the output, change
-- your habits and elect
-- politicians who support
-- strong and immediate climate
-- action.
--
-- when the tone reaches C4,
-- we will have likely reached
-- 1.5c of warming, the threshold
-- for severe climate impacts on
-- people, wildlife and
-- ecosystems.
--
-- suggestions:
--
-- - tune your oscillators to the
-- health of the planet
--
-- - plug in crow to get cv in
-- the 0-10v range on all four
-- output channels
--
-- - use it to start conversations
-- about climate with friends
--
engine.name = "TestSine"
local Graph = include("lib/lightergraph")
local json = include("lib/json")
-- https://github.com/rxi/json.lua
-- Constants
local preindustrial = 278
local threshold = 507
local C0 = 16.35
local C4 = 261.63
local api = "https://global-warming.org/api/co2-api"
local backup = "data.json"
-- Variables
local dl
local data
local dataset = {}
local areweloaded = false
-- On startup
function init()
redraw()
engine.amp(0)
clock.run(grabdata_clock)
end
-- Visuals
function redraw()
-- clear the screen
screen.clear()
if (areweloaded == true) then
-- drawing time
screen.aa(1)
chart:redraw()
-- ppm
screen.font_size(35)
screen.font_face(19)
screen.level(11)
screen.move(0, 38)
screen.text(string.format("%.0f", data.cycle) .. "ppm")
-- date
screen.font_size(8)
screen.font_face(4)
screen.level(4)
screen.move(124, 60)
screen.text_right(data.year .. "-" .. data.month .. "-" .. data.day)
else
screen.aa(1)
screen.font_size(8)
screen.font_face(1)
screen.level(15)
screen.move(64, 32)
screen.text_center("please wait - loading...")
end
-- trigger a screen update
screen.update()
end
-- Function to run after data is downloaded
function process(download)
local everything = json.decode(download).co2
-- Fill out the dataset
for i = 1, #everything do
table.insert(dataset, tonumber(everything[i].cycle))
end
-- Make the graph
screen.level(3)
chart = Graph.new(1, #dataset, "lin", preindustrial, threshold, "lin",
"spline", false, false)
chart:set_position_and_size(0, 0, 128, 64)
for i = 1, #dataset do chart:add_point(i, dataset[i]) end
-- Latest datapoint
data = everything[#everything]
print(
"The data " .. data.cycle .. " was gathered on " .. data.year .. "-" ..
data.month .. "-" .. data.day)
-- Use the data
engine.hz(map(data.cycle, preindustrial, threshold, C0, C4))
local volts = map(data.cycle, preindustrial, threshold, 0, 10)
for i = 1, 4 do crow.output[i].volts = volts end
engine.amp(0.5)
end
function grabdata_clock()
clock.sleep(0.5)
dl = util.os_capture("curl -s -m 30 -k " .. api)
if (#dl > 75) then
print("API successfully reached")
local File = io.open(_path.code .. "ppm_norns/" .. backup, 'w')
File:write(dl)
print("New backup saved")
File:close()
else
print("Failed to access API, using backup instead.")
io.input(_path.code .. "ppm_norns/" .. backup)
dl = io.read("*all")
end
process(dl)
areweloaded = true
redraw()
end
-- Function to map values from one range to another
function map(n, start, stop, newStart, newStop, withinBounds)
local value = ((n - start) / (stop - start)) * (newStop - newStart) +
newStart
-- // Returns basic value
if not withinBounds then return value end
-- // Returns values constrained to exact range
if newStart < newStop then
return math.max(math.min(value, newStop), newStart)
else
return math.max(math.min(value, newStart), newStop)
end
end
-- Runs when script is stopped
function cleanup() engine.amp(0) end