2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Tisan - 404
10 |
11 |
12 |
13 |
14 | <%include navigation.ejs%>
15 |
16 |
17 |
18 |

19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/views/500.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Tisan - 404
10 |
11 |
12 |
13 |
14 | <%include navigation.ejs%>
15 |
16 |
17 |
18 |

19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/public/iotboard/dummy.model.min.js:
--------------------------------------------------------------------------------
1 | /*! iot-board 2015-11-09 */
2 | !function(){if(!window.iotboard)return void console.log("iotboard not initialized!");var a={};a.onWidgetStatusChanged=function(a,b,c){console.log("widget {"+a+"} status changed:"+b),console.log(JSON.stringify(c))},a.getCurrentStatus=function(a,b,c){switch(a){case"text":c({text:"status changed:"+new Date});break;case"switch":setTimeout(function(){c({on:Math.floor(100*Math.random())%2==0?!0:!1})},1e3);break;case"led":setTimeout(function(){c([Math.floor(256*Math.random()),Math.floor(256*Math.random()),Math.floor(256*Math.random())])},1e3);break;case"atmosphere":setTimeout(function(){c({temperature:30.3,humidity:45.1,pm25:56.6})},1e3);break;case"temperature":case"humiture":setTimeout(function(){c([33.33333])},1e3);break;case"pm25":case"air":setTimeout(function(){c([345])},1e3);break;case"motor":setTimeout(function(){c([8])},1e3);break;case"default":setTimeout(function(){c([1,2,3.3])},1e3);break;default:console.log("widget {"+a+"} handler not found!")}},window.iotboard.setModel(a)}();
--------------------------------------------------------------------------------
/views/template/humiture.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
26 |
--------------------------------------------------------------------------------
/source/widgets/atmosphere/atmosphere.widget.min.css:
--------------------------------------------------------------------------------
1 | .widget[iotb-widget=atmosphere]{color:#fff;padding:30% 4px 4px;background-color:transparent;border:none;opacity:1;font-family:'Arial Narrow'}.widget[iotb-widget=atmosphere] .temperature{font-weight:700;text-align:center;font-size:30px;width:200px;height:200px;margin:auto;line-height:200px;border:2px solid #ccc;border-radius:100px;box-shadow:1px 1px 1px #888}.widget[iotb-widget=atmosphere] .temperature-val{font-size:60px}.widget[iotb-widget=atmosphere] .humidity-val,.widget[iotb-widget=atmosphere] .pm25-val{font-size:30px}.widget[iotb-widget=atmosphere] .humidity{margin-top:30px;text-align:center;width:45%;display:inline-block}.widget[iotb-widget=atmosphere] .humidity-icon{background:url(water.svg) no-repeat;width:20px;height:20px;display:inline-block;margin-right:10px}.widget[iotb-widget=atmosphere] .pm25{margin-top:30px;text-align:center;width:45%;margin-left:10%;display:inline-block}.widget[iotb-widget=atmosphere] .pm25-icon{background:url(air.svg) no-repeat;width:20px;height:20px;display:inline-block;margin-right:10px}
--------------------------------------------------------------------------------
/models/mysql/user.js:
--------------------------------------------------------------------------------
1 | var Sequelize = require("sequelize");
2 | var DbSequelize = require("../../db/mysql.js");//todo path
3 |
4 | var User = DbSequelize.define("tbl_user",{
5 | "id": { type:Sequelize.INTEGER, primaryKey: true, autoIncreament: true },
6 | "email": { type: Sequelize.CHAR(500)},
7 |
8 | "nickname": { type: Sequelize.CHAR(100)},
9 | "realname": { type: Sequelize.CHAR(100)},
10 | "avatar": { type: Sequelize.CHAR(100)},
11 | "username": { type: Sequelize.CHAR(100)},
12 | "password": { type: Sequelize.CHAR(100)},
13 |
14 | "sex": { type: Sequelize.CHAR(1)},
15 | "telephone": {type: Sequelize.INTEGER},
16 |
17 | "province": { type: Sequelize.CHAR(100)},
18 | "city": { type: Sequelize.CHAR(100)},
19 | "register_time": { type: Sequelize.INTEGER},
20 | "age": { type: Sequelize.INTEGER},
21 | "birthday": { type: Sequelize.INTEGER},
22 | "hardwarekey": { type: Sequelize.CHAR(3000)},
23 | },{
24 | timestamps: false,
25 | underscored: true,
26 | freezeTableName: true,
27 | tableName: "tbl_user"
28 | });
29 | exports.User = User;
30 |
--------------------------------------------------------------------------------
/views/template/temperature.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
26 |
--------------------------------------------------------------------------------
/source/widgets/atmosphere/water.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
--------------------------------------------------------------------------------
/source/js/widget.js:
--------------------------------------------------------------------------------
1 | !function(global){
2 | global.iotboard = global.iotboard || {};
3 |
4 | /**
5 | * Object Widget manage the behavour and look of a widget.
6 | * @param {Object} [dom] [a jQuery/Zepto Dom Selector Object]
7 | * @param {Object} conf [config]
8 | */
9 | function Widget(dom, conf){
10 |
11 | var defaultConf = {
12 |
13 | };
14 |
15 | this.dom = dom;
16 | var config = $.extend({}, defaultConf, conf);
17 |
18 | var render = function(){
19 | dom.html(config.render(dom[0].dataset));
20 |
21 | if(config.onRendered){
22 | config.onRendered(dom);
23 | }
24 | }
25 |
26 | Object.defineProperty(this, 'status', {
27 | get: function(){
28 | return config.status;
29 | },
30 | set: function(newStatus){
31 | config.status = newStatus;
32 | render();
33 | },
34 | enumerable: true,
35 | configurable: true
36 | });
37 |
38 | this.config = config;
39 | this.render = render;
40 | }
41 |
42 |
43 | window.iotboard.Widget = Widget;
44 | }(window);
--------------------------------------------------------------------------------
/views/document/web-ide.md:
--------------------------------------------------------------------------------
1 | # WebIDE介绍
2 | WebIDE首先是为了配合Tisan的pando开发框架而生,另外一方面,WebIDE给开发者提供了一个新的开发模式和开发思维,非常具有创新意义!当然更重要的是给开发者带来了简单、快速、高效的开发!
3 | WebIDE以可视化的界面进行呈现, 开发者通过WebIDE添加产品,在产品里面添加应用组件,把产品组件的自动生成代码拷贝到SDK的指定文件夹里的新建文件里,具体过程可参考[SDK固件开发](firmware.md)。
4 | WebIDE还提供微信二维码扫描,帮助用户使用微信接入的功能,具体详情可参考[微信支持](wechat-support.md)。
5 |
6 |
7 | ## WebIDE开发指南
8 |
9 | 进入[WebIDE](http://tisan.pandocloud.com)所在网址:
10 | 
11 |
12 | 1 注册用户:
13 | 
14 |
15 | 注册后会提示到注册邮箱激活:
16 | 
17 |
18 | 2 登陆账户:
19 | 
20 |
21 | 3 在工作区添加产品:
22 | 
23 |
24 | 4 获取产品Key,录入产品信息(产品名称、介绍),添加产品需要的组件,操作结束后保存:
25 | 
26 |
27 | 录入产品信息、介绍:
28 | 
29 |
30 | 添加产品需要的组件:
31 | 
32 |
33 | 添加完成后可直接浏览手机应用程序的界面:
34 | 
35 |
36 | 最后保存:
37 | 
38 |
39 |
--------------------------------------------------------------------------------
/public/codemirror/addon/lint/json-lint.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | // Depends on jsonlint.js from https://github.com/zaach/jsonlint
5 |
6 | // declare global: jsonlint
7 |
8 | (function(mod) {
9 | if (typeof exports == "object" && typeof module == "object") // CommonJS
10 | mod(require("../../lib/codemirror"));
11 | else if (typeof define == "function" && define.amd) // AMD
12 | define(["../../lib/codemirror"], mod);
13 | else // Plain browser env
14 | mod(CodeMirror);
15 | })(function(CodeMirror) {
16 | "use strict";
17 |
18 | CodeMirror.registerHelper("lint", "json", function(text) {
19 | var found = [];
20 | jsonlint.parseError = function(str, hash) {
21 | var loc = hash.loc;
22 | found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column),
23 | to: CodeMirror.Pos(loc.last_line - 1, loc.last_column),
24 | message: str});
25 | };
26 | try { jsonlint.parse(text); }
27 | catch(e) {}
28 | return found;
29 | });
30 |
31 | });
32 |
--------------------------------------------------------------------------------
/public/codemirror/addon/edit/trailingspace.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) {
13 | if (prev == CodeMirror.Init) prev = false;
14 | if (prev && !val)
15 | cm.removeOverlay("trailingspace");
16 | else if (!prev && val)
17 | cm.addOverlay({
18 | token: function(stream) {
19 | for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {}
20 | if (i > stream.pos) { stream.pos = i; return null; }
21 | stream.pos = l;
22 | return "trailingspace";
23 | },
24 | name: "trailingspace"
25 | });
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Tisan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/public/iotboard/iotboard.min.css:
--------------------------------------------------------------------------------
1 | body,html{min-height:100%}html{font-family:'Open Sans','Helvetica Neue'}.widget{background-color:#fff;border:1px solid #ccc;border-radius:4px;font-size:14px;margin-bottom:10px;position:relative;box-shadow:0 0 10px rgba(0,0,0,.1)}.widget .title{color:#fff;background-color:#61c0ec;height:30px;line-height:30px;text-align:center;font-size:1.1em}.clf{clear:both};html,a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:'';content:none}table{border-collapse:collapse;border-spacing:0}*{-webkit-tap-highlight-color:transparent}
--------------------------------------------------------------------------------
/source/widgets/led/led.widget.min.css:
--------------------------------------------------------------------------------
1 | .clf{clear:both}.widget[iotb-widget=led] .colorpicker{border-radius:5px;color:#FFF;font-size:12px;width:200px;margin:10px;float:left}.widget[iotb-widget=led] .picker{cursor:crosshair;border:0}.widget[iotb-widget=led] .controls{margin:10px}.widget[iotb-widget=led] .preview{float:right;margin:50px 10px}.widget[iotb-widget=led] .preview>div{margin-top:20px}.widget[iotb-widget=led] .controls>div{border:1px solid #2F2F2F;margin-bottom:5px;overflow:hidden;padding:5px}.widget[iotb-widget=led] .controls label{float:left}.widget[iotb-widget=led] .controls>div input{border:1px solid #2F2F2F;color:#DDD;float:right;font-size:10px;height:14px;margin-left:6px;text-align:center;text-transform:uppercase;width:150px}.widget[iotb-widget=led] .preview>div input{background-color:#CCC;width:10px;height:10px;text-align:center;border:0}.widget[iotb-widget=led] .btn{margin:0 10px;width:100px;height:30px;border-radius:5px;color:#fff;line-height:30px;text-align:center;font-weight:700}.widget[iotb-widget=led] .btn-refresh{float:left}.widget[iotb-widget=led] .btn-set{float:right}.widget[iotb-widget=led]{color:#000;padding:4px}.widget[iotb-widget=led] .text{margin-top:4px}
--------------------------------------------------------------------------------
/service/authcheck.js:
--------------------------------------------------------------------------------
1 | var Product = require('../models/mysql/product').Product;
2 | //登录输入数据合法性检测
3 | exports.loginCheck=function(username,password){
4 | var q=0;
5 | if(username.length>5&&username.length>50){
6 | q=1;
7 | } if(password.length<5||password.length>20){
8 | q=1;
9 | }
10 | //username是否是邮箱格式
11 | var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
12 | if(!filter.test(username)){
13 | q=1;
14 | }
15 | //password特殊字符验证
16 |
17 | if(/[^a-zA-Z0-9]/.test(password)){
18 | q=1;
19 | }
20 | //如果输入格式错误
21 | if(q){ return false};
22 |
23 | //去空格
24 | return {
25 | username:username.replace(/\s+/g,""),
26 | password:password.replace(/\s+/g,""),
27 | }
28 | }
29 | exports.productHandleCheck=function(req,id,callback){
30 | if(!req.session.user){
31 | callback(false);
32 | return;
33 | }
34 |
35 | Product.find({where:{product_id:id}}).then(function(result){
36 | if(!result){
37 | callback(false);
38 | return;
39 | }
40 | if(result.dataValues.user_id==req.session.user.id){
41 | callback(true);
42 | return;
43 | }else{
44 | callback(false);
45 | }
46 | })
47 | }
48 |
--------------------------------------------------------------------------------
/public/codemirror/mode/rust/test.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function() {
5 | var mode = CodeMirror.getMode({indentUnit: 4}, "rust");
6 | function MT(name) {test.mode(name, mode, Array.prototype.slice.call(arguments, 1));}
7 |
8 | MT('integer_test',
9 | '[number 123i32]',
10 | '[number 123u32]',
11 | '[number 123_u32]',
12 | '[number 0xff_u8]',
13 | '[number 0o70_i16]',
14 | '[number 0b1111_1111_1001_0000_i32]',
15 | '[number 0usize]');
16 |
17 | MT('float_test',
18 | '[number 123.0f64]',
19 | '[number 0.1f64]',
20 | '[number 0.1f32]',
21 | '[number 12E+99_f64]');
22 |
23 | MT('string-literals-test',
24 | '[string "foo"]',
25 | '[string r"foo"]',
26 | '[string "\\"foo\\""]',
27 | '[string r#""foo""#]',
28 | '[string "foo #\\"# bar"]',
29 | '[string r##"foo #"# bar"##]',
30 |
31 | '[string b"foo"]',
32 | '[string br"foo"]',
33 | '[string b"\\"foo\\""]',
34 | '[string br#""foo""#]',
35 | '[string br##"foo #" bar"##]',
36 |
37 | "[string-2 'h']",
38 | "[string-2 b'h']");
39 |
40 | })();
41 |
--------------------------------------------------------------------------------
/source/widgets/motor/motor.widget.js:
--------------------------------------------------------------------------------
1 | !function(){
2 | if (!window.iotboard){
3 | console.log("iotboard not initialized!");
4 | return;
5 | }
6 |
7 | var widgetName='motor';
8 | window.iotboard.defineWidget(widgetName, {
9 | status: {
10 | speed:'-'
11 | },
12 | render: function(dataset){
13 | var dataset=clone(dataset);
14 | dataset.status=this.status;
15 | return template('template-'+widgetName,dataset);
16 | },
17 | listeners: [
18 | {
19 | selector: ".motor-range",
20 | event: "change",
21 | behavior: "set"
22 | },{
23 | selector: ".btn-refresh",
24 | event: "click",
25 | behavior: "get"
26 | }
27 | ],
28 | parseStatus: function(dom){
29 | return {
30 | speed: dom.find(".motor-range").val()
31 | }
32 | },
33 | onRendered:function(dom){
34 | dom.find('.motor-range').on('input',function(){
35 | dom.find('.motor-speed').text($(this).val());
36 | });
37 | dom.find('.btn-reset').on('click',function(){
38 | dom.find('.motor-range').val(0);
39 | dom.find('.motor-speed').text(0);
40 | dom.find('.motor-range').change();
41 | });
42 | }
43 | });
44 | }();
45 |
--------------------------------------------------------------------------------
/public/css/page/account.css:
--------------------------------------------------------------------------------
1 | .avant-img{
2 | width150px;
3 | height:90%;
4 | max-height:150px;
5 | margin-bottom:10px;
6 | cursor:pointer;
7 | border-radius:100%;
8 | }
9 | .avant-img-box{
10 | border-radius:100%;
11 | margin-left:50px;
12 | }
13 | .avant-img-a{
14 | padding:0px;!important;
15 | margin-bottom:0px;!important;
16 | }
17 | .avant-img-title{
18 | display:none;
19 | top:60px;
20 | left:65px;
21 | font-size:24px;
22 | font-weight:bold;
23 | color:#337ab7;
24 | position:absolute;
25 | cursor:pointer;
26 | }
27 | .form-center{
28 | width:180px;
29 | }
30 | .bs-example{
31 | position:relative;
32 | padding:45px 15px 15px;
33 | margin:0 -15px 15px;
34 | border-color:#e5e5e5;
35 | border-style:solid;
36 | border-width:1px;
37 | border-radius:5px;
38 | -webkit-box-shadow:inset 0 3px 6px rgba(0,0,0,.05);
39 | box-shadow:inset 0 3px 6px rgba(0,0,0,.05)
40 | }
41 | .remarks-title{
42 | line-height:33px;
43 | color:#777;
44 | font-size:80%;
45 | }
46 | #user-face{
47 | background: #ccc;
48 | width: 300px;
49 | height: 300px;
50 | border-radius: 150px;
51 | display: inline-block;
52 | }
53 | .head-portrait-warp{
54 | width:400px;
55 | }
56 | .upload-avant-cancle{
57 | background-color:#d9534f;
58 | }
59 |
--------------------------------------------------------------------------------
/public/css/page/iphone.css:
--------------------------------------------------------------------------------
1 | .iphone {
2 | background: #aaa;
3 | border-radius: 40px;
4 | font-family: Helvetica, Arial, sans-serif;
5 | font-size: 14px;
6 | font-weight: 100;
7 | -webkit-transform-origin-y:0;
8 | -webkit-transform:scale(0.8);
9 | height: 666px;
10 | margin: auto;
11 | max-width: 350px;
12 | padding: 80px 15px;
13 | position: relative;
14 | }
15 | .iphone:before {
16 | background: rgba(0,0,0,0.35);
17 | border-radius: 4px;
18 | content: " ";
19 | height: 8px;
20 | left: 50%;
21 | margin-left: -30px;
22 | position: absolute;
23 | top: 45px;
24 | width: 60px;
25 | z-index: 99;
26 | }
27 | .iphone:after {
28 | background: rgba(0,0,0,0.35);
29 | border: 4px solid rgba(255,255,255,0.6);
30 | border-radius: 50%;
31 | bottom: 11px;
32 | content: " ";
33 | height: 50px;
34 | left: 50%;
35 | margin-left: -29px;
36 | position: absolute;
37 | width: 50px;
38 | z-index: 99;
39 | }
40 | .screen {
41 | background: #fff;
42 | border-radius: 2px;
43 | width:320px;
44 | height: 100%;
45 | overflow: auto;
46 | position: relative;
47 | z-index: 1;
48 | }
49 | .screen:after {
50 | clear: both;
51 | content: " ";
52 | display: table;
53 | }
54 | * {
55 | * box-sizing: border-box;
56 | * }
57 |
--------------------------------------------------------------------------------
/source/css/reset.css:
--------------------------------------------------------------------------------
1 | html, body, div, span, applet, object, iframe,
2 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
3 | a, abbr, acronym, address, big, cite, code,
4 | del, dfn, em, img, ins, kbd, q, s, samp,
5 | small, strike, strong, sub, sup, tt, var,
6 | b, u, i, center,
7 | dl, dt, dd, ol, ul, li,
8 | fieldset, form, label, legend,
9 | table, caption, tbody, tfoot, thead, tr, th, td,
10 | article, aside, canvas, details, embed,
11 | figure, figcaption, footer, header, hgroup,
12 | menu, nav, output, ruby, section, summary,
13 | time, mark, audio, video {
14 | margin: 0;
15 | padding: 0;
16 | border: 0;
17 | font-size: 100%;
18 | font: inherit;
19 | vertical-align: baseline;
20 | }
21 | /* HTML5 display-role reset for older browsers */
22 | article, aside, details, figcaption, figure,
23 | footer, header, hgroup, menu, nav, section {
24 | display: block;
25 | }
26 | body {
27 | line-height: 1;
28 | }
29 | ol, ul {
30 | list-style: none;
31 | }
32 | blockquote, q {
33 | quotes: none;
34 | }
35 | blockquote:before, blockquote:after,
36 | q:before, q:after {
37 | content: '';
38 | content: none;
39 | }
40 | table {
41 | border-collapse: collapse;
42 | border-spacing: 0;
43 | }
44 |
45 | *{
46 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
47 | }
--------------------------------------------------------------------------------
/public/css/page/login.css:
--------------------------------------------------------------------------------
1 | textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input {
2 | border: 2px solid #dce4ec;
3 | color: #34495e;
4 | font-family: "Lato", sans-serif;
5 | font-size: 14px;
6 | padding: 8px 0 9px 10px;
7 | text-indent: 1px;
8 | -webkit-border-radius: 6px;
9 | -moz-border-radius: 6px;
10 | border-radius: 6px;
11 | -webkit-box-shadow: none;
12 | -moz-box-shadow: none;
13 | box-shadow: none;
14 | }
15 | .login-screen {
16 | background-color: #1abc9c;
17 | min-height: 317px;
18 | padding: 123px 199px 33px 306px;
19 | }
20 | .login-form {
21 | background-color: #eceff1;
22 | border-radius: 6px;
23 | padding: 24px 23px 20px;
24 | position: relative;
25 | }
26 | .login-form .control-group {
27 | margin-bottom: 6px;
28 | position: relative;
29 | }
30 | .margintop{
31 | margin-top:100px;
32 | }
33 | .form-control-lg{
34 | height:50px; !important
35 | }
36 | .marginup{
37 | margin-top:40px;
38 | }
39 | .login-btn{
40 | widht:80%;
41 | }
42 | .wrong-tag{
43 | margin-left:0px;
44 | }
45 |
--------------------------------------------------------------------------------
/views/document/interface.md:
--------------------------------------------------------------------------------
1 | #WebIDE开发指南
2 | WebIDE的介绍
3 |
4 | ## WebIDE
5 | 进入[WebIDE](http://tisan.pandocloud.com)所在网址
6 |
7 |
8 |
9 | 1 注册用户
10 |
11 |
12 |
13 | 注册后会提示到注册邮箱激活
14 |
15 | ----
16 |
17 | ----
18 | 2 登陆账户
19 |
20 | 3 在工作区添加产品
21 |
22 | 4 获取产品Key,录入产品信息(产品名称、介绍),添加产品需要的组件,操作结束后保存。
23 |
24 | 录入产品信息、介绍
25 |
26 | 添加产品需要的组件
27 |
28 | 添加完成后可直接浏览手机应用程序的界面
29 |
30 | 最后保存:
31 |
32 |
33 |
--------------------------------------------------------------------------------
/public/codemirror/addon/lint/css-lint.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | // Depends on csslint.js from https://github.com/stubbornella/csslint
5 |
6 | // declare global: CSSLint
7 |
8 | (function(mod) {
9 | if (typeof exports == "object" && typeof module == "object") // CommonJS
10 | mod(require("../../lib/codemirror"));
11 | else if (typeof define == "function" && define.amd) // AMD
12 | define(["../../lib/codemirror"], mod);
13 | else // Plain browser env
14 | mod(CodeMirror);
15 | })(function(CodeMirror) {
16 | "use strict";
17 |
18 | CodeMirror.registerHelper("lint", "css", function(text) {
19 | var found = [];
20 | if (!window.CSSLint) return found;
21 | var results = CSSLint.verify(text), messages = results.messages, message = null;
22 | for ( var i = 0; i < messages.length; i++) {
23 | message = messages[i];
24 | var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col;
25 | found.push({
26 | from: CodeMirror.Pos(startLine, startCol),
27 | to: CodeMirror.Pos(endLine, endCol),
28 | message: message.message,
29 | severity : message.type
30 | });
31 | }
32 | return found;
33 | });
34 |
35 | });
36 |
--------------------------------------------------------------------------------
/routes/workspace.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 | var grpc = require('../service/grpc');
4 | var Product = require('../models/mysql/product').Product; var Objects = require('../models/mysql/object').Objects;
5 | var authCheck = require('../service/authcheck');
6 | router.use(auth);
7 |
8 | router.get('/', function(req, res) {
9 | Product.findAll({where:{user_id:req.session.user.id}}).then(function(result){
10 | var p=[];
11 | for(var i in result){
12 | p.push(result[i].product_id);
13 | }
14 | grpc.readProduct(p,function(result){
15 | if(!result){
16 | result['products']="";
17 | }
18 | console.log(result);
19 | var data=[];
20 | for(var i in result.products){
21 | var tmp=result.products[i];
22 | data.push({
23 | avatar:tmp.icon,
24 | descript:tmp.description,
25 | name:tmp.name,
26 | id:tmp.id
27 | })
28 | }
29 | res.render('workspace', {
30 | user: req.session.user,
31 | navigation:'workspace',
32 | product:data
33 | });
34 | })
35 | })
36 | });
37 |
38 |
39 | function auth(req,res,next){
40 | if(!req.session.user){
41 | res.redirect('/user/login');
42 | }
43 | next();
44 | }
45 | module.exports = router;
46 |
--------------------------------------------------------------------------------
/views/document/wechat-support.md:
--------------------------------------------------------------------------------
1 | # 微信支持
2 | 本文档说明如何通过关注freeiot公众号对硬件进行联网控制。
3 |
4 | ## 具体步骤
5 |
6 | 1. 关注freeiot微信公众账号;
7 | 搜索微信公众号:freeiot
8 | 
9 | 点击FreeIOT,并关注:
10 | 
11 |
12 | 2. 如果设备还没有连上网,需要对设备进行wifi联网配置;如果设备已经联上网了,直接进行第三步即可。长按配置键3秒,核心板上的绿色灯快速闪烁,表示设备进入wifi联网配置状态,微信公众号这边点击“添加设备”——>“WiFi配置”——>“开始配置”——>输入wifi账号密码——>配置中——>配置结束。示例图如下。
13 | 在菜单选择“WiFi配置”:
14 | 
15 | 点击“开始配置”:
16 | 
17 | 输入wifi账号密码:
18 | 
19 | 联网配置中:
20 | 
21 | 配置结束:
22 | 
23 |
24 |
25 | 3. 点击WebIDE手机图形界面下面的二维码按钮,点击公众号菜单中的扫描设备扫描二维码。如果设备的MAC地址还没有录入,WebIDE会提示录入MAC地址。具体过程如下:
26 | 点击WebIDE下面的二维码按钮:
27 | 
28 | 如果没有录入设备的MAC地址,请录入MAC地址,设备的MAC地址可由烧写软件得出:
29 | 
30 | 再点击二维码按钮,即可出现生成的二维码图片:
31 | 
32 | 在微信公众号里点击“添加设备”,再点击“扫描二维码”的选项:
33 | 
34 | 扫描二维码图片:
35 | 
36 | 添加设备成功,在“我的设备”里面会新增刚添加进来的设备,名称与WebIDE里面创建的产品名称相同:
37 | 
38 |
39 | 4. 如果添加成功,便可以在我的设备菜单找到设备,进行控制测试。
40 | 在“我的设备”里面找到要控制的设备,点击进入控制界面:
41 | 
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/source/widgets/default/default.widget.js:
--------------------------------------------------------------------------------
1 | !function(){
2 | if (!window.iotboard){
3 | console.log("iotboard not initialized!");
4 | return;
5 | }
6 |
7 | var widgetName='default';
8 | window.iotboard.defineWidget(widgetName, {
9 | status: {
10 | 'loading':''
11 | },
12 | render: function(dataset){
13 | console.log(dataset);
14 | var id=dataset.id;
15 | var no=dataset.no;
16 |
17 | var w;
18 | for(var i in addedWidgets.objects){
19 | if(addedWidgets.objects[i].id==id&&addedWidgets.objects[i].no==no){
20 | w=clone(addedWidgets.objects[i]);
21 | break;
22 | }
23 | }
24 | for(i in dataset.status){
25 | w.status[i]=dataset.status[i];
26 | }
27 | console.log(w);
28 | return template('template-'+widgetName,w);
29 | },
30 | listeners: [
31 | {
32 | selector: ".btn-set",
33 | event: "click",
34 | behavior: "set"
35 | },
36 | {
37 | selector: ".btn-refresh",
38 | event: "click",
39 | behavior: "get"
40 | }
41 | ],
42 | parseStatus: function(dom){
43 | var res={
44 | };
45 | dom.find('.default-status-wrap').each(function(){
46 | res[$(this).find('.default-status-name').text()+'']=$(this).find('.default-status-input').val();
47 | });
48 | return res;
49 | },
50 | });
51 | }();
52 |
--------------------------------------------------------------------------------
/public/codemirror/mode/diff/diff.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | CodeMirror.defineMode("diff", function() {
15 |
16 | var TOKEN_NAMES = {
17 | '+': 'positive',
18 | '-': 'negative',
19 | '@': 'meta'
20 | };
21 |
22 | return {
23 | token: function(stream) {
24 | var tw_pos = stream.string.search(/[\t ]+?$/);
25 |
26 | if (!stream.sol() || tw_pos === 0) {
27 | stream.skipToEnd();
28 | return ("error " + (
29 | TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, '');
30 | }
31 |
32 | var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd();
33 |
34 | if (tw_pos === -1) {
35 | stream.skipToEnd();
36 | } else {
37 | stream.pos = tw_pos;
38 | }
39 |
40 | return token_name;
41 | }
42 | };
43 | });
44 |
45 | CodeMirror.defineMIME("text/x-diff", "diff");
46 |
47 | });
48 |
--------------------------------------------------------------------------------
/views/document/quick-start.md:
--------------------------------------------------------------------------------
1 | # Tisan快速体验
2 |
3 | ## 体验Tisan
4 | 首次拿到Tisan开发板,默认已经烧录三色灯的固件,可以立马体验!注意请在WiFi环境中体验,因为需要WiFi的SSID和密码。
5 |
6 | FreeIOT与设备之间通过smartconfig进行配置。FreeIOT是Tisan的在移动端的通用App,自由免费的,同时开源,有兴趣的开发者可在github下载[安卓版](https://github.com/PandoCloud/freeiot-android)或[IOS版](https://github.com/PandoCloud/freeiot-ios)的源码进行参考研究。
7 | 首先下载FreeIOT。
8 | - [安卓版下载地址](http://shouji.baidu.com/software/item?docid=7996553&from=as&qq-pf-to=pcqq.discussion)。
9 | - IOS版请在appstore里面搜索最新版本的FreeIOT,并下载安装。
10 |
11 |
12 |
13 | 下面以安卓为例,介绍App与设备之间的操作流程:
14 | 1. 安装**FreeIOT**
15 | 
16 |
17 | 2. 启动FreeIOT,如果没有账户,先注册用户,再登陆。
18 | 注册用户:
19 | 
20 | 用户登陆:
21 | 
22 | 第一次进入的时候可以看到列表是空的:
23 | 
24 |
25 | 3. 长按Tisan开发板的配置键3秒,LED快闪,表示设备进入配置模式
26 | 
27 |
28 | 4. 点击FreeIOT右上角的“添加”键,输入能够联网的WiFi以及密码,输完后点击“确定”,静等5到10秒,配置成功后会返回设备列表界面,配置结束时LED灭;
29 | 
30 |
31 | 5. 如果没配成功,可重复操作步骤3和步骤4;
32 | 6. 配置成功后,往下拉一下,刷新设备列表,找到刚配置成功的设备,点击进去,就进入操作该设备的主界面!用户可进行设备状态查询、远程控制等功能。
33 |
34 | 
35 | 点击进去可以看到如下控制界面:
36 | 
37 |
38 | ## 更多体验
39 | 更多体验可参考[示例说明](demo.md),可直接烧写程序进行其他项目的体验!
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/views/template/thermohygrometer.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
35 |
--------------------------------------------------------------------------------
/public/codemirror/addon/tern/worker.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | // declare global: tern, server
5 |
6 | var server;
7 |
8 | this.onmessage = function(e) {
9 | var data = e.data;
10 | switch (data.type) {
11 | case "init": return startServer(data.defs, data.plugins, data.scripts);
12 | case "add": return server.addFile(data.name, data.text);
13 | case "del": return server.delFile(data.name);
14 | case "req": return server.request(data.body, function(err, reqData) {
15 | postMessage({id: data.id, body: reqData, err: err && String(err)});
16 | });
17 | case "getFile":
18 | var c = pending[data.id];
19 | delete pending[data.id];
20 | return c(data.err, data.text);
21 | default: throw new Error("Unknown message type: " + data.type);
22 | }
23 | };
24 |
25 | var nextId = 0, pending = {};
26 | function getFile(file, c) {
27 | postMessage({type: "getFile", name: file, id: ++nextId});
28 | pending[nextId] = c;
29 | }
30 |
31 | function startServer(defs, plugins, scripts) {
32 | if (scripts) importScripts.apply(null, scripts);
33 |
34 | server = new tern.Server({
35 | getFile: getFile,
36 | async: true,
37 | defs: defs,
38 | plugins: plugins
39 | });
40 | }
41 |
42 | this.console = {
43 | log: function(v) { postMessage({type: "debug", message: v}); }
44 | };
45 |
--------------------------------------------------------------------------------
/views/template/led.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
34 |
--------------------------------------------------------------------------------
/public/codemirror/addon/lint/coffeescript-lint.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | // Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js
5 |
6 | // declare global: coffeelint
7 |
8 | (function(mod) {
9 | if (typeof exports == "object" && typeof module == "object") // CommonJS
10 | mod(require("../../lib/codemirror"));
11 | else if (typeof define == "function" && define.amd) // AMD
12 | define(["../../lib/codemirror"], mod);
13 | else // Plain browser env
14 | mod(CodeMirror);
15 | })(function(CodeMirror) {
16 | "use strict";
17 |
18 | CodeMirror.registerHelper("lint", "coffeescript", function(text) {
19 | var found = [];
20 | var parseError = function(err) {
21 | var loc = err.lineNumber;
22 | found.push({from: CodeMirror.Pos(loc-1, 0),
23 | to: CodeMirror.Pos(loc, 0),
24 | severity: err.level,
25 | message: err.message});
26 | };
27 | try {
28 | var res = coffeelint.lint(text);
29 | for(var i = 0; i < res.length; i++) {
30 | parseError(res[i]);
31 | }
32 | } catch(e) {
33 | found.push({from: CodeMirror.Pos(e.location.first_line, 0),
34 | to: CodeMirror.Pos(e.location.last_line, e.location.last_column),
35 | severity: 'error',
36 | message: e.message});
37 | }
38 | return found;
39 | });
40 |
41 | });
42 |
--------------------------------------------------------------------------------
/public/codemirror/mode/mscgen/index_msgenny.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CodeMirror: msgenny mode
6 |
7 |
8 |
9 |
10 |
11 |
12 | CodeMirror: msgenny mode
13 |
14 |
34 |
35 |
41 |
42 | MIME types defined: text/x-msgenny
43 |
44 |
45 |
--------------------------------------------------------------------------------
/public/codemirror/addon/runmode/colorize.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"), require("./runmode"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror", "./runmode"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/;
15 |
16 | function textContent(node, out) {
17 | if (node.nodeType == 3) return out.push(node.nodeValue);
18 | for (var ch = node.firstChild; ch; ch = ch.nextSibling) {
19 | textContent(ch, out);
20 | if (isBlock.test(node.nodeType)) out.push("\n");
21 | }
22 | }
23 |
24 | CodeMirror.colorize = function(collection, defaultMode) {
25 | if (!collection) collection = document.body.getElementsByTagName("pre");
26 |
27 | for (var i = 0; i < collection.length; ++i) {
28 | var node = collection[i];
29 | var mode = node.getAttribute("data-lang") || defaultMode;
30 | if (!mode) continue;
31 |
32 | var text = [];
33 | textContent(node, text);
34 | node.innerHTML = "";
35 | CodeMirror.runMode(text.join(""), mode, node);
36 |
37 | node.className += " cm-s-default";
38 | }
39 | };
40 | });
41 |
--------------------------------------------------------------------------------
/public/codemirror/mode/asciiarmor/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: ASCII Armor (PGP) mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | ASCII Armor (PGP) mode
27 |
36 |
37 |
42 |
43 | MIME types
44 | defined: application/pgp, application/pgp-keys, application/pgp-signature
45 |
46 |
47 |
--------------------------------------------------------------------------------
/views/download_chrome.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Tisan - 404
10 |
11 |
12 |
18 |
19 |
20 |
21 |
22 | 抱歉您的浏览器不支持Tisan-ide,请下载最新webkit内核浏览器
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/source/widgets/atmosphere/air.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
16 |
--------------------------------------------------------------------------------
/public/codemirror/mode/htmlembedded/htmlembedded.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
7 | require("../../addon/mode/multiplex"));
8 | else if (typeof define == "function" && define.amd) // AMD
9 | define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
10 | "../../addon/mode/multiplex"], mod);
11 | else // Plain browser env
12 | mod(CodeMirror);
13 | })(function(CodeMirror) {
14 | "use strict";
15 |
16 | CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
17 | return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), {
18 | open: parserConfig.open || parserConfig.scriptStartRegex || "<%",
19 | close: parserConfig.close || parserConfig.scriptEndRegex || "%>",
20 | mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec)
21 | });
22 | }, "htmlmixed");
23 |
24 | CodeMirror.defineMIME("application/x-ejs", {name: "htmlembedded", scriptingModeSpec:"javascript"});
25 | CodeMirror.defineMIME("application/x-aspx", {name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
26 | CodeMirror.defineMIME("application/x-jsp", {name: "htmlembedded", scriptingModeSpec:"text/x-java"});
27 | CodeMirror.defineMIME("application/x-erb", {name: "htmlembedded", scriptingModeSpec:"ruby"});
28 | });
29 |
--------------------------------------------------------------------------------
/public/codemirror/mode/ntriples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: NTriples mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
28 |
29 |
30 | NTriples mode
31 |
40 |
41 |
44 | MIME types defined: text/n-triples.
45 |
46 |
--------------------------------------------------------------------------------
/public/codemirror/mode/twig/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Twig mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Twig mode
27 |
40 |
45 |
46 |
--------------------------------------------------------------------------------
/public/codemirror/mode/spreadsheet/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Spreadsheet mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
25 |
26 |
27 | Spreadsheet mode
28 |
29 |
30 |
37 |
38 | MIME types defined: text/x-spreadsheet.
39 |
40 | The Spreadsheet Mode
41 | Created by Robert Plummer
42 |
43 |
--------------------------------------------------------------------------------
/public/codemirror/mode/http/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: HTTP mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | HTTP mode
27 |
28 |
29 |
39 |
40 |
43 |
44 | MIME types defined: message/http.
45 |
46 |
--------------------------------------------------------------------------------
/views/document/demo.md:
--------------------------------------------------------------------------------
1 | # 示例项目
2 | 如果还不想编写代码,可直接烧写程序进行快速体验所有示例项目!直接下载示例项目所有的[默认固件](http://pan.baidu.com/s/1nttObVj),具体烧录方法可参考[开发环境](environment.md)关于固件烧录的方法说明,记得每个示例项目所需要的跳帽连接,具体可参考下面的图。
3 | 在使用板子之前,请注意核心板插在底板上的方向,如下图所示:
4 | 
5 |
6 | ### 1.RGB三色灯例子
7 | 用跳帽短接三色灯和模块GPIO:BLED连GPIO13,RlED连GPIO14,GLED连GPIO15,如下图:
8 | 
9 | 在user_main文件中添加文件引用:
10 | ```c
11 | #include "objects/led.h"
12 | ```
13 | 在user_main文件的user_init函数中添加以下代码:
14 | ```c
15 | led_object_init();
16 | ```
17 | ### 2.电机的例子
18 | 用跳帽短接电机驱动和模块GPIO:IA连GPIO13,IB连GPIO12,如下图:
19 | 
20 | 在user_main文件中添加文件引用:
21 | ```c
22 | #include "objects/motor.h"
23 | ```
24 | 在user_main文件的user_init函数中添加以下代码:
25 | ```c
26 | motor_object_init();
27 | ```
28 | ### 3.温度的例子
29 | 用跳帽短接DHT11和模块GPIO:DHT连GPIO12,如下图:
30 | 
31 | 在user_main文件中添加文件引用:
32 | ```c
33 | #include "objects/temperature.h"
34 | ```
35 | 在user_main文件的user_init函数中添加以下代码:
36 | ```c
37 | temperature_object_init();
38 | ```
39 | ### 4.湿度的例子
40 | 用跳帽短接DHT11和模块GOIO:DHT连GPIO12,同温度的例子
41 | 在user_main文件中添加文件引用:
42 | ```c
43 | #include "objects/humiture.h"
44 | ```
45 | 在user_main文件的user_init函数中添加以下代码:
46 | ```c
47 | humiture_object_init();
48 | ```
49 | ### 5.继电器的例子
50 | 用跳帽短接继电器和模块GPIO:JDQ连GPIO12,如下图:
51 | 
52 | 在user_main文件中添加文件引用:
53 | ```c
54 | #include "objects/jdq.h"
55 | ```
56 | 在user_main文件的user_init函数中添加以下代码:
57 | ```c
58 | jdq_object_init();
59 | ```
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/public/codemirror/mode/clike/test.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function() {
5 | var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-c");
6 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
7 |
8 | MT("indent",
9 | "[variable-3 void] [def foo]([variable-3 void*] [variable a], [variable-3 int] [variable b]) {",
10 | " [variable-3 int] [variable c] [operator =] [variable b] [operator +]",
11 | " [number 1];",
12 | " [keyword return] [operator *][variable a];",
13 | "}");
14 |
15 | MT("indent_switch",
16 | "[keyword switch] ([variable x]) {",
17 | " [keyword case] [number 10]:",
18 | " [keyword return] [number 20];",
19 | " [keyword default]:",
20 | " [variable printf]([string \"foo %c\"], [variable x]);",
21 | "}");
22 |
23 | MT("def",
24 | "[variable-3 void] [def foo]() {}",
25 | "[keyword struct] [def bar]{}",
26 | "[variable-3 int] [variable-3 *][def baz]() {}");
27 |
28 | MT("double_block",
29 | "[keyword for] (;;)",
30 | " [keyword for] (;;)",
31 | " [variable x][operator ++];",
32 | "[keyword return];");
33 |
34 | var mode_cpp = CodeMirror.getMode({indentUnit: 2}, "text/x-c++src");
35 | function MTCPP(name) { test.mode(name, mode_cpp, Array.prototype.slice.call(arguments, 1)); }
36 |
37 | MTCPP("cpp14_literal",
38 | "[number 10'000];",
39 | "[number 0b10'000];",
40 | "[number 0x10'000];",
41 | "[string '100000'];");
42 | })();
43 |
--------------------------------------------------------------------------------
/public/codemirror/mode/solr/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Solr mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
20 |
33 |
34 |
35 | Solr mode
36 |
37 |
38 |
47 |
48 |
49 |
55 |
56 | MIME types defined: text/x-solr.
57 |
58 |
--------------------------------------------------------------------------------
/source/widgets/led/led.widget.min.js:
--------------------------------------------------------------------------------
1 | /*! iot-board 2015-09-13 */
2 | !function(){return window.iotboard?(window.iotboard.defineWidget("led",{status:{red:255,green:255,blue:255,freq:100,white:100},render:function(a){var a=clone(a);return a.status=this.status,template("template-led",a)},listeners:[{selector:".btn-refresh",event:"click",behavior:"get"},{selector:".btn-set",event:"click",behavior:"set"}],parseStatus:function(a){return{red:parseInt(a.find(".rVal").val()),green:parseInt(a.find(".gVal").val()),blue:parseInt(a.find(".bVal").val()),freq:parseInt(a.find(".freqVal").text()),white:parseInt(a.find(".wVal").text())}},onRendered:function(a){console.log("on widget rendered."),a.find(".picker").each(function(){var a=this.getContext("2d"),b=new Image;b.onload=function(){console.log("color picker loaded..."),a.drawImage(b,0,0)};var c="/iotboard/dist/widgets/led/colorwheel.png";b.src=c}),a.find(".picker").on("click",function(a){var b=$(this).closest(".widget"),c=this.getContext("2d"),d=$(this).offset(),e=Math.floor(a.pageX-d.left),f=Math.floor(a.pageY-d.top),g=c.getImageData(e,f,1,1),h=g.data;b.find(".rPrev").css("background-color","#"+h[0].toString(16)+"0000"),b.find(".gPrev").css("background-color","#00"+h[1].toString(16)+"00"),b.find(".bPrev").css("background-color","#0000"+h[2].toString(16)),b.find(".rVal").val(h[0]),b.find(".gVal").val(h[1]),b.find(".bVal").val(h[2])}),a.find(".freqCtrl").change(function(){$(this).closest(".controls").find(".freqVal").text($(this).val())}),a.find(".wCtrl").change(function(){$(this).closest(".controls").find(".wVal").text($(this).val())})}}),void console.log("add widget {led}")):void console.log("iotboard not initialized!")}();
3 |
--------------------------------------------------------------------------------
/public/codemirror/mode/ecl/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: ECL mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | ECL mode
27 |
45 |
48 |
49 | Based on CodeMirror's clike mode. For more information see HPCC Systems web site.
50 | MIME types defined: text/x-ecl.
51 |
52 |
53 |
--------------------------------------------------------------------------------
/public/codemirror/mode/z80/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Z80 assembly mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Z80 assembly mode
27 |
28 |
29 |
45 |
46 |
51 |
52 | MIME types defined: text/x-z80, text/x-ez80.
53 |
54 |
--------------------------------------------------------------------------------
/source/widgets/led/led.template:
--------------------------------------------------------------------------------
1 | <#if(title){#>
2 | <#=title#>
3 | <#}#>
4 |
5 |
6 |
7 |
21 |
22 |
23 |
"/>
24 |
"/>
25 |
"/>
26 |
27 |
28 | "/>
29 |
30 |
31 |
32 | "/>
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/public/js/page/product.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | var avantPlay={
3 | block:function(){
4 | $('.avant-img-title').css({display:'block'});
5 | $('.avant-img').css({opacity:0.4});
6 | },
7 | none:function(result){
8 | if(result==''){
9 | $('.avant-img-title').css({display:'none'});
10 | $('.avant-img').css({opacity:1});
11 | return;
12 | }
13 | if(result.toElement.className!='avant-img-title'){
14 | $('.avant-img-title').css({display:'none'});
15 | $('.avant-img').css({opacity:1});
16 | }
17 | }
18 | }
19 | $('.avant-img').mouseenter(function(){
20 | avantPlay.block();
21 | })
22 |
23 | $('.avant-img').mouseout(function(result){
24 | avantPlay.none(result);
25 | })
26 | $('.avant-img').click(function(result){
27 | $('.cutting-avant-fix-btn').click();
28 | })
29 | $('.avant-img-title').on('click',function(){
30 | $('.cutting-avant-fix-btn').click();
31 | })
32 | $('.avant-img-title,.avant-img').on('click',function(){
33 | $('.cutting-avant-fix-box').css({'display':'block'})
34 | })
35 |
36 | $('.save-btn').on('click',function(){
37 | var tmp={
38 | productName:$('.name-input').val(),
39 | productDescript:$('.descript-input').val()
40 | }
41 |
42 | $.ajax({
43 | url:'/workspace/product/info',
44 | type:'POST',
45 | data:tmp,
46 | success:function(result){
47 | console.log(result);
48 | }
49 | })
50 | })
51 | })()
52 |
53 |
54 |
--------------------------------------------------------------------------------
/public/codemirror/mode/oz/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Oz mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
26 |
27 |
28 | Oz mode
29 |
50 | MIME type defined: text/x-oz.
51 |
52 |
59 |
60 |
--------------------------------------------------------------------------------
/views/commercial.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 | Tisan不支持您使用的浏览器,建议使用最新Chrome浏览器
15 |
16 | <%include navigation.ejs%>
17 |
18 |

19 |
Tisan服务仅适用于个人开发者和企业Demo应用,如需商用请联系:
24 | qq:1034579387 e-mail:wusiwei@pandocloud.com
25 |
26 |
27 |
28 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/views/iot.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IOT Board
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | <% if(from=='ide') { %>
22 |
23 | <% } else {%>
24 |
25 | <% } %>
26 |
27 |
28 |
29 | <% if( config.objects ) {
30 | for(var i=0; i
34 |
35 | <% } else {%>
36 |
37 | <% }%>
38 | <% } %>
39 | <% } %>
40 |
41 |
42 |
--------------------------------------------------------------------------------
/public/codemirror/addon/scroll/simplescrollbars.css:
--------------------------------------------------------------------------------
1 | .CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div {
2 | position: absolute;
3 | background: #ccc;
4 | -moz-box-sizing: border-box;
5 | box-sizing: border-box;
6 | border: 1px solid #bbb;
7 | border-radius: 2px;
8 | }
9 |
10 | .CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical {
11 | position: absolute;
12 | z-index: 6;
13 | background: #eee;
14 | }
15 |
16 | .CodeMirror-simplescroll-horizontal {
17 | bottom: 0; left: 0;
18 | height: 8px;
19 | }
20 | .CodeMirror-simplescroll-horizontal div {
21 | bottom: 0;
22 | height: 100%;
23 | }
24 |
25 | .CodeMirror-simplescroll-vertical {
26 | right: 0; top: 0;
27 | width: 8px;
28 | }
29 | .CodeMirror-simplescroll-vertical div {
30 | right: 0;
31 | width: 100%;
32 | }
33 |
34 |
35 | .CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler {
36 | display: none;
37 | }
38 |
39 | .CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div {
40 | position: absolute;
41 | background: #bcd;
42 | border-radius: 3px;
43 | }
44 |
45 | .CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical {
46 | position: absolute;
47 | z-index: 6;
48 | }
49 |
50 | .CodeMirror-overlayscroll-horizontal {
51 | bottom: 0; left: 0;
52 | height: 6px;
53 | }
54 | .CodeMirror-overlayscroll-horizontal div {
55 | bottom: 0;
56 | height: 100%;
57 | }
58 |
59 | .CodeMirror-overlayscroll-vertical {
60 | right: 0; top: 0;
61 | width: 6px;
62 | }
63 | .CodeMirror-overlayscroll-vertical div {
64 | right: 0;
65 | width: 100%;
66 | }
67 |
--------------------------------------------------------------------------------
/source/widgets/atmosphere/atmosphere.widget.css:
--------------------------------------------------------------------------------
1 | .widget[iotb-widget="atmosphere"] {
2 | color: #fff;
3 | padding: 4px;
4 | background-color: #fff;
5 | background-color: transparent;
6 | border: none;
7 | opacity: 1;
8 | padding-top: 30%;
9 | font-family: 'Arial Narrow';
10 | }
11 |
12 | .widget[iotb-widget="atmosphere"] .temperature {
13 | font-weight: bold;
14 | text-align: center;
15 | font-size: 30px;
16 | width: 200px;
17 | height: 200px;
18 | margin: auto;
19 | line-height: 200px;
20 | border: 2px solid #ccc;
21 | border-radius: 100px;
22 | box-shadow: 1px 1px 1px #888;
23 | }
24 |
25 | .widget[iotb-widget="atmosphere"] .temperature-val {
26 | font-size: 60px;
27 | }
28 |
29 | .widget[iotb-widget="atmosphere"] .humidity {
30 | margin-top: 30px;
31 | text-align: center;
32 | width: 45%;
33 | display: inline-block;
34 | }
35 |
36 | .widget[iotb-widget="atmosphere"] .humidity-icon {
37 | background:url(water.svg);
38 | background-repeat: no-repeat;
39 | width: 20px;
40 | height: 20px;
41 | display: inline-block;
42 | margin-right: 10px;
43 | }
44 |
45 | .widget[iotb-widget="atmosphere"] .humidity-val {
46 | font-size: 30px;
47 | }
48 |
49 | .widget[iotb-widget="atmosphere"] .pm25 {
50 | margin-top: 30px;
51 | text-align: center;
52 | width: 45%;
53 | margin-left: 10%;
54 | display: inline-block;
55 | }
56 |
57 | .widget[iotb-widget="atmosphere"] .pm25-val {
58 | font-size: 30px;
59 | }
60 |
61 | .widget[iotb-widget="atmosphere"] .pm25-icon {
62 | background:url(air.svg);
63 | background-repeat: no-repeat;
64 | width: 20px;
65 | height: 20px;
66 | display: inline-block;
67 | margin-right: 10px;
68 | }
--------------------------------------------------------------------------------
/public/codemirror/addon/display/fullscreen.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | CodeMirror.defineOption("fullScreen", false, function(cm, val, old) {
15 | if (old == CodeMirror.Init) old = false;
16 | if (!old == !val) return;
17 | if (val) setFullscreen(cm);
18 | else setNormal(cm);
19 | });
20 |
21 | function setFullscreen(cm) {
22 | var wrap = cm.getWrapperElement();
23 | cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
24 | width: wrap.style.width, height: wrap.style.height};
25 | wrap.style.width = "";
26 | wrap.style.height = "auto";
27 | wrap.className += " CodeMirror-fullscreen";
28 | document.documentElement.style.overflow = "hidden";
29 | cm.refresh();
30 | }
31 |
32 | function setNormal(cm) {
33 | var wrap = cm.getWrapperElement();
34 | wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, "");
35 | document.documentElement.style.overflow = "";
36 | var info = cm.state.fullScreenRestore;
37 | wrap.style.width = info.width; wrap.style.height = info.height;
38 | window.scrollTo(info.scrollLeft, info.scrollTop);
39 | cm.refresh();
40 | }
41 | });
42 |
--------------------------------------------------------------------------------
/routes/index.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 | var Remarkable = require('remarkable');
4 | var md = new Remarkable();
5 | var fs = require('fs');
6 | var config = require('../config/index');
7 |
8 | /* GET home page. */
9 | router.get('/', function(req, res) {
10 | res.render('index', {
11 | user: req.session.user,
12 | navigation:'index'
13 | });
14 | });
15 |
16 | router.get('/document/:page', function(req, res) {
17 | var page = req.params['page'];
18 | if(page.indexOf('.')!=-1) page=page.split('.')[0];
19 |
20 | console.log(page);
21 | fs.readFile(__dirname+'/../views/document/'+page+'.md','utf-8',function(err,data){
22 | res.render('document', {
23 | user: req.session.user,
24 | page:page,
25 | navigation:'document',
26 | data:md.render(data)
27 | });
28 | })
29 | });
30 |
31 | router.get('/about', function(req, res){
32 | res.render('about', {
33 | user: req.session.user,
34 | navigation:'about'
35 | });
36 | })
37 |
38 | router.get('/contribute', function(req, res){
39 | res.render('contribute', {
40 | user: req.session.user,
41 | navigation:'contribute'
42 | });
43 | })
44 | router.get('/commercial', function(req, res){
45 | res.render('commercial', {
46 | user: req.session.user,
47 | navigation:'commercial'
48 | });
49 | })
50 |
51 | router.get('/404',function(req,res){
52 | res.render('404',{
53 | user: req.session.user,
54 | navigation:'index'
55 | });
56 | })
57 | router.get('/500',function(req,res){
58 | res.render('500',{
59 | user: req.session.user,
60 | navigation:'index'
61 | });
62 | })
63 |
64 | module.exports = router;
65 |
--------------------------------------------------------------------------------
/views/about.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 | Tisan不支持您使用的浏览器,建议使用最新Chrome浏览器
15 |
16 | <%include navigation.ejs%>
17 |
18 |

19 |
20 |
21 |

22 |
23 |
24 |

25 |
26 |
27 |

28 |
29 |
30 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/public/codemirror/mode/turtle/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Turtle mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Turtle mode
27 |
41 |
47 |
48 | MIME types defined: text/turtle.
49 |
50 |
51 |
--------------------------------------------------------------------------------
/public/codemirror/addon/scroll/scrollpastend.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) {
15 | if (old && old != CodeMirror.Init) {
16 | cm.off("change", onChange);
17 | cm.off("refresh", updateBottomMargin);
18 | cm.display.lineSpace.parentNode.style.paddingBottom = "";
19 | cm.state.scrollPastEndPadding = null;
20 | }
21 | if (val) {
22 | cm.on("change", onChange);
23 | cm.on("refresh", updateBottomMargin);
24 | updateBottomMargin(cm);
25 | }
26 | });
27 |
28 | function onChange(cm, change) {
29 | if (CodeMirror.changeEnd(change).line == cm.lastLine())
30 | updateBottomMargin(cm);
31 | }
32 |
33 | function updateBottomMargin(cm) {
34 | var padding = "";
35 | if (cm.lineCount() > 1) {
36 | var totalH = cm.display.scroller.clientHeight - 30,
37 | lastLineH = cm.getLineHandle(cm.lastLine()).height;
38 | padding = (totalH - lastLineH) + "px";
39 | }
40 | if (cm.state.scrollPastEndPadding != padding) {
41 | cm.state.scrollPastEndPadding = padding;
42 | cm.display.lineSpace.parentNode.style.paddingBottom = padding;
43 | cm.setSize();
44 | }
45 | }
46 | });
47 |
--------------------------------------------------------------------------------
/public/codemirror/addon/lint/html-lint.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | // Depends on htmlhint.js from http://htmlhint.com/js/htmlhint.js
5 |
6 | // declare global: HTMLHint
7 |
8 | (function(mod) {
9 | if (typeof exports == "object" && typeof module == "object") // CommonJS
10 | mod(require("../../lib/codemirror"), require("htmlhint"));
11 | else if (typeof define == "function" && define.amd) // AMD
12 | define(["../../lib/codemirror", "htmlhint"], mod);
13 | else // Plain browser env
14 | mod(CodeMirror);
15 | })(function(CodeMirror) {
16 | "use strict";
17 |
18 | var defaultRules = {
19 | "tagname-lowercase": true,
20 | "attr-lowercase": true,
21 | "attr-value-double-quotes": true,
22 | "doctype-first": false,
23 | "tag-pair": true,
24 | "spec-char-escape": true,
25 | "id-unique": true,
26 | "src-not-empty": true,
27 | "attr-no-duplication": true
28 | };
29 |
30 | CodeMirror.registerHelper("lint", "html", function(text, options) {
31 | var found = [];
32 | if (!window.HTMLHint) return found;
33 | var messages = HTMLHint.verify(text, options && options.rules || defaultRules);
34 | for (var i = 0; i < messages.length; i++) {
35 | var message = messages[i];
36 | var startLine = message.line - 1, endLine = message.line - 1, startCol = message.col - 1, endCol = message.col;
37 | found.push({
38 | from: CodeMirror.Pos(startLine, startCol),
39 | to: CodeMirror.Pos(endLine, endCol),
40 | message: message.message,
41 | severity : message.type
42 | });
43 | }
44 | return found;
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/public/codemirror/mode/pascal/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Pascal mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Pascal mode
27 |
28 |
29 |
52 |
53 |
59 |
60 | MIME types defined: text/x-pascal.
61 |
62 |
--------------------------------------------------------------------------------
/public/codemirror/mode/pig/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Pig Latin mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Pig Latin mode
27 |
39 |
40 |
47 |
48 |
49 | Simple mode that handles Pig Latin language.
50 |
51 |
52 | MIME type defined: text/x-pig
53 | (PIG code)
54 |