教程:http://geek-workshop.com/thread-37484-1-1.html

源码:链接:https://pan.baidu.com/s/1yuYYqsM-WSOb0AbyAT0qrQ 密码:d8e8

本帖最后由 zyzand 于 2018-5-10 16:00 编辑

前段时间,学校发了通知,说寝室要安智能电表了,由原来的每月底后付费改成预付费,说是没余额会自动断电,通过微信平台查询和缴纳电费。打开查电费的界面看了一下,发现缴费的界面是需要在微信里才能打开的,但查询的界面能直接在普通浏览器打开:

<ignore_js_op>

(最近刚安装上,学校实行保电模式,所以暂时没电费也能用哈)

正好实验室有几块ESP8266和几块OLED。我想能不能拿ESP8266来显示当前的实时电费信息呢?这样就避免舍友吃鸡的时候突然断电的尴尬了。

电费信息的解析
研究了一下查询电费的方式,发现只要更改地址就能查到不同楼层的电费信息,返回的html的源码如下

<ignore_js_op>

代码还是比较短的,有1M内存的ESP8266完全能应付得来。
        思路也很简单,就只先用http库获取到网页源码,然后使用关键信息前后的字符截取出相应的信息。解析信息的方法如下。(代码可能写的不太规范,欢迎大神指点)

  1. struct priceinf {
  2.   float price;
  3.   char timestr[20 * 7];
  4.   int year;
  5.   int month;
  6.   int day;
  7.   int hh;
  8.   int mm;
  9.   int ss;
  10.   char lou[20];
  11.   char qinshi[10];
  12.  
  13. };
  14. /*
  15.         返回信息解析
  16.         传入:html代码
  17.         返回:解析出来的信息(priceinf 结构体)
  18.                 未解析到则返回空的结构体
  19. */
  20. priceinf getPrice(String s) {
  21.   priceinf dat;
  22.   int datStart = 0, datEnd = 0;
  23.   String datstr;
  24.   char buf[50];
  25.  
  26.   char datsign[] = "<span class=\"price\"";
  27.   datStart = s.indexOf(datsign) + strlen(datsign) + 23;
  28.   if (datStart == strlen(datsign) + 23 - 1) { //没有找到price
  29.     memset(&dat, 0, sizeof(dat));
  30.     return dat;
  31.   }
  32.   datEnd = s.indexOf("</span>", datStart) - 2;   //减2是为了减去字符“元”
  33.   datstr = s.substring(datStart, datEnd);
  34.   dat.price = datstr.toFloat();
  35.  
  36.   char timesign[] = "<font style=\"color:#2d9fd3\"><b>";
  37.   datStart = s.indexOf(timesign) + strlen(timesign);
  38.   datEnd = s.indexOf("</b></font>", datStart);   //结尾
  39.   datstr = s.substring(datStart, datEnd);
  40.   datstr.toCharArray(dat.timestr, 20);
  41.   dat.timestr[19] = 0;
  42.  
  43.   dat.year = datstr.substring(0, 4).toInt();
  44.   dat.month = datstr.substring(5, 7).toInt();
  45.   dat.day = datstr.substring(8, 10).toInt();
  46.   dat.hh = datstr.substring(11, 13).toInt();
  47.   dat.mm = datstr.substring(14, 16).toInt();
  48.   dat.ss = datstr.substring(17, 19).toInt();
  49.  
  50.   char lousign[] = "楼幢:";
  51.   datStart = s.indexOf(lousign) + strlen(lousign);
  52.   datEnd = s.indexOf("</p>", datStart);   //结尾
  53.   datstr = s.substring(datStart, datEnd);
  54.   datstr.toCharArray(dat.lou, 20);
  55.   dat.lou[19] = 0;
  56.  
  57.   char qinshisign[] = "寝室号:";
  58.   datStart = s.indexOf(qinshisign) + strlen(qinshisign);
  59.   datEnd = s.indexOf("</p>", datStart);   //结尾
  60.   datstr = s.substring(datStart, datEnd);
  61.   datstr.toCharArray(dat.qinshi, 10);
  62.   dat.qinshi[9] = 0;
  63.  
  64.   //Serial.println(s);
  65.   Serial.print("time=");
  66.   Serial.println(dat.timestr);
  67.   Serial.print("price=");
  68.   Serial.println(dat.price);
  69.   Serial.print("lou=");
  70.   Serial.println(dat.lou);
  71.   Serial.print("qinshi=");
  72.   Serial.println(dat.qinshi);
  73.   Serial.println();
  74.   return dat;
  75. }

     这个函数能实现对截止时间,楼,寝室号,剩余电费的解析,并把解析到的信息储存在结构体里。

