1.前言
前段时间玩了树莓派的GPIO,串口和I2C接口,把树莓派当成单片机来玩,期间深入分析了wiringPi。相对于单片机,以linux为操作系统的树莓派在网络功能方面要强大的多,下面就结合当下流行的云平台yeelink实现远程控制LED灯。该部分的代码通过python实现,它的简洁易用深深吸引了我。LED的控制由PCF8474实现,树莓派通过I2C接口和PCF8574相连,PCF8574是一个简单易用的GPIO扩展IC。
2.相关博文
列举一些相关博客,你一定会有所收获。
2.1 Yeelink相关
【Yeelink平台使用——远程控制 RT Thread + LwIP+ STM32】使用STM32+LWIP+RTThread实现,需要有一定的嵌入式基础和套接字编程经验才可以上手,相对于本文来说难度大的多。
【Yeelink Http请求格式分析】带你上手yeelink平台,体会REST API的设计和使用。
【cURL 学习笔记——结合yeelink平台】cURL工具可以帮助你测试yeelink平台API函数,如果遇到问题这是一个很好的解决问题的途径。
【Yeelink平台查询开关量——套接字编程 Windows平台】在windows平台上使用mingw实现,通过该方法可以熟悉socket。
2.2 树莓派相关
【树莓派学习笔记——I2C PCF8574 BCM2835 Library】使用BCM2835 Library实现PCF8574扩展IO
【树莓派学习笔记 ——I2C PCF8574 SysFs方式】使用SysFS方式实现PCF8574扩展IO
【树莓派学习笔记——I2C SMBUS python方式】 (突然发现还没有写,下次补充)
3.工作流程
可通过手机客户端发送POST请求,该LED的URI为/v1.0/device/1949/sensor/2511/datapoints。通过POST请求修改LED状态,树莓派间隔想Yeelink平台请求该LED状态,通过响应中的value结构设置真正的LED。
设置LED状态——手机客户端。
POST请求格式如下:
POST /v1.0/device/1949/sensor/2511/datapoints HTTP/1.1 U-ApiKey: ffa3826972d6cc7ba5b17e104ec5xxxx Host: api.yeelink.net Content-Length: 11 {"value":1}
查询LED状态——树莓派间隔向yeelink请求开关状态
GET响应格式如下:
HTTP/1.1 200 OK Content-Type: text/html Connection: keep-alive Content-Length: 45 {"timestamp":"2013-02-24T20:05:44","value":0}
此时value的值为处理的核心。
4.代码实现
#!/usr/bin/env python # -*- coding: utf-8 -*- import requests import smbus import RPi.GPIO as GPIO import time # 打开 /dev/i2c-1 bus = smbus.SMBus(1) # 设备URI apiurl = ‘http://api.yeelink.net/v1.0/device/1949/sensor/2511/datapoints‘ # 用户密码 apiheaders = {‘U-ApiKey‘: ‘ffa3826972d6cc7ba5b17e104ec5xxxx‘} while True: #发送请求 r = requests.get(apiurl,headers=apiheaders) # 打印响应内容 print(r.text) # 转换为字典类型 请注意 2.7.4版本使用r.json() led = r.json # {‘value‘:x} x=1打开状态,x=0关闭状态 if led[‘value‘] == 1: print("led on") bus.write_byte( 0x20 , 1 ) else: print("led off") bus.write_byte( 0x20 , 0 ) # 延时5S time.sleep(5)
【运行结果】
图1 LED状态从关闭到打开
【代码分析】
1.设备URI,请根据设备实际URI修改。
apiurl = ‘http://api.yeelink.net/v1.0/device/1949/sensor/2511/datapoints‘
2.U-Apikey本质为用户密码,请根据实际密码修改。
apiheaders = {‘U-ApiKey‘: ‘ffa3826972d6cc7ba5b17e104ec5xxxx‘}
3.发送请求,使用requests库实现get请求,请注意headers为该HTTP请求首部,该首部需要包括用户APIKEY。requests是一个简单好用的网络通信工具,后期的博文还要整理归类一下。
r = requests.get(apiurl,headers=apiheaders)
4.响应转换内容为字典形式,把json格式变化为python字典形式,那么就可以通过“键”查询到“值”,此时键为value,值为1或者0。通过测试发现,树莓派中的python版本为2.7.3,r.json的类型是字典类型,但是在2.7.4(我的windows电脑安装的python)中r.json()才是字典类型。
led = r.json
5.根据value键的值修改LED状态。
# {‘value‘:x} x=1打开状态,x=0关闭状态
if led[‘value‘] == 1:
print("led on")
bus.write_byte( 0x20 , 0x01 )
else:
print("led off")
bus.write_byte( 0x20 , 0x00 )
6.SMBUS操作简述
打开I2C设备。树莓派版本2为I2C设备的编号为1(从0开始编号)
bus = smbus.SMBus(1)
向PCF8574写入一个字节,请千万小心0x01代表打开LED1,0x02代笔打开LED2,但是0x03并不是打开LED3,而是打开了LED1和LED2。
bus.write_byte( 0x20 , 0x01 )
6.总结和文字债
可以在未来继续总结的内容——python requests库使用;python smbus使用。