rWTT - 基于 Raspberry 硬件并链接到 Dynamics AX 的工作时间追踪器。
一个工作时间跟踪解决方案,它读取基于 Raspberry 的终端上的 RFID 标签,该终端已集成到 Dynamics AX 2009 中。
引言
项目概述(30字内及三图)
本项目是一个基于Raspberry硬件的RFID考勤打卡解决方案,并集成了Microsoft Dynamics AX 2009 ERP系统。
优点(硬件)

缺点(软件)

不足之处(结果)

背景
当时有一个亚洲某分公司需要替换现有的(非常基础的)工时打卡系统。
最初的想法是购买现成的产品,认为这应该不是难事,市面上有很多产品可供选择。因此,一开始没有进行“自制还是外购”的决策。但正如项目(尤其是IT项目)的常态,事情总不会一帆风顺。当需要定义需求时,发现将所有数据保存在ERP中会是个好主意,该站点使用的ERP是MS Dynamics AX 2009。主要原因之一是所有员工数据已经存在于其数据库中。
这似乎也不是个问题…… 是的,可能不是,但价格合理的现成解决方案却找不到。事实上,我们已经订购了一个现有解决方案,但事实证明,它似乎不像供应商保证的那样工作。于是,我们又回到了“自制还是外购”的决策,并开始评估各种选项。
事实证明,使用基于Raspberry硬件的系统可以满足我们对终端的所有需求,并且我们可以自行完成ERP系统集成。
于是我们进行了一些原型开发,效果看起来不错,我们决定推进这个项目。
要求
项目定义的需求如下:
- 一个终端解决方案,用户可以在签到或签出过程中扫描唯一的RFID标签进行身份识别。
- 所有签到/签出数据记录应存储在ERP中。
- 一个报表,显示当前在场的所有人员。
- 一个可定义日期范围的报表,显示员工在指定日期范围内工作时长的概览,包括总计。
这些需求是在项目实施阶段定义的。
- 触摸显示屏必须是7英寸,否则太小了。
- 硬件应基于Raspberry,使用Raspbian操作系统。
- 为了准确跟踪时间,员工需要能够选择签出休息或出差。
- 即使网络中断或ERP不可用,也必须能够进行签到/签出。
- 该解决方案应可移植到其他ERP系统。
- 用户在签到/签出时应有蜂鸣声作为反馈。
- 错误的签到/签出记录或遗漏的记录需要在ERP中进行更正。
- 在ERP中,所有手动添加的记录都应有一个标记,以便识别。
- 不得在ERP中删除记录。
- 所有工时处理均以分钟为单位。
- 系统应具有服务菜单功能,允许特权用户重启或关闭系统。菜单应通过扫描特殊RFID标签或输入数字代码打开。
- 每条记录都应单独由服务器获取,以确保在最坏情况下(例如,在传输过程中网络连接丢失)我们最多只会丢失一条记录。
硬件
硬件方面,我们决定使用一个带有7英寸触摸屏的终端,因此我们订购了包含以下物品的Raspberry入门套件:
- Raspberry Pi 3
- 7英寸电容触摸屏
- 触摸屏外壳
- SD卡
- 电源
- HDMI线
- 电源
- 散热片
作为附加硬件,我们使用了:
- USB RFID读卡器,它模拟键盘,像从键盘输入一样输入唯一的RFID ID。
- 一个有源蜂鸣器,用于Raspberry,以最大程度地减少控制所需的代码量。
入门套件中的大多数组件。

USB-RFID读卡器。

蜂鸣器模块。

组装过程
第一步是将Raspberry连接到显示面板,并将电缆插入DSI接口。

显示屏还需要两条电源线,将在下一步添加。

完成此操作后,可以安装散热模块,并将显示屏安装到外壳上。
(我建议在执行此操作之前插入SD卡,因为在未安装外壳背面时更容易完成。)



最后一步是将蜂鸣器模块用热熔胶固定在外壳上,并连接到电源和GPIO引脚23。
(为确保蜂鸣器粘牢,我用砂纸打磨了外壳上涂抹热熔胶的区域。我建议不要撕掉贴纸,不撕的话蜂鸣器会非常响。)

启动系统,检查一切是否正常运行。