然后把信息用OLED显示出来,不过这块OLED默认是SPI的,而我用的ESP-01最多只有3个能自定义的io,完全不够用。所以要改成IIC接口。按照说明改一下背后的电阻,然后将RES接VCC,CS、DC接GND,这样D0就是SCL,D1是SDA了。分别连接到ESP8266的GPOP0和GPIO2上。
        把OLED 屏幕的软件IIC库导入到Arduino里,测试一下还挺好用。

其他功能
        到这里这个程序就基本完成了,难度不是很大。但感觉这个程序好简单啊,ESP8266的潜能还没全发挥出来,于是,当做练习,在这个程序里加入了SmartConfig,用来应对应对没有已知密码的wifi的情况,然后让他能开机时从指定网址先获取查询电费的网址,并能从指定网址进行OTA空中升级。这样就不止能查询自己的宿舍,并且就算送给别人用也能随时对程序进行修改。
获取查询网址和升级信息
        获取查询网址和升级信息的函数,为了方便可管理多个终端,在开机的时候会先获取本芯片的唯一SN号,然后程序会访问自己SN号对应的网址,这样就不用为每一个芯片单独烧写固件了,同一个固件就能去访问不同的网址:

  1. int site_Get() {
  2.   int ret = 0;
  3.   if ((WiFiMulti.run() == WL_CONNECTED)) {
  4.  
  5.     HTTPClient http;
  6.  
  7.     Serial.printf("[www.zyzand.com]Connect to www.zyzand.com...\n");
  8.     http.begin("www.zyzand.com", 80, (String)"/IoT/clients/" + SN + "/index.php"); //HTTP
  9.     int httpCode = http.GET();
  10.     int i = 5;//重试次数
  11.     while (i-- > 0 && httpCode != 200) {
  12.       Serial.printf("[www.zyzand.com]code: %d Try again...", httpCode);
  13.       delay(1000);
  14.       httpCode = http.GET();
  15.     }
  16.     //从www.zyzand.com获取信息失败
  17.     if (httpCode != 200) {
  18.       Serial.printf("[www.zyzand.com] GET Fail!");
  19.       ret = 2;
  20.     }
  21.     //成功则进行数据解析
  22.     else  {
  23.       Serial.println("[www.zyzand.com]GET data:");
  24.       String payload = http.getString();
  25.       Serial.println(payload);
  26.       int nflag = payload.indexOf("\n");
  27.       Serial.println(nflag);
  28.       Serial.println(payload.indexOf("\n", nflag));
  29.       dat1 = payload.substring(0, nflag);
  30.       dat2 = payload.substring(nflag + 1, payload.indexOf("\n", nflag + 1));
  31.  
  32.       Serial.print("[www.zyzand.com]dat1 = ");
  33.       Serial.println(dat1);
  34.       Serial.print("[www.zyzand.com]dat2 = ");
  35.       Serial.println(dat2);
  36.  
  37.       //OTA
  38.       if (strcmp(dat1.c_str(), "updata") == 0) {
  39.         OTA();
  40.       }
  41.     }
  42.   }
  43.   else {//WiFi连接失败
  44.     Serial.print("[www.zyzand.com]WiFi failed\n");
  45.     ret = 1;
  46.   }
  47.  
  48.   //失败时的处理
  49.   if (ret != 0) {
  50.     dat1 = "zyzand.com";
  51.     dat2 = (String)"/IoT/clients/" + SN + "/error/index.php";
  52.   }
  53.   return ret;
  54. }

  在测试OTA空中升级的时候,遇到的问题值得提一下。开始时空中升级总是返回flash配置错误:

  1. Flash config wrong real

