subduino 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/Readme.textile +48 -2
  2. data/VERSION +1 -1
  3. data/bin/subduino +21 -5
  4. data/duino/Makefile +53 -50
  5. data/duino/duino.pde +271 -5
  6. data/lib/subduino.rb +1 -1
  7. data/lib/subduino/parse.rb +23 -34
  8. data/lib/subduino/parse/bool.rb +13 -0
  9. data/lib/subduino/parse/lux.rb +13 -0
  10. data/lib/subduino/parse/temp.rb +17 -0
  11. data/lib/subduino/scaffold/Makefile +59 -51
  12. data/lib/subduino/store.rb +21 -12
  13. data/subduino.gemspec +88 -2
  14. data/webapp/config.yml +20 -0
  15. data/webapp/lib/app.rb +2 -2
  16. data/webapp/lib/duino.rb +9 -16
  17. data/webapp/public/custom.js +187 -0
  18. data/webapp/public/date_input.css +149 -0
  19. data/webapp/public/facebox.css +83 -0
  20. data/webapp/public/facebox.js +319 -0
  21. data/webapp/public/favicon.ico +0 -0
  22. data/webapp/public/icons/current.png +0 -0
  23. data/webapp/public/icons/day.png +0 -0
  24. data/webapp/public/icons/door-big.png +0 -0
  25. data/webapp/public/icons/favicon.png +0 -0
  26. data/webapp/public/icons/irrigation.png +0 -0
  27. data/webapp/public/icons/lamp-big.png +0 -0
  28. data/webapp/public/icons/lightbulb_off.png +0 -0
  29. data/webapp/public/icons/locked.png +0 -0
  30. data/webapp/public/icons/lux.png +0 -0
  31. data/webapp/public/icons/night.png +0 -0
  32. data/webapp/public/icons/noise.png +0 -0
  33. data/webapp/public/icons/onoff.png +0 -0
  34. data/webapp/public/icons/rain.png +0 -0
  35. data/webapp/public/icons/refrigeration.png +0 -0
  36. data/webapp/public/icons/temp.png +0 -0
  37. data/webapp/public/icons/unlocked.png +0 -0
  38. data/webapp/public/images/ajax-loader.gif +0 -0
  39. data/webapp/public/images/b.png +0 -0
  40. data/webapp/public/images/bendl.gif +0 -0
  41. data/webapp/public/images/bendr.gif +0 -0
  42. data/webapp/public/images/bendsb.gif +0 -0
  43. data/webapp/public/images/bg.jpg +0 -0
  44. data/webapp/public/images/bhead.gif +0 -0
  45. data/webapp/public/images/bheadl.gif +0 -0
  46. data/webapp/public/images/bheadr.gif +0 -0
  47. data/webapp/public/images/bl.png +0 -0
  48. data/webapp/public/images/bnd.gif +0 -0
  49. data/webapp/public/images/br.png +0 -0
  50. data/webapp/public/images/bread.gif +0 -0
  51. data/webapp/public/images/btnb.gif +0 -0
  52. data/webapp/public/images/btnb_.gif +0 -0
  53. data/webapp/public/images/btnm.gif +0 -0
  54. data/webapp/public/images/btnm_.gif +0 -0
  55. data/webapp/public/images/btns.gif +0 -0
  56. data/webapp/public/images/btns_.gif +0 -0
  57. data/webapp/public/images/cal.jpg +0 -0
  58. data/webapp/public/images/close.png +0 -0
  59. data/webapp/public/images/closelabel.gif +0 -0
  60. data/webapp/public/images/error.gif +0 -0
  61. data/webapp/public/images/ft.gif +0 -0
  62. data/webapp/public/images/hdr.gif +0 -0
  63. data/webapp/public/images/hdrl.gif +0 -0
  64. data/webapp/public/images/hdrr.gif +0 -0
  65. data/webapp/public/images/hld.jpg +0 -0
  66. data/webapp/public/images/imgb.gif +0 -0
  67. data/webapp/public/images/imgo.gif +0 -0
  68. data/webapp/public/images/imgt.gif +0 -0
  69. data/webapp/public/images/info.gif +0 -0
  70. data/webapp/public/images/jquery.wysiwyg.gif +0 -0
  71. data/webapp/public/images/li.gif +0 -0
  72. data/webapp/public/images/mbg.png +0 -0
  73. data/webapp/public/images/nsp.gif +0 -0
  74. data/webapp/public/images/phs.gif +0 -0
  75. data/webapp/public/images/sdd.jpg +0 -0
  76. data/webapp/public/images/sdd_.jpg +0 -0
  77. data/webapp/public/images/sidebar.gif +0 -0
  78. data/webapp/public/images/sorta.gif +0 -0
  79. data/webapp/public/images/sortd.gif +0 -0
  80. data/webapp/public/images/srch.gif +0 -0
  81. data/webapp/public/images/srch_.gif +0 -0
  82. data/webapp/public/images/success.gif +0 -0
  83. data/webapp/public/images/thumb1.jpg +0 -0
  84. data/webapp/public/images/thumb2.jpg +0 -0
  85. data/webapp/public/images/thumb3.jpg +0 -0
  86. data/webapp/public/images/tiny.gif +0 -0
  87. data/webapp/public/images/tiny_.gif +0 -0
  88. data/webapp/public/images/tl.png +0 -0
  89. data/webapp/public/images/tr.png +0 -0
  90. data/webapp/public/images/upload.gif +0 -0
  91. data/webapp/public/images/warning.gif +0 -0
  92. data/webapp/public/jquery.img.preload.js +152 -0
  93. data/webapp/public/jquery.sparkline.js +85 -0
  94. data/webapp/public/jquery.tablesorter.min.js +2 -0
  95. data/webapp/public/jquery.visualize.js +452 -0
  96. data/webapp/public/jquery.wysiwyg.css +56 -0
  97. data/webapp/public/style.css +881 -0
  98. data/webapp/public/visualize.css +32 -0
  99. data/webapp/views/index.haml +365 -49
  100. data/webapp/views/layout.haml +78 -7
  101. data/webapp/views/template.haml +676 -0
  102. metadata +89 -3
