Noduino OpenLight

来自Jack's Lab
(版本间的差异)
跳转到: 导航, 搜索
(Open API)
(Power)
 
(未显示1个用户的85个中间版本)
第4行: 第4行:
 
OpenLight Bulb:
 
OpenLight Bulb:
  
[[文件:Openbulb-12.jpg | 600px]]
+
[[文件:Openlight-bulb-1024.jpg | 760px]]
[[文件:Openbulb-8.jpg | 600px]]
+
 
+
  
 
OpenLight Controller:
 
OpenLight Controller:
  
[[文件:OpenLight-Controller-2.jpg | 600px]]
+
[[文件:OpenLight-ceiling-1-1280.jpg | 760px]]
[[文件:Openlight-ctrl-demo.jpg | 600px]]
+
  
 +
[[文件:OpenLight-ceiling-4-1280.jpg | 760px]]
 +
 +
[[文件:Openlight-ctrl-demo.jpg | 760px]]
 +
 +
 +
[[文件:Noduino-works-with-logo.png | 600px]]
  
 
<br><br>
 
<br><br>
第21行: 第24行:
 
[[文件:Maike-wifi-bulb-2955-all-en.jpg]]
 
[[文件:Maike-wifi-bulb-2955-all-en.jpg]]
  
* Power on, waiting 8s to light
+
 
 +
* Install the WeChat APP from AppStore or GooglePlay
 +
 
 +
* Power on, waiting to light
  
 
* Light is flashing slowly in red means waiting for network connection
 
* Light is flashing slowly in red means waiting for network connection
  
* If the light is not flashing in red, please turn on and off 3 times, (eg. turn on - light on - turn off, 3 times) the light will be in red gradient for network connection
+
* If the light is not flashing in red, turn on and off 3 times, (eg. turn on - light on - turn off, 3 times) the light will be in red gradient for network connection. (Light is flashing slowly in red means waiting for network connection)
  
* Connect mobile to Wifi then scan QR code in WeChat to click “Network Connection”
+
* Connect mobile to WiFi router, open WeChat APP, enter ‘Discover’ -> ‘scan QR code’, scan the upright QR code to click “Network Connection”
  
 
* Enter WiFi password, click "Connect" then waiting for network connecting complete. (P.S. only 2.4G WiFi is applicable, 5G WiFi and WiFi enterprise-level security certifications are not applicable)
 
* Enter WiFi password, click "Connect" then waiting for network connecting complete. (P.S. only 2.4G WiFi is applicable, 5G WiFi and WiFi enterprise-level security certifications are not applicable)
第35行: 第41行:
 
* Click the first device then press "Link Device" button to bind the device. (P.S. if the device has been binding, then the button at bottom is "Enter Official Account")
 
* Click the first device then press "Link Device" button to bind the device. (P.S. if the device has been binding, then the button at bottom is "Enter Official Account")
  
* Finish above steps, please press "Enter Official Account" button then click "My Device" button to find your binding devices list. Click the device to enter control page.
+
* Finish above steps, please press "Enter Official Account" button then click "Devices" button to find your binding devices list. Click the device to enter control page.
  
  
[[文件:Openlight-ui.jpg | 640px]]
+
[[文件:Openlight-wechat-ui.jpg | 800px]]
  
  
第66行: 第72行:
 
<source lang=php>
 
<source lang=php>
 
var devid = YOUR_DEVICE_ID;
 
var devid = YOUR_DEVICE_ID;
var mqtt_uname = xxxxxxxx;
+
var mqtt_uname = YOUR_MQTT_UNAME;
var mqtt_pass = TTTTTTTTTTTTTTTT;                          < ---- 3600s life time
+
var mqtt_server = xxx.xxx.xxx.xxx;
+
var mqtt_port = xxx;
+
 
</source>
 
</source>
  
 +
<br><br>
 +
 +
=== Go ===
 +
 +
==== Prepare ====
 +
 +
Prepare  the Go lang:
 +
 +
<source lang=bash>
 +
$ sudo apt-get install golang-go
 +
$ sudo apt-get install golang-eclipse-paho-dev
 +
$ export GOPATH=/usr/share/gocode
 +
</source>
 +
 +
Refer to:
 +
 +
* https://golang.org
 +
* http://www.eclipse.org/paho/clients/golang/
 +
 +
<br>
 +
 +
==== Turn On/Off ====
 +
 +
<source lang=cpp>
 +
package main
 +
 +
import (
 +
"fmt"
 +
"os"
 +
"strconv"
 +
"strings"
 +
"net/http"
 +
"encoding/json"
 +
MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
 +
)
 +
 +
//define a function for the default message handler
 +
var f MQTT.MessageHandler = func(client *MQTT.Client, msg MQTT.Message) {
 +
fmt.Printf("TOPIC: %s\n", msg.Topic())
 +
fmt.Printf("MSG: %s\n", msg.Payload())
 +
}
 +
 +
var uid string = "YOUR_mqtt_uname"
 +
 +
func main() {
 +
if len(os.Args[1:]) >= 2 {
 +
 +
devid := os.Args[1]
 +
cmd := os.Args[2]
 +
msg := ""
 +
 +
if cmd == "on" {
 +
msg = "{\"m\":\"set\", \"d\":{\"s\":1}}"
 +
} else if cmd == "off" {
 +
msg = "{\"m\":\"set\", \"d\":{\"s\":0}}"
 +
} else if cmd == "ota" {
 +
msg = "ota"
 +
} else if _, err := strconv.Atoi(cmd); err == nil {
 +
msg = "{\"m\":\"bri\", \"d\":" + cmd + "}"
 +
}
 +
 +
pass := get_token(uid)
 +
send_msg(devid, msg, pass)
 +
 +
} else {
 +
help_msg()
 +
}
 +
}
 +
 +
func help_msg() {
 +
fmt.Println("Supported cmd:")
 +
fmt.Println("\topenlight dev_id on")
 +
fmt.Println("\topenlight dev_id off")
 +
fmt.Println("\topenlight dev_id 23")
 +
fmt.Println("\topenlight dev_id ota")
 +
}
 +
 +
func send_msg(devid string, msg string, pass string) {
 +
 +
opts := MQTT.NewClientOptions().AddBroker("tcp://mqtt.noduino.org:1883")
 +
opts.SetClientID("cid_" + devid)
 +
opts.SetUsername(devid)
 +
opts.SetPassword(pass)
 +
opts.SetDefaultPublishHandler(f)
 +
 +
c := MQTT.NewClient(opts)
 +
if token := c.Connect(); token.Wait() && token.Error() != nil {
 +
panic(token.Error())
 +
}
 +
 +
mqtt_tx_topic := "app2dev/" + devid
 +
 +
token := c.Publish(mqtt_tx_topic, 0, false, msg)
 +
token.Wait()
 +
}
 +
 +
func get_token(user_id string) (string) {
 +
url := "http://api.noduino.org/user/token"
 +
 +
type Body struct {
 +
UID string `json:"user_id"`
 +
}
 +
 +
var body = Body {
 +
UID: user_id,
 +
}
 +
 +
data, err := json.Marshal(body)
 +
//fmt.Println(string(data))
 +
 +
if err == nil {
 +
resp, err := http.Post(url, "application/json", strings.NewReader(string(data)))
 +
if err != nil {
 +
fmt.Println(err)
 +
}
 +
defer resp.Body.Close()
 +
 +
dec := json.NewDecoder(resp.Body)
 +
var v map[string]interface{}
 +
if err := dec.Decode(&v); err != nil {
 +
fmt.Printf("error: %v\n", err)
 +
} else {
 +
if val, ok := v["user_token"].(string); ok {
 +
return val
 +
}
 +
}
 +
}
 +
 +
return ""
 +
}
 +
</source>
 +
 +
 +
<source lang=bash>
 +
$ go build openlight.go
 +
$ ./openlight MKD12343405300  on
 +
$ ./openlight MKD12343405300  off
 +
</source>
 +
 +
<br><br>
 +
 +
==== Set Brightness ====
 +
 +
<source lang=bash>
 +
$ go build openlight.go
 +
$ ./openlight MKD12343405300  255
 +
$ ./openlight MKD12343405300  10
 +
</source>
 +
 +
<br><br>
 +
 +
=== node.js ===
 +
 +
Prepare the node.js:
 +
 +
<source lang=bash>
 +
# download the node-v6.9.1-xxx.tgz from http://nodejs.org
 +
$ tar xf node-v6.9.1-*.tar.xz
 +
