CubieBoard博客-HomeCubieTech公司网站

cubie.cc CubieBoard中文论坛

 找回密码
 立即注册
搜索
热搜: unable
查看: 2276|回复: 2

wifi + DHCP 实现基本的入户感知

[复制链接]

13

主题

0

好友

2564

积分

金牌会员

Rank: 6Rank: 6

贡献
480
金钱
1062
威望
480
买家信用
卖家信用
积分
2564
发表于 2017-5-15 14:38:47 |显示全部楼层
本帖最后由 kappa8086 于 2017-5-15 15:40 编辑

说到智能家居入口,之前脑中先闪现了一堆协议名词比如 zigbee, ibeacon
然而除了特定的单个应用,似乎根本没有可扩展性的成熟产品出现
而我这里只是想开始做一个最简单的功能:主人进门后自动放一段音乐

经过了很多绕弯子的想法后(连 NFC 都用上了,甚至还要给手机专门写 app),头脑终于才清灵过来。

这个事情很简单,回家后手机必然自动连接 wifi (如果这个也不靠谱蓝牙类应用就更难说了),AP 端一般不能进行二次开发,何况很多人家里不只一个无线 AP;但 DHCP 服.务通常有且只有一个,而 wifi 也要靠这个来分配 IP。这就是切入点。

DHCP如何触发到我们自己的应用?当然首先要看家中网络的DHCP是什么具体服.务提供的,其有没有扩展能力。
一般来说,这个服.务都由路由器来提供,如果你的路由器可以刷机且系统是基于 openwrt 的或者是 tomato 的某个改版(我这里用的是 shibby),那么就天然的具体扩展能力,而其 DHCP 服.务通常是 dnsmasq;这个前提并不重要,如果你的路由器或 DHCP server 本身没有扩展能力,你大可以关掉路由的 DHCP 功能,在任一个 linux 开发板上如 ct 自己部署一个 dnsmasq,这样 DNS 和 DHCP 就都可以自己折腾着玩儿了。

于是这就以 dnsmasq 为例。其打开 DHCP 功能后,有一个配置项叫 dhcp-script:
  1. dhcp-script=/tmp/home/root/dhcp-register.sh
复制代码
在 tomato 系统当中,最好是把这项从管理界面上配置到 DHCP/DNS 的自定义配置中去,这样存在 nvram 里不会丢失。

然后 ssh 进入,创建该脚本
vi /tmp/home/root/dhcp-register.sh
内容为
  1. #!/bin/sh

  2. wget -T 2 "http://192.168.1.23:1024/entry?action=$1&mac=$2&ip=$3&host=$4" > /dev/null
复制代码
tomato 下没有 curl,以 wget 代劳,无论如何,这只是一个引线,当一个设备以 DHCP 注册一个 IP 的时候,该脚本触发,参数含义分别为:$1 - 动作类型 (add/old/del/...),$2 - MAC 地址,$3 - 分配IP地址, $4 - 设备主机名

如果 dnsmasq 是被部署在开发板上并且和目标应用在一块,那这里甚至可以直接执行目标应用,但注意异步,否则执行不完卡死 dnsmasq 就不好玩了。我这里三部分分开,dnsmasq 这里的脚本只做触发端,于是还需要一个接收端和一个应用脚本。





回复

使用道具 举报

13

主题

0

好友

2564

积分

金牌会员

Rank: 6Rank: 6

贡献
480
金钱
1062
威望
480
买家信用
卖家信用
积分
2564
发表于 2017-5-15 14:59:45 |显示全部楼层
本帖最后由 kappa8086 于 2017-5-15 15:23 编辑

老办法,python + Flask 写一个简单的 webserver 并用 service 文件包装一下成为 systemd 服.务。
  1. #!/bin/python

  2. from flask import Flask,request
  3. import subprocess

  4. app = Flask(__name__)
  5. ctrlscript = os.path.expanduser('~/bin/homectrl.sh')

  6. @app.route('/')
  7. def index():
  8.     return ''

  9. @app.route('/entry', methods=['GET', 'POST'])
  10. def entry():
  11.     subprocess.Popen([ctrlscript, request.args.get('action'),
  12.         request.args.get('mac'), request.args.get('ip')])
  13.     return 'ok'

  14. if __name__ == '__main__':
  15.     app.run(host= '0.0.0.0', port=1024)
复制代码
执行脚本,在一个mpd的曲库列表里随机抽三首播放。这里的关键是执行条件,除了要判断手机的MAC地址,还需要有个时间限定,以及执行次数限定,这个场景一天只应该出现一次
  1. #!/bin/bash

  2. action=$1
  3. mac=$2
  4. ipaddr=$3

  5. ts_file=/var/tmp/homectrl.ts
  6. tm_start=1800
  7. tm_end=2200
  8. music_list_file=~/welcome-music.list

  9. function mpcfadein {
  10.     #mpd音量渐入过程,进门被突然出现的高音吓一跳绝对不是一种好的体验
  11.     ((steps=($2-$1)/5))
  12.     ((interval=$3/$steps))
  13.     c=0
  14.     while [ $c -lt $steps ]; do
  15.         ((cvol=$1+5*$c))
  16.     ((c=$c+1))
  17.         mpc volume $cvol
  18.         usleep $interval
  19.     done
  20.     mpc volume $2
  21. }

  22. if [ "$mac" == "01:23:45:67:89:ab" ] && [ "$action" == "old" ]; then    #除第一次注册时是add,之后都是old...
  23.     dt=`date +%Y%m%d`
  24.     ts=`date +%H%M`
  25.     saved_dt=""
  26.     [ -f $ts_file ] && saved_dt=`cat $ts_file`
  27.     if [ "$dt" != "$saved_dt" ] && [ $ts -gt $tm_start ] && [ $ts -lt $tm_end ]; then
  28.         randomsongs=`sort -R $music_list_file | head -n 3`
  29.         mpc clear
  30.         IFS=
  31. \n'
  32.         for song in $randomsongs; do
  33.             mpc add "$song"
  34.             mpc volume 10
  35.             mpc play
  36.             mpcfadein 10 60 2000000
  37.         done
  38.         echo $dt > $ts_file
  39.     fi
  40. fi
复制代码

回复

使用道具 举报

0

主题

0

好友

173

积分

注册会员

Rank: 2

贡献
39
金钱
52
威望
39
买家信用
卖家信用
积分
173
发表于 2019-4-9 23:11:59 |显示全部楼层
路过,发几张美女图片



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

QQ|Archiver|手机版|邮件群发|cubie.cc---深刻的嵌入式技术和应用讨论中文社区 ( 粤ICP备13051116号-1  

GMT+8, 2019-7-16 16:31 , Processed in 0.021713 second(s), 6 queries , Apc On.

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc. | Style by Coxxs

回顶部