data/webapp/config.yml ADDED
@@ -0,0 +1,20 @@
1
+ ---
2
+ log_interval: 60
3
+ inputs:
4
+ i1:
5
+ type: Temp
6
+ name: Cafofo temp
7
+ i2:
8
+ type: Temp
9
+ name: Out temp
10
+ i3:
11
+ type: Lux
12
+ name: Cafofo light
13
+ # i2:
14
+ # i3:
15
+ # i4:
16
+ # i5:
17
+ outputs:
18
+ d2:
19
+ type: door
20
+ name: Cafofo door
data/webapp/lib/app.rb CHANGED
@@ -35,7 +35,7 @@ get '/' do
35
35
  # @watches << watch.to_s
36
36
  # end
37
37
  # @watches = @watches.group_by { |w| @statuses[w][:state].to_s }
38
- @sensors = DUINO.sensors
38
+ @sensors = DUINO.sensors || []
39
39
  @host = `hostname`
40
40
  @stats = Duino.cpu_status
41
41
  @footer = "Subduino www v0.0.1 - #{@host}"
@@ -98,6 +98,6 @@ private
98
98
 
99
99
  def show(template, title = 'Duino')
100
100
  @title = title
101
- p request.env['HTTP_XHR']
101
+ request.env['HTTP_XHR']
102
102
  haml(template, :layout => get_layout)
103
103
  end
data/webapp/lib/duino.rb CHANGED
@@ -1,6 +1,7 @@
1
1
 
2
2
  class Duino
3
- Sensors = { :i0 => "Bool", :i1 => "Bool", :temp => "Temp", :lux => "Lux", :knob => "Knob" }
3
+
4
+ Config = YAML.load(File.read("config.yml"))
4
5
 
5
6
  def initialize(config)
6
7
  @config = config
@@ -8,22 +9,14 @@ class Duino
8
9
  end
9
10
 
10
11
  def sensors(one=nil)
11
- s = one ? Sensors.select { |k,v| k.to_s == one.to_s } : Sensors
12
- s.reduce({}) do |h, s|
13
- val = @redis.get(s[0]) rescue nil
12
+ sensors = Config["inputs"]
13
+ # s = one ? Sensors.select { |k,v| k.to_s == one.to_s } : Sensors
14
+ sensors.map do |s|
15
+ p s
16
+ val = @redis.get(s[0]) #rescue nil
14
17
  next unless val
15
- k, v = *s
16
- sensor = Subduino::Parse.work(v, val)
17
- # if v == "Bool"
18
- # info = "#{)} (#{val}~)"
19
- # val = k
20
- # else
21
- # info = "#{k.capitalize} (#{val}~)"
22
- # val = Subduino::Parse.work(v, val).to_s
23
- # end
24
- h.merge!({ k => sensor })
25
- h
26
- end
18
+ Subduino::Parse.work(s[1]["type"], val, s[1]["name"])
19
+ end.reject(&:nil?)
27
20
  end