$ sudo cp -a node-v6.9.1*/*  /usr/local/
 +
$ sudo npm install -g MQTTClient
 +
$ sudo npm install -g request
 +
</source>
 +
 +
<br><br>
 +
 +
==== Turn Off ====
 +
 +
Using the node.js to switch off the OpenLigh:
 +
 +
<source lang=bash>
 +
$ cat light-off.js
 +
#! /usr/bin/env node
 +
 +
var opt = {
 +
    username: "YOUR_mqtt_uname",
 +
    password: ""
 +
};
 +
var http_req = require('/usr/local/lib/node_modules/request');
 +
http_req.post(
 +
'http://api.noduino.org/user/token',
 +
{ json: {user_id: opt.username} },
 +
function (error, response, body) {
 +
if (!error && response.statusCode == 200) {
 +
console.log(body);
 +
 +
opt.password = body.user_token;
 +
 +
var MQTTClient = require('MQTTClient').Client;
 +
var client = new MQTTClient('mqtt.noduino.org', 1883, opt);
 +
client.connect(function () {
 +
console.log("connect ok!");
 +
 +
var pubopt = {
 +
qos_level:  2
 +
};
 +
 +
var state = {
 +
on: 0          <---- off
 +
};
 +
var data = '{"m":"set", "d":{' + '"s":' + state.on + '}}';
 +
client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) {
 +
console.log("public ok! message_id = " + message_id);
 +
process.exit(0);
 +
});
 +
});
 +
} else {
 +
console.log("Request the user token failed");
 +
process.exit(1);
 +
}
 +
}
 +
);
 +
 +
$ ./light-off.js
 +
</source>
 +
 +
<br><br>
 +
 +
==== Turn On ====
 +
 +
Turn on the OpenLight:
 +
 +
<source lang=bash>
 +
$ cat light-on.js
 +
#! /usr/bin/env node
 +
 +
var opt = {
 +
    username: "YOUR_mqtt_uname",
 +
    password: ""
 +
};
 +
var http_req = require('/usr/local/lib/node_modules/request');
 +
http_req.post(
 +
'http://api.noduino.org/user/token',
 +
{ json: {user_id: opt.username, app_id:"mj2030064278", app_key:"0077d4829f52b1b2d668f8a82c5f5ded"} },
 +
function (error, response, body) {
 +
if (!error && response.statusCode == 200) {
 +
console.log(body);
 +
 +
opt.password = body.user_token;
 +
 +
var MQTTClient = require('MQTTClient').Client;
 +
var client = new MQTTClient('mqtt.noduino.org', 1883, opt);
 +
client.connect(function () {
 +
console.log("connect ok!");
 +
 +
var pubopt = {
 +
qos_level:  2
 +
};
 +
 +
var state = {
 +
on: 1          <---- on
 +
};
 +
var data = '{"m":"set", "d":{' + '"s":' + state.on + '}}';
 +
client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) {
 +
console.log("public ok! message_id = " + message_id);
 +
process.exit(0);
 +
});
 +
});
 +
} else {
 +
console.log("Request the user token failed");
 +
process.exit(1);
 +
}
 +
}
 +
);
 +
 +
$ ./light-on.js
 +
</source>
 +
 +
<br><br>
 +
 +
==== Set Color ====
 +
 +
Change the color of the OpenLight:
 +
 +
<source lang=bash>
 +
$ cat light-color.js
 +
#! /usr/bin/env node
 +
 +
var opt = {
 +
    username: "YOUR_mqtt_uname",
 +
    password: ""
 +
};
 +
 +
var http_req = require('/usr/local/lib/node_modules/request');
 +
http_req.post(
 +
'http://api.noduino.org/user/token',
 +
{ json: {user_id: opt.username, app_id:"mj2030064278", app_key:"0077d4829f52b1b2d668f8a82c5f5ded"} },
 +
function (error, response, body) {
 +
if (!error && response.statusCode == 200) {
 +
console.log(body);
 +
 +
opt.password = body.user_token;
 +
 +
var MQTTClient = require('MQTTClient').Client;
 +
var client = new MQTTClient('mqtt.noduino.org', 1883, opt);
 +
client.connect(function () {
 +
console.log("connect ok!");
 +
 +
var pubopt = {
 +
qos_level:  2
 +
};
 +
 +
var state = {
 +
red: 0,
 +
green: 0,
 +
blue: 255,    <--------- outputting full power of the blue channel
 +
white: 0,
 +
on: 1
 +
};
 +
 +
data = '{"m":"set", "d":{' + '"r":' + state.red + ',"g":' + state.green
 +
      + ',"b":' + state.blue + ',"w":' + state.white
 +
      + ',"s":' + state.on + '}}';
 +
client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) {
 +
console.log("public ok! message_id = " + message_id);
 +
process.exit(0);
 +
});
 +
});
 +
} else {
 +
console.log("Request the user token failed");
 +
process.exit(1);
 +
}
 +
}
 +
);
 +
 +
$ ./light-color.js
 +
</source>
 +
 +
<br><br>
 +
 +
==== FAQ ====
 +
 +
<font color=red><b>If you get the following error:</b></font>
 +
 +
<source lang=bash>
 +
/usr/local/lib/node_modules/MQTTClient/client.js:56
 +
throw Error('user names are kept to 12 characters or fewer');
 +
^
 +
 +
Error: user names are kept to 12 characters or fewer
 +
</source>
 +
 +
Please patch the /usr/local/lib/node_modules/MQTTClient/client.js to remove the line of checking the length of username and password:
 +
 +
<source lang=bash>
 +
--- a/client.js
 +
+++ b/client.js
 +
@@ -52,10 +52,10 @@ var Client = exports.Client = function (host, port, options) {
 +
                options.alive_timer = 30;
 +
        options.ping_timer = parseInt(options.alive_timer * 0.6 * 1000);
 +
        // 用户名和密码
 +
-      if (typeof options.username == 'string' && options.username.length > 12)
 +
-              throw Error('user names are kept to 12 characters or fewer');
 +
-      if (typeof options.password == 'string' && options.password.length > 12)
 +
-              throw Error('passwords are kept to 12 characters or fewer');
 +
+      //if (typeof options.username == 'string' && options.username.length > 12)
 +
+      //      throw Error('user names are kept to 12 characters or fewer');
 +
+      //if (typeof options.password == 'string' && options.password.length > 12)
 +
+      //      throw Error('passwords are kept to 12 characters or fewer');
 +
        // Will flag
 +
        if (options.will_flag && (typeof options.will_topic != 'string' || typeof options.will_message != 'string'))
 +
                throw Error('missing will_topic or will_message when will_flag is set');
 +
</source>
 +
 +
<br><br>
 +
 +
=== python ===
 +
 +
==== Prepare ====
 +
 +
<source lang=bash>
 +
$ python3 --version
 +
Python 3.5.3rc1
 +
 +
$ pip3 install paho-mqtt
 +
Collecting paho-mqtt
 +
  Downloading paho-mqtt-1.2.tar.gz (49kB)
 +
    100% |████████████████████████████████| 51kB 308kB/s
 +
Building wheels for collected packages: paho-mqtt
 +
  Running setup.py bdist_wheel for paho-mqtt ... done
 +
  Stored in directory: /home/comcat/.cache/pip/wheels/fa/db/fb/b495e37057e2f40534726b3c00ab26a58fc80fb8d17223df07
 +
Successfully built paho-mqtt
 +
Installing collected packages: paho-mqtt
 +
Successfully installed paho-mqtt-1.2
 +
</source>
 +
 +
 +
More infor: https://pypi.python.org/pypi/paho-mqtt
 +
 +
<br>
 +
 +
==== Turn off ====
 +
 +
* replace the mqtt_uname in line 10
 +
 +
<source lang=python>
 +
$ cat openlight.py
 +
#!/usr/bin/python3
 +
 +
import json, requests
 +
import paho.mqtt.client as mqtt
 +
import sys
 +
 +
# replace it to your id
 +
###########################################
 +
mqtt_uname = 'o7okr76757879RfhBs_XM339'    <---- YOUR_mqtt_uname
 +
devid = 'MJD123456789012'                  <---- YOUR_devid
 +
###########################################
 +
 +
# mqtt json message
 +
###########################################
 +
# {"m":"set", "d":{"r":255,"g":255,"b":255,"w":255,"s":1}}
 +
# {"m":"bri", "d":23}  -->  bri:[0, 255]
 +
# {"m":"set_voice_name", "d":"room light"}
 +
# {"m":"get_voice_name"}
 +
# {"m":"get_state"}
 +
# ota
 +
###########################################
 +
 +
DEBUG = True
 +
 +
def dbg(msg):
 +
    global DEBUG
 +
    if DEBUG:
 +
        print(msg)
 +
        sys.stdout.flush()
 +
 +
#http://docs.python-requests.org/en/latest/user/quickstart/#json-response-content
 +
 +
def help_msg():
 +
    print("Supported cmd:")
 +
    print("\tlight.py dev_id on")
 +
    print("\tlight.py dev_id off")
 +
    print("\tlight.py dev_id 23")
 +
    print("\tlight.py dev_id ota")
 +
    print("\tlight.py dev_id set_vn \"kitchen light\"")
 +
    print("\tlight.py dev_id get_vn")
 +
 +
if len(sys.argv) >= 2:
 +
    devid = sys.argv[1]
 +
    set_state = sys.argv[2]
 +
else:
 +
    help_msg()
 +
    sys.exit(-2)
 +
 +
if set_state == "on":
 +
    mqtt_msg = '{"m":"set", "d":{"s":1}}'
 +
elif set_state == "off":
 +
    mqtt_msg = '{"m":"set", "d":{"s":0}}'
 +
elif set_state.isdigit():
 +
    mqtt_msg = '{"m":"bri", "d":' + set_state + '}'
 +
elif set_state == "ota":
 +
    mqtt_msg = "ota"
 +
elif set_state == "get_state":
 +
    mqtt_msg = '{"m":"get_state", "d":""}'
 +
elif set_state == "set_vn":
 +
    mqtt_msg = '{"m":"set_voice_name", "d":"' + sys.argv[3] + '"}'
 +
elif set_state == "get_vn":
 +
    mqtt_msg = '{"m":"get_voice_name", "d":""}'
 +
elif set_state == "set_cold_on":
 +
    mqtt_msg = '{"m":"set_cold_on", "d":' + sys.argv[3] + '}'
 +
elif set_state == "get_cold_on":
 +
    mqtt_msg = '{"m":"get_cold_on", "d":""}'
 +
elif set_state == "set_grad_on":
 +
    mqtt_msg = '{"m":"set_grad_on", "d":' + sys.argv[3] + '}'
 +
elif set_state == "get_grad_on":
 +
    mqtt_msg = '{"m":"get_grad_on", "d":""}'
 +
elif set_state == "set_alexa_on":
 +
    mqtt_msg = '{"m":"set_alexa_on", "d":' + sys.argv[3] + '}'
 +
elif set_state == "get_alexa_on":
 +
    mqtt_msg = '{"m":"get_alexa_on", "d":""}'
 +
else:
 +
    help_msg()
 +
    sys.exit(-2)
 +
 +
url = 'http://api.noduino.org/user/login'
 +
 +
dat = dict (
 +
        user_id = mqtt_uname,
 +
        app_id = 'mj2030064278',
 +
        app_key = '0077d4829f52b1b2d668f8a82c5f5ded'
 +
)
 +
 +
#print(json.dumps(dat))
 +
try:
 +
    resp = requests.post(url = url, json = dat)
 +
except Exception as e:
 +
    dbg(e)
 +
    sys.exit(-1)
 +
 +
mqtt_rx_topic = 'dev2app/' + devid
 +
mqtt_tx_topic = 'app2dev/' + devid
 +
 +
mqtt_host = 'mqtt.noduino.org'
 +
mqtt_port = 1883
 +
 +
print("mqtt msg: " + mqtt_msg)
 +
 +
def on_connect(client, u_dat, rc):
 +
    if rc == 0:
 +
        print("Connected successfully")
 +
    else:
 +
        print("Connection failed. rc = "+str(rc))
 +
 +
def on_publish(client, u_dat, rc):
 +
    print("Message "+str(rc)+" published.")
 +
 +
def on_subscribe(client, u_dat, mid, qos):
 +
    print("Subscribe with "+str(mid)+" received")
 +
 +
def on_message(client, udat, msg):
 +
    print("Message received on topic "+msg.topic+" and payload "+str(msg.payload))
 +
 +
mqttc = mqtt.Client()
 +
 +
mqttc.on_connect = on_connect
 +
mqttc.on_publish = on_publish
 +
mqttc.on_subscribe = on_subscribe
 +
mqttc.on_message = on_message
 +
 +
#mqttc.username_pw_set(mqtt_uname, mqtt_pass)
 +
mqttc.username_pw_set(tu, tp)
 +
mqttc.connect(mqtt_host, mqtt_port)
 +
 +
mqttc.publish(mqtt_tx_topic, mqtt_msg)
 +
 +
mqttc.subscribe(mqtt_rx_topic)
 +
mqttc.loop_forever()
 +
</source>
 +
 +
 +
<source lang=bash>
 +
$ ./openlight.py your_dev_id off
 +
</source>
 +
 +
<br>
 +
 +
==== Turn On ====
 +
 +
Turn on the bulb:
 +
 +
<source lang=bash>
 +
$ ./openlight.py your_dev_id on
 +
</source>
 +
 +
<br><br>
 +
 +
==== OTA ====
 +
 +
* upload your firmware through http://dev.noduino.org/openlight
 +
 +
* request device to download your new firmware:
 +
 +
<source lang=bash>
 +
$ ./openlight.py your_dev_id ota
 +
</source>
 +
 +
<br><br>
 +
 +
=== HTML5 ===
  
 
The device control page in WeChat is a H5 page. Using a MQTT  client implement in javascript , using the mqttws31.js library:
 
The device control page in WeChat is a H5 page. Using a MQTT  client implement in javascript , using the mqttws31.js library:
第128行: 第690行:
 
</source>
 
</source>
  
 +
<br><br>
  
Using the node.js to switch off the OpenLigh:
+
== Open API (HTTP in LAN) ==
  
<source lang=bash>
+
<b style="color:#f00">Note: the device security policy using the WiFi router's password, that is: the users who are authorized to connect to the WiFi router, is a trusted user</b>
$ sudo npm install -g MQTTClient
+
$ cat switch-off.js
+
#! /usr/bin/env node
+
  
var opt = {
+
Device start a HTTP service by default. You can send the following HTTP request to turn on or turn off the device. This way independent of MQTT cloud service can be used in local area network when you don't want to make device access Internet.
    username: "YOUR_mqtt_uname",
+
    password: "YOUR_mqtt_pass"
+
};
+
  
var MQTTClient = require('MQTTClient').Client;
+
<br>
  
var client = new MQTTClient('YOUR_mqtt_server', 1883, opt);
+
=== Get the device IP ===
  
client.connect(function () {
+
You can use the Fing app in iOS to scan the LAN network.
console.log("connect ok!");
+
  
var pubopt = {
+
The device named '''Espressif''' is your OpenLight device:
qos_level: 2
+
};
+
  
var state = {
 
red: 0,
 
green: 0,
 
blue: 0,
 
white: 0,
 
on: 0
 
};
 
  
    var data = '{"m":"set", "d":{' + '"s":' + state.on + '}}';
+
[[文件:Fing-lan-scan.png | 400px]]
    client.publish('app2dev/YOUR_devid', data, pubopt, function (message_id) {
+
            console.log("public ok! message_id = " + message_id);
+
});
+
});
+
  
$ ./light-off.js
+
<br>
</source>
+
  
 +
=== Turn On via HTTP ===
  
Turn on the OpenLight:
+
192.168.1.75 is the OpenLight device IP
 +
 
 +
Turn On:
  
 
<source lang=bash>
 
<source lang=bash>
$ cat light-on.js
+
$ cat light-on.txt
#! /usr/bin/env node
+
PUT /api/noduino/lights/0/state HTTP/1.1
 +
Host: 192.168.1.75
 +
Accept: */*
 +