猜测是在编译固件时选择的Flash不对,我的ESP-01的flash型号是EN25Q80B-104,网上查了一下说是8Mbit(1M)的。于是在编译时选择Flash Size为1M(128k SPIFFS),这样再把编译好的固件上传到网站上就能空中升级了。
        
通过杭电i-hdu上网认证
        我所在的学校有校园免费wifi,连接是不需要密码的,但是连接后会自动跳转到一个网页,需要进行认证才能访问外网。一直对他的认证方法感兴趣,于是用Fiddler抓了一下包,发现用来认证信息的只是一个post请求,也不是很复杂。在电脑上模拟成功,用ESP8266试了一下,也成功通过。

  1. /*
  2.         通过i-HDU认证,请自己修改postDate中的学号和密码
  3. */
  4. int hdulogin() {
  5.   const char * host = "2.2.2.2";
  6.   const int httpPort = 80;
  7.  
  8.   WiFiClient client;
  9.  
  10.   if (!client.connect(host, httpPort)) {
  11.     Serial.println("connection failed");
  12.     return 1;
  13.   }
  14.   delay(10);
  15.   String postDate = "opr=pwdLogin&userName=你的学号&pwd=学号对应的密码&rememberPwd=1";//将从串口接收的数据发送到服务器,readLine()方法可以自行设计
  16.   if (postDate.length() && postDate != "0") {
  17.     String data = (String)postDate;
  18.     int length = data.length();
  19.  
  20.     String postRequest = (String)("POST ") + "/ac_portal/login.php HTTP/1.1\r\n" +
  21.                          "Host: " + host + "\r\n" +
  22.                          "Connection: Keep Alive\r\n" +
  23.                          "Content-Length: " + length + "\r\n" +
  24.                          "Accept: */*\r\n" +
  25.                          "Origin: http://2.2.2.2\r\n" +
  26.                          "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" + "\r\n" +
  27.                          "User-Agent: zyzandESP8266\r\n" +
  28.                          "\r\n" +
  29.                          data + "\r\n";
  30.     //Serial.println(postRequest);
  31.     Serial.println();
  32.     client.print(postRequest);
  33.     delay(600);
  34.     //处理返回信息
  35.     String line = client.readStringUntil('\n');
  36.     while (client.available() > 0) {
  37.       line += client.readStringUntil('\n');
  38.     }
  39.     //  Serial.println(line);
  40.     client.stop();
  41.     if (line.indexOf("logon success") != -1 || line.indexOf("不需要") != -1) { //认证成功
  42.       return 0;
  43.     }
  44.     else {
  45.       return 2;
  46.     }
  47.  
  48.   }
  49. }

  最后自己焊接了个小板子,用AMS1117-3.3进行降压:
         <ignore_js_op> 
         <ignore_js_op>

