44cd2ec293e4b056a2d058052f2012403772a5c8
[profiled] / profiled.lua
1 -- Profiled  -  automatic profile switcher for Maemo
2 --
3 --  Copyright (C)         Lumiera.org
4 --    2010,               Christian Thaeter <ct@pipapo.org>
5 --
6 --  This program is free software; you can redistribute it and/or
7 --  modify it under the terms of the GNU General Public License as
8 --  published by the Free Software Foundation; either version 2 of the
9 --  License, or (at your option) any later version.
10 --
11 --  This program is distributed in the hope that it will be useful,
12 --  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 --  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 --  GNU General Public License for more details.
15 --
16 --  You should have received a copy of the GNU General Public License
17 --  along with this program; if not, write to the Free Software
18 --  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20
21 -- queries contains functions for each aspect to supervise
22 -- this functions return the table containing the current applicable definition
23 queries = {}
24
25 -- just for playing
26 function queries.test()
27    return { test = 'working' }
28 end
29
30 -- the defaults table biases voting
31 function queries.defaults()
32    return defaults
33 end
34
35 -- TODO
36 -- orientation = function() end
37 -- moving = function () end
38 -- charging = function () end
39 -- playing = function () end
40 -- display = function () end
41 -- locked = function () end
42
43
44 -- engines contains functions to alter the state of some aspect of the system
45 -- this functions take a single string as parameter describing the target state
46 engines = {}
47
48 function engines.test(state)
49    print("test state:", state)
50 end
51
52 --TODO
53 --engines.gps(state)
54 --engines.availability(state)
55 --engines.profile(state)
56 --engines.celluar(state)
57 --engines.secure(state)
58 --engines.lock(state)
59 --engines.wlan(state)
60
61 -- the voting function, takes the votes table with all current votes, the key for which shall be voted and the value of its attribute
62 function vote(votes, key, value)
63    attr, bias = value:match("^([^+-]*)([+-]*)")
64
65    if bias == "" then
66       bias = "+"
67    end
68
69    local counter = 0
70
71    for v in bias:gmatch "." do
72       if v == "+" then
73          counter = counter + 1
74       elseif v == "-" then
75          counter = counter - 1
76       else
77          break
78       end
79    end
80
81    if votes[key] == nil then
82       votes[key] = {}
83    end
84    if votes[key][attr] == nil then
85       votes[key][attr] = 0
86    end
87    votes[key][attr] = votes[key][attr] + counter
88
89    print("voting:", counter, "for:", key..":"..attr, "giving:", votes[key][attr])
90 end
91
92 function mainloop()
93    --sleep(sample_interval)
94    --config()
95
96    print("mainloop")
97
98    local votes = {}
99
100    -- do the voting
101    for name, func in pairs(queries) do
102       if type(_G[name]) == 'table' then
103
104          for k,v in pairs(func() or {}) do
105             vote(votes, k, v)
106          end
107       end
108    end
109
110    -- calculate results
111    for engine, values in pairs(votes) do
112       if engines[engine] then
113          local winner
114          local winning_votes = 0
115          for attr, votes in pairs(values) do
116             print (attr, votes)
117             if votes > winning_votes then
118                winner = attr
119                winning_votes = votes
120             end
121          end
122          print ("elected:", engine..":"..winner, "votes:", winning_votes)
123
124          if winner then
125             engines[engine](winner)
126          end
127       end
128    end
129 end
130
131
132 -- example config:
133
134 sample_interval = 30000
135
136 --voting system, not fair but usable
137 -- Examples:
138 --  key = 'value'     votes +1 for 'value' on 'key'
139 --  key = 'value-'    votes -1 for 'value' on 'key'
140 --  key = 'value+++'  votes +4 for 'value' on 'key'
141 --  key = 'value---'  votes -3 for 'value' on 'key'
142 --  key = 'value++--' votes +1 for 'value' on 'key'
143 --
144 -- only things which got not manually altered get voted for,
145 -- after voting the value with the most votes and being positive is choosen
146 -- if it passes this becomes the new setting for the associated thing.
147 --
148
149 -- the default table gives some bias for all voting
150 defaults = {
151    gps = 'on--',    -- need at least 2 votes to turn the gps on
152 }
153
154
155 -- timespans hh:mm in hhmm notation (700 is 7:00h)
156 time = {
157    [100] = {
158       availability = 'offline',
159       profile = 'silent',
160       celluar = 'off',
161    },
162    [700] = {
163    },
164 }
165
166 -- loadavg times 100
167 load = {
168    [0] = {},
169    [20] = {
170       secure = 'no',
171       lock = 'no',
172       wlan = 'on'
173    }
174 }
175
176
177 -- orientation of the device
178 orientation = {
179    face_down = {
180       availability = 'offline',
181       profile = 'silent',
182       celluar = 'off',
183       secure = 'yes',
184       gps = 'off'
185    },
186    face_up = {
187       gps = 'on'
188    }
189 }
190
191 -- moving around
192 moving = {
193    yes = {
194       availability = 'online',
195       profile = 'normal',
196       celluar = 'on',
197       secure = 'no',
198       gps = 'on'
199    },
200    no = {
201       availability = 'offline',
202       secure = 'yes'
203    }
204 }
205
206 -- connected to charger
207 charging = {
208    yes = {
209       celluar = 'on',
210       wlan = 'on',
211       gps = 'off'
212    }
213 }
214
215 -- if sound/multimedia is playing
216 playing = {
217    yes = {
218       secure = 'no',
219    }
220 }
221
222 -- display state
223 display = {
224    on = {
225       secure = 'no'
226    }
227 }
228
229 -- manually locked
230 locked = {
231    yes = {
232       secure = 'yes'
233    },
234    no = {
235       secure = 'no'
236    }
237 }
238
239 -- by location, gps must be enabled for this, gps will not be enabled for this rules, 'unknown' is special for any unknown position
240 location = {
241    home = {
242       secure = 'no'
243    },
244
245    unknown = {
246       secure = 'yes',
247       celluar = 'on',
248       wlan = 'off',
249       gps = 'on'
250    }
251 }
252
253 test = {}
254
255
256 mainloop()