Content-type: application/x-www-form-urlencoded
 +
Content-Length: 12
  
var opt = {
+
{"on": true}
    username: "YOUR_mqtt_uname",
+
$ cat light-on.txt | nc 192.168.1.75 80
    password: "YOUR_mqtt_pass"
+
HTTP/1.0 200 OK
};
+
Server: lwIP/1.4.0
 +
Content-type: text/plain
 +
Content-Length: 0
 +
Connection: close
  
var MQTTClient = require('MQTTClient').Client;
+
</source>
  
var client = new MQTTClient('YOUR_mqtt_server', 1883, opt);
+
<br>
  
client.connect(function () {
+
=== Turn Off via HTTP ===
console.log("connect ok!");
+
  
var pubopt = {
+
192.168.1.75 is the OpenLight device IP
qos_level:  2
+
};
+
  
var state = {
+
Turn Off:
red: 0,
+
green: 0,
+
blue: 0,
+
white: 0,
+
on: 1            <--------- on
+
};
+
  
var data = '{"m":"set", "d":{' + '"s":' + state.on + '}}';
+
<source lang=bash>
client.publish('app2dev/YOUR_devid', data, pubopt, function (message_id) {
+
$ cat light-off.txt
console.log("public ok! message_id = " + message_id);
+
PUT /api/noduino/lights/0/state HTTP/1.1
});
+
Host: 192.168.1.75
});
+
Accept: */*
 +
Content-type: application/x-www-form-urlencoded
 +
Content-Length: 13
 +
 +
{"on": false}
 +
$ cat light-off.txt | nc 192.168.1.75 80
 +
HTTP/1.0 200 OK
 +
Server: lwIP/1.4.0
 +
Content-type: text/plain
 +
Content-Length: 0
 +
Connection: close
  
$ ./light-on.js
 
 
</source>
 
</source>
  
  
Change the color of the OpenLight:
+
<br><br>
 +
 
 +
=== Change brightness via HTTP ===
 +
 
 +
192.168.1.75 is the OpenLight device IP
 +
 
  
 
<source lang=bash>
 
<source lang=bash>
$ cat light-color.js
+
$ cat light-bri.txt
#! /usr/bin/env node
+
PUT /api/noduino/lights/0/state HTTP/1.1
 +
Host: 192.168.1.53
 +
Accept: */*
 +