28
21
 
29
22
  def switch(pins, comm)
@@ -0,0 +1,187 @@
1
+ $(function () {
2
+
3
+ // Preload images
4
+ $.preloadCssImages();
5
+
6
+
7
+ // CSS tweaks
8
+ $('#header #nav li:last').addClass('nobg');
9
+ $('.block_head ul').each(function() { $('li:first', this).addClass('nobg'); });
10
+ $('.block form input[type=file]').addClass('file');
11
+
12
+
13
+ // Web stats
14
+ $('table.stats').each(function() {
15
+
16
+ if($(this).attr('rel')) { var statsType = $(this).attr('rel'); }
17
+ else { var statsType = 'area'; }
18
+
19
+ var chart_width = ($(this).parent('.block_content').width()) - 60;
20
+
21
+ $(this).hide().visualize({
22
+ type: statsType, // 'bar', 'area', 'pie', 'line'
23
+ width: chart_width,
24
+ height: '240px',
25
+ colors: ['#6fb9e8', '#ec8526', '#9dc453', '#ddd74c']
26
+ });
27
+ });
28
+
29
+
30
+ // Sort table
31
+ $("table.sortable").tablesorter({
32
+ headers: { 0: { sorter: false}, 5: {sorter: false} }, // Disabled on the 1st and 6th columns
33
+ widgets: ['zebra']
34
+ });
35
+
36
+ $('.block table tr th.header').css('cursor', 'pointer');
37
+
38
+
39
+ // Check / uncheck all checkboxes
40
+ $('.check_all').click(function() {
41
+ $(this).parents('form').find('input:checkbox').attr('checked', $(this).is(':checked'));
42
+ });
43
+
44
+
45
+ // Set WYSIWYG editor
46
+ // $('.wysiwyg').wysiwyg({css: "css/wysiwyg.css"});
47
+
48
+
49
+ // Modal boxes - to all links with rel="facebox"
50
+ $('a[rel*=facebox]').facebox()
51
+
52
+
53
+ // Messages
54
+ $('.block .message').hide().append('<span class="close" title="Dismiss"></span>').fadeIn('slow');
55
+ $('.block .message .close').hover(
56
+ function() { $(this).addClass('hover'); },
57
+ function() { $(this).removeClass('hover'); }
58
+ );
59
+
60
+ $('.block .message .close').click(function() {
61
+ $(this).parent().fadeOut('slow', function() { $(this).remove(); });
62
+ });
63
+
64
+
65
+ // Form select styling
66
+ // $("form select.styled").select_skin();
67
+
68
+
69
+ // Tabs
70
+ $(".tab_content").hide();
71
+ $("ul.tabs li:first-child").addClass("active").show();
72
+ $(".block").find(".tab_content:first").show();
73
+
74
+ $("ul.tabs li").click(function() {
75
+ $(this).parent().find('li').removeClass("active");
76
+ $(this).addClass("active");
77
+ $(this).parents('.block').find(".tab_content").hide();
78
+
79
+ var activeTab = $(this).find("a").attr("href");
80
+ $(activeTab).show();
81
+ return false;
82
+ });
83
+
84
+
85
+
86
+ // Sidebar Tabs
87
+ $(".sidebar_content").hide();
88
+
89
+ if(window.location.hash && window.location.hash.match('sb')) {
90
+
91
+ $("ul.sidemenu li a[href="+window.location.hash+"]").parent().addClass("active").show();
92
+ $(".block .sidebar_content#"+window.location.hash).show();
93
+ } else {
94
+
95
+ $("ul.sidemenu li:first-child").addClass("active").show();
96
+ $(".block .sidebar_content:first").show();
97
+ }
98
+
99
+ $("ul.sidemenu li").click(function() {
100
+
101
+ var activeTab = $(this).find("a").attr("href");
102
+ window.location.hash = activeTab;
103
+
104
+ $(this).parent().find('li').removeClass("active");
105
+ $(this).addClass("active");
106
+ $(this).parents('.block').find(".sidebar_content").hide();
107
+ $(activeTab).show();
108
+ return false;
109
+ });
110
+
111
+
112
+
113
+ // Block search
114
+ $('.block .block_head form .text').bind('click', function() { $(this).attr('value', ''); });
115
+
116
+
117
+ // Image actions menu
118
+ $('ul.imglist li').hover(
119
+ function() { $(this).find('ul').css('display', 'none').fadeIn('fast').css('display', 'block'); },
120
+ function() { $(this).find('ul').fadeOut(100); }
121
+ );
122
+
123
+
124
+ // Image delete confirmation
125
+ $('ul.imglist .delete a').click(function() {
126
+ if (confirm("Are you sure you want to delete this image?")) {
127
+ return true;
128
+ } else {
129
+ return false;
130
+ }
131
+ });
132
+
133
+
134
+ // Style file input
135
+ // $("input[type=file]").filestyle({
136
+ // image: "images/upload.gif",
137
+ // imageheight : 30,
138
+ // imagewidth : 80,
139
+ // width : 250
140
+ // });
141
+
142
+
143
+ // File upload
144
+ if ($('#fileupload').length) {
145
+ new AjaxUpload('fileupload', {
146
+ action: 'upload-handler.php',
147
+ autoSubmit: true,
148
+ name: 'userfile',
149
+ responseType: 'text/html',
150
+ onSubmit : function(file , ext) {
151
+ $('.fileupload #uploadmsg').addClass('loading').text('Uploading...');
152
+ this.disable();
153
+ },
154
+ onComplete : function(file, response) {
155
+ $('.fileupload #uploadmsg').removeClass('loading').text(response);
156
+ this.enable();
157
+ }
158
+ });
159
+ }
160
+
161
+
162
+
163
+ // Date picker
164
+ // $('input.date_picker').date_input();
165
+
166
+
167
+ // Navigation dropdown fix for IE6
168
+ if(jQuery.browser.version.substr(0,1) < 7) {
169
+ $('#header #nav li').hover(
170
+ function() { $(this).addClass('iehover'); },
171
+ function() { $(this).removeClass('iehover'); }
172
+ );
173
+ }
174
+
175
+ // IE6 PNG fix
176
+ //$(document).pngFix();
177
+
178
+ // Sparklines
179
+ $('.sparklines').sparkline('html',
180
+ {'width': "70px",
181
+ 'height': "27px",
182
+ 'lineColor': "#666",
183
+ 'fillColor': "#ccc"});
184
+
185
+ // #i1graph
186
+
187
+ });
@@ -0,0 +1,149 @@
1
+ /* Some resets for compatibility with existing CSS */
2
+ .date_selector, .date_selector * {
3
+ width: auto;
4
+ height: auto;
5
+ border: none;
6
+ background: none;
7
+ margin: 0;
8
+ padding: 0;
9
+ text-align: left;
10
+ text-decoration: none;
11
+ }
12
+
13
+ .date_selector {
14
+ background: #fbfbfb;
15
+ border: 1px solid #ccc;
16
+ padding: 10px;
17
+ margin: 0;
18
+ margin-top: -1px;
19
+ position: absolute;
20
+ z-index: 100000;
21
+ display: none;
22
+ -webkit-border-radius: 3px;
23
+ -moz-border-radius: 3px;
24
+ border-radius: 3px;
25
+ box-shadow: 0 0 5px #aaa;
26
+ -moz-box-shadow: 0 0 5px #aaa;
27
+ -webkit-box-shadow: 0 0 5px #aaa;
28
+ }
29
+
30
+ .date_selector_ieframe {
31
+ position: absolute;
32
+ z-index: 99999;
33
+ display: none;
34
+ }
35
+
36
+ .date_selector .nav {
37
+ width: 17.5em; /* 7 * 2.5em */
38
+ }
39
+
40
+ .date_selector .nav p { clear: none; }
41
+
42
+ .date_selector .month_nav, .date_selector .year_nav {
43
+ margin: 0 0 3px 0;
44
+ padding: 0;
45
+ display: block;
46
+ position: relative;
47
+ text-align: center;
48
+ }
49
+
50
+ .date_selector .month_nav {
51
+ float: left;
52
+ width: 55%;
53
+ }
54
+
55
+ .date_selector .year_nav {
56
+ float: right;
57
+ width: 42%;
58
+ margin-right: -8px; /* Compensates for cell borders */
59
+ }
60
+
61
+ .date_selector .month_name, .date_selector .year_name {
62
+ font-weight: bold;
63
+ line-height: 20px;
64
+ }
65
+
66
+ .date_selector .button {
67
+ display: block;
68
+ position: absolute;
69
+ top: 0;
70
+ width: 18px;
71
+ height: 18px;
72
+ line-height: 16px;
73
+ font-weight: bold;
74
+ color: #008ee8;
75
+ text-align: center;
76
+ font-size: 12px;
77
+ overflow: hidden;
78
+ border: 1px solid #ccc;
79
+ -webkit-border-radius: 2px;
80
+ -moz-border-radius: 2px;
81
+ border-radius: 2px;
82
+ }
83
+
84
+ .date_selector .button:hover, .date_selector .button.hover {
85
+ background: #ed9c35;
86
+ color: #fff;
87
+ cursor: pointer;
88
+ border-color: #d77011;
89
+ }
90
+
91
+ .date_selector .prev {
92
+ left: 0;
93
+ }
94
+
95
+ .date_selector .next {
96
+ right: 0;
97
+ }
98
+
99
+ .date_selector table {
100
+ border-spacing: 0;
101
+ border-collapse: collapse;
102
+ clear: both;
103
+ margin: 0;
104
+ }
105
+
106
+ .date_selector th, .date_selector td {
107
+ width: 2.5em;
108
+ height: 2em;
109
+ padding: 0 !important;
110
+ text-align: center !important;
111
+ color: #666;
112
+ font-weight: normal;
113
+ }
114
+
115
+ .date_selector th {
116
+ font-size: 11px;
117
+ }
118
+
119
+ .date_selector td {
120
+ border: 1px solid #ccc;
121
+ line-height: 2em;
122
+ text-align: center;
123
+ white-space: nowrap;
124
+ color: #008ee8;
125
+ background: #fff;
126
+ }
127
+
128
+ .date_selector td.today {
129
+ background: #eee;
130
+ }
131
+
132
+ .date_selector td.unselected_month {
133
+ color: #ccc;
134
+ }
135
+
136
+ .date_selector td.selectable_day {
137
+ cursor: pointer;
138
+ }
139
+
140
+ .date_selector td.selected {
141
+ background: #008ee8;
142
+ color: #fff;
143
+ font-weight: bold;
144
+ }
145
+
146
+ .date_selector td.selectable_day:hover, .date_selector td.selectable_day.hover {
147
+ background: #ec8526;
148
+ color: #fff;
149
+ }
@@ -0,0 +1,83 @@
1
+ #facebox .b { background:url(b.png); }
2
+ #facebox .tl { background:url(tl.png); }
3
+ #facebox .tr { background:url(tr.png); }
4
+ #facebox .bl { background:url(bl.png); }
5
+ #facebox .br { background:url(br.png); }
6
+
7
+ #facebox {
8
+ position: absolute;
9
+ top: 0;
10
+ left: 0;
11
+ z-index: 100;
12
+ text-align: left;
13
+ }
14
+
15
+ #facebox .popup {
16
+ position: relative;
17
+ }
18
+
19
+ #facebox table {
20
+ border-collapse: collapse;
21
+ }
22
+
23
+ #facebox td {
24
+ border-bottom: 0;
25
+ padding: 0;
26
+ }
27
+
28
+ #facebox .body {
29
+ padding: 10px;
30
+ background: #fff;
31
+ width: auto !important
32
+ width: 400px;
33
+ min-width: 400px;
34
+ }
35
+
36
+ #facebox .loading {
37
+ text-align: center;
38
+ }
39
+
40
+ #facebox .image {
41
+ text-align: center;
42
+ }
43
+
44
+ #facebox img {
45
+ border: 0;
46
+ margin: 0;
47
+ }
48
+
49
+ #facebox .footer {
50
+ border-top: 1px solid #DDDDDD;
51
+ padding-top: 5px;
52
+ margin-top: 10px;
53
+ text-align: right;
54
+ }
55
+
56
+ #facebox .tl, #facebox .tr, #facebox .bl, #facebox .br {
57
+ height: 10px;
58
+ width: 10px;
59
+ overflow: hidden;
60
+ padding: 0;
61
+ }
62
+
63
+ #facebox_overlay {
64
+ position: fixed;
65
+ top: 0px;
66
+ left: 0px;
67
+ height:100%;
68
+ width:100%;
69
+ }
70
+
71
+ .facebox_hide {
72
+ z-index:-100;
73
+ }
74
+
75
+ .facebox_overlayBG {
76
+ background-color: #000;
77
+ z-index: 99;
78
+ }
79
+
80
+ * html #facebox_overlay { /* ie6 hack */
81
+ position: absolute;
82
+ height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px');
83
+ }