谢作如
在去年的疫情期间,我用虚谷号做了一个能够定时打铃、广播的创客作品——定时铃声广播系统,让家里的作息时间和学校保持一致。想不到这个简单的作品吸引了很多朋友的目光,常常有人来询问作品的编程细节问题。
从功能上分析,我们常见的创客作品大都属于“动作触发”类型,借助传感器感知外界的信息,然后根据输入的信息来执行相应的动作。而定时铃声广播系统则是根据系统内部的时间进行触发,属于“时间触发”类型。这种作品的编程重点在于如何定时执行一个个任务,即实现定时任务或者任务调度功能。
● “定时任务”的技术分析
我们知道,现在的计算机操作系统都支持“多任务”(Multitasking)。虽然计算机的中央处理器(CPU)在同一时刻只能运行一个程序(双核心则支持两个),但是由于CPU的速度极快,每秒能执行几十亿条机器语言指令,因此系统可以划分出微秒级的时间片,通过合理的任务调度快速切换执行程序,从人类的角度看就是在同时运行了。
虚谷号上运行的是Linux系统,有很多方法实现任务调度。说起用Python代码实现定时执行任务,大家肯定会想到用“sleep”,代码如图1所示。
在循环中加“sleep”的做法显然不够好,最大的缺點是只能执行固定间隔时间的任务,不支持定时任务,如早上六点半播放起床铃声。另外,“sleep”是一个阻塞函数,也就是说在“sleep”这一段时间,计算机什么都不能做。因而,要实现很多任务的调度,一般会使用Python标准库中的sched模块,参考代码如图2所示。
sched模块在调度器类使用一个延迟函数,等待特定的时间执行任务,同时支持多线程应用程序,在每个任务执行后会立刻调用延时函数,以确保其他线程也能执行。但是,如果要调度的任务是周期性的,而且任务比较多,用sched模块实现依然不够方便。这时,我们需要使用功能更加强大的第三方库,如schedule或者APScheduler。
● Python的任务调度库Schedule简介
Schedule是一个非常小巧的任务调度库,其安装方法如下:
pip install schedule
Schedule的使用方法很简单,只要把要执行的任务封装为一个个函数,然后用Schedule去调用对应的函数名即可,代码可读性非常好。参考代码如下页图3所示。
看到“seconds.do”的语句,是不是立刻秒懂?这就是Schedule的最大优势之一。Schedule支持很多种调度任务的方法,具体如下表所示:
Schedule还支持传递参数,具体请参考Schedule的官方文档。
(地址:https://schedule.readthedocs.io/en/stable/)
需要强调的是,Schedule也是阻塞型的。如果要避免阻塞,我们可以借助threading模块,以多线程的方式进行工作。
● 定时铃声广播系统的代码编写
我做的定时铃声广播系统并没有使用其他硬件,一块虚谷号加声卡和小音箱即可。当然,因为定时广播内容来自网络,如天气预报和英语听力,所以需要设置上网。这里的代码其实适用于绝大多数类似虚谷号的迷你电脑,如树莓派、拿铁熊猫,或者其他小型的电脑主机。
1.获取天气预报信息
这里采用的是“心知天气”的接口,用Requests获取,然后逐一取出需要的信息即可。参考代码如图4所示。
2.获取英语听力内容
通过Requests获取一个词典网站上的“每日一句”的内容,再用正则表达式找到需要的内容。参考代码如下页图5所示。
函数返回两个字符型变量,分别为文本和音频地址,如下页图6所示。
3.合成声音
虽然声音的合成可以直接用Pytts库,但如果追求语音的质量,则推荐调用百度AI平台的接口。考虑到突然间的语音播放会吓人一跳,我在播放语音前,先播放一个“叮”的提示音。参考代码如下页图7所示。
4.定时播放铃声
虽然核心代码看起来有点长(如下页图8),但它类似于计划任务的清单,一看就明白。
相关代码已经收集在虚谷号的课程中,下载地址为:https://github.com/vvlink/vvBoard-docs。
● “定时任务”功能的应用
在中小学的创客作品中,“动作触发”类多如牛毛,而“时间触发”类却寥寥无几。其中的原因有很多。例如,之前习惯于使用Arduino,而Arduino没有内置时间模块,实现定时任务的功能有点麻烦,大家的思维被局限了。又如,定时任务往往在内部执行,在外部看不出工作流程,展示起来不直观。再如,很多作品并没有“真正”运行,仅仅停留在展示层面。“时间触发”类作品解决的是需要长期运行的问题。
生活中很多问题需要用定时执行的方式去解决,如定时打铃、定时开门、定时拍照等。当我们从Arduino、掌控板等单片机系统,逐步升级到虚谷号、树莓派、拿铁熊猫等能够运行Linux、Windows操作系统的迷你电脑时,借助于Python强大的第三方库,能够实现的功能就越来越多了。创客教师需要引导学生关注生活中的各种应用,不断提出新的需求,不断挑战新的难题。