Content-type: application/x-www-form-urlencoded
 +
Content-Length: 24
  
var opt = {
+
{"on": true, "bri": 200}
    username: "YOUR_mqtt_uname",
+
$ cat light-bri.txt | nc 192.168.1.75 80
    password: "YOUR_mqtt_pass"
+
</source>
};
+
  
var MQTTClient = require('MQTTClient').Client;
 
  
var client = new MQTTClient('YOUR_mqtt_server', 1883, opt);
+
"bri" is from 0 to 255
  
client.connect(function () {
+
<br><br>
console.log("connect ok!");
+
  
var pubopt = {
+
== HomeBridge ==
qos_level:  2
+
};
+
  
var state = {
+
To use the Siri to control the OpenLight :)
red: 0,
+
green: 0,
+
blue: 255,          <--------- outputting full power of the blue channel
+
white: 0,
+
on: 1
+
};
+
  
data = '{"m":"set", "d":{' + '"r":' + state.red + ',"g":' + state.green
+
<br><br>
+ ',"b":' + state.blue + ',"w":' + state.white
+
+ ',"s":' + state.on + '}}';
+
client.publish('app2dev/YOUR_devid', data, pubopt, function (message_id) {
+
console.log("public ok! message_id = " + message_id);
+
});
+
});
+
  
$ ./light-color.js
+
== Alexa ==
 +
 
 +
'''Support Amazon Alexa:'''
 +
 
 +
<br>
 +
 
 +
=== Discover ===
 +
 
 +
[[文件:Alexa-noduino-discove.png | 500px]]
 +
 
 +
 
 +
<b style="color:red">You need to request echo to re-discover devices when you changed the voice name of the device in WeChat control page</b>
 +
 
 +
<br>
 +
 
 +
=== Turn On/Off ===
 +
 
 +
[[文件:Alexa-openlight-turnon.png | 500px]]
 +
 
 +
<br>
 +
 
 +
=== Set brightness ===
 +
 
 +
[[文件:Alexa-openlight-brighten.png | 500px]]
 +
 
 +
 
 +
[[文件:Alexa-openlight-dim.png | 500px]]
 +
 
 +
 
 +
[[文件:Alexa-openlight-dim-num.png | 500px]]
 +
 
 +
 
 +
[[文件:Alexa-openlight-set.png | 500px]]
 +
 
 +
 
 +
<br><br>
 +
 
 +
=== Debug ===
 +
 
 +
upnp discovery:
 +
 
 +
<source  lang=bash>
 +
comcat@jackslab:/work/alexa/test$ cat dis-openlight.txt
 +
M-SEARCH * HTTP/1.1
 +
HOST: 239.255.255.250:1900
 +
MAN: "ssdp:discover"
 +
ST: urn:schemas-upnp-org:device:basic:1
 +
MX: 3
 +
comcat@jackslab:/work/alexa/test$ socat -T1 STDIO UDP4-DATAGRAM:239.255.255.250:1900 < dis-openlight.txt
 +
HTTP/1.1 200 OK
 +
EXT:
 +
CACHE-CONTROL: max-age=86400
 +
SERVER: Noduino/1.0 UPNP/1.1 OpenLight Bulb/1.0
 +
USN: uuid:38323636-4558-4dda-9188-cda094daa050
 +
ST: urn:schemas-upnp-org:device:basic:1
 +
LOCATION: http://192.168.1.39:80/setup.xml
 +
hue-bridgeid: 8989898989
 +
 
 +
HTTP/1.1 200 OK
 +
EXT:
 +
CACHE-CONTROL: max-age=86400
 +
SERVER: Noduino/1.0 UPNP/1.1 OpenLight Bulb/1.0
 +
USN: uuid:38323636-4558-4dda-9188-cda080ddbe50
 +
ST: urn:schemas-upnp-org:device:basic:1
 +
LOCATION: http://192.168.1.231:80/setup.xml
 +
hue-bridgeid: 8989898989
 
</source>
 
</source>
  
第260行: 第869行:
  
 
<source lang=bash>
 
<source lang=bash>
$ git clone --recursive git://github.com/icamgo/noduino-sdk.git noduino-sdk
+
$ git clone --recursive git://github.com/noduino/noduino-sdk.git noduino-sdk
 
</source>
 
</source>
  
第302行: 第911行:
  
 
'''Upload firmware throught serial for OpenLight Controller:'''
 
'''Upload firmware throught serial for OpenLight Controller:'''
 
[[文件:5pin.jpg]]
 
 
  
  
第381行: 第987行:
 
=== Schemmatics ===
 
=== Schemmatics ===
  
[[文件:Noduino-open-light-v2.4-sch.png | 1024px]]
+
[[文件:Noduino-open-light-v2.4-sch.png | 800px]]
  
 
<br><br>
 
<br><br>
第387行: 第993行:
 
=== LED ===
 
=== LED ===
  
OpenLight 铝基板上,LED 灯珠默认布局为:
 
  
 
OpenLight MCPCB, LED lamp bead default layout:
 
OpenLight MCPCB, LED lamp bead default layout:
  
* Red LED 6 颗串联,正极接 12V,负极接控制板 R (MY9291 之 OUTA)
+
* Red LED 6 series,positive answer 12v, negative link control panel R (OUTA of MY9291)
  
Red LED 6 series,positive answer 12v, negative link control panel R (OUTA of MY9291)
+
* Green LED 4 series, positive answer 12v, negative link control panel G (OUTB of MY9291)
  
* Green LED 4 颗串联,正极接 12V,负极接控制板 G (MY9291 之 OUTB)
+
* Blue LED 4 series, positive answer 12v, negative link control panel B (OUTC of MY9291)
  
Green LED 4 series, positive answer 12v, negative link control panel G (OUTB of MY9291)
+
* White LED*8 (4 series as a set, 2 groups parallel, positive answer 12v, negative link control panel W (OUTC of MY9291)
  
* Blue LED 4 颗串联,正极接 12V,负极接控制板 B (MY9291 之 OUTC)
 
 
Blue LED 4 series, positive answer 12v, negative link control panel B (OUTC of MY9291)
 
 
* White LED x8 (4 颗串联为一组, 2 组并联,正极接 12V,负极接控制板 W (MY9291 之 OUTC))
 
 
White LED*8 (4 series as a set, 2 groups parallel, positive answer 12v, negative link control panel W (OUTC of MY9291)
 
 
LED 灯珠 (5730) 单颗特性为:
 
  
 
LED bead (5730) features:
 
LED bead (5730) features:
  
* 尺寸 5.7 x 3.0 mm
+
* Size 5.7 x 3.0 mm
  
Size 5.7 x 3.0 mm
+
* Max current 150mA (0.5W)
  
* 最大电流 150mA (0.5W)
+
* VF is 3.0 - 3.4V (Red LED is 2.0 - 2.2V)
  
Max current 150mA (0.5W)
+
* Brightness 50 - 55 lm
  
* VF 为 3.0 - 3.4V (Red LED为 2.0 - 2.2V)
 
 
VF is 3.0 - 3.4V (Red LED is 2.0 - 2.2V)
 
 
* 亮度 50 - 55 lm
 
 
Brightness 50 - 55 lm
 
 
LED 灯珠其实就是一个二极管,只要有一个正向导通电压 (VF) 就能发光,一般为 2 - 3.5V,低于此电压灯珠不能发光,高于此电压,灯珠会烧坏。
 
  
 
LED bead is just a diode, will light as long as there is a positive forward voltage(VF), 2-3.5V. The bead will not light if voltage below this range and will burn if above this range
 
LED bead is just a diode, will light as long as there is a positive forward voltage(VF), 2-3.5V. The bead will not light if voltage below this range and will burn if above this range
  
控制灯珠亮度的,是电流大小,因此调光灯实际调得是电流的大小。电流超过额定电流,会加速灯珠老化,缩短灯珠寿命
 
  
 
Current control the bead brightness, so dimmer switch lamp actually switch the current. If current exceed the rated current that will speed up bead aging and shorten life
 
Current control the bead brightness, so dimmer switch lamp actually switch the current. If current exceed the rated current that will speed up bead aging and shorten life
第438行: 第1,024行:
  
 
=== MY9291 ===
 
=== MY9291 ===
 
OpenLight 采用台湾明阳 4 通道恒流 LED 驱动芯片,控制 R, G, B, W 四路 LED 灯珠
 
  
 
OpenLight use the Taiwan Mingyang 4 - channel constant current LED driver ICS to control the R, G, B, w 4 LED lamp bead
 
OpenLight use the Taiwan Mingyang 4 - channel constant current LED driver ICS to control the R, G, B, w 4 LED lamp bead
  
;;Feature:
 
  
* 3.3 - 5V 电源电压范围(±10%)
+
;;Feature:
  
 
* 3.3 - 5V power supply voltage range (±10%)
 
* 3.3 - 5V power supply voltage range (±10%)
 
* 每个通道 5 - 350 mA 恒流输出范围
 
  
 
* Each channel 5-350mA constant current output range
 
* Each channel 5-350mA constant current output range
 
* 可承受最大输出电压 24V,支持多颗 LED 串联
 
  
 
* Maximum output voltage of 24V, support more than one LED in series
 
* Maximum output voltage of 24V, support more than one LED in series
 
* 外接器件少,仅需四个外接电组来设定四組恆流电流
 
  
 
* Few external components, only need four external groups to set the four constant - current
 
* Few external components, only need four external groups to set the four constant - current
 +
  
 
;;Block Diagrame:
 
;;Block Diagrame:
第465行: 第1,043行:
 
[[文件:MY9291.app.jpg | 600px]]
 
[[文件:MY9291.app.jpg | 600px]]
  
电源为恒压源,可以多片级联,MCU 的控制线就两个:DI 和 DCK
 
  
 
For constant voltage power source, can be cascaded, MCU control of two lines : DI & DCK
 
For constant voltage power source, can be cascaded, MCU control of two lines : DI & DCK
  
;; 电源电压与灯珠串并联确定:
 
 
Power supply voltage and lamp bead series - parallel connection established
 
 
* 12V 电源的情形,如选用 VF 为 3V 左右的 LED 灯珠,则需要 4 颗串联,这样每颗灯珠分到电压为 3V 左右;2V 左右的灯珠,则需要 6 颗串联
 
 
* 12V Power supply, If use LED beads with 3V for VF then 4 beads shall be in series. So distribution voltage for every bead is about 3V ; 6beads shall be in series if the bead is 2V
 
  
* 24V 电源,则 3V 灯珠 8 颗串联,2V 灯珠 12 颗串联
 
  
* 24V Power supply, If use LED beads with 3V for VF then 8 beads shall be in series, 12beads shall be in series if the bead is 2V
+
;; Power supply voltage and lamp bead series/parallel connection and to make sure:
  
* 6V 电源,则 3V 灯珠 2 颗串联,2V 灯珠 3 颗串联
+
* 12V Power supply, 4 LED beads shall be in series if the LED VF is 3V. 6 LED beads shall be in series if the LED VF is 2V
  
* 6V Power supply, 2 beads with 3V for VF shall be in series, 3beads shall be in series if the bead is 2V
+
* 24V Power supply, 8 LED beads shall be in series if the LED VF is 3V. 12 LED beads shall be in series if the LED VF is 2V
  
;; 输出限流
+
* 6V Power supply,  2 LED beads shall be in series if the LED VF is 3V. 3 LED beads shall be in series if the LED VF is 2V
  
Output current
 
  
MY9291 单路最大输出 350mA,为节约灯珠寿命,可限制通过灯珠的最大电流以节约灯珠寿命
+
;; Output current
  
 
MY9291, maximum output of 350mA for single channel, in order to save life of lamp beads, can limit the maximum current through the lamp bead to save the life of lamp beads
 
MY9291, maximum output of 350mA for single channel, in order to save life of lamp beads, can limit the maximum current through the lamp bead to save the life of lamp beads
  
最大输出电流限制:
 
  
 
Maximum output current limit:
 
Maximum output current limit:
第499行: 第1,066行:
 
   R = 380mV / Iout
 
   R = 380mV / Iout
  
满输出 350mA,则每路的限流电阻都得选为:1R,1/4 W 够用
 
  
 
Full output of 350mA, then each current resistance has to be selected as follows : 1R,1/4 w enough
 
Full output of 350mA, then each current resistance has to be selected as follows : 1R,1/4 w enough
  
 
OpenLight 球泡灯,R/G/B 选用电阻 4R7,限流为 81mA 左右,W 用两个 4R7 并联 2.35R 左右,限流为 162mA 左右。这样基本限制经过每颗 5730 (0.5W) 灯珠的电流为 80mA 左右,以延迟灯珠老化。这样整体功率被限制在 5W,如要增加亮度,可将这 5 个 4R7 电阻替换为 3R0,可将输出功率增加到 7W
 
  
 
OpenLight bulbs,  R/G/B use 4R7 resistor, and current limit is about 81mA, W use parallel of 2.35R and two 4R7,current limit is about 162mA.This basically limit the current at around 80mA through each 5730 ( 0.5W ) lamp to delay aging of the lamp beads. Thus overall power is limited to 5W, if need to increase the brightness, the 5 4R7 resistor can be replaced by 3R0, also can increase the output power to 7W
 
OpenLight bulbs,  R/G/B use 4R7 resistor, and current limit is about 81mA, W use parallel of 2.35R and two 4R7,current limit is about 162mA.This basically limit the current at around 80mA through each 5730 ( 0.5W ) lamp to delay aging of the lamp beads. Thus overall power is limited to 5W, if need to increase the brightness, the 5 4R7 resistor can be replaced by 3R0, also can increase the output power to 7W
第512行: 第1,076行:
 
<br><br>
 
<br><br>
  
== Power ==
+
=== RX5804 ===
  
=== 12V ===
+
4-channel constant current LED driver IC to control the R, G, B, W
  
220V 转 12V 恒压电源模块,额定 12W,1A 电流输出
+
* http://www.runxinic.com/cn/produce/led/2011/1104/7.html
 +
* http://www.runxinic.com/img/5804cn.pdf
  
220V switch to 12V constant voltage power supply model, rated 12W and 1A current output
 
 
<br><br>
 
<br><br>
  
=== 3.3V ===
+
== Power ==
  
ESP8266/ESP8285 chip、MY9291/MY9231 chip、SPI Flash chip are all 3.3V power.
+
=== 12V ===
 
+
==== MP1470 ====
+
 
+
* Wide 4.7V to 16V Operating Input Range
+
* Fixed 500kHz Switching Frequency
+
* Over-Current Protection and Hiccup
+
* Thermal Shutdown
+
* Output Adjustable from 0.8V
+
* Available in a 6-pin TSOT-23 package
+
  
 +
220V switch to 12V constant voltage power supply model, rated 12W and 1A current output
  
[[文件:Mp1470-typical.jpg]]
+
* ACT522/ACT520/ACT41x  http://www.active-semi.com/products/acdc-converters/secondary-side-regulators/
 +
* OB2263/OB2273 http://www.on-bright.com/cn/english/products_PWM.htm
  
 
<br><br>
 
<br><br>
  
==== MP2359 ====
+
=== 24V ===
  
* Wide 4.5V to 24V Operating Input Range
 
* 1.2A Peak Output Current
 
* 0.35Ω Internal Power MOSFET Switch
 
* Stable with Low ESR Output Ceramic Capacitors
 
* Up to 92% Efficiency
 
* 0.1μA Shutdown Mode
 
* Fixed 1.4MHz Frequency
 
* Thermal Shutdown
 
* Cycle-by-Cycle Over Current Protection
 
* Output Adjustable from 0.81V to 15V
 
  
 
+
<br><br>
[[文件:Mp2359-sch.jpg]]
+
 
+
<br><br><br>
+
  
 
== Reference ==
 
== Reference ==
第562行: 第1,106行:
  
 
* [[Noduino]]
 
* [[Noduino]]
 +
* [[IndoorLight]]
  
<br><br>
 
 
<br><br>
 
<br><br>
 
<br><br>
 
<br><br>
 
<br><br>
 
<br><br>
 
<br><br>
 
<br><br>
 
<br><br>
 
 
<br><br>
 
<br><br>

2021年1月26日 (二) 10:33的最后版本

目录

[编辑] 1 Overview

OpenLight Bulb:

Openlight-bulb-1024.jpg

OpenLight Controller:

OpenLight-ceiling-1-1280.jpg

OpenLight-ceiling-4-1280.jpg

Openlight-ctrl-demo.jpg


Noduino-works-with-logo.png



[编辑] 2 Quick Start

Maike-wifi-bulb-2955-all-en.jpg


  • Install the WeChat APP from AppStore or GooglePlay
  • Power on, waiting to light
  • Light is flashing slowly in red means waiting for network connection
  • If the light is not flashing in red, turn on and off 3 times, (eg. turn on - light on - turn off, 3 times) the light will be in red gradient for network connection. (Light is flashing slowly in red means waiting for network connection)
  • Connect mobile to WiFi router, open WeChat APP, enter ‘Discover’ -> ‘scan QR code’, scan the upright QR code to click “Network Connection”
  • Enter WiFi password, click "Connect" then waiting for network connecting complete. (P.S. only 2.4G WiFi is applicable, 5G WiFi and WiFi enterprise-level security certifications are not applicable)
  • Complete WiFi configuration, WeChat will be in LAN devices discovery mode. Available devices list will be visible.
  • Click the first device then press "Link Device" button to bind the device. (P.S. if the device has been binding, then the button at bottom is "Enter Official Account")
  • Finish above steps, please press "Enter Official Account" button then click "Devices" button to find your binding devices list. Click the device to enter control page.


Openlight-wechat-ui.jpg


Note:
  • If more people need to control the device, please connect to the same router and scan the same QR code while the device is power on. Click "Device connected and skip" -> "Link Device"->"Enter Official Account" to control smart devices
  • To connect the device to another router in same network, please turn on and off the light 3 times and scan the QR code in Wechat to connect the network, binding is not necessary.
  • To transfer the device to different place(networks), the light will be in red gradient waiting for networks matching. To connect networks please just scan QR code in WeChat.
  • Turn on and off the light 6 times to restore the factory settings



[编辑] 3 Open API

Afer you guys 'Link Device' in WeChat, Enter Official Account:


  • click "Devices" to list your binding devices
  • select your OpenLight in the list, enter control page, click upright corner, then Copy URL
  • paste the URL into web browser (Chrome or Safari) to access the control page in browser
  • check the source code of the page to get the following variables:


var devid = YOUR_DEVICE_ID;
var mqtt_uname = YOUR_MQTT_UNAME;



[编辑] 3.1 Go

[编辑] 3.1.1 Prepare

Prepare the Go lang:

$ sudo apt-get install golang-go
$ sudo apt-get install golang-eclipse-paho-dev
$ export GOPATH=/usr/share/gocode

Refer to:


[编辑] 3.1.2 Turn On/Off

package main

import (
	"fmt"
	"os"
	"strconv"
	"strings"
	"net/http"
	"encoding/json"
	MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
)

//define a function for the default message handler
var f MQTT.MessageHandler = func(client *MQTT.Client, msg MQTT.Message) {
	fmt.Printf("TOPIC: %s\n", msg.Topic())
	fmt.Printf("MSG: %s\n", msg.Payload())
}

var uid string = "YOUR_mqtt_uname"

func main() {
	if len(os.Args[1:]) >= 2 {

		devid := os.Args[1]
		cmd := os.Args[2]
		msg := ""

		if cmd == "on" {
			msg = "{\"m\":\"set\", \"d\":{\"s\":1}}"
		} else if cmd == "off" {
			msg = "{\"m\":\"set\", \"d\":{\"s\":0}}"
		} else if cmd == "ota" {
			msg = "ota"
		} else if _, err := strconv.Atoi(cmd); err == nil {
			msg = "{\"m\":\"bri\", \"d\":" + cmd + "}"
		}

		pass := get_token(uid)
		send_msg(devid, msg, pass)

	} else {
		help_msg()
	}
}

func help_msg() {
	fmt.Println("Supported cmd:")
	fmt.Println("\topenlight dev_id on")
	fmt.Println("\topenlight dev_id off")
	fmt.Println("\topenlight dev_id 23")
	fmt.Println("\topenlight dev_id ota")
}

func send_msg(devid string, msg string, pass string) {

		opts := MQTT.NewClientOptions().AddBroker("tcp://mqtt.noduino.org:1883")
		opts.SetClientID("cid_" + devid)
		opts.SetUsername(devid)
		opts.SetPassword(pass)
		opts.SetDefaultPublishHandler(f)

		c := MQTT.NewClient(opts)
		if token := c.Connect(); token.Wait() && token.Error() != nil {
			panic(token.Error())
		}

		mqtt_tx_topic := "app2dev/" + devid

		token := c.Publish(mqtt_tx_topic, 0, false, msg)
		token.Wait()
}

func get_token(user_id string) (string) {
	url := "http://api.noduino.org/user/token"

	type Body struct {
		UID string `json:"user_id"`
	}

	var body = Body {
		UID: user_id,
	}

	data, err := json.Marshal(body)
	//fmt.Println(string(data))

	if err == nil {
		resp, err := http.Post(url, "application/json", strings.NewReader(string(data)))
		if err != nil {
			fmt.Println(err)
		}
		defer resp.Body.Close()

		dec := json.NewDecoder(resp.Body)
		var v map[string]interface{}
		if err := dec.Decode(&v); err != nil {
			fmt.Printf("error: %v\n", err)
		} else {
			if val, ok := v["user_token"].(string); ok {
				return val
			}
		}
	}

	return ""
}


$ go build openlight.go
$ ./openlight MKD12343405300  on
$ ./openlight MKD12343405300  off



[编辑] 3.1.3 Set Brightness

$ go build openlight.go
$ ./openlight MKD12343405300  255
$ ./openlight MKD12343405300  10



[编辑] 3.2 node.js

Prepare the node.js:

# download the node-v6.9.1-xxx.tgz from http://nodejs.org
$ tar xf node-v6.9.1-*.tar.xz
$ sudo cp -a node-v6.9.1*/*  /usr/local/
$ sudo npm install -g MQTTClient
$ sudo npm install -g request



[编辑] 3.2.1 Turn Off

Using the node.js to switch off the OpenLigh:

$ cat light-off.js
#! /usr/bin/env node

var opt = {
    username: "YOUR_mqtt_uname",
    password: ""
};
var http_req = require('/usr/local/lib/node_modules/request');
http_req.post(
	'http://api.noduino.org/user/token',
	{ json: {user_id: opt.username} },
	function (error, response, body) {
		if (!error && response.statusCode == 200) {
			console.log(body);

			opt.password = body.user_token;

			var MQTTClient = require('MQTTClient').Client;
			var client = new MQTTClient('mqtt.noduino.org', 1883, opt);
			client.connect(function () {
				console.log("connect ok!");

				var pubopt = {
					qos_level:  2
				};

				var state = {
					on: 0          <---- off
				};
				var data = '{"m":"set", "d":{' + '"s":' + state.on + '}}';
				client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) {
					console.log("public ok! message_id = " + message_id);
					process.exit(0);
				});
			});
		} else {
			console.log("Request the user token failed");
			process.exit(1);
		}
	}
);

$ ./light-off.js



[编辑] 3.2.2 Turn On

Turn on the OpenLight:

$ cat light-on.js
#! /usr/bin/env node

var opt = {
    username: "YOUR_mqtt_uname",
    password: ""
};
var http_req = require('/usr/local/lib/node_modules/request');
http_req.post(
	'http://api.noduino.org/user/token',
	{ json: {user_id: opt.username, app_id:"mj2030064278", app_key:"0077d4829f52b1b2d668f8a82c5f5ded"} },
	function (error, response, body) {
		if (!error && response.statusCode == 200) {
			console.log(body);

			opt.password = body.user_token;

			var MQTTClient = require('MQTTClient').Client;
			var client = new MQTTClient('mqtt.noduino.org', 1883, opt);
			client.connect(function () {
				console.log("connect ok!");

				var pubopt = {
					qos_level:  2
				};

				var state = {
					on: 1          <---- on
				};
				var data = '{"m":"set", "d":{' + '"s":' + state.on + '}}';
				client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) {
					console.log("public ok! message_id = " + message_id);
					process.exit(0);
				});
			});
		} else {
			console.log("Request the user token failed");
			process.exit(1);
		}
	}
);

$ ./light-on.js



[编辑] 3.2.3 Set Color

Change the color of the OpenLight:

$ cat light-color.js
#! /usr/bin/env node

var opt = {
    username: "YOUR_mqtt_uname",
    password: ""
};

var http_req = require('/usr/local/lib/node_modules/request');
http_req.post(
	'http://api.noduino.org/user/token',
	{ json: {user_id: opt.username, app_id:"mj2030064278", app_key:"0077d4829f52b1b2d668f8a82c5f5ded"} },
	function (error, response, body) {
		if (!error && response.statusCode == 200) {
			console.log(body);

			opt.password = body.user_token;

			var MQTTClient = require('MQTTClient').Client;
			var client = new MQTTClient('mqtt.noduino.org', 1883, opt);
			client.connect(function () {
				console.log("connect ok!");

				var pubopt = {
					qos_level:  2
				};

				var state = {
					red: 0,
					green: 0,
					blue: 255,     <--------- outputting full power of the blue channel
					white: 0,
					on: 1
				};

				data = '{"m":"set", "d":{' + '"r":' + state.red + ',"g":' + state.green
					       + ',"b":' + state.blue + ',"w":' + state.white
					       + ',"s":' + state.on + '}}';
				client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) {
					console.log("public ok! message_id = " + message_id);
					process.exit(0);
				});
			});
		} else {
			console.log("Request the user token failed");
			process.exit(1);
		}
	}
);

$ ./light-color.js



[编辑] 3.2.4 FAQ

If you get the following error:

/usr/local/lib/node_modules/MQTTClient/client.js:56
		throw Error('user names are kept to 12 characters or fewer');
		^

Error: user names are kept to 12 characters or fewer

Please patch the /usr/local/lib/node_modules/MQTTClient/client.js to remove the line of checking the length of username and password:

--- a/client.js
+++ b/client.js
@@ -52,10 +52,10 @@ var Client = exports.Client = function (host, port, options) {
                options.alive_timer = 30;
        options.ping_timer = parseInt(options.alive_timer * 0.6 * 1000);
        // 用户名和密码
-       if (typeof options.username == 'string' && options.username.length > 12)
-               throw Error('user names are kept to 12 characters or fewer');
-       if (typeof options.password == 'string' && options.password.length > 12)
-               throw Error('passwords are kept to 12 characters or fewer');
+       //if (typeof options.username == 'string' && options.username.length > 12)
+       //      throw Error('user names are kept to 12 characters or fewer');
+       //if (typeof options.password == 'string' && options.password.length > 12)
+       //      throw Error('passwords are kept to 12 characters or fewer');
        // Will flag
        if (options.will_flag && (typeof options.will_topic != 'string' || typeof options.will_message != 'string'))
                throw Error('missing will_topic or will_message when will_flag is set');



[编辑] 3.3 python

[编辑] 3.3.1 Prepare

$ python3 --version
Python 3.5.3rc1

$ pip3 install paho-mqtt
Collecting paho-mqtt
  Downloading paho-mqtt-1.2.tar.gz (49kB)
    100% |████████████████████████████████| 51kB 308kB/s 
Building wheels for collected packages: paho-mqtt
  Running setup.py bdist_wheel for paho-mqtt ... done
  Stored in directory: /home/comcat/.cache/pip/wheels/fa/db/fb/b495e37057e2f40534726b3c00ab26a58fc80fb8d17223df07
Successfully built paho-mqtt
Installing collected packages: paho-mqtt
Successfully installed paho-mqtt-1.2


More infor: https://pypi.python.org/pypi/paho-mqtt


[编辑] 3.3.2 Turn off

  • replace the mqtt_uname in line 10
$ cat openlight.py
#!/usr/bin/python3

import json, requests
import paho.mqtt.client as mqtt
import sys

# replace it to your id
###########################################
mqtt_uname = 'o7okr76757879RfhBs_XM339'     <---- YOUR_mqtt_uname
devid = 'MJD123456789012'                   <---- YOUR_devid
###########################################

# mqtt json message
###########################################
# {"m":"set", "d":{"r":255,"g":255,"b":255,"w":255,"s":1}}
# {"m":"bri", "d":23}  -->  bri:[0, 255]
# {"m":"set_voice_name", "d":"room light"}
# {"m":"get_voice_name"}
# {"m":"get_state"}
# ota
###########################################

DEBUG = True

def dbg(msg):
    global DEBUG
    if DEBUG:
        print(msg)
        sys.stdout.flush()

#http://docs.python-requests.org/en/latest/user/quickstart/#json-response-content

def help_msg():
    print("Supported cmd:")
    print("\tlight.py dev_id on")
    print("\tlight.py dev_id off")
    print("\tlight.py dev_id 23")
    print("\tlight.py dev_id ota")
    print("\tlight.py dev_id set_vn \"kitchen light\"")
    print("\tlight.py dev_id get_vn")

if len(sys.argv) >= 2:
    devid = sys.argv[1]
    set_state = sys.argv[2]
else:
    help_msg()
    sys.exit(-2)

if set_state == "on":
    mqtt_msg = '{"m":"set", "d":{"s":1}}'
elif set_state == "off":
    mqtt_msg = '{"m":"set", "d":{"s":0}}'
elif set_state.isdigit():
    mqtt_msg = '{"m":"bri", "d":' + set_state + '}'
elif set_state == "ota":
    mqtt_msg = "ota"
elif set_state == "get_state":
    mqtt_msg = '{"m":"get_state", "d":""}'
elif set_state == "set_vn":
    mqtt_msg = '{"m":"set_voice_name", "d":"' + sys.argv[3] + '"}'
elif set_state == "get_vn":
    mqtt_msg = '{"m":"get_voice_name", "d":""}'
elif set_state == "set_cold_on":
    mqtt_msg = '{"m":"set_cold_on", "d":' + sys.argv[3] + '}'
elif set_state == "get_cold_on":
    mqtt_msg = '{"m":"get_cold_on", "d":""}'
elif set_state == "set_grad_on":
    mqtt_msg = '{"m":"set_grad_on", "d":' + sys.argv[3] + '}'
elif set_state == "get_grad_on":
    mqtt_msg = '{"m":"get_grad_on", "d":""}'
elif set_state == "set_alexa_on":
    mqtt_msg = '{"m":"set_alexa_on", "d":' + sys.argv[3] + '}'
elif set_state == "get_alexa_on":
    mqtt_msg = '{"m":"get_alexa_on", "d":""}'
else:
    help_msg()
    sys.exit(-2)

url = 'http://api.noduino.org/user/login'

dat = dict (
        user_id = mqtt_uname,
        app_id = 'mj2030064278',
        app_key = '0077d4829f52b1b2d668f8a82c5f5ded'
)

#print(json.dumps(dat))
try:
    resp = requests.post(url = url, json = dat)
except Exception as e:
    dbg(e)
    sys.exit(-1)

mqtt_rx_topic = 'dev2app/' + devid
mqtt_tx_topic = 'app2dev/' + devid

mqtt_host = 'mqtt.noduino.org'
mqtt_port = 1883

print("mqtt msg: " + mqtt_msg)

def on_connect(client, u_dat, rc):
    if rc == 0:
        print("Connected successfully")
    else:
        print("Connection failed. rc = "+str(rc))

def on_publish(client, u_dat, rc):
    print("Message "+str(rc)+" published.")

def on_subscribe(client, u_dat, mid, qos):
    print("Subscribe with "+str(mid)+" received")

def on_message(client, udat, msg):
    print("Message received on topic "+msg.topic+" and payload "+str(msg.payload))

mqttc = mqtt.Client()

mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
mqttc.on_message = on_message

#mqttc.username_pw_set(mqtt_uname, mqtt_pass)
mqttc.username_pw_set(tu, tp)
mqttc.connect(mqtt_host, mqtt_port)

mqttc.publish(mqtt_tx_topic, mqtt_msg)

mqttc.subscribe(mqtt_rx_topic)
mqttc.loop_forever()


$ ./openlight.py your_dev_id off


[编辑] 3.3.3 Turn On

Turn on the bulb:

$ ./openlight.py your_dev_id on



[编辑] 3.3.4 OTA

  • request device to download your new firmware:
$ ./openlight.py your_dev_id ota



[编辑] 3.4 HTML5

The device control page in WeChat is a H5 page. Using a MQTT client implement in javascript , using the mqttws31.js library:

var client_id = parseInt(Math.random() * 10000, 10) + '_' + mqtt_uname;
var client = new Paho.MQTT.Client(mqtt_server, mqtt_port, "/mqtt", client_id);
function failConnect(e) {
	console.log("connect failed");
	console.log(e);
	console.log("reconnecting ...");
	client.connect({userName: mqtt_uname, password: mqtt_pass, onSuccess:onConnect, onFailure: failConnect, mqttVersion:3});
}
function onConnect() {
	console.log("onConnect OK!");
	subscribe('dev2app/' + devid);
}
function subscribe(topic) {
	client.subscribe(topic);
}
function onMessageArrived (message) {
	console.log("Arrived Message: [", message.payloadString, "]");
	try {
		job = JSON.parse(message.payloadString);
		set = job.d;
	} catch(e) {
		console.log("JSON object error!");
		alert("JSON error, RX data is: " + message.payloadString);
		return;
	}
	if(job.m == 'set' || job.m == 'status') {
		//console.log("set ui state");
		set_ui_state(set);
	}
	if(job.m == 'offline') {
		blockUI();
	}
}
function onDisConnect() {
	console.log("reconnecting ...");
	client.connect({userName: mqtt_uname, password: mqtt_pass, onSuccess:onConnect, onFailure: failConnect, mqttVersion:3});
}
function mqtt_publish(msg){
	var topic = 'app2dev/' + devid;
	message = new Paho.MQTT.Message(msg);
	message.destinationName = topic;
	client.send(message);
	console.log("publish message: " + msg);
}
function mqtt_init() {
	client.connect({userName: mqtt_uname, password: mqtt_pass, onSuccess:onConnect, onFailure: failConnect, mqttVersion:3});
	client.onMessageArrived = onMessageArrived;
	client.onConnectionLost = onDisConnect;
}
mqtt_init();



[编辑] 4 Open API (HTTP in LAN)

Note: the device security policy using the WiFi router's password, that is: the users who are authorized to connect to the WiFi router, is a trusted user

Device start a HTTP service by default. You can send the following HTTP request to turn on or turn off the device. This way independent of MQTT cloud service can be used in local area network when you don't want to make device access Internet.


[编辑] 4.1 Get the device IP

You can use the Fing app in iOS to scan the LAN network.

The device named Espressif is your OpenLight device:


Fing-lan-scan.png


[编辑] 4.2 Turn On via HTTP

192.168.1.75 is the OpenLight device IP

Turn On:

$ cat light-on.txt 
PUT /api/noduino/lights/0/state HTTP/1.1
Host: 192.168.1.75
Accept: */*
Content-type: application/x-www-form-urlencoded
Content-Length: 12

{"on": true}
$ cat light-on.txt | nc 192.168.1.75 80
HTTP/1.0 200 OK
Server: lwIP/1.4.0
Content-type: text/plain
Content-Length: 0
Connection: close


[编辑] 4.3 Turn Off via HTTP

192.168.1.75 is the OpenLight device IP

Turn Off:

$ cat light-off.txt 
PUT /api/noduino/lights/0/state HTTP/1.1
Host: 192.168.1.75
Accept: */*
Content-type: application/x-www-form-urlencoded
Content-Length: 13
 
{"on": false}
$ cat light-off.txt | nc 192.168.1.75 80
HTTP/1.0 200 OK
Server: lwIP/1.4.0
Content-type: text/plain
Content-Length: 0
Connection: close




[编辑] 4.4 Change brightness via HTTP

192.168.1.75 is the OpenLight device IP


$ cat light-bri.txt 
PUT /api/noduino/lights/0/state HTTP/1.1
Host: 192.168.1.53
Accept: */*
Content-type: application/x-www-form-urlencoded
Content-Length: 24

{"on": true, "bri": 200}
$ cat light-bri.txt | nc 192.168.1.75 80


"bri" is from 0 to 255



[编辑] 5 HomeBridge

To use the Siri to control the OpenLight :)



[编辑] 6 Alexa

Support Amazon Alexa:


[编辑] 6.1 Discover

Alexa-noduino-discove.png


You need to request echo to re-discover devices when you changed the voice name of the device in WeChat control page


[编辑] 6.2 Turn On/Off

Alexa-openlight-turnon.png


[编辑] 6.3 Set brightness

Alexa-openlight-brighten.png


Alexa-openlight-dim.png


Alexa-openlight-dim-num.png


Alexa-openlight-set.png




[编辑] 6.4 Debug

upnp discovery:

comcat@jackslab:/work/alexa/test$ cat dis-openlight.txt 
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
ST: urn:schemas-upnp-org:device:basic:1
MX: 3
comcat@jackslab:/work/alexa/test$ socat -T1 STDIO UDP4-DATAGRAM:239.255.255.250:1900 < dis-openlight.txt 
HTTP/1.1 200 OK
EXT:
CACHE-CONTROL: max-age=86400
SERVER: Noduino/1.0 UPNP/1.1 OpenLight Bulb/1.0
USN: uuid:38323636-4558-4dda-9188-cda094daa050
ST: urn:schemas-upnp-org:device:basic:1
LOCATION: http://192.168.1.39:80/setup.xml
hue-bridgeid: 8989898989

HTTP/1.1 200 OK
EXT:
CACHE-CONTROL: max-age=86400
SERVER: Noduino/1.0 UPNP/1.1 OpenLight Bulb/1.0
USN: uuid:38323636-4558-4dda-9188-cda080ddbe50
ST: urn:schemas-upnp-org:device:basic:1
LOCATION: http://192.168.1.231:80/setup.xml
hue-bridgeid: 8989898989



[编辑] 7 Firmware

[编辑] 7.1 Compile

Getting noduino-sdk:

$ git clone --recursive git://github.com/noduino/noduino-sdk.git noduino-sdk


Generate toolchain (you need Python 2.7):

$ cd noduino-sdk/toolchain
$ ./gen.py

Compile:

$ cd ../sketch/open-light
$ make


The generated firmware is located in build/ dir named user1.bin annnd user2.bin


Window environment please refer to Getting Started with Noduino SDK on Windows, you can get how to setup the basic developmennt environment



[编辑] 7.2 Upload

[编辑] 7.2.1 Serial

Prepare a USB2UART board, something like FT232RL or CP2102/CP2104:

Ft232.jpg


Upload firmware throught serial for OpenLight Bulb:

Openlight-bulb-upload-serial-900.jpg]