软件
软件包含三个组件:
- Raspbian操作系统及其配置。
- 运行在Raspberry上的几个Python脚本。
- ERP系统中的实现,包含获取和处理数据的代码。
概念
在考虑满足项目需求的最佳架构方法时,做出了以下决定:
所有签到/签出记录应本地存储在文件系统中,并由处理系统通过HTTP或HTTPS获取。处理系统不应局限于Dynamics AX。如果实现了支持HTTP或HTTPS的任何其他系统,甚至Microsoft Access,都应该是可能的。
从终端获取数据后,应将其删除,以防止SD卡耗尽内存。
终端上的用户界面应作为一个网页运行。
应该支持多个终端,并且用户在哪个终端签到/签出都无关紧要。
Apache2被用作应用程序服务器组件,所有脚本均用Python编写。
下载次数
本项目需要一些可以在互联网上找到的工具。
- Raspbian镜像(当前版本2017-07-05-raspbian-jessie)可以在这里找到。
- 将镜像写入SD卡的工具可以在这里找到。
- VNC-Viewer,用于图形化远程访问系统,可以从此链接下载。
- Putty SSH客户端,用于终端级别的访问Raspbian系统,可以在此链接找到。
操作系统
下载Raspbian镜像和写入SD卡的程序后,应将镜像写入SD卡。


从SD卡启动系统后,第一步是启用SSH和VNC。


重启后,所有服务都将运行,并且当您将Raspberry连接到网络时,可以通过SSH和VNC进行访问。
首先应该更改默认密码,并启用root帐户并为其设置密码。我知道Debian(Raspbian的基础)使用sudo方法,但我更喜欢直接以root用户身份登录并直接在root上下文中进行操作。如果您有安全方面的顾虑,之后可以禁用root帐户。


下一步是安装midnight commander,对我来说,进行系统安装和维护是必不可少的。

安装apache2需要先更新当前Raspbian发行版的系统。

安装apache2

快速检查表明Apache2正在运行。

为了启用Python的CGI功能,需要在控制台和mc中执行一些步骤。

将红色标记的配置行添加到/etc/apache2/conf-enabled。


为了获得音频反馈,必须允许apache进程与GPIO交互以开启蜂鸣器。这通过以下命令完成:

所有签到/签出数据将存储在名为/tk/的目录中,需要创建此目录并使其可供apache进程写入。

apache用户还需要通过服务菜单关闭系统的访问权限。


pi用户拥有过多的访问权限,因此我们创建一个名为guest的新用户帐户,并配置自动登录以及Chromium的自动启动,并为其打开签到/签出网页。



现在系统需要重启,因为用户的主目录当前不包含需要编辑的autostart文件,并添加此行:
@chromium-browser --noerrdialogs --kiosk --incognito --disable-pinch 
--overscroll-history-navigation=0 https:///cgi-bin/wtt.py

这将自动以Kiosk模式启动浏览器,禁用捏合缩放和历史滑动功能。
在项目文件中,您会找到一个名为mutebeep.py的脚本,位于/usr/bin/文件夹中。安装稍后进行。如果您已经添加了蜂鸣器,您会注意到系统启动时它会发出声音。原因在于它是一个低电平有效的设备,GPIO引脚23的输出必须是高电平才能使蜂鸣器静音。这由mutebeep.py脚本完成。
我们将其添加到位于/etc/的rc.local文件中。


如果您想使用raspi-config程序更改系统的hostname,则下一步是可选的。




当前,系统通过dhcp获取IP地址。如果您想分配一个静态IP地址,请执行此步骤。


为了确保终端时间准确,我们还需要设置时区(对我来说是德国柏林)。






说到时间,最好始终让终端与时间服务器同步本地时间。如果您在AD域中,可以使用任何域控制器,或者使用互联网上的时间服务器,前提是系统允许直接与外部通信。

如果您处于代理环境中,此链接可能会很有用,它显示了如何配置Raspbian。
Python脚本
下载并解压项目后,您将获得三个文件夹。
- AX -> 包含所有用于在AX中作为Project和单个文件导入的文件。
- Raspi_bin -> 包含所有用于/usr/bin文件夹的文件。
- Raspi_cgi-bin -> 包含所有用于/usr/lib/cgi-bin文件夹的文件。
Raspi*文件夹中的文件需要复制到Raspberry的正确文件夹中,并最终使其可执行。您可以通过USB闪存驱动器将它们复制到终端并运行以下命令:
chmod +0755  /usr/bin/mutebeep.py
chmod +0755  /usr/lib/cgi-bin/reboot.py
chmod +0755  /usr/lib/cgi-bin/service.py
chmod +0755  /usr/lib/cgi-bin/shutdown.py
chmod +0755  /usr/lib/cgi-bin/wtt.py
chmod +0755  /usr/lib/cgi-bin/wtt_get.py

cgi-bin文件夹中的文件详解
reboot.py	-> Script that does the system reboot
service.py	-> Script that shows the service menu
shutdown.py	-> Script that does the system shutdown
wtt_get.py	-> Script called from remote application to get the sign in/out data 
			-> Returns OK:posting data if data is returned or 
                       NONE: if no data is available
wtt.py		-> Script that shows the main application and creates the sign in/out records
wtt.py提供了一些可配置选项。

