用树莓派监报自己微博各种消息未读数

 

去年双十一的时候也是心血来潮入手了一树莓派,但无线网卡一直驱动不起来,最近正好有机会又捣鼓了几下,竟然成功连上网络了,并且开启了 ssh,所以不再需要拖着一个显示屏了和外接键盘了,我直接就用我的笔记本或手机便能控制它。

  • 配置树莓派

这里说一下,如果有同样驱动不了无线网卡的,其实最简单的方法是重刷最新的系统。并且修改 /etc/network/interfaces

sudo vi /etc/network/interfaces


树莓派初始是没有 vim 的,所以只能用 vi ,或者 nano 编辑也行,interfaces 的内容改为:

auto lo

iface lo inet loopback
iface eth0 inet dhcp

auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-ssid 你的wifi名
wpa-psk 你的wifi密码
gateway 192.163.23.1 # 设置个网关

:wq 保存退出后,马上重启无线网络:

sudo /etc/init.d/networking restart

成功后,用 ifconfig 命令可以看到 wlan0 设备,且有了IP地址(已连接),以后每次启动,系统都将自动连接到你指定的那个的 wifi 热点。

另外,一些相关且可能需要的命令:

查看自己的无线网卡是否生效,查看挂载的USB设备:

sudo lsusb

测试wifi信号:

sudo iwlist wlan0 scan

如果要设置成获取静态 ip 的,请参考这篇文章:树莓派无线网卡配置方法 (但我发现我的路由器不支持连接设备自选 ip ,所以我上面才使用 dhcp ,随路由器分配)

    • 编写访问微博 api 的程序

首先你得给你的 Linux 装上 libghttp 这个 http 库,具体安装过程我已经在上一篇文章里面讲得很详细了,所以请转到 《用C语言写自动发微博程序》阅读。

而这一次我们要做的是通过树莓派去访问微博的未读消息数,比如说“新评论数”、“新@数”、“新粉丝数”等等这些消息。新浪微博提供了 GET 方法访问的接口,所以相比上一次写“发微博”的程序会更加简单,但由于用到 https ,所以我仍然用到了 Java 写的代理服务器,仍然没有去探索更好的方法。其实可以给树莓派直接装上 JDK 的,但由于最新的 JDK 8 有 135MB+ ,而且我的树莓派SD卡已经只剩下 130MB 的空间了,所以还是不推荐直接装 Java,我们还是要纠结地用 C 写。可爱

新浪微博 remind/unread_count 获取某个用户的各种消息未读数 api 介绍:

必要提交的参数其实就只有一个 access_token ,也就是你的 OAuth 认证码,关于这一点,我在上一篇文章里面也说明了,你可以申请一个应用 key ,然后再进入微博提供的 API测试工具 可得你的这个 token 。

这个接口返回的 Json 内容示例是这样的:
{"status":48,"follower":0,"cmt":3,"dm":0,"mention_status":0,"mention_cmt":0,"group":0,"notice":0,"invite":0,"badge":0,"photo":0}
其中 cmt 就是“新评论数”,mention_status 就是“新提及我的微博数”,这两个是我比较关注的,所以我就只要解析这两个 key 的 value 。其余的若想了解,自行查看新浪提供的文档。

了解了新浪的接口之后,接下来就是编写代码的工作了。这是我写的访问代理服务器的 url ,并获得新浪反馈回来的 Json 内容,再粗暴提取解析 Json 内容的 C 代码(=。=这句话真长。。。):

#include <stdio.h>
#include <string.h>
#include <ghttp.h>
#include <stdlib.h>

#define TRUE 1

int do_get(char *);
int analyse_and_play(char * body);
int temp = -1;

int main(int argc, char **argv) {

    char body[256] = {0};

    while(TRUE) {
        printf("GET return: %d\n",  do_get(body));
        analyse_and_play(body);
    }
    return 0;
}

int analyse_and_play(char * body) {

    int i = 0, cmt = '0', ms = '0';
    while( body[i] != '\0') {
       if(body[i] == '"' && body[i+1] == 'c') {  // 简单粗暴的获取 cmt 值的方法:
           cmt = body[i+6];
       }
       if(body[i] == '_' && body[i+1] == 's') {
           ms = body[i+10];
       }
       i++;
    }

    if(cmt > '0' && temp != cmt) {
        system("mplayer sms.mp3");
    	temp = cmt; // don't loop
    	return 1;
    }

    return 0;
}

int do_get(char * body) {

    char * uri = "http://****我的代理服务器。。隐去****/WeiboProxy?do_what=unread_count";
    ghttp_request *request = NULL;
    ghttp_status status;
    char *buf;
    int size;

    request = ghttp_request_new();
    if(ghttp_set_uri(request, uri) == -1)
        return -1;
    if(ghttp_set_type(request, ghttp_type_get) == -1)//get
        return -1;
    ghttp_prepare(request);
    status = ghttp_process(request);
    if(status == ghttp_error)
        return -1;
    printf("Status code: %d\n", ghttp_status_code(request));
    buf = ghttp_get_body(request);

    size = strlen(buf);
    printf("ghttp get body: %s\n", buf);
    strcpy(body, buf);
}

其中system("mplayer sms.mp3"); 用到 Linux 下的 mplayer 命令,如果你没有 mplayer 的话,需要 sudo apt-get install mplayer 下载安装一下这个播放器。如果下载安装过程出错,可能你需要更新一下你的 apt-get ,因为我就遇到这个问题,更新之后再重新安装 mplayer 就可以了。

Java 代理服务器方面的代码我也顺带贴一下吧:(部分)

private String unreadCount() {

	HttpClient client = new HttpClient();
	client.getHostConfiguration().setHost(UNREAD_COUNT_HOST, LOGON_PORT);
	GetMethod get = new GetMethod(UNREAD_COUNT_HOST);
	try {
		client.executeMethod(get);
	} catch (HttpException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}

	String responseString = null;
	try {
		responseString = new String(get.getResponseBodyAsString()
				.getBytes("utf-8"));
	} catch (UnsupportedEncodingException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	get.releaseConnection();
	return responseString;
}

最后在 Linux 上运行的状态:

如果你想后台运行这个程序,并且在你的 ssh 关闭了之后仍然后台运行,你可以使用这个命令:

nohup 你的程序 &

还有我用的新评论提示音(很赞的哦^ ^):

参考到的资料:

更新、补充:

这是我后来想到的第二种方法,相比本文的方法,这个方法更加简单,而且不需要依赖 libghtt 这个库。