Upload firmware throught serial for OpenLight Controller:


  • USB2UART_GND ------> SmartNode_GPIO0 / Bulb_GPIO0
  • USB2UAR_GND -----> SmartNode_GND / Bulb_GND
  • USB2UAR_RXD -----> SmartNode_TX / Bulb_TX
  • USB2UAR_TXD -----> SmartNode_RX / Bulb_TX


Connect USB2UAR_VCC3.3 -----> SmartNode_VCC / Bulb_3V3 at last

ESP8285 will be enter upload mode, we can upload the compiled firmware through serial using following commands in Linux:

$ cd /path/to/noduino-sdk/sketch/open-light
$ make produce ESPPORT=/dev/ttyUSB1


In windows:

$ make produce ESPPORT=COM7

COM7 is your USB2UART device


In MAC OS, maybe it's:

$ make produce ESPPORT=/dev/cu.SLAB_USBtoUART

/dev/cu.SLAB_USBtoUART is your USB2UART device



[编辑] 7.2.2 Online

Access
http://dev.noduino.org/openlight


Login
  • Username: noduino
  • password: noduino1234


Click the "Add files", select the user1.bin and user2.bin located in /path/to/noduino-sdk/sketch/open-light/build/


Then click "Start upload" to upload the user1.bin and user2.bin into the server temporaily


