subduino 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }