From d58a409eb2b32ed1aa21194bc4dd97ff83b8134d Mon Sep 17 00:00:00 2001
From: "Ke, Mingze" <mingze.ke@gmail.com>
Date: Wed, 9 Sep 2015 11:45:22 +0800
Subject: [PATCH 01/18] Bumped dependency versions

- versioning: "MAJOR.x"
---
 bower.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bower.json b/bower.json
index 59879ed..10416b8 100644
--- a/bower.json
+++ b/bower.json
@@ -6,7 +6,7 @@
   "keywords": ["arduino", "webduino", "web-components"],
   "license": "MIT",
   "dependencies": {
-    "webcomponentsjs": "= 0.7.3",
-    "webduino-js": "= 0.1.7"
+    "webcomponentsjs": "0.x",
+    "webduino-js": "0.x"
   }
 }

From 6e32d24a137d96afdd108e5ad5ede44036eb3e09 Mon Sep 17 00:00:00 2001
From: "Ke, Mingze" <mingze.ke@gmail.com>
Date: Wed, 30 Sep 2015 12:22:55 +0800
Subject: [PATCH 02/18] Tune connection parameters. Multi-client mode set to
 false by default.

---
 web-arduino.html | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/web-arduino.html b/web-arduino.html
index be4a3de..b9a981f 100644
--- a/web-arduino.html
+++ b/web-arduino.html
@@ -28,6 +28,22 @@
         set: function(val) {
           this.setAttribute('server', val);
         }
+      },
+      multi: {
+        get: function() {
+          return this.getAttribute('multi');
+        },
+        set: function(val) {
+          this.setAttribute('multi', val);
+        }
+      },
+      autoReconnect: {
+        get: function() {
+          return this.getAttribute('autoReconnect');
+        },
+        set: function(val) {
+          this.setAttribute('autoReconnect', val);
+        }
       }
     });
 
@@ -36,16 +52,21 @@
         self = this,
         WebArduino = webduino.WebArduino,
         BoardEvent = webduino.BoardEvent,
+        util = webduino.util,
         events = self.events_,
         device = self.device,
-        server = self.server;
+        server = self.server,
+        multi = self.multi,
+        autoReconnect = self.autoReconnect;
 
       if (device) {
-        board = (server ? new WebArduino({
-          server: server,
-          device: self.device
-        }) : new WebArduino(device));
-        self.board = board;
+        self.board = board = new WebArduino(util.extend({
+          device: device
+        }, {
+          server: server || undefined,
+          multi: multi || undefined,
+          autoReconnect: autoReconnect || undefined
+        }));
 
         board.on(BoardEvent.READY, function(event) {
           var children = self.children;

From b8737084551fe673c6c41bd085428f1553e1f9d4 Mon Sep 17 00:00:00 2001
From: "Ke, Mingze" <mingze.ke@gmail.com>
Date: Wed, 30 Sep 2015 23:51:37 +0800
Subject: [PATCH 03/18] Added serial transport

---
 web-arduino.html | 47 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/web-arduino.html b/web-arduino.html
index b9a981f..e9d84ff 100644
--- a/web-arduino.html
+++ b/web-arduino.html
@@ -44,6 +44,22 @@
         set: function(val) {
           this.setAttribute('autoReconnect', val);
         }
+      },
+      path: {
+        get: function() {
+          return this.getAttribute('path');
+        },
+        set: function(val) {
+          this.setAttribute('path', val);
+        }
+      },
+      baudRate: {
+        get: function() {
+          return this.getAttribute('baudRate');
+        },
+        set: function(val) {
+          this.setAttribute('baudRate', val);
+        }
       }
     });
 
@@ -51,22 +67,33 @@
       var board, ev,
         self = this,
         WebArduino = webduino.WebArduino,
+        Arduino = webduino.Arduino,
         BoardEvent = webduino.BoardEvent,
         util = webduino.util,
         events = self.events_,
         device = self.device,
         server = self.server,
         multi = self.multi,
-        autoReconnect = self.autoReconnect;
-
-      if (device) {
-        self.board = board = new WebArduino(util.extend({
-          device: device
-        }, {
-          server: server || undefined,
-          multi: multi || undefined,
-          autoReconnect: autoReconnect || undefined
-        }));
+        autoReconnect = self.autoReconnect,
+        path = self.path,
+        baudRate = self.baudRate;
+
+      if (device || path) {
+        if (device) {
+          self.board = board = new WebArduino(util.extend({
+            device: device
+          }, {
+            server: server || undefined,
+            multi: multi || undefined,
+            autoReconnect: autoReconnect || undefined
+          }));
+        } else {
+          self.board = board = new Arduino(util.extend({
+            path: path
+          }, {
+            baudRate: baudRate || undefined
+          }));
+        }
 
         board.on(BoardEvent.READY, function(event) {
           var children = self.children;

From 9b8248080572f7ba97d2c371df7103f92d16e7f6 Mon Sep 17 00:00:00 2001
From: "Ke, Mingze" <mingze.ke@gmail.com>
Date: Wed, 28 Oct 2015 14:46:19 +0800
Subject: [PATCH 04/18] Added chrome-bluetooth transport

---
 web-arduino.html | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/web-arduino.html b/web-arduino.html
index e9d84ff..564c152 100644
--- a/web-arduino.html
+++ b/web-arduino.html
@@ -60,6 +60,14 @@
         set: function(val) {
           this.setAttribute('baudRate', val);
         }
+      },
+      address: {
+        get: function() {
+          return this.getAttribute('address');
+        },
+        set: function(val) {
+          this.setAttribute('address', val);
+        }
       }
     });
 
@@ -76,9 +84,10 @@
         multi = self.multi,
         autoReconnect = self.autoReconnect,
         path = self.path,
-        baudRate = self.baudRate;
+        baudRate = self.baudRate,
+        address = self.address;
 
-      if (device || path) {
+      if (device || path || address) {
         if (device) {
           self.board = board = new WebArduino(util.extend({
             device: device
@@ -87,12 +96,18 @@
             multi: multi || undefined,
             autoReconnect: autoReconnect || undefined
           }));
-        } else {
+        } else if (path) {
           self.board = board = new Arduino(util.extend({
+            transport: 'serial',
             path: path
           }, {
             baudRate: baudRate || undefined
           }));
+        } else {
+          self.board = board = new Arduino({
+            transport: 'bluetooth',
+            address: address
+          });
         }
 
         board.on(BoardEvent.READY, function(event) {

From de8228be246b8bfe7adcd84bd592b8600100aa43 Mon Sep 17 00:00:00 2001
From: shengyuan <karokya@gmail.com>
Date: Wed, 25 Nov 2015 15:28:13 +0800
Subject: [PATCH 05/18] Add RFID.

---
 demo/rfid.html | 171 +++++++++++++++++++++++++++++++++++++++++++++++++
 wa-rfid.html   |  39 +++++++++++
 2 files changed, 210 insertions(+)
 create mode 100644 demo/rfid.html
 create mode 100644 wa-rfid.html

diff --git a/demo/rfid.html b/demo/rfid.html
new file mode 100644
index 0000000..383a5fb
--- /dev/null
+++ b/demo/rfid.html
@@ -0,0 +1,171 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+  <title>RFID(RC522)</title>
+  <script src="../../webcomponentsjs/webcomponents.js"></script>
+  <link rel='import' href='../web-arduino.html'></link>
+  <link rel='import' href='../wa-rfid.html'></link>
+  <style>
+  * {
+    font-size: 20px;
+  }
+
+  #msg.default::after {
+    content: "訊息";
+  }
+  
+  #msg.waiting::after {
+    content: "Loading...";
+  }
+  
+  #msg.ready::after {
+    content: "Ready!";
+  }
+  
+  #msg.setting::after {
+    content: "設定中...";
+  }
+  
+  #msg.set::after {
+    content: "設定完成";
+  }
+  
+  input {
+    width: 100px;
+    margin: 5px 0;
+  }
+  
+  button {
+    margin: 5px 0;
+  }
+
+  .container {
+    position: relative;
+  }
+
+  .msgContainer {
+    position: absolute; 
+    top: 0; 
+    right: 0; 
+    width: 60%;
+  }
+  
+  #light img {
+    width: 25%;
+    display: none;
+  }
+  
+  #light.off img:first-child {
+    display: inline-block;
+  }
+  
+  #light.on img:last-child {
+    display: inline-block;
+  }
+  
+  #msgRecv {
+    word-break: break-all;
+    height: 300px;
+    width: 100%;
+    overflow: auto;
+  }
+  
+  #msgRecv::before {
+    content: 'message:';
+  }
+  </style>
+</head>
+
+<body>
+  <web-arduino id="board">
+    <wa-rfid id='rfid'></wa-rfid>
+  </web-arduino>
+  <div id="msg" class="waiting"></div>
+  <form>
+    <label>device : </label>
+    <input type="text" id="device">
+    <button class="setting" id="set">設定</button>
+  </form>
+  <p>接線：3.3v 和 gnd 及 SDA(10), MOSI(11), MISO(12), SCK(13)</p>
+  <p>說明：
+    <br>接收到訊號時，會拋出字串，訊號源離開時，會收到空字串。
+  </p>
+
+  <div class="container">
+    <p>點擊燈炮亮起，啟動 RFID，熄燈則關閉 RFID</p>
+    <div id='light' class="off">
+      <img src='http://i.imgur.com/T5H4MHE.png'></img>
+      <img src='http://i.imgur.com/8qFj2Ou.png'></img>
+    </div>
+    <div class="msgContainer">
+      <button id='clearMsg'>clear message</button>
+      <br>
+      <div id='msgRecv'></div>
+    </div>
+  </div>
+
+  <script>
+  window.addEventListener('WebComponentsReady', function() {
+    var board = document.getElementById('board');
+    var device = document.getElementById('device');
+    var light = document.getElementById('light');
+    var clearMsg = document.getElementById('clearMsg');
+    var msgRecv = document.getElementById('msgRecv');
+    var msg = document.getElementById('msg');
+    var setBtn = document.getElementById('set');
+
+    // 使用 localStorage 記錄 device id
+    device.setAttribute('value', localStorage.device || "");
+
+    msg.className = "ready";
+
+    setBtn.addEventListener('click', function(e) {
+      msg.className = "setting";
+      light.className = 'off';
+      msgRecv.innerHTML = '';
+      board.device = device.value;
+      localStorage.device = device.value;
+      board.on('ready', ready);
+      board.init();
+      e.stopPropagation();
+      e.preventDefault();
+      return false;
+    }, false);
+
+    // 清除訊息
+    clearMsg.addEventListener('click', function() {
+      msgRecv.innerHTML = '';
+    });
+
+    function ready() {
+      var rfid = document.getElementById('rfid');
+
+      light.addEventListener('click', function() {
+        if (light.className == 'on') {
+          light.className = 'off';
+          rfid.off();
+        } else {
+          light.className = 'on';
+          rfid.on(success);
+        }
+      }, false);
+
+      msg.className = "set";
+    }
+
+    function success(val) {
+      var msgRecv = document.getElementById('msgRecv');
+      var ss = document.createElement('span');
+      ss.innerHTML += '<br>';
+      ss.innerHTML += val;
+      ss.innerHTML += '<span>, ' + new Date().toLocaleTimeString() + '</span>';
+      msgRecv.insertBefore(ss, msgRecv.childNodes[0]);
+    }
+  });
+  </script>
+</body>
+
+</html>
diff --git a/wa-rfid.html b/wa-rfid.html
new file mode 100644
index 0000000..aceace2
--- /dev/null
+++ b/wa-rfid.html
@@ -0,0 +1,39 @@
+<html>
+
+<head>
+  <script type="text/javascript" src="../webduino-js/src/module/RFID.js"></script>
+</head>
+
+<body>
+  <script>
+  (function() {
+    var proto = Object.create(HTMLElement.prototype);
+
+    proto.init_ = function(board) {
+      var RFID = webduino.module.RFID;
+      this.rfid = new RFID(board);
+    };
+
+    proto.on = function(callback) {
+      if (typeof callback === 'function') {
+        this.rfid.on(callback);
+      }
+    };
+
+    proto.off = function() {
+      this.rfid.off();
+    };
+
+    proto.detachedCallback = function() {
+      this.off();
+    };
+
+    document.registerElement('wa-rfid', {
+      prototype: proto
+    });
+
+  })();
+  </script>
+</body>
+
+</html>
\ No newline at end of file

From 42ae2f78db6e340d5185cfa523546dda35588008 Mon Sep 17 00:00:00 2001
From: shengyuan <karokya@gmail.com>
Date: Thu, 26 Nov 2015 15:40:59 +0800
Subject: [PATCH 06/18] RFID rewritten.

---
 demo/rfid.html |  4 ++--
 wa-rfid.html   | 24 +++++++++++++++++-------
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/demo/rfid.html b/demo/rfid.html
index 383a5fb..fccca81 100644
--- a/demo/rfid.html
+++ b/demo/rfid.html
@@ -146,10 +146,10 @@
       light.addEventListener('click', function() {
         if (light.className == 'on') {
           light.className = 'off';
-          rfid.off();
+          rfid.stopListen();
         } else {
           light.className = 'on';
-          rfid.on(success);
+          rfid.listen(success, success);
         }
       }, false);
 
diff --git a/wa-rfid.html b/wa-rfid.html
index aceace2..0877b29 100644
--- a/wa-rfid.html
+++ b/wa-rfid.html
@@ -14,18 +14,28 @@
       this.rfid = new RFID(board);
     };
 
-    proto.on = function(callback) {
-      if (typeof callback === 'function') {
-        this.rfid.on(callback);
-      }
+    proto.listen = function(enterHandler, leaveHandler) {
+      this.rfid.listen(enterHandler, leaveHandler);
     };
 
-    proto.off = function() {
-      this.rfid.off();
+    proto.stopListen = function() {
+      this.rfid.stopListen();
+    };
+
+    proto.isListened = function() {
+      return this.rfid.isListened();
+    };
+
+    proto.on = function(evtType, handler) {
+      this.rfid.on(evtType, handler);
+    };
+
+    proto.off = function(evtType, handler) {
+      this.rfid.off(evtType, handler);
     };
 
     proto.detachedCallback = function() {
-      this.off();
+      this.rfid.destroy();
     };
 
     document.registerElement('wa-rfid', {

From e39ead155a515f29d90e241e1fba67cf46022e8a Mon Sep 17 00:00:00 2001
From: "Ke, Mingze" <mingze.ke@gmail.com>
Date: Thu, 26 Nov 2015 17:58:15 +0800
Subject: [PATCH 07/18] Changed some wording of RFID

---
 wa-rfid.html | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/wa-rfid.html b/wa-rfid.html
index 0877b29..eb7bf52 100644
--- a/wa-rfid.html
+++ b/wa-rfid.html
@@ -7,23 +7,25 @@
 <body>
   <script>
   (function() {
-    var proto = Object.create(HTMLElement.prototype);
+    var proto = Object.create(HTMLElement.prototype, {
+      isReading: {
+        get: function() {
+          return !!(this.rfid && this.rfid.isReading);
+        }
+      }
+    });
 
     proto.init_ = function(board) {
       var RFID = webduino.module.RFID;
       this.rfid = new RFID(board);
     };
 
-    proto.listen = function(enterHandler, leaveHandler) {
-      this.rfid.listen(enterHandler, leaveHandler);
-    };
-
-    proto.stopListen = function() {
-      this.rfid.stopListen();
+    proto.read = function(enterHandler, leaveHandler) {
+      this.rfid.read(enterHandler, leaveHandler);
     };
 
-    proto.isListened = function() {
-      return this.rfid.isListened();
+    proto.stopRead = function() {
+      this.rfid.stopRead();
     };
 
     proto.on = function(evtType, handler) {

From 53a980f2f4fd4d244a7243286d2085854dd5fdd1 Mon Sep 17 00:00:00 2001
From: shengyuan <karokya@gmail.com>
Date: Fri, 15 Apr 2016 17:48:42 +0800
Subject: [PATCH 08/18] Add soil.

---
 demo/soil.html | 170 +++++++++++++++++++++++++++++++++++++++++++++++++
 wa-soil.html   |  50 +++++++++++++++
 2 files changed, 220 insertions(+)
 create mode 100644 demo/soil.html
 create mode 100644 wa-soil.html

diff --git a/demo/soil.html b/demo/soil.html
new file mode 100644
index 0000000..5109948
--- /dev/null
+++ b/demo/soil.html
@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+  <title>土壤溼度</title>
+  <script src="../../webcomponentsjs/webcomponents.js"></script>
+  <link rel='import' href='../web-arduino.html'></link>
+  <link rel='import' href='../wa-soil.html'></link>
+  <link rel='import' href='../wa-photocell.html'></link>
+  <style>
+  * {
+    font-size: 20px;
+  }
+
+  #msg.default::after {
+    content: "訊息";
+  }
+  
+  #msg.waiting::after {
+    content: "Loading...";
+  }
+  
+  #msg.ready::after {
+    content: "Ready!";
+  }
+  
+  #msg.setting::after {
+    content: "設定中...";
+  }
+  
+  #msg.set::after {
+    content: "設定完成";
+  }
+  
+  input {
+    width: 100px;
+    margin: 5px 0;
+  }
+  
+  button {
+    margin: 5px 0;
+  }
+
+  .container {
+    position: relative;
+  }
+
+  .msgContainer {
+    position: absolute; 
+    top: 0; 
+    right: 0; 
+    width: 60%;
+  }
+  
+  #light img {
+    width: 25%;
+    display: none;
+  }
+  
+  #light.off img:first-child {
+    display: inline-block;
+  }
+  
+  #light.on img:last-child {
+    display: inline-block;
+  }
+  
+  #msgRecv {
+    word-break: break-all;
+    height: 300px;
+    width: 100%;
+    overflow: auto;
+  }
+  
+  #msgRecv::before {
+    content: 'message:';
+  }
+  </style>
+</head>
+
+<body>
+  <web-arduino id="board">
+    <wa-soil id='soil' analogpin='5'></wa-soil>
+  </web-arduino>
+  <div id="msg" class="waiting"></div>
+  <form>
+    <label>device : </label>
+    <input type="text" id="device">
+    <button class="setting" id="set">設定</button>
+  </form>
+  <p>soil analog pin : 5 (A3)</p>
+  <p>說明：
+    <br>值介於 0 ~ 100% 之間，數字愈大，溼度愈高。
+  </p>
+
+  <div class="container">
+    <p>點擊燈炮，啟動土壤溼度感測器</p>
+    <div id='light' class="off">
+      <img src='http://i.imgur.com/T5H4MHE.png'></img>
+      <img src='http://i.imgur.com/8qFj2Ou.png'></img>
+    </div>
+    <div class="msgContainer">
+      <button id='clearMsg'>clear message</button>
+      <br>
+      <div id='msgRecv'></div>
+    </div>
+  </div>
+
+  <script>
+  window.addEventListener('WebComponentsReady', function() {
+    var board = document.getElementById('board');
+    var device = document.getElementById('device');
+    var light = document.getElementById('light');
+    var clearMsg = document.getElementById('clearMsg');
+    var msgRecv = document.getElementById('msgRecv');
+    var msg = document.getElementById('msg');
+    var setBtn = document.getElementById('set');
+
+    device.setAttribute('value', localStorage.device || "");
+
+    msg.className = "ready";
+
+    setBtn.addEventListener('click', function(e) {
+      msg.className = "setting";
+      light.className = 'off';
+      msgRecv.innerHTML = '';
+      board.device = device.value;
+      localStorage.device = device.value;
+      board.on('ready', ready);
+      board.init();
+      e.stopPropagation();
+      e.preventDefault();
+      return false;
+    }, false);
+
+    clearMsg.addEventListener('click', function() {
+      msgRecv.innerHTML = '';
+    });
+
+    function ready() {
+      var soil = document.getElementById('soil');
+
+      light.addEventListener('click', function() {
+        if (light.className == 'on') {
+          light.className = 'off';
+          soil.off();
+        } else {
+          light.className = 'on';
+          soil.on(success);
+        }
+      }, false);
+
+      msg.className = "set";
+    }
+
+    function success(val) {
+      var msgRecv = document.getElementById('msgRecv');
+      var ss = document.createElement('span');
+      ss.innerHTML += '<br>';
+      ss.innerHTML += val;
+      ss.innerHTML += '<span>, ' + new Date().toLocaleTimeString() + '</span>';
+      msgRecv.insertBefore(ss, msgRecv.childNodes[0]);
+    }
+  });
+  </script>
+</body>
+
+</html>
diff --git a/wa-soil.html b/wa-soil.html
new file mode 100644
index 0000000..5dfe588
--- /dev/null
+++ b/wa-soil.html
@@ -0,0 +1,50 @@
+<html>
+
+<head>
+  <script type="text/javascript" src="../webduino-js/src/module/Soil.js"></script>
+</head>
+
+<body>
+  <script>
+  (function() {
+    var proto = Object.create(HTMLElement.prototype, {
+      analogpin: {
+        get: function() {
+          return this.getAttribute('analogpin');
+        },
+        set: function(val) {
+          this.setAttribute('analogpin', val);
+        }
+      }
+    });
+
+    proto.init_ = function(board) {
+      var Soil = webduino.module.Soil;
+      this.soil = new Soil(board, this.analogpin);
+    };
+
+    proto.on = function(callback) {
+      if (typeof callback === 'function') {
+        this.soil.on(function(val) {
+          callback(val);
+        });
+      }
+    };
+
+    proto.off = function() {
+      this.soil.off();
+    };
+
+    proto.detachedCallback = function() {
+      this.off();
+    };
+
+    document.registerElement('wa-soil', {
+      prototype: proto
+    });
+
+  })();
+  </script>
+</body>
+
+</html>
\ No newline at end of file

From c9caf083f5f8e99a693b34b7fc37a98b8288a8b1 Mon Sep 17 00:00:00 2001
From: "Ke, Mingze" <mingze.ke@gmail.com>
Date: Sat, 23 Apr 2016 04:58:16 +0800
Subject: [PATCH 09/18] Use latest webduino-js

---
 bower.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bower.json b/bower.json
index 10416b8..075441c 100644
--- a/bower.json
+++ b/bower.json
@@ -7,6 +7,6 @@
   "license": "MIT",
   "dependencies": {
     "webcomponentsjs": "0.x",
-    "webduino-js": "0.x"
+    "webduino-js": "master"
   }
 }

From 6d834acf10bb244b5b20dfbf91d2049127dcc792 Mon Sep 17 00:00:00 2001
From: marty <marty.shu@gmail.com>
Date: Wed, 8 Jun 2016 17:29:19 +0800
Subject: [PATCH 10/18] add g3 webComponent

---
 demo/g3.html | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 wa-g3.html   | 52 +++++++++++++++++++++++++++++
 2 files changed, 144 insertions(+)
 create mode 100644 demo/g3.html
 create mode 100644 wa-g3.html

diff --git a/demo/g3.html b/demo/g3.html
new file mode 100644
index 0000000..0af0455
--- /dev/null
+++ b/demo/g3.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+  <title>Detect humidity and temperature</title>
+
+  <script src="../../webcomponentsjs/webcomponents.js"></script>
+  <link rel='import' href='../web-arduino.html'></link>
+  <link rel='import' href='../wa-g3.html'></link>
+
+  <style>
+  * {
+    font-size: 20px;
+  }
+
+  #msg.default::after {
+    content: "訊息";
+  }
+  #msg.waiting::after {
+    content: "Loading...";
+  }
+  #msg.ready::after {
+    content: "Ready!";
+  }
+  #msg.setting::after {
+    content: "設定中...";
+  }
+  #msg.set::after {
+    content: "設定完成";
+  }
+  </style>
+</head>
+
+<body>
+  <web-arduino id='board'>
+    <wa-g3 id='g3' rx='2' tx='3'></wa-g3>
+  </web-arduino>
+
+  <div id="msg" class="waiting"></div>
+
+  <form>
+    <label>device : </label><input type="text" id="device">
+    <button class="setting" id="set">設定</button>
+  </form>
+
+  <p>需接地及5V電源, G3 rx: 2 , tx: 3</p>
+  <p>使用G3傳感器，偵測現場PM25 , PM10</p>
+  <p id='data'>none</p>
+  
+
+  <script>
+  window.addEventListener('WebComponentsReady', function() {
+    var board = document.getElementById('board'),
+      msg = document.getElementById('msg'),
+      device = document.getElementById('device'),
+      g3 = document.getElementById('g3'),
+      setBtn = document.getElementById('set'),
+      data = document.getElementById('data');
+
+    device.setAttribute('value', localStorage.device || "");
+
+    msg.className = "ready";
+
+    setBtn.addEventListener('click', function(e) {
+      msg.className = "setting";
+      board.device = device.value;
+      localStorage.device = device.value;
+      board.on('ready', ready);
+      board.init();
+      e.stopPropagation();
+      e.preventDefault();
+      return false;
+    }, false);
+
+    function ready() {
+      // 示意 board ready
+      msg.className = "set";
+      run();
+    }
+
+    function run(times) {
+      g3.read(function(evt) {
+        data.innerHTML = Date() + "<br>PM25:" + evt.pm25 + ", PM10:" + evt.pm10;
+      }, 3000);
+    }
+  });
+  </script>
+</body>
+
+</html>
diff --git a/wa-g3.html b/wa-g3.html
new file mode 100644
index 0000000..5346d20
--- /dev/null
+++ b/wa-g3.html
@@ -0,0 +1,52 @@
+<html>
+
+<head>
+    <script type="text/javascript" src="../webduino-js/src/module/G3.js"></script>
+</head>
+
+<body>
+    <script>
+    (function() {
+        var proto = Object.create(HTMLElement.prototype, {
+            rx: {
+                get: function() {
+                    return this.getAttribute('rx');
+                },
+                set: function(val) {
+                    this.setAttribute('rx', val);
+                }
+            },
+            tx: {
+                get: function() {
+                    return this.getAttribute('tx');
+                },
+                set: function(val) {
+                    this.setAttribute('tx', val);
+                }
+            }
+        });
+
+        proto.init_ = function(board) {
+            var G3 = webduino.module.G3;
+            this.g3 = new G3(board,
+                board.getDigitalPin(this.rx),
+                board.getDigitalPin(this.tx));
+        };
+
+        proto.read = function(callback, interval) {
+            this.g3.read(callback, interval);
+        }
+
+        proto.stopRead = function() {
+            this.g3.stopRead();
+        }
+
+        document.registerElement('wa-g3', {
+            prototype: proto
+        });
+
+    })();
+    </script>
+</body>
+
+</html>
\ No newline at end of file

From 6b00a1b8eb502618ea94ab281214a7cd06aabe18 Mon Sep 17 00:00:00 2001
From: shengyuan <karokya@gmail.com>
Date: Fri, 1 Jul 2016 13:30:10 +0800
Subject: [PATCH 11/18] Add stepper.

---
 demo/stepper.html | 171 ++++++++++++++++++++++++++++++++++++++++++----
 img/stepper.jpg   | Bin 0 -> 512974 bytes
 wa-stepper.html   | 103 ++++++++++++++++++++++++++++
 3 files changed, 259 insertions(+), 15 deletions(-)
 create mode 100644 img/stepper.jpg
 create mode 100644 wa-stepper.html

diff --git a/demo/stepper.html b/demo/stepper.html
index f1d43f7..7efafa7 100644
--- a/demo/stepper.html
+++ b/demo/stepper.html
@@ -2,38 +2,179 @@
 <html>
 
 <head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+  <title>步進馬達</title>
   <script src="../../webcomponentsjs/webcomponents.js"></script>
   <link rel='import' href='../web-arduino.html'></link>
   <link rel='import' href='../wa-stepper.html'></link>
-
   <style>
-    img {
-      width: 200px;
-    }
+  * {
+    font-size: 20px;
+  }
+
+  #msg.default::after {
+    content: "訊息";
+  }
+  
+  #msg.waiting::after {
+    content: "Loading...";
+  }
+  
+  #msg.ready::after {
+    content: "Ready!";
+  }
+  
+  #msg.setting::after {
+    content: "設定中...";
+  }
+  
+  #msg.set::after {
+    content: "設定完成";
+  }
+  
+  input {
+    width: 100px;
+    margin: 5px 0;
+  }
+  
+  button {
+    margin: 5px 0;
+  }
+
+  .container {
+    position: relative;
+  }
+
+  .msgContainer {
+    position: absolute; 
+    top: 0; 
+    right: 0; 
+    width: 60%;
+  }
+  
+  #light img {
+    width: 25%;
+    display: none;
+  }
+  
+  #light.off img:first-child {
+    display: inline-block;
+  }
+  
+  #light.on img:last-child {
+    display: inline-block;
+  }
+  
+  #msgRecv {
+    word-break: break-all;
+    height: 300px;
+    width: 100%;
+    overflow: auto;
+  }
+  
+  #msgRecv::before {
+    content: 'message:';
+  }
   </style>
 </head>
 
 <body>
-  <web-arduino id='board' device='wahaha'>
-    <wa-stepper id='stepper'></wa-stepper>
+  <web-arduino id="board">
+    <wa-stepper id='stepper' stepperNumber="2" interface="4" stepsPerRevolution="2048" pin1='8' pin2='9' pin3='10' pin4='11'></wa-stepper>
   </web-arduino>
+  <div id="msg" class="waiting"></div>
+  <form>
+    <label>device : </label>
+    <input type="text" id="device">
+    <button class="setting" id="set">設定</button>
+  </form>
+  <p> ULN2003 達林頓晶片驅動步進馬達驅動板上的 IN1, IN2, IN3, IN4 分別接上四個數位腳位 8, 9, 10, 11<br>
+      stepperNumber：設定馬達的編號 0~5<br>
+      interface：馬達的相數<br>
+      stepsPerRevolution：馬達轉一圈的步數
+  </p>
+
+  <p> 控制命令<br>
+      direction：0, 1 (CW clockwise 順時針, CCW counterclockwise 逆時針)<br>
+      stepNumber：轉動步數<br>
+      speed：步進馬達(型號28BYJ-48, 5V DC)，建議 10~160 單位(0.01 rad/sec)
+  </p>
 
-  <img src="http://www.hua.com/flower_picture/meiguihua/images/r17.jpg"></img>
-  <button id='rotate'>旋轉</button>
+  <div class="container">
+    <p>點擊燈炮，步進馬達會執行指令</p>
+    <div id='light' class="off">
+      <img src='http://i.imgur.com/T5H4MHE.png'></img>
+      <img src='http://i.imgur.com/8qFj2Ou.png'></img>
+    </div>
+    <div class="msgContainer">
+      <img src="../img/stepper.jpg" width="100%" alt="">
+      <button id='clearMsg'>clear message</button>
+      <br>
+      <div id='msgRecv'></div>
+    </div>
+  </div>
 
   <script>
   window.addEventListener('WebComponentsReady', function() {
     var board = document.getElementById('board');
+    var device = document.getElementById('device');
+    var light = document.getElementById('light');
+    var clearMsg = document.getElementById('clearMsg');
+    var msgRecv = document.getElementById('msgRecv');
+    var msg = document.getElementById('msg');
+    var setBtn = document.getElementById('set');
 
-    board.on('ready', function() {
-      var rotate = document.getElementById('rotate'),
-        stepper = document.getElementById('stepper');
+    device.setAttribute('value', localStorage.device || "");
 
-      rotate.addEventListener('click', function() {
-        stepper.rotate();
-      }, false);
+    msg.className = "ready";
+
+    setBtn.addEventListener('click', function(e) {
+      msg.className = "setting";
+      light.className = 'off';
+      msgRecv.innerHTML = '';
+      board.device = device.value;
+      localStorage.device = device.value;
+      board.on('ready', ready);
+      board.init();
+      e.stopPropagation();
+      e.preventDefault();
+      return false;
+    }, false);
+
+    clearMsg.addEventListener('click', function() {
+      msgRecv.innerHTML = '';
     });
-  }, false);
+
+    function ready() {
+      var stepper = document.getElementById('stepper');
+
+      light.addEventListener('click', function() {
+        if (light.className == 'on') {
+          light.className = 'off';
+        } else {
+          light.className = 'on';
+          stepper.on({
+            "stepperNumber": stepper.getAttribute('stepperNumber'),
+            "direction": 0,
+            "stepNumber": 2048,
+            "speed": 160
+          }, success);
+        }
+      }, false);
+
+      msg.className = "set";
+    }
+
+    function success(val) {
+      var msgRecv = document.getElementById('msgRecv');
+      var ss = document.createElement('span');
+      ss.innerHTML += '<br>';
+      ss.innerHTML += 'stepperNumber: ' + val.stepperNumber;
+      ss.innerHTML += '<span>, ' + new Date().toLocaleTimeString() + '</span>';
+      msgRecv.insertBefore(ss, msgRecv.childNodes[0]);
+    }
+  });
   </script>
 </body>
 
diff --git a/img/stepper.jpg b/img/stepper.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f5f2a5522a969c52efd4ee476b711e487b9b0a87
GIT binary patch
diff --git a/wa-stepper.html b/wa-stepper.html
new file mode 100644
index 0000000..c21e271
--- /dev/null
+++ b/wa-stepper.html
@@ -0,0 +1,103 @@
+<html>
+
+<head>
+  <script type="text/javascript" src="../webduino-js/src/module/Stepper.js"></script>
+</head>
+
+<body>
+  <script>
+  (function() {
+    var proto = Object.create(HTMLElement.prototype, {
+      stepperNumber: {
+        get: function() {
+          return this.getAttribute('stepperNumber');
+        },
+        set: function(val) {
+          this.setAttribute('stepperNumber', val);
+        }
+      },
+      interface: {
+        get: function() {
+          return this.getAttribute('interface');
+        },
+        set: function(val) {
+          this.setAttribute('interface', val);
+        }
+      },
+      stepsPerRevolution: {
+        get: function() {
+          return this.getAttribute('stepsPerRevolution');
+        },
+        set: function(val) {
+          this.setAttribute('stepsPerRevolution', val);
+        }
+      },
+      pin1: {
+        get: function() {
+          return this.getAttribute('pin1');
+        },
+        set: function(val) {
+          this.setAttribute('pin1', val);
+        }
+      },
+      pin2: {
+        get: function() {
+          return this.getAttribute('pin2');
+        },
+        set: function(val) {
+          this.setAttribute('pin2', val);
+        }
+      },
+      pin3: {
+        get: function() {
+          return this.getAttribute('pin3');
+        },
+        set: function(val) {
+          this.setAttribute('pin3', val);
+        }
+      },
+      pin4: {
+        get: function() {
+          return this.getAttribute('pin4');
+        },
+        set: function(val) {
+          this.setAttribute('pin4', val);
+        }
+      }
+    });
+
+    proto.init_ = function(board) {
+      var Stepper = webduino.module.Stepper;
+      var infoObj = {
+        "stepperNumber": this.stepperNumber,
+        "interface": this.interface,
+        "stepsPerRevolution": this.stepsPerRevolution,
+        "pin1": this.pin1,
+        "pin2": this.pin2,
+        "pin3": this.pin3,
+        "pin4": this.pin4
+      };
+      this.stepper = new Stepper(board, infoObj);
+    };
+
+    proto.on = function(command, callback) {
+      if (typeof callback === 'function') {
+        this.stepper.on(command, function(val) {
+          callback(val);
+        });
+      }
+    };
+
+    proto.detachedCallback = function() {
+      this.stepper.off();
+    };
+
+    document.registerElement('wa-stepper', {
+      prototype: proto
+    });
+
+  })();
+  </script>
+</body>
+
+</html>
\ No newline at end of file

