详述群晖NAS配置DPF数码相框历程,分享lcd4linux精心配置CONF
本帖最后由 waylon 于 2015-9-12 10:02 编辑本人于今年(2015)二月份入手万由U-NAS后,一直在隔壁网和U-Share论坛汲取知识,最近终于有点空闲为NAS搞了个数码相框做监视器,期间一波数折,查阅了隔壁网和U-Share上几乎能找到的所有帖子,经过一番努力后,终于有了个几乎完美的结果,现将过程经验总结到这里,一来回报前辈们传承的知识,二来便于后来者能更为系统的掌握整个配置的过程,免得老走弯路。因本人能力有限、设备有限,也只能就目前遇到的问题做些总结,大家如有问题我能帮就帮,帮不了的也希望大家发扬钻研精神去找到答案。
说起液晶屏改造DIY的应用,早在十多年前在单位信息中心工作时,就面临过许多废旧设备拆下来的LCD如何处理的问题,当时找过制造部门负责维修的同事帮忙看看能不能通过单片机来废物利用,无奈大家学识有限,我自己又不善与硬件打交道,最终没能成功,这个心愿却一直没了,自从今年上了NAS之后,看到有前辈通过DPF(数码相框)改造作为NAS的监视器后就决定自己也配一个DPF,隔壁网上好像在2014年4月-8月间曾经一度流行DPF的改造,不过之后好像又逐步归于沉寂,以至于到现在我遇到众多的问题都找不到人帮助解决,只能自己摸索了。当然前辈们留下的文字还是很有帮助,在此先谢过以下各位前辈:superelchi大侠提供的DPF固件破解、olderzeus大侠编译的lcd4linux、nonzhe大侠提供的DPF固件破解指导、mrqian7188大侠提供的lcd4linux安装指导、xjcsuper大侠提供的CONF语法说明及CONF文件、amthb大侠提供的界面布局及CONF文件、yuko4632大侠提供的开关机脚本及raid配置查询方法,以及其他众多分享DPF经验的前辈们。
下面我分几个部分来总结DPF配置的整个过程:
一、购买DPF
二、破解DPF
三、安装lcd4linux
四、编写CONF配置文件
五、NAS中完善DPF的控制
个人原创主要在第四部分和第五部分,其他的基本上是参考各位大侠的经验总结
一、购买DPF
如众多帖子提到的,购买DPF上淘宝即可,但是就好像DPF改造逐步沉寂一样,淘宝上卖DPF的也少了很多,既找不到那个清仓的东北人,也找不到所谓9元的数码相框了,我就连刚开始都不知道应该在淘宝上输什么关键字来搜索,因为搜出来的要么就是大屏的相框,要么就是工控用的LCD,后来通过“数码相框 1.5寸”或“电子相框 1.5寸”终于找到了目标,可是这些设备是AX206芯片的么?卖家也说不知道,只能在网上搜AX206芯片DPF供应商网站的图片再来与淘宝的进行比较了,就这么选了一款深圳本地卖家的DPF撞运气,本想同城第二天就能拿到货,没想到愣是给我整了三天才快递收货,真是晕啊!由于时效性问题,淘宝的链接我就不贴出来了。(另外除了淘宝,国外ebay等很多网站也都有卖,有些链接至今有效,我是后面破解时才看到的)
这里要说下,因为目前破解的方案都是基于建荣AX206芯片的,因此如果能与店家确认是最好的,否则只能像我这样撞运气了,我在后面寻找破解时就遇到很多无法破解的非AX206芯片的人,如果遇到这种不幸的事只能重新购买。
有关DPF的基础知识可以查看nonzhe大侠的帖子:http://www.gebi1.com/thread-83915-1-1.html
二、破解DPF
DPF买回来后当然就需要破解刷新的固件进去了,前面提到的nonzhe大侠的帖子给了我非常大的帮助,基本上过程就像nonzhe大侠说的:
[*]备份DPF原固件
[*]检测DPF是否支持破解
[*]支持破解直接第4步刷固件,不支持破解找superelchi大侠破解
[*]刷固件
破解前特意把DPF打开看了下芯片,竟然和网上的图片不一样,没看到AX206的字样,瞬间心里就咯噔一下,不会这么衰吧!把DPF接上PC,在DPF的菜单中选择连接USB后,Win 7下会出现一个光驱盘符,这个虚拟光盘中有个DPFMate.exe是用来上传下载照片用的,试了下原固件的功能,就是简单的显示照片、时间之类的信息,接下来立刻尝试破解。
按nonzhe大侠的帖子,先在http://sourceforge.net/projects/dpf-ax/files/下载了windows下的工具包,并安装python,然后在windows下备份原固件,在cmd中执行命令:python fulldump.py f:,f:是那个光驱的盘符,这步倒是成功了,生成了fulldump_win_20150902-134439.bin文件,用WinISO打开bin文件看,原来就是那个虚拟光盘的内容,顺便打开了StartInfoUnicode.ini文件看看,其中一段:
FirmwareVer=EDPF1.1_STANDARD_V2.0.0
FlashType=Pm25LV040
FlashSize=512
PID=0x1315
LogoStr=Welcome
Titlename=DPFMate v5.0.2.1
CorpLink=http://www.buildwin.com.cn
www.buildwin.com.cn是建荣科技的网站,果然还是建荣的芯片,只不过Pm25LV040是个啥东东不太清楚,在dpf-ax包中的knowntypes.html文件中没找到Pm25LV040,心里还是悬着。(前面提到的ebay之类的购买网址,可以在knowntypes.html中查到)
接着识别DPF是否支持破解,执行python identify.py f:,得到的却是:
Running on windows - unable to detect flash size
Reading 100000 bytes from flash...
Flash written to file 'fulldump_win_20150903-000212.bin'.
Looking for firmware.............: Not found.
This in no known firmware!
Sorry, no matching dpf found.
顿时心里泼凉泼凉的,这是要废掉的节奏啊,果断决定按nonzhe大侠的提示去找superelchi大侠破解,注册并登录http://forum.doozan.com/read.php?9,10026后发现superelchi大侠在8月份还回过帖,这下遇到活菩萨了。接着把我的情况发帖说明并请求破解,因为之前得到的bin文件是1024KB的,无法传上去,只好把StartInfoUnicode.ini文件上传做参考,后面只能等待superelchi大侠回复了,superelchi大侠很快就回复了,告诉我就像程序提示的那样,unknow的firmware无法支持,不过他还是让我把bin文件想办法给他检查一下,于是把百度云盘的链接回复给了他。
继续等待回复期间查看了其他人与superelchi大侠的对话,果然很多AX208或者其他芯片是无法支持的,又仔细查看了superelchi大侠在篇首的说明,推荐在linux下检测DPF破解的支持性,于是想到直接在NAS的DSM系统中执行identify.py,可是问题来了,有段时间我的DSM无法识别USB设备,外接USB硬盘也无法在外接设备中显示,U-Share的QQ群中问过也没得到答复,再查各论坛的帖子,初步判断是DSM升级到5.1-5022.3时,XPEnoboot引导程序没有成功挂载USB驱动,看来得升级到5.2才能解决这个问题,可是现在DPF还没破解,暂时我还不准备升级,于是打算第二天用VirturalBox搭个Linux环境。
次日下载Ubuntu,安装虚拟机等过程按下不表,OS环境终于搭建好了,按照nonzhe大侠的介绍,一步一步下载源码编译,却遇到这个错误:
waylon@ubuntn-vm:~/dpf-ax$ cd trunk
waylon@ubuntn-vm:~/dpf-ax/trunk$ cd dpflib
waylon@ubuntn-vm:~/dpf-ax/trunk/dpflib$ make
cc -Wall -fPIC -I../include -g -c -o dpflib.o dpflib.c
In file included from dpflib.c:14:0:
dpf.h:8:17: fatal error: usb.h: 没有那个文件或目录
#include <usb.h>
^
compilation terminated.
<builtin>: recipe for target 'dpflib.o' failed
make: *** Error 1
网上搜了一通没找到答案,只能放弃....,这时superelchi大侠有了回复:
Hi waylon,
good news. I'm getting:
$ ./identify.py fulldump_win_20150903-000212.bin
Looking for firmware.............: Found (buildwin, 128x128 px).
Looking for Openwin..............: Found.
Looking for LcdIniTbl............: Found.
Looking for backlight & contrast.: Found, Found.
Looking for known signatures.....: Found.
Your dpf is compatible with model ['dx27893'].
So: this dump is compatible with dx27893. You can use the custom firmware fw_dx27893.bin.
superelchi
这个回复终于让我看到了希望,我顺便又将ubuntu下的编译问题咨询了他,并得到他的指导,执行sudo apt-get install libusb-dev后顺利编译,在ubuntu下执行identify.py,终于成功的得到了一样的提示:
Detecting & reading dpf flash...
Opening generic SCSI device '/dev/sg2'
Manufacturer: Apple
Size : 1 MB
Reading 100000 bytes from flash...
Flash written to file 'fulldump_20150904-212909.bin'.
Looking for firmware.............: Found (buildwin, 128x128 px).
Looking for Openwin..............: Found.
Looking for LcdIniTbl............: Found.
Looking for backlight & contrast.: Found, Found.
Looking for known signatures.....: Found.
Your dpf is compatible with model ['dx27893'].
看来windows下的确不如linux下的识别率高,难怪superelchi大侠之前推荐在linux环境下运行工具,如果后续大家出现windows下无法识别DPF的问题不要灰心,可以努力尝试一下linux下是否OK!在这里还是要再次感谢一下superelchi大侠,这么多年来一直在做dpf-ax的支持,这个德国人真棒!
接着从http://sourceforge.net/projects/dpf-ax/files/下载包含各种破解固件的dpf-ax_firmware_20140926.zip文件,根据dpf-ax工具包中README.windows的提示,从http://openschemes.com/2011/08/24/ax206-hardware-bootloader-well-that-was-easy/下载刷机工具AX206_HW_Bootflasher.zip,刷机中果然遇到README.windows中描述的“Can't find flash info, please add its info to flash library according to the flash ID”问题,按照提示,继续去superelchi大侠的帖子找到最新的FlashLib.ini文件,替换后顺利刷新固件。
顺便说下,刷固件过程比较简单,windows中执行AX206_HW_Bootflasher.zip中ProgSPI.exe程序,Setting中有说选Update,有说选Program,好像哪个都可以,我选了Update,同时Reset选上,固件路径选上dpf-ax_firmware_20140926.zip中的兼容固件(我的是fw_dx27893.bin),然后Execute即可,很快就刷入完成并在DPF中见到两个大眼睛了。
三.安装lcd4linux
DPF破解成功了,开始进入激动人心的数据展示阶段,可却一开始就遇到困难,olderzeus大侠的网盘已经失效,他编译的lcd4linux找不到了,翻遍隔壁网论坛都找不到下载地址了,据olderzeus大侠说lcd4linux的编译是个浩大工程,而且还没有提供编译的教程,正好那几天https://lcd4linux.bulix.org/又宕机,索性放弃自行编译的念头,只能上网去搜索,找到一个lcd4linux.x86.r1197.rar,里面的lcd4linux可以识别DPF设备,也许就是olderzeus大侠编译的文件吧,但是没有看到olderzeus大侠说的安装脚本,只能自己直接在linux下调用了。(写此文时找到一个百度网盘比较完整,见附录)
前面说了我的DSM无法支持USB设备,在Ubuntu下测试成功lcd4linux后,果断的将DSM从5.1升级到5.2-5592.2(如何在虚拟机中先测试升级就不说了,毕竟NAS中数据宝贵),顺利解决了USB设备的驱动问题,我的DPF终于可以正常连接到NAS上了。
执行过程中遇到的问题基本上在mrqian7188大侠的http://www.gebi1.com/forum.php?mod=viewthread&tid=83997中已经解决,主要注意两个问题:
[*]libgd.so.2通过lib/libgd.so.3或libgd.so.3.0.0复制一份即可
[*]CONF配置文件需要修改权限为600
我将lcd4linux及其配置文件都放在/volume1/homes/xxx/lcd4linux下,也就是DSM登录后的home共享文件夹下,主要是为了方便在windows中通过文件共享来编辑配置文件及更新lcd4linux程序,后面CONF中的配置及任务计划中的路径请记得修改为自己的个人配置。
四、编写CONF配置文件
终于可以将数据输出到DPF了,在参考了olderzeus大侠、xjcsuper大侠、amthb大侠的界面后,决定以amthb大侠的http://www.gebi1.com/forum.php?mod=viewthread&tid=239237&highlight=LCD界面为基础加以优化改造重写CONF,一来是128*128界面比较小,空间有限,amthb大侠的界面比较紧凑,二来毕竟是作为NAS的监视器,天气及时间等大图片没有必要,这些信息现在任何手机中都唾手可得,没必要占用这么宝贵的屏幕资源。
首先通xjcsuper大侠的http://www.gebi1.com/thread-84267-1-1.html学习了CONF文件的基本语法,然后自己拉下了lcd4linux的源代码来查看各种支持的plugin,无奈olderzeus大侠编译的版本好像比较老,icon类型的widget竟然不支持,hddtemp插件也不支持,大大约束了CONF的表现能力,甚是遗憾!(9-12注:昨晚在lcd4linux官网发现icon的代码2003年就有了,测试olderzeus编译的版本可以支持icon类型的widget,可能是当时我测试时用的代码不正确,用官网的demo代码测试无问题,特补充说明!)
其次整体的思路是:
[*]NAS最为核心的是存储设备,因此磁盘的读写是重点,我放在最中间的区域;
[*]由于展示信息的较少,CPU状态、网络状态放左侧(左侧宽度较小);
[*]相对的展示信息较为丰富的存储空间状态、内存状态放右侧;
[*]所有数据单位能精简的都精简,例如GB就只写G,部分KB甚至忽略掉;
[*]所有数据能换算减少宽度的就换算,例如>1024GB就转换为TB,>1024KB就转换为MB;
[*]头部时间到秒精度没有必要,改造为到分钟即可;
[*]CONF中所有颜色都统一改为变量,方便大家自行配置;
[*]屏幕亮度精简olderzeus大侠的文件,只保留一个值,通过DSM的任务计划手工或自动调整。
本来温度是NAS的重要数据,但是我的U-NAS主板不支持i2c传感器,这个版本的lcd4linux又不支持hddtemp,只能放弃温度的显示,有需要的朋友可以自行修改增加温度信息,下面详细讲下改造的情况。
1.Disk区
我的U-NAS是四盘位机型,四块硬盘中第一和第二块硬盘做了raid1,因此DPF中需要显示出disk1/2的读写情况,以及disk3、disk4的读写情况,我对amthb大侠这块的界面改动最大,将两盘符改为三盘符显示,整个Disk分区及读写类型形成纵横交叉的表格状态,任何磁盘读都会在行首显示“<-”标志,任何磁盘写都会在行首显示“->”标志,任何磁盘读或写都会变更列头的颜色。本来准备在widget的前景色或背景色中通过表达式来动态修改颜色,测试过程中发现widget每次update时都无法更新前景色、背景色、小数位,后来只能引入图片来作为背景色进行处理。
另外raid设备不用sda、sdb这种配置,根据yuko4632大侠的提示,直接查看/tmp/space/space_mapping.xml就知道了,我的是分别是md2为disk1和disk2的raid1,md3是disk3,md4是disk4,即便disk3和disk4没做raid,一样可以读取数据,所以我统一改为md2、md3、md4,并在代码中将diskpath及diskname都设为变量,方便朋友们自行根据自己的设备进行修改。
2.CPU区
基本上直接引用官方的配置,原本Load希望改为>1.0时显红字,如前所述update无法更新前景色,只能作罢。还有如前所述根据个人情况删除了温度数据。
3.Volume区
根据olderzeus大侠的代码,新增一个三相状态变量的timer,将Volume1、2、3的使用及空闲情况轮询显示,百分比为已使用空间占比,数值为剩余空间大小。
4.Network区
amthb大侠的一图双条看着很不清晰,分拆为upload和download为两个独立的进度条,因为现在一般都是百兆网络,因此最大值改为100Mbps,如果有需要可以自行修改最大值,代码中100/8的意思是将网络的计算方法转换为计算机的计算方法,基本上100Mbps的百兆网络等于12.5MB/s的每秒传输12.5兆数据。
5.Memory区
内存区是一开始最困扰我的问题,我准备上DPF也是因为拜读了xjcsuper大侠的http://www.gebi1.com/thread-84333-1-1.html,linux的内存分为used、cached、buffers、free等几种,进度条只能显示二值,所以有的大侠的配置显示的是used、cached+free,有的显示的是used+cached、free(buffers因为比较小一般都忽略不计了),那么有没有办法能将进度条显示出二值以上的多值呢?就像DSM的系统监控中一样显示,这样会更加清晰的了解当前内存的使用状况。
于是我想到了两个进度条叠加的方法,上面的进度条显示为used、cached+free,背景改为透明,下面的进度条显示为used+cached、free,背景正常,但是试了老半天都没法实现,总是上面的透明背景直接显示为黑色覆盖了下面的进度条,动态计算上面的进度条宽度来避免覆盖也失败了,正在准备放弃的时候,想起是不是可以用layer把两个进度条分层分开了,一试果然成功,上面的进度条背景变为透明,显示出了下面进度条的内容,于是成功实现一图三值。
顺便说一句,Layout中支持3层Layer,默认的是Layer 1,Layer 0位于Layer 1的上面,Layer 2位于Layer 1的下面,除了内存状态我使用了分层实现三值之外,Disk区的列头背景色也是通过分层来综合Text和Image两种widget。
好了,CONF文件的编写就讲这么多,再重复一遍,详细的语法看xjcsuper大侠的http://www.gebi1.com/thread-84267-1-1.html,已经足够详细,我就不累述了,我的CONF内容附于本文最后。
五、NAS中完善DPF的控制
最后来说下NAS中如何完善DPF的控制,首先是这么好的东东,必须要开机自动启动lcd4linux啊,我直接使用了yuko4632大侠http://www.gebi1.com/forum.php?mod=viewthread&tid=84004&highlight=lcd4linux中的脚本实现开关机的处理。但是日常可能要根据时间动态修改DPF的背光强度,更新CONF文件时也需要重启lcd4linux,每次登录SSH挺麻烦的,我们可以通过DSM的任务计划来实现这些控制,我增加了三个控制DPF状态的自定义脚本,五个控制背光强度的自定义脚本,其中三个背光脚本是自动执行的,分别为:
[*]每天0点关闭背光,脚本:echo 0 > /volume1/homes/xxx/lcd4linux/light.conf
[*]每天7点开白天背光,脚本:echo 5 > /volume1/homes/xxx/lcd4linux/light.conf
[*]每天19点开夜晚背光,脚本:echo 3 > /volume1/homes/xxx/lcd4linux/light.conf
其中xxx是本机的用户名,CONF中定义了每5秒会去读light.conf取背光控制,另外两个背光脚本就是手动控制最亮写入7,最暗写入1即可。
启动、关闭的脚本参考yuko4632大侠的开关机脚本即可,重启的脚本为:killall lcd4linux
sleep 1s
chown root:root /volume1/homes/xxx/lcd4linux/lcd4linux
chown root:root /volume1/homes/xxx/lcd4linux/128.conf
chmod 777 /volume1/homes/xxx/lcd4linux/lcd4linux
chmod 600 /volume1/homes/xxx/lcd4linux/128.conf
/volume1/homes/xxx/lcd4linux/lcd4linux -f /volume1/homes/xxx/lcd4linux/128.conf执行前重新修改own和mod的原因是因为windows中通过共享修改的文件会变更该文件的own和mod,如果有误可能启动不会成功。
希望以上的内容能够帮到你成功实现DPF监视器,下一步我有空的话将把DPF装到U-NAS机器上,另找个时间研究下lcd4linux是否能编译一个新版本,以便支持更多的特性。
附录花絮:刚刚写本帖子时突然在一个百度空间中找到了olderzeus大侠的那个文件包,包括lcd4linux、简易安装说明、conf文件、主题资源等,还包括DPF工具包共享出来免得后人再去到处寻找:http://pan.baidu.com/s/1o60q99S#render-type=list-view&path=%252F,盘主arthasqian不知道是不是隔壁网的朋友,在此一并谢过!
为免该网盘资源再度丢失,我做了个备份,并与前述相关工具及我个人配置的CONF和资源文件一并分享在百度网盘中:
**** Hidden Message *****
帖子字数限制,CONF文件的内容分享在二楼
本帖最后由 waylon 于 2015-9-10 00:38 编辑
完整配置的CONF文件内容:# Create by waylon (waylon.bbs@gmail.com)
# Create date: 2015/9/9
Display dpf {
Driver 'DPF'
Port 'usb0'
Font '6x8'
Foreground FG_Default
Background BG_Default
Basecolor BG_Default
Orientation 0 # 0 = standard, 1 = rotate 90° CW, 2 = rotate 180°, 3 = rotate 90° CCW
Backlight 3 # Backlight variable control, 0..7 (0=off, 7=max)
}
# Head
Widget Machine {
class 'Text'
expression uname('nodename')
width 8
align 'L'
update minute
Background BG_Head
Foreground FG_Head
}
Widget Date {
class 'Text'
expression flagOnOff?(strftime('%m-%d %H:%M',time())):(uptime('Run %dd %H:%M'))
width 13
align 'R'
update tick
Background BG_Head
Foreground FG_Head
}
# CPU status
Widget CPU {
class 'Text'
expression proc_stat::cpu('busy', 500)
prefix 'CPU '
postfix '%'
width 9
precision 1
align 'R'
update tick
}
Widget CPUBar {
class 'Bar'
expression proc_stat::cpu('busy', 500)
length 9
max 100
direction 'E'#E,W,N,S
style 'H'
update tick
Foreground FG_BarFrame
Background BG_BarGreen
BarColor0 BC_Red
BarColor1 BC_Red
}
Widget Load {
class 'Text'
expression loadavg(1)
prefix 'Load'
postfix loadavg(1)>1.0?'!':' '
width 9
precision 1
align 'R'
update second
Foreground FG_Blue
}
# Volume Status
Widget Vol {
class 'Text'
expression (statfs('/volume'.flagState, 'blocks') - statfs('/volume'.flagState, 'bavail')) / statfs('/volume'.flagState, 'blocks')* 100
prefix 'Vol'.flagState
postfix '%'
precision 1
width 11
align 'R'
update tick
}
Widget VolBar {
class 'Bar'
expression (statfs('/volume'.flagState, 'blocks') - statfs('/volume'.flagState, 'bavail')) / statfs('/volume'.flagState, 'blocks')
#expression2statfs('/volume1', 'bavail') / statfs('/volume1', 'blocks')
max 1
length 11
direction 'E'
style 'H'
update tick
Foreground FG_BarFrame
Background BG_BarGreen
BarColor0 BG_BarRed
BarColor1 BG_BarRed
}
Widget VolU {
class 'Text'
expression (statfs('/volume'.flagState, 'blocks') - statfs('/volume'.flagState, 'bavail')) * statfs('/volume'.flagState, 'bsize') / 1024 / 1024 / 1024
precision 1
prefix 'U'
postfix 'GB'
width 11
align 'R'
update tick
Foreground FG_Red
}
Widget VolF {
class 'Text'
expression statfs('/volume'.flagState, 'bavail') * statfs('/volume'.flagState, 'bsize') / 1024 / 1024 / 1024 / ((statfs('/volume'.flagState, 'bavail') * statfs('/volume'.flagState, 'bsize')> 1024*1024*1024*1024)?1024:1)
precision 1
prefix 'Free'
postfix (statfs('/volume'.flagState, 'bavail') * statfs('/volume'.flagState, 'bsize')> 1024*1024*1024*1024)?'T':'G'
width 11
align 'R'
update tick
Foreground BG_BarGreen
}
# Disk status
Widget Disk {
class 'Text'
expression'Disk'
width 5
align 'L'
update minute
}
Widget Disk1 {
class 'Text'
expression diskname1
width 5
align 'C'
update tick
Background BG_Transparency
}
Widget Disk1BG {
class 'Image'
file imgpath . 'diskhead' . (diskstats(diskpath1, 'read_sectors',500)|diskstats(diskpath1, 'write_sectors',500)?'1':'0') . '.png'
reload 1
update tick
inverted 0
visible 1
}
Widget Disk2 {
class 'Text'
expressiondiskname2
width 5
align 'C'
update tick
Background BG_Transparency
}
Widget Disk2BG {
class 'Image'
file imgpath . 'diskhead' . (diskstats(diskpath2, 'read_sectors',500)|diskstats(diskpath2, 'write_sectors',500)?'1':'0') . '.png'
reload 1
update tick
inverted 0
visible 1
}
Widget Disk3 {
class 'Text'
expressiondiskname3
width 5
align 'C'
update tick
Background BG_Transparency
}
Widget Disk3BG {
class 'Image'
file imgpath . 'diskhead' . (diskstats(diskpath3, 'read_sectors',500)|diskstats(diskpath3, 'write_sectors',500)?'1':'0') . '.png'
reload 1
update tick
inverted 0
visible 1
}
Widget Disk1BarR {
class 'Bar'
expression diskstats(diskpath1, 'read_sectors',500)
max 8
length 1
direction 'N'
style 'H'
update tick
Foreground FG_DiskFrame
Background BG_Disk
BarColor0 BC_Yellow
BarColor1 BC_Yellow
}
Widget Disk1BarW {
class 'Bar'
expression diskstats(diskpath1, 'write_sectors', 500)
max 8
length 1
direction 'N'
style 'H'
update tick
Foreground FG_DiskFrame
Background BG_Disk
BarColor0 BC_Red
BarColor1 BC_Red
}
Widget Disk2BarR {
class 'Bar'
expression diskstats(diskpath2, 'read_sectors',500)
max 8
length 1
direction 'N'
style 'H'
update tick
Foreground FG_DiskFrame
Background BG_Disk
BarColor0 BC_Yellow
BarColor1 BC_Yellow
}
Widget Disk2BarW {
class 'Bar'
expression diskstats(diskpath2, 'write_sectors', 500)
max 8
length 1
direction 'N'
style 'H'
update tick
Foreground FG_DiskFrame
Background BG_Disk
BarColor0 BC_Red
BarColor1 BC_Red
}
Widget Disk3BarR {
class 'Bar'
expression diskstats(diskpath3, 'read_sectors',500)
max 8
length 1
direction 'N'
style 'H'
update tick
Foreground FG_DiskFrame
Background BG_Disk
BarColor0 BC_Yellow
BarColor1 BC_Yellow
}
Widget Disk3BarW {
class 'Bar'
expression diskstats(diskpath3, 'write_sectors', 500)
max 8
length 1
direction 'N'
style 'H'
update tick
Foreground FG_DiskFrame
Background BG_Disk
BarColor0 BC_Red
BarColor1 BC_Red
}
Widget DiskR {
class 'Text'
expression 'R ' . (diskstats(diskpath1, 'read_sectors',500)|diskstats(diskpath2, 'read_sectors',500)|diskstats(diskpath3, 'read_sectors',500)?'\177':'')
width 4
align 'L'
update tick
Foreground FG_Yellow
}
Widget DiskW {
class 'Text'
expression 'W ' . (diskstats(diskpath1, 'write_sectors',500)|diskstats(diskpath2, 'write_sectors',500)|diskstats(diskpath3, 'write_sectors',500)?'\176':'')
width 4
align 'L'
update tick
Foreground FG_Red
}
Widget Disk1R {
class 'Text'
expression diskstats(diskpath1, 'read_sectors', 500)/2/(diskstats(diskpath1, 'read_sectors', 500)/2>1024?1024:1)
postfix diskstats(diskpath1, 'read_sectors', 500)/2>1024?'M':''
precision0
width 4
align 'R'
update tick
Foreground FG_Disk
Background BG_Disk
}
Widget Disk1W {
class 'Text'
expression diskstats(diskpath1, 'write_sectors', 500)/2/(diskstats(diskpath1, 'write_sectors', 500)/2>1024?1024:1)
postfix diskstats(diskpath1, 'write_sectors', 500)/2>1024?'M':''
precision0
width 4
align 'R'
update tick
Foreground FG_Disk
Background BG_Disk
}
Widget Disk2R {
class 'Text'
expression diskstats(diskpath2, 'read_sectors', 500)/2/(diskstats(diskpath2, 'read_sectors', 500)/2>1024?1024:1)
postfix diskstats(diskpath2, 'read_sectors', 500)/2>1024?'M':''
precision0
width 4
align 'R'
update tick
Foreground FG_Disk
Background BG_Disk
}
Widget Disk2W {
class 'Text'
expression diskstats(diskpath2, 'write_sectors', 500)/2/(diskstats(diskpath2, 'write_sectors', 500)/2>1024?1024:1)
postfix diskstats(diskpath2, 'write_sectors', 500)/2>1024?'M':''
precision0
width 4
align 'R'
update tick
Foreground FG_Disk
Background BG_Disk
}
Widget Disk3R {
class 'Text'
expression diskstats(diskpath3, 'read_sectors', 500)/2/(diskstats(diskpath3, 'read_sectors', 500)/2>1024?1024:1)
postfix diskstats(diskpath3, 'read_sectors', 500)/2>1024?'M':''
precision0
width 4
align 'R'
update tick
Foreground FG_Disk
Background BG_Disk
}
Widget Disk3W {
class 'Text'
expression diskstats(diskpath3, 'write_sectors', 500)/2/(diskstats(diskpath3, 'write_sectors', 500)/2>1024?1024:1)
postfix diskstats(diskpath3, 'write_sectors', 500)/2>1024?'M':''
precision0
width 4
align 'R'
update tick
Foreground FG_Disk
Background BG_Disk
}
# Network status
Widget Net {
class 'Text'
expression 'Network'
width 9
align 'L'
update minute
}
Widget NetUpBar {
class 'Bar'
expression netdev(netdev, 'Tx_bytes', 500)/1024/1024
max 100/8#100Mbps:12.5MB/s
length 9
direction 'E'
style 'H'
update second
Foreground FG_BarFrame
Background '666666'
BarColor0 BC_Yellow
BarColor1 BC_Yellow
}
Widget NetDwBar {
class 'Bar'
expression netdev(netdev, 'Rx_bytes', 500)/1024/1024
max 100/8#100Mbps:12.5MB/s
length 9
direction 'E'
style 'H'
update second
Foreground FG_BarFrame
Background '666666'
BarColor0 BC_Blue
BarColor1 BC_Blue
}
Widget NetUp {
class 'Text'
expression netdev::fast('eth0', 'Tx_bytes', 500)/1024/(netdev::fast('eth0', 'Tx_bytes', 500)/1024>1024?1024:1)
prefix 'U'
postfix (netdev::fast('eth0', 'Tx_bytes', 500)/1024>1024?'M':'K').'B/s'
width 9
precision 0
align 'R'
update second
Foreground FG_Yellow
}
Widget NetDw {
class 'Text'
expression netdev::fast('eth0', 'Rx_bytes', 500)/1024/(netdev::fast('eth0', 'Rx_bytes', 500)/1024>1024?1024:1)
prefix 'D'
postfix (netdev::fast('eth0', 'Rx_bytes', 500)/1024>1024?'M':'K').'B/s'
precision 0
width 9
align 'R'
update second
Foreground FG_Blue
}
# Memory status
Widget RAM {
class 'Text'
expression 'Memory'
width 11
align 'L'
update minute
}
Widget RAMBar {
class 'Bar'
expression(meminfo('MemTotal') - meminfo('MemFree'))/meminfo('MemTotal')
min 0
max 1
length 11
direction 'E'
style 'H'
update second
Foreground FG_BarFrame
Background BG_BarGreen
BarColor0 BC_Yellow
BarColor1 BC_Yellow
}
Widget RAMBarU {
class 'Bar'
expression(meminfo('MemTotal') - meminfo('MemFree') - meminfo('Cached'))/meminfo('MemTotal')
min 0
max 1
length 11
direction 'E'
style 'H'
update second
Foreground FG_BarFrame
Background BG_Transparency
BarColor0 BC_Red
BarColor1 BC_Red
}
Widget RAMFp {
class 'Text'
expression meminfo('MemFree')/meminfo('MemTotal') * 100
postfix '%'
precision 0
width 3
align 'R'
update second
Foreground FG_Green
}
Widget RAMUp {
class 'Text'
expression (meminfo('MemTotal') - meminfo('MemFree') - meminfo('Cached'))/meminfo('MemTotal') * 100
postfix '%'
precision 0
width 3
align 'R'
update second
Foreground FG_Red
}
Widget RAMCp {
class 'Text'
expression meminfo('Cached')/meminfo('MemTotal') * 100
postfix '%'
precision 0
width 3
align 'R'
update second
Foreground FG_Yellow
}
Widget RAMF {
class 'Text'
expression meminfo('MemFree')/1024/(meminfo('MemFree')/1024>1024?1024:1)
prefix 'F'
postfix meminfo('MemFree')/1024>1024?'G':'M'
precision meminfo('MemFree')/1024>1024?2:0
width 7
align 'R'
update second
Foreground FG_Green
}
Widget RAMU {
class 'Text'
expression (meminfo('MemTotal') - meminfo('MemFree') - meminfo('Cached'))/1024/((meminfo('MemTotal') - meminfo('MemFree') - meminfo('Cached'))/1024>1024?1024:1)
prefix 'U'
postfix (meminfo('MemTotal') - meminfo('MemFree') - meminfo('Cached'))/1024>1024?'G':'M'
precision (meminfo('MemTotal') - meminfo('MemFree') - meminfo('Cached'))/1024>1024?2:0
width 7
align 'R'
update second
Foreground FG_Red
}
Widget RAMC {
class 'Text'
expression meminfo('Cached')/1024/(meminfo('Cached')/1024>1024?1024:1)
prefix 'C'
postfix meminfo('Cached')/1024>1024?'G':'M'
precision meminfo('Cached')/1024>1024?2:0
width 7
align 'R'
update second
Foreground FG_Yellow
}
Widget Foot {
class 'Text'
expression '-= waylon.wang =-'
align 'C'
width 21
update minute
Foreground FG_BarFrame
}
# Timer
Widget FlagOnOffTimer {
class 'Timer'
expression flagOnOff=(time() % 10 < 5)?0:1
active 1
update tick
}
Widget FlagStateTimer {
class 'Timer'
expression flagState=(time() % 15 < 5)?1:((time() % 15 > 9)?3:2)
active 1
update tick
}
Widget LcdLightTimer{
class 'Timer'
expression LCD::backlight(file::readline(cfgpath . 'light.conf', 1))
active 1
update second * 5
}
Display 'DPF'
Layout layout_128x128 {
# Title
Row01.Col01 'Machine'
Row01.Col09 'Date'
# CPU & Volume
Row03.Col01 'CPU'
Row03.Col11 'Vol'
Row04.Col01 'CPUBar'
Row04.Col11 'VolBar'
Row05.Col01 'Load'
Row05.Col11 'VolF'
# Disks
Row07.Col01 'Disk'
Row08.Col01 'DiskR'
Row08.Col05 'Disk1BarR'
Row08.Col06 'Disk1R'
Row08.Col11 'Disk2BarR'
Row08.Col12 'Disk2R'
Row08.Col17 'Disk3BarR'
Row08.Col18 'Disk3R'
Row09.Col01 'DiskW'
Row09.Col05 'Disk1BarW'
Row09.Col06 'Disk1W'
Row09.Col11 'Disk2BarW'
Row09.Col12 'Disk2W'
Row09.Col17 'Disk3BarW'
Row09.Col18 'Disk3W'
# Network & Memory
Row11.Col01 'Net'
Row11.Col11 'RAM'
Row12.Col01 'NetUpBar'
Row12.Col11 'RAMBar'
Row13.Col01 'NetUp'
Row13.Col11 'RAMU'
Row13.Col19 'RAMUp'
Row14.Col01 'NetDwBar'
Row14.Col11 'RAMC'
Row14.Col19 'RAMCp'
Row15.Col01 'NetDw'
Row15.Col11 'RAMF'
Row15.Col19 'RAMFp'
# Foot
Row16.Col01 'Foot'
# Layer
Layer 1{
X49.Y25 'Disk1BG'
X49.Y61 'Disk2BG'
X49.Y97 'Disk3BG'
}
Layer 0 {
Row07.Col05 'Disk1' #Overlap Disk1BG
Row07.Col11 'Disk2' #Overlap Disk2BG
Row07.Col17 'Disk3' #Overlap Disk3BG
Row12.Col11 'RAMBarU'#Overlap RAMBar
}
# Timer
Timer1 'FlagOnOffTimer'
Timer2 'FlagStateTimer'
Timer3 'LcdLightTimer'
}
Layout 'layout_128x128'
Variables {
# Time variables
tick 500
second 1000
minute 60000
# Disk variables
diskname1 '1/2'
diskname2 '3'
diskname3 '4'
diskpath1 'md2'
diskpath2 'md3'
diskpath3 'md4'
# File path
cfgpath '/volume1/homes/waylon/lcd4linux/'
imgpath '/volume1/homes/waylon/lcd4linux/'
# Background color
BG_Default '000000'
BG_Head '336699'
BG_Disk '333333'
BG_BarRed 'FF0000'
BG_BarGreen '00FF00'
BG_Transparency '00000000'
# Foreground color
FG_Default 'FFFFFF'
FG_Head 'FFFFFF'
FG_Disk 'CCCCCC'
FG_BarFrame '6F6F6F'
FG_DiskFrame '666666'
FG_Red 'FF0000'
FG_Blue '99CCFF'
FG_Green '00FF00'
FG_Yellow 'FFCC33'
# Bar color
BC_Red 'FF0000'
BC_Blue '99CCFF'
BC_Yellow 'FFCC33'
}
不错的文章,值得收藏。 原创好文,支持! 很详细的教程,感谢分享。 本帖最后由 ianpeng 于 2015-9-10 10:30 编辑
很詳細的教程,
感謝樓主分享!!
PS. 大大方便提供DPF淘寶的link嗎?
ianpeng 发表于 2015-9-10 10:25
很詳細的教程,
感謝樓主分享!!
PS. 大大方便提供DPF淘寶的link嗎?
我买的这款是https://item.taobao.com/item.htm?spm=a1z09.2.0.0.cGD5Ak&id=18752046714&_u=agcfhtc677,不过要注意,不知道是设备本身的问题还是我的安装有问题,在windows下的AIDA64还是认不到这个芯片,没法在windows下直接通过AIDA64来输出屏幕,只能在linux下用了 果然很强大,谢谢分享 好东西啊,谢谢楼主分享 看下,学习来。{:7_186:} 很好的技术贴,谢谢分享! 必须支持下啊 牛逼的人!!!!!!!!!!!!!!!!!!!!! 谢谢楼主分享好教材 这个帖子是干活啊,还没看到dpf的购买地址,建议贴出来,这样大家就可以直接照抄了 v-far 发表于 2015-9-10 22:48
这个帖子是干活啊,还没看到dpf的购买地址,建议贴出来,这样大家就可以直接照抄了 ...
7楼已经贴出地址,不过我个人不是特别推荐这款DPF,因为AIDA64不支持 感谢分享。 很详细,感谢分享 学习乐试试 帖子字数限制