初步部署
2018.1.27
- 舵机安装,用热熔胶将SG92R 9g小型舵机粘到门锁旁,舵机牵扯尼龙绳实现开锁动作
- 利用原有的papersignals固件对舵机开门的可行性进行测试,发现舵机在门锁有阻力的情况下,在舵机通电一刻仍能高效开锁
- 对该项目的架构进行构思
1.借鉴papersignals项目:
- esp8266充当客户端,定时请求服务端获取json数据
- 手机端发送请求到达服务端,服务端解析请求并修改本地json数据
- 从而达到伪装实时开锁的目的
工作与过年原因项目搁置许久
2.构思内网穿透方案
- 利用pandorabox的可扩展性,安装内网穿透客户端ngrok
- 在搬瓦工vps上安装ngrokd服务端
- 抛弃papersignals的类似方式,将esp8266作为服务端,手机作为客户端
- 鉴于小程序的跨平台特性,决定采用小程序的方式进行手机端开发
在搬瓦工vps搭建ngrok服务端的过程
- 参考这篇博客在vps上进行ngrok的编译
- 该博客中遇到的问题,我全都遇到了,按照相应的步骤操作即可解决
- 另外在go1.4安装操作步骤混乱的时候,造成goroot路径的错乱,从而无法安装上go1.4和go1.6,只需要unset GOROOT即可
- 一切安装就绪,卡在ngrok的go编译上,在编译过程中报错:go build project/test: signal: killed 查阅资料,发现是vps内存太小导致的无法编译
- 改用centos进行编译,但是只有visualbox的centos镜像,而visualbox复制文件上面完全比不上vmware方便,所以改用ubuntu进行ngrok编译。
- 在ubuntu中部署ngrok编译环境的时候,使用yum命令,发现yum是centos专用的安装命令,在ubuntu上使用会导致很多问题的发生,例如yum的源不知如何配置,所以用回apt命令
- 由于无法使用yum,造成很多依赖包无法安装上,所以无法安装上官网下载的go1.10包
- 查找资料发现可以使用sudo apt-get install go-lang命令直接安装go环境,若找不到直接apt update更新源即可
- 开启sslocal,把ngrok项目从git中拉下来
- 对ngrok项目进行编译
- 其中最重要的是$NGROK_DOMAIN的设置,在该教程中直接关系到openssl证书的生成
- 编译出ngrokd服务端
- 丢进vps中跑一下
- 问题:80端口和443端口的占用
- 解决:启动ngrok命令中修改-httpAddr以及httpsAddr 以更改监听端口,4443为透传接入端口,更改之后直接启动即可,在浏览器中输入www.sinowrt.cn:81 出现trunnel…的即表示启动成功
- 编译出windows的客户端,windows的客户端必须要在cmd中才能运行,新建ngrok.cfg,将内容
server_addr: "www.sinowrt.cn:4443"
trust_host_root_certs: false
写入该文件中,在cmd进入该目录,敲入命令
ngrok.exe -config="ngrok.cfg" -subdomain="abc" 80
连接上ngrok服务端即可将本地的80端口暴露出外网
- 问题:一开始死活连接不上,出现fail
- 原因:abc.www.sinowrt.cn没有配置解析,dns无法解析该url所以造成无法连接上服务器,在腾讯云中添加*.www的泛解析,问题解决
- 问题:出现reconnecting
- 原因:server_addr后面的内容必须跟证书生成过程中的地址完全匹配,重新填写该参数或重新生成证书而重新编译即可解决问题
- 至此,服务器端部署告一段落 直接敲入命令
以上部署在应用到小程序中会有坑,请看小程序中的分析
最终版的命令
./ngrokd -domain=ngrok.sinowrt.cn -httpAddr=:80 -httpsAddr=:443 -tlsCrt /etc/ngrok_ssl/server.crt -tlsKey /etc/ngrok_ssl/server.key&
即可启动ngrok服务端
小程序“我只是个开门的玩意儿”开发的过程
- 小程序账号的申请
- 基本信息的填写
- 开发工具的下载
- 根据原有的框架,对bindViewTap函数进行改写,点击即调用wx.request方法发起post请求
- 由于wx.request会对url进行安全校验,根据网上资料指示,在开发工具中关闭校验
- 问题:发现wx.request不能加端口号
- 解决: 修改vps的apache监听端口为81,ngrokd的监听端口为80
- 添加toast对开门过程进行文字弹幕展示
以上部署在应用到小程序中会有坑,请看后续分析
- 2018.3.2进行了体验版本的发布,回来想试用一下app进行开门,发现竟然无响应
- 无意中开启调试模式,竟然又可以了(此事用的是http协议)
- 查阅网上资料,发现要进行合法域名配置,于是配置合法域名为abc.ngrok.sinowrt.cn(发现一个问题,域名的前缀为https,且无法更改)
- 发现仍是在开发工具中成功运行,而app中始终是调试模式才能成功
- 继续查阅资料,发现只有调试模式才没有进行域名校验
- 查看vps中的443端口占用,ssserver占用了,对sserver进行kill -9 pid操作,再用其他端口重新开启,再重新开启ngrok服务,https连接没问题
- 再修改客户端中的连接协议为https
- 开启开发工具和域名合法检测,发现始终无法请求成功(重启ngrokd的时候发现有配置服务器证书的参数)
- 在腾讯云上为ngrok.sinowrt.cn申请免费的ssl证书,审核成功后,下载,放入vps,指定ngrokd的证书为/etc/ngrok_ssl/server.csr与/etc/ngrok_ssl/server.key
- 发现请求abc.ngrok.sinowrt.cn仍然为不安全,而ngrok.sinowrt.cn却是安全的了
- 于是再为abc.ngrok.sinowrt.cn申请ssl证书,
- 为了减少错误的发生,将ngrok.sinowrt.cn的证书放进ubuntu的ngrok编译环境中,重新编译出ngrokd扔进去vps中
- 按上述的方法指定该证书,重启ngrokd,成功
- 但是小程序似乎仍然毫无反应,而改回http之后才有反应,判断应该是请求的时候被拦截了
- 查看服务器端的tls支持情况,发现服务器端是支持tls1.2以下版本的
- 再查阅资料1以及资料2,按照相应步骤配置中间证书后,小程序请求问题终于解决了,一切正常使用
- 在使用过程中,点下按钮由于服务端会有延时操作,所以过了几秒才有开锁成功,所以添加“正在开锁”的toast
esp8266服务端的搭建
- 参考网上资料
- 将如下源码进行改写
/*
This sketch demonstrates how to set up a simple HTTP-like server.
The server will set a GPIO pin depending on the request
http://server_ip/gpio/0 will set the GPIO2 low,
http://server_ip/gpio/1 will set the GPIO2 high
server_ip is the IP address of the ESP8266 module, will be
printed to Serial when the module is connected.
*/
#include <ESP8266WiFi.h>
#define LED 2
const char* ssid = "YFROBOT";
const char* password = "yfrobot2016";
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
void setup() {
WiFi.mode(WIFI_STA);
Serial.begin(115200);
delay(10);
// prepare GPIO2
pinMode(LED, OUTPUT);
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.println(WiFi.localIP());
digitalWrite(LED, 1); // LOW
}
void loop() {
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Read the first line of the request
String req = client.readStringUntil('\r');
Serial.println(req);
client.flush();
delay(10);
// Match the request
int val = 1;
if (req.indexOf("/gpio/0") != -1)
val = 1;
else if (req.indexOf("/gpio/1") != -1)
val = 0;
else {
Serial.println("invalid request");
client.stop();
return;
}
// Set GPIO2 according to the request
digitalWrite(LED, val);
// Prepare the response
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
s += (val) ? "low" : "high";
s += "</html>\n";
// Send the response to the client
client.print(s);
delay(1);
Serial.println("Client disonnected");
// The client will actually be disconnected
// when the function returns and 'client' object is detroyed
}
- 添加servo控制,以及相应的请求解析即可完成舵机的控制
- 将改写好的ino文件烧录进esp8266即可
- 烧写接线与正常运行接线区别只在于gpio0
gpio15 -> -
ch_en -> +
vcc -> +
gnd ->-
烧录:gpio -> - 运行:gpio -> + 或 置空+
pandorabox的ngrok客户端部署
- 查阅资料发现openwrt上的ngrok客户端为c编写的ngrokc
- ngrokc的github地址:https://github.com/dosgo/ngrok-c
- 无意中又发现python版本的ngrok:https://github.com/hauntek/python-ngrok
- 正好我的路由配置了python环境,为了省事,直接用python版本的
- 将ngrok客户端的py文件扔进/usr/bin中,运行发现缺少ssl.py模块,安装完整版的python以及openssl也无法解决,最后配置源,安装了python-openssl问题才解决
python版本的ngrok客户端由于我在windows中已经配置好它的配置文件,放到路由中直接运行即可,下面贴出配置文件:
{ "server": { "host": "ngrok.sinowrt.cn", "port": 4443, "bufsize": 1024 }, "client": [ { "protocol": "http", "hostname": "", "subdomain": "abc", "rport": 0, "lhost": "127.0.0.1", "lport": 8080 } ] }
直接运行命令:
python ./ngrok /etc/config/ngrok.config&
即可启动客户端
以上部署在应用小程序的时候会有坑,请看小程序中的分析
最终版的ngrok.config:
{ "server": { "host": "ngrok.sinowrt.cn", "port": 4443, "bufsize": 1024 }, "client": [ { "protocol": "https", "hostname": "", "subdomain": "abc", "rport": 0, "lhost": "192.168.1.121", "lport": 80 } ] }
StartSSL
2018/3/7
- 晚上发现舵机扫齿了,果然,塑料齿轮还是太脆了
2018/3/8
- 早上淘了一个金属齿轮的国产舵机MG945,看了店家描述,总结下
- MG996和MG995优点在于响应快,扭力相对小
- MG945优点在于扭力大,响应相对较慢
2018/3/10
- 下午拿了舵机装上直接点亮
- 修复发现很久的bug
- 由于舵机初始化时currentposition角度为unlockposition 90,开机时由于
MoveServoToPosition(RESETPOSITION, 10);
语句,舵机会先转到90度再转到180度 - 更改为初始化currentposition角度为RESTPOSTION
- 更改unlockposition为0
- 更改resetposition为90