serviceTagID存储了用于打开服务菜单的标签ID。
adminCode是在键盘上输入的用于打开服务菜单的代码。
storagePath配置了用于临时存储签到/签出数据的文件夹在文件系统中的绝对路径。
postText*定义了在网页上发布签到/签出时显示的文本。
buzzerPort定义了蜂鸣器连接到哪个GPIO端口。
ERP软件组件
压缩项目中的AX文件夹包含AX 2009组件,位于两个单独的文件夹中:
所有元素都分别导出到objects文件夹中,可以单独导入。
在子文件夹中,project包含整个AX开发项目。

重要的项目包括三个窗体、两个报表以及两个类:WTTcloseLastWorkingDays和WTTfetchTerminalData。
窗体 WTT-Terminals
在此窗体中,必须添加所有将要获取数据的终端。

提示:未启用的终端将不获取任何数据。
窗体 WTT_RfidTagTable
在此表中,需要输入每个RFID标签并将其与使用该标签的员工关联。

窗体 WTT_WorkingDayTable
这是应用程序的主窗体。

对于每个签到/签出的用户,工作日网格(上方)中会创建一个记录。只要该日未关闭,工作时间分钟数就不会被准确计算。日期由夜间运行的批处理作业关闭。在“记录”部分(下方),您可以看到终端上的每一次签到/签出过程以及手动生成的更正记录。手动更正记录通过相应字段中的“是”进行标记。
通过单击“提交更正”按钮,将打开此对话框,您需要在此处指定签到/签出记录的详细信息。


报表 WTT_CheckedInEmployees
此报表打印了站点上所有当前签到员工的概览。目的是在紧急情况下能够快速获取信息。


报表 WTT_WorkTimeOverview
此报表显示了员工在可定义时间段内工作的小时数。


请注意,此报表仅考虑已关闭的日期。
类 WTTcloseLastWorkingDays
此类可以手动运行,但通常设计为在早上作为批处理作业运行。其主要目的是关闭带有记录的日期并计算工作分钟数。它会查看过去七天,并检查是否需要进行任何更正。
提示:如果某天已关闭并手动进行了更正记录,则工作时间将立即重新计算。
类 WTTfetchTerminalData
此类旨在以批处理模式运行。它会从所有终端获取所有可用的记录。
每条记录都单独传输,以确保在发生网络丢失或其他错误的情况下,我们最多只会丢失一条签到/签出信息。
应每小时运行一次,或根据您的需求调整频率。
菜单项
您会注意到目前没有元素被添加到现有的AX菜单中。
您可以根据自己的意愿将这些项添加到任何菜单中。
Using the Code
源代码相当直接,您可以根据需要进行修改。
附加功能
我发现的一些有趣但尚未实现的功能包括:
- 将员工姓名从ERP发送到终端,以便终端可以按姓名欢迎员工,或者作为增强功能显示签名人员的照片。
- 跟踪假期(也许可以添加一个额外的菜单按钮,员工可以通过该按钮选择休假)。
- 通过在月底发送电子邮件来自动化报告。
提示和技巧
如果您想在工作站上进行签到/签出,可以连接一个USB-RFID读卡器,并在该工作站上打开终端网页wtt.py。
您可以轻松自定义终端的用户界面,添加公司徽标,因为一切都是HTML。


如果您遇到将显示屏安装在墙上后屏幕倒置的问题,可以编辑配置文件/boot/config.txt并在末尾添加以下行:
lcd_rotate=2

关于安全性的几点说明
如果您处于安全至上的环境中,可以采取以下措施来提高安全性:
- 禁用VNC。
- 禁用SSH(但SSH目前是安全的)。
- 禁用用户pi帐户的SSH登录。
- 将传输协议更改为HTTPS(但请注意,您需要负责证书的有效性!)。
- 将用于交换签到/签出数据的传输协议更改为SSH。
- 使用防火墙限制入站和出站网络访问。
- (物理上)阻止Raspberry的USB端口。
结论
通过低成本的Raspberry硬件终端和RFID读卡器,可以以合理的成本完成工时跟踪。
有用链接(截至2017年8月5日)
- 另一种基于Raspberry硬件的工时跟踪实现(德语):http://www.solongo.de/de/spielplatz/timr/
- Raspbian镜像:https://www.raspberrypi.org/downloads/raspbian/
- 将磁盘映像写入SD卡的工具:https://sourceforge.net/projects/win32diskimager/
- VNC-Viewer:https://www.realvnc.com/en/download/viewer/
- Putty SSH客户端:https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
历史
- 2017年8月6日:版本1.00 初始发布
- 2017年8月8日:版本1.01 格式更正和一些拼写错误
代码许可证
我提供的所有代码均获得GPL v3或更高版本的许可。
© 2017 Ulrich Fiege