From 6cff161df4e80062cb1ec127c2b95df65f9d2f17 Mon Sep 17 00:00:00 2001
From: marty <marty.shu@gmail.com>
Date: Sun, 7 Aug 2016 17:46:12 +0800
Subject: [PATCH 12/18] add electronic scales (hx711)

---
 demo/hx711.html | 154 ++++++++++++++++++++++++++++++++++++++++++++++++
 wa-hx711.html   |  66 +++++++++++++++++++++
 2 files changed, 220 insertions(+)
 create mode 100644 demo/hx711.html
 create mode 100644 wa-hx711.html

diff --git a/demo/hx711.html b/demo/hx711.html
new file mode 100644
index 0000000..b4e42a1
--- /dev/null
+++ b/demo/hx711.html
@@ -0,0 +1,154 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+  <title>電子秤(hx711)</title>
+  <script src="../../webcomponentsjs/webcomponents.js"></script>
+  <link rel='import' href='../web-arduino.html'></link>
+  <link rel='import' href='../wa-hx711.html'></link>
+  <style>
+  * {
+    font-size: 20px;
+  }
+
+  #msg.default::after {
+    content: "訊息";
+  }
+  
+  #msg.waiting::after {
+    content: "Loading...";
+  }
+  
+  #msg.ready::after {
+    content: "Ready!";
+  }
+  
+  #msg.setting::after {
+    content: "設定中...";
+  }
+  
+  #msg.set::after {
+    content: "設定完成";
+  }
+  
+  input {
+    width: 100px;
+    margin: 5px 0;
+  }
+  
+  button {
+    margin: 5px 0;
+  }
+  
+  #light img {
+    width: 25%;
+    display: none;
+  }
+  
+  #light.off img:first-child {
+    display: inline-block;
+  }
+  
+  #light.on img:last-child {
+    display: inline-block;
+  }
+  
+  #msgRecv {
+    word-break: break-all;
+    height: 300px;
+    width: 100%;
+    overflow: auto;
+  }
+  
+  #msgRecv::before {
+    content: 'message:';
+  }
+  </style>
+</head>
+
+<body>
+  <web-arduino id="board">
+    <wa-hx711 id='hx711' sck='6' dt='7'></wa-hx711>
+  </web-arduino>
+  <div id="msg" class="waiting"></div>
+  <form>
+    <label>device : </label>
+    <input type="text" id="device">
+    <button class="setting" id="set">設定</button>
+  </form>
+  <p>說明：
+    <br>等顯示0g後，季可開始測量物體重量
+  </p>
+
+  <div style="position: relative">
+    <p>點擊燈炮，啟動電子秤</p>
+    <div id='light' class="off">
+      <img src='http://i.imgur.com/T5H4MHE.png'></img>
+      <img src='http://i.imgur.com/8qFj2Ou.png'></img>
+    </div>
+    <div style="position: absolute; top: 0; right: 0; width: 60%;">
+      <button id='clearMsg'>clear message</button>
+      <br>
+      <div id='msgRecv'></div>
+    </div>
+  </div>
+
+  <script>
+  window.addEventListener('WebComponentsReady', function() {
+    var board = document.getElementById('board');
+    var device = document.getElementById('device');
+    var light = document.getElementById('light');
+    var clearMsg = document.getElementById('clearMsg');
+    var msgRecv = document.getElementById('msgRecv');
+    var msg = document.getElementById('msg');
+    var setBtn = document.getElementById('set');
+
+    device.setAttribute('value', localStorage.device || "");
+
+    msg.className = "ready";
+
+    setBtn.addEventListener('click', function(e) {
+      msg.className = "setting";
+      light.className = 'off';
+      msgRecv.innerHTML = '';
+      board.device = device.value;
+      localStorage.device = device.value;
+      board.on('ready', ready);
+      board.init();
+      e.stopPropagation();
+      e.preventDefault();
+      return false;
+    }, false);
+
+    clearMsg.addEventListener('click', function() {
+      msgRecv.innerHTML = '';
+    });
+
+    function ready() {
+      var hx711 = document.getElementById('hx711');
+
+      light.addEventListener('click', function() {
+        if (light.className == 'on') {
+          light.className = 'off';
+          hx711.off();
+        } else {
+          light.className = 'on';
+          hx711.on(callback);
+        }
+      }, false);
+
+      msg.className = "set";
+    }
+
+    function callback(weight) {
+      console.log('callback',weight);
+      var msgRecv = document.getElementById('msgRecv');
+      msgRecv.innerHTML = weight+' g<br>'+msgRecv.innerHTML;
+    }
+  });
+  </script>
+</body>
+
+</html>
diff --git a/wa-hx711.html b/wa-hx711.html
new file mode 100644
index 0000000..8b8c6a3
--- /dev/null
+++ b/wa-hx711.html
@@ -0,0 +1,66 @@
+<html>
+
+<head>
+    <script type="text/javascript" src="../webduino-js/src/module/HX711.js"></script>
+</head>
+
+<body>
+    <script>
+    (function() {
+        var proto = Object.create(HTMLElement.prototype, {
+            sck: {
+                get: function() {
+                    return this.getAttribute('sck');
+                },
+                set: function(val) {
+                    this.setAttribute('sck', val);
+                }
+            },
+            dt: {
+                get: function() {
+                    return this.getAttribute('dt');
+                },
+                set: function(val) {
+                    this.setAttribute('dt', val);
+                }
+            },
+            state: {
+                get: function() {
+                    return this.getAttribute('state');
+                },
+                set: function(val) {
+                    this.setAttribute('state', val);
+                }
+            }
+        });
+
+        proto.init_ = function(board) {
+            var HX711 = webduino.module.HX711;
+            this.hx711 = new HX711(board, board.getDigitalPin(this.sck), board.getDigitalPin(this.dt));
+        };
+
+        proto.on = function(callback) {
+            if (typeof callback === 'function') {
+                this.hx711.on(callback);
+                this._state = 'on';
+            }
+        };
+
+        proto.off = function() {
+            this.hx711.off();
+            this._state = 'off';
+        };
+
+        proto.detachedCallback = function() {
+            this.off();
+        };
+
+        document.registerElement('wa-hx711', {
+            prototype: proto
+        });
+
+    })();
+    </script>
+</body>
+
+</html>
\ No newline at end of file

From 655d7d1ceb1d4fe073bdd641f6f2b74db9cd7781 Mon Sep 17 00:00:00 2001
From: marty <marty.shu@gmail.com>
Date: Sat, 13 Aug 2016 18:43:43 +0800
Subject: [PATCH 13/18] add barcode webcomponent

---
 demo/barcode.html | 151 ++++++++++++++++++++++++++++++++++++++++++++++
 wa-barcode.html   |  66 ++++++++++++++++++++
 2 files changed, 217 insertions(+)
 create mode 100644 demo/barcode.html
 create mode 100644 wa-barcode.html

diff --git a/demo/barcode.html b/demo/barcode.html
new file mode 100644
index 0000000..22c86cd
--- /dev/null
+++ b/demo/barcode.html
@@ -0,0 +1,151 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+  <title>Barcode Scanner</title>
+  <script src="../../webcomponentsjs/webcomponents.js"></script>
+  <link rel='import' href='../web-arduino.html'></link>
+  <link rel='import' href='../wa-barcode.html'></link>
+  <style>
+  * {
+    font-size: 20px;
+  }
+
+  #msg.default::after {
+    content: "訊息";
+  }
+  
+  #msg.waiting::after {
+    content: "Loading...";
+  }
+  
+  #msg.ready::after {
+    content: "Ready!";
+  }
+  
+  #msg.setting::after {
+    content: "設定中...";
+  }
+  
+  #msg.set::after {
+    content: "設定完成";
+  }
+  
+  input {
+    width: 100px;
+    margin: 5px 0;
+  }
+  
+  button {
+    margin: 5px 0;
+  }
+  
+  #light img {
+    width: 25%;
+    display: none;
+  }
+  
+  #light.off img:first-child {
+    display: inline-block;
+  }
+  
+  #light.on img:last-child {
+    display: inline-block;
+  }
+  
+  #msgRecv {
+    word-break: break-all;
+    height: 300px;
+    width: 100%;
+    overflow: auto;
+  }
+  
+  #msgRecv::before {
+    content: 'message:';
+  }
+  </style>
+</head>
+
+<body>
+  <web-arduino id="board">
+    <wa-barcode id='barcode' rx='2' tx='3'></wa-barcode>
+  </web-arduino>
+  <div id="msg" class="waiting"></div>
+  <form>
+    <label>device : </label>
+    <input type="text" id="device">
+    <button class="setting" id="set">設定</button>
+  </form>
+  <p>說明：</p>
+  <div style="position: relative">
+    <p>點擊燈炮，啟動接收Barcode資料</p>
+    <div id='light' class="off">
+      <img src='http://i.imgur.com/T5H4MHE.png'></img>
+      <img src='http://i.imgur.com/8qFj2Ou.png'></img>
+    </div>
+    <div style="position: absolute; top: 0; right: 0; width: 60%;">
+      <button id='clearMsg'>clear message</button>
+      <br>
+      <div id='msgRecv'></div>
+    </div>
+  </div>
+
+  <script>
+  window.addEventListener('WebComponentsReady', function() {
+    var board = document.getElementById('board');
+    var device = document.getElementById('device');
+    var light = document.getElementById('light');
+    var clearMsg = document.getElementById('clearMsg');
+    var msgRecv = document.getElementById('msgRecv');
+    var msg = document.getElementById('msg');
+    var setBtn = document.getElementById('set');
+
+    device.setAttribute('value', localStorage.device || "");
+
+    msg.className = "ready";
+
+    setBtn.addEventListener('click', function(e) {
+      msg.className = "setting";
+      light.className = 'off';
+      msgRecv.innerHTML = '';
+      board.device = device.value;
+      localStorage.device = device.value;
+      board.on('ready', ready);
+      board.init();
+      e.stopPropagation();
+      e.preventDefault();
+      return false;
+    }, false);
+
+    clearMsg.addEventListener('click', function() {
+      msgRecv.innerHTML = '';
+    });
+
+    function ready() {
+      var barcode = document.getElementById('barcode');
+
+      light.addEventListener('click', function() {
+        if (light.className == 'on') {
+          light.className = 'off';
+          barcode.off();
+        } else {
+          light.className = 'on';
+          barcode.on(callback);
+        }
+      }, false);
+
+      msg.className = "set";
+    }
+
+    function callback(scanData) {
+      console.log('callback',scanData);
+      var msgRecv = document.getElementById('msgRecv');
+      msgRecv.innerHTML = scanData+'<br>'+msgRecv.innerHTML;
+    }
+  });
+  </script>
+</body>
+
+</html>
diff --git a/wa-barcode.html b/wa-barcode.html
new file mode 100644
index 0000000..e4bff0b
--- /dev/null
+++ b/wa-barcode.html
@@ -0,0 +1,66 @@
+<html>
+
+<head>
+    <script type="text/javascript" src="../webduino-js/src/module/Barcode.js"></script>
+</head>
+
+<body>
+    <script>
+    (function() {
+        var proto = Object.create(HTMLElement.prototype, {
+            rx: {
+                get: function() {
+                    return this.getAttribute('rx');
+                },
+                set: function(val) {
+                    this.setAttribute('rx', val);
+                }
+            },
+            tx: {
+                get: function() {
+                    return this.getAttribute('tx');
+                },
+                set: function(val) {
+                    this.setAttribute('tx', val);
+                }
+            },
+            state: {
+                get: function() {
+                    return this.getAttribute('state');
+                },
+                set: function(val) {
+                    this.setAttribute('state', val);
+                }
+            }
+        });
+
+        proto.init_ = function(board) {
+            var Barcode = webduino.module.Barcode;
+            this.barcode = new Barcode(board, board.getDigitalPin(this.rx), board.getDigitalPin(this.tx));
+        };
+
+        proto.on = function(callback) {
+            if (typeof callback === 'function') {
+                this.barcode.on(callback);
+                this._state = 'on';
+            }
+        };
+
+        proto.off = function() {
+            this.barcode.off();
+            this._state = 'off';
+        };
+
+        proto.detachedCallback = function() {
+            this.off();
+        };
+
+        document.registerElement('wa-barcode', {
+            prototype: proto
+        });
+
+    })();
+    </script>
+</body>
+
+</html>
\ No newline at end of file

From 2c3859d03b20a0ea8f9f38b7f9a4ff722ac4cbab Mon Sep 17 00:00:00 2001
From: "Ke, Mingze" <mingze.ke@gmail.com>
Date: Fri, 9 Sep 2016 18:38:30 +0800
Subject: [PATCH 14/18] use webduino-js#dist

---
 bower.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bower.json b/bower.json
index 075441c..97d3d22 100644
--- a/bower.json
+++ b/bower.json
@@ -7,6 +7,6 @@
   "license": "MIT",
   "dependencies": {
     "webcomponentsjs": "0.x",
-    "webduino-js": "master"
+    "webduino-js": "dist"
   }
 }

From 121de95f2e81fcaa8bf9c2a7c336db0526cd6699 Mon Sep 17 00:00:00 2001
From: marty <marty.shu@gmail.com>
Date: Mon, 19 Sep 2016 20:37:56 +0800
Subject: [PATCH 15/18] add websocket

---
 web-arduino.html | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/web-arduino.html b/web-arduino.html
index 564c152..e1e8e8e 100644
--- a/web-arduino.html
+++ b/web-arduino.html
@@ -9,7 +9,6 @@
 <body>
   <script>
   (function() {
-
     var count_ = 0;
 
     var proto = Object.create(HTMLElement.prototype, {
@@ -68,6 +67,14 @@
         set: function(val) {
           this.setAttribute('address', val);
         }
+      },
+      ws: {
+        get: function() {
+          return this.getAttribute('ws');
+        },
+        set: function(val) {
+          this.setAttribute('ws', val);
+        }
       }
     });
 
@@ -85,9 +92,10 @@
         autoReconnect = self.autoReconnect,
         path = self.path,
         baudRate = self.baudRate,
-        address = self.address;
+        address = self.address,
+        ws = self.ws;
 
-      if (device || path || address) {
+      if (device || path || address || ws) {
         if (device) {
           self.board = board = new WebArduino(util.extend({
             device: device
@@ -103,11 +111,16 @@
           }, {
             baudRate: baudRate || undefined
           }));
-        } else {
+        } else if (address){
           self.board = board = new Arduino({
             transport: 'bluetooth',
             address: address
           });
+        } else {
+          self.board = board = new Arduino({
+            transport: 'websocket',
+            url: ws
+          })
         }
 
         board.on(BoardEvent.READY, function(event) {

From d8401f2ba6ea7443505c2d5a016b79798f1d938e Mon Sep 17 00:00:00 2001
From: marty <marty.shu@gmail.com>
Date: Sat, 7 Jan 2017 16:59:46 +0800
Subject: [PATCH 16/18] add ssd1306 support

---
 demo/oled.html  | 29 ++++++++++++++++++++
 wa-ssd1306.html | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+)
 create mode 100644 demo/oled.html
 create mode 100644 wa-ssd1306.html

diff --git a/demo/oled.html b/demo/oled.html
new file mode 100644
index 0000000..66357e4
--- /dev/null
+++ b/demo/oled.html
@@ -0,0 +1,29 @@
+<html>
+
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+  <title>OLED(SSD1306)</title>
+  <script src="../../webcomponentsjs/webcomponents.min.js"></script>
+  <link rel='import' href='../web-arduino.html'></link>
+  <link rel='import' href='../wa-ssd1306.html'></link>
+</head>
+
+<body>
+  <web-arduino id='board' device="10X417v3">
+    <wa-ssd1306 id='display' x='0' y='0' textSize='2' text="OLED Test">
+    </wa-ssd1306>
+  </web-arduino>
+  <script>
+  window.addEventListener('WebComponentsReady', function() {
+    var board = document.getElementById('board');
+    board.on('ready', function() {
+      console.log("board ready...");
+      display.textSize = 4;
+      display.print(40, 30, "OK");
+    });
+  });
+  </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/wa-ssd1306.html b/wa-ssd1306.html
new file mode 100644
index 0000000..65c4121
--- /dev/null
+++ b/wa-ssd1306.html
@@ -0,0 +1,73 @@
+<html>
+
+<head>
+  <script type="text/javascript" src="../webduino-js/src/module/SSD1306.js"></script>
+</head>
+
+<body>
+  <script>
+  (function() {
+    var proto = Object.create(HTMLElement.prototype, {
+      textSize: {
+        get: function() {
+          return this.getAttribute('textSize');
+        },
+        set: function(val) {
+          this.setAttribute('textSize', val);
+        }
+      },
+      x: {
+        get: function() {
+          return this.getAttribute('x');
+        },
+        set: function(val) {
+          this.setAttribute('x', val);
+        }
+      },
+      y: {
+        get: function() {
+          return this.getAttribute('y');
+        },
+        set: function(val) {
+          this.setAttribute('y', val);
+        }
+      },
+      text: {
+        get: function() {
+          return this.getAttribute('text');
+        },
+        set: function(val) {
+          this.setAttribute('text', val);
+        }
+      }
+    });
+
+    proto.init_ = function(board) {
+      this.display = new webduino.module.SSD1306(board);
+      this.display.clear();
+      this.display.textSize = this.textSize;
+      this.display.print(this.x, this.y, this.text);
+    };
+
+    proto.print = function(x, y, text) {
+      this.display.textSize = this.textSize;
+      this.display.print(x, y, text);
+    };
+
+    proto.clear = function() {
+      this.display.clear();
+    };
+
+    proto.detachedCallback = function() {
+      //this.off();
+    };
+
+    document.registerElement('wa-ssd1306', {
+      prototype: proto
+    });
+
+  })();
+  </script>
+</body>
+
+</html>
\ No newline at end of file

From b948dee308e4f057d69c43addf5f64105cc5288e Mon Sep 17 00:00:00 2001
From: marty <marty.shu@gmail.com>
Date: Tue, 10 Jan 2017 11:41:50 +0800
Subject: [PATCH 17/18] remove unless step

---
 README.md | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/README.md b/README.md
index 3f6e1c6..e6e8b22 100644
--- a/README.md
+++ b/README.md
@@ -8,13 +8,6 @@ Web components for Webduino
 $ bower install webduino
 ```
 
-Build webduino-js dist files:
-
-```Shell
-$ cd bower_components/webduino-js
-$ npm install && npm run build
-```
-
 ## Usage
 
 Insert webduino web-components and polyfill:

From 82ed174cddd8887238f2a056e084c3262ff3a92e Mon Sep 17 00:00:00 2001
From: osk2 <sc60714@gmail.com>
Date: Mon, 17 Apr 2017 17:47:32 +0800
Subject: [PATCH 18/18] Update README.md

---
 README.md | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index e6e8b22..cd99ce5 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ $ bower install webduino
 
 Insert webduino web-components and polyfill:
 
-```
+```html
 <script src='bower_components/webcomponentsjs/webcomponents.js'></script>
 <link rel='import' href='bower_components/webduino/web-arduino.html'></link>
 <link rel='import' href='bower_components/webduino/wa-led.html'></link>
@@ -20,7 +20,7 @@ Insert webduino web-components and polyfill:
 
 Use it in your html:
 
-```
+```html
 <web-arduino id='board' device='device_id'>
   <wa-led id='led' pin='10'></wa-led>
 </web-arduino>
@@ -47,4 +47,6 @@ _(coming soon...)_
 
 [webduino-js](https://github.com/webduinoio/webduino-js) (The javascript core that powers webduino)
 
-## [License](LICENSE)
\ No newline at end of file
+## License
+
+This project is licensed under MIT, please see [LICENSE](LICENSE) for more information.