Enter Official Account, then click "Add" menu, enter "Debug" page

Maike-upload-online-1.jpg


Select your device and the input "ota" in the data aera then click "send data"


Maike-upload-online-2.jpg


Device will download your user1.bin or user2.bin and write it into flash when the device received the "ota" message

You will see the device online message in the Debug page when the uploading is finished




[编辑] 8 Hardware

[编辑] 8.1 Schemmatics

Noduino-open-light-v2.4-sch.png



[编辑] 8.2 LED

OpenLight MCPCB, LED lamp bead default layout:

  • Red LED 6 series,positive answer 12v, negative link control panel R (OUTA of MY9291)
  • Green LED 4 series, positive answer 12v, negative link control panel G (OUTB of MY9291)
  • Blue LED 4 series, positive answer 12v, negative link control panel B (OUTC of MY9291)
  • White LED*8 (4 series as a set, 2 groups parallel, positive answer 12v, negative link control panel W (OUTC of MY9291)


LED bead (5730) features:

  • Size 5.7 x 3.0 mm
  • Max current 150mA (0.5W)
  • VF is 3.0 - 3.4V (Red LED is 2.0 - 2.2V)
  • Brightness 50 - 55 lm


LED bead is just a diode, will light as long as there is a positive forward voltage(VF), 2-3.5V. The bead will not light if voltage below this range and will burn if above this range


Current control the bead brightness, so dimmer switch lamp actually switch the current. If current exceed the rated current that will speed up bead aging and shorten life



[编辑] 8.3 MY9291

OpenLight use the Taiwan Mingyang 4 - channel constant current LED driver ICS to control the R, G, B, w 4 LED lamp bead


Feature:
  • 3.3 - 5V power supply voltage range (±10%)
  • Each channel 5-350mA constant current output range
  • Maximum output voltage of 24V, support more than one LED in series
  • Few external components, only need four external groups to set the four constant - current


Block Diagrame:

MY9291.app.jpg


For constant voltage power source, can be cascaded, MCU control of two lines : DI & DCK


Power supply voltage and lamp bead series/parallel connection and to make sure
  • 12V Power supply, 4 LED beads shall be in series if the LED VF is 3V. 6 LED beads shall be in series if the LED VF is 2V
  • 24V Power supply, 8 LED beads shall be in series if the LED VF is 3V. 12 LED beads shall be in series if the LED VF is 2V
  • 6V Power supply, 2 LED beads shall be in series if the LED VF is 3V. 3 LED beads shall be in series if the LED VF is 2V


Output current

MY9291, maximum output of 350mA for single channel, in order to save life of lamp beads, can limit the maximum current through the lamp bead to save the life of lamp beads


Maximum output current limit:

 R = 380mV / Iout


Full output of 350mA, then each current resistance has to be selected as follows : 1R,1/4 w enough


OpenLight bulbs, R/G/B use 4R7 resistor, and current limit is about 81mA, W use parallel of 2.35R and two 4R7,current limit is about 162mA.This basically limit the current at around 80mA through each 5730 ( 0.5W ) lamp to delay aging of the lamp beads. Thus overall power is limited to 5W, if need to increase the brightness, the 5 4R7 resistor can be replaced by 3R0, also can increase the output power to 7W




[编辑] 8.4 RX5804

4-channel constant current LED driver IC to control the R, G, B, W



[编辑] 9 Power

[编辑] 9.1 12V

220V switch to 12V constant voltage power supply model, rated 12W and 1A current output



[编辑] 9.2 24V



[编辑] 10 Reference

For more information please refer to



个人工具
名字空间

变换
操作
导航
工具箱