1.前言
前段时间玩了树莓派的GPIO,串口和I2C接口,把树莓派当成单片机来玩,期间深入分析了wiringPi。相对于单片机,以Linux为操作系统的树莓派在网络功能方面要强大的多,下面就结合当下流行的云平台yeelink实现远程控制LED灯。该部分的代码通过python实现,它的简洁易用深深吸引了我。LED的控制由PCF8574实现,树莓派通过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使用 PCF8574 Python SMBUS】
使用Python SMBUS实现PCF8574扩展IO
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 )
5.总结和文字债
可以在未来继续总结的内容——python requests库使用;python smbus使用。