WiFi-ESP8266入门http(3-1)网页认证上网-post请求(原教程)的更多相关文章

  1. WiFi-ESP8266入门http(3-3)网页认证上网-post请求-ESP8266程序

    第一版 原型系统 连上西电的网 直接发送上网的认证信息 返回认证结果网页 成功上网 #include <ESP8266WiFi.h> #define Use_Serial Serial s ...

  2. WiFi-ESP8266入门http(3-2)网页认证上网-post请求

    测试账号密码 加密模式  1 18011210338  + 015871     - 测试2 1601120382       +1 mimaHENFuzb  -1 打开网页 手机端 http://1 ...

  3. WiFi-ESP8266入门http(3-4)网页一键配网(1若为普通wifi直连 2若为西电网页认证自动网页post请求连接)+网页按钮灯控+MQTT通信

    网页一键配网(1若为普通wifi直连  2若为西电网页认证自动网页post请求连接)+网页按钮灯控+MQTT通信 工程连接:https://github.com/Dongvdong/ESP8266_H ...

  4. 我了解到的新知识之—Apple Captive Portal 网页认证登陆公共Wifi

    因为今天一个用户遇到选择公司WiFi后,无法弹出网页认证登陆界面的问题,随即上网搜索相关信息,因为公司内没有VPN,无法FQ,只能用bing来搜索一下相关信息了. Captive Portal听起来好 ...

  5. 6-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(Wi-Fi模块SSL连接MQTT)

    5-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(配置MQTT的SSL证书,验证安全通信) 首先确定自己的固件打开了SSL,升级篇里面的固件我打开了SSL,如 ...

  6. 5-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(配置MQTT的SSL证书,验证安全通信)

    4-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(为域名申请SSl证书) 前面的准备工作终于完了 复制这两个证书 放到云端MQTT的这个位置,其实放哪里都可以 ...

  7. 4-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(为域名申请SSl证书)

    3-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(购买域名,域名绑定IP) 然后就是等着..... 假设可以了 咱呢是配置MQTT实现SSL安全加密通信,所以 ...

  8. 3-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(购买域名,域名绑定IP)

    2-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(监听Wi-Fi和APP的数据) 因为安全连接是和域名绑在一块的,所以需要申请域名 有没有不知道域名是什么的, ...

  9. 2-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(监听Wi-Fi和APP的数据)

    1-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(来看一下怎么样监听网络数据,监听电脑上位机软件的数据) 因为那个软件只能监听咱自己电脑上的数据,所以咱就用电 ...

随机推荐

  1. VUE 利用webpack 给生产环境和发布环境配置不同的接口地址

    第一步,分别设置不同的接口地址 首先,我们分别找到下面的文件: /config/dev.env.js /config/prod.env.js 其实,这两个文件就是针对生产环境和发布环境设置不同参数的文 ...

  2. [转]Javascript实现图片的预加载详解

    下面的函数实现了一个我们想要的最基本的图片预加载效果 function preloadimages(arr){ var newimages=[] var arr=(typeof arr!=" ...

  3. cf1136E. Nastya Hasn't Written a Legend(二分 线段树)

    题意 题目链接 Sol yy出了一个暴躁线段树的做法. 因为题目保证了 \(a_i + k_i <= a_{i+1}\) 那么我们每次修改时只需要考虑取max就行了. 显然从一个位置开始能影响到 ...

  4. IDEA项目搭建十四——Web站点Controller基类及布局页静态资源设计

    一.简介 站点搭建完成后,编写页面时一般会有如下几个需求 1.嵌套静态页面时有很大一部分通用代码,如css.js这部分可以使用thymeleaf的局部片段代码块组成 2.这些静态资源默认放在程序中,但 ...

  5. java读写properties工具代码

    package test612; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExc ...

  6. springboot 整合 redis

    jedis 和 lettuce 都是用来连接 redis 的客户端,jedis 如果不使用连接池是非线程安全的,lettuce 使用 netty 线程安全且并发性能更好: springboot 2.x ...

  7. 利用ChromeCROSS可以在chrome浏览器上调试跨域代码

    利用ChromeCROSS可以在chrome浏览器上调试跨域代码 1.下载ChromeCROSS文件,可百度下载,或者在我的百度云上下载:链接: https://pan.baidu.com/s/10_ ...

  8. git 入门教程之忽略文件

    忽略文件 "并不是所有的牛奶都叫特仑苏",在版本控制系统中也有相似的表达,那就是"并不是所有的文件都需要提交". 有的是因为没必要提交,比如日志文件,系统缓存文 ...

  9. 前后端分离djangorestframework——版本控制组件

    什么是版本控制 在实际开发中,随着时间的更新迭代,我们维护的项目可能会有很多个版本,所以我们写的API也有很多个版本,但是迭代到高版本,不可能以前的版本就不用了,比如一个手机端的app,不定期发布新版 ...

  10. SQL 一列拆分多行

    select a.col1,b.col2 from (select col1,col2=convert(xml,' <root> <v>'+replace(col2,',',' ...