当年曾入手Chrome第一代,折腾过后,还是放弃了。原因有两个:一要联网才能用,二要能访问Google。相关的资料整理如下:
刷机
刷机,为了获取root权限,也为了获取更多的可能性(最后的结论是,然并卵…)。相关的教程都在:
记得当时还入手了Arduino Nano(好像吧),用于破解。
开发
只是好奇查了相关的开发资料,但一直没深入。
然后,就酱……
当年曾入手Chrome第一代,折腾过后,还是放弃了。原因有两个:一要联网才能用,二要能访问Google。相关的资料整理如下:
刷机,为了获取root权限,也为了获取更多的可能性(最后的结论是,然并卵…)。相关的教程都在:
记得当时还入手了Arduino Nano(好像吧),用于破解。
只是好奇查了相关的开发资料,但一直没深入。
然后,就酱……
搞了几天,终于弄懂了自建Git服务。正如绝大多数的教程所说,基于ssh来部署git服务,是最简单的。
1)服务器和客户端都安装Git。
sudo apt-get update
sudo apt-get install git
2)服务器上建立Git仓库。我比较懒,就用现有的用户,比如用户名为:user。用user登录后,执行命令。git init --bare是用于建立裸仓。执行成功后,会建立project.git文件夹,确保user对该文件夹有读写权限。
mkdir /path/git
cd /path/git
git init --bare project.git
3)客户端clone项目。ssh://是指,基于ssh的git服务。user就是用户名。server_ip就是服务器ip,也可以是域名。22是ssh服务的端口,根据部署的ssh服务而定。/path/git/project.git就是前面建立的项目路径。
git clone ssh://user@server_ip:22/path/git/project.git
然后就可以愉快地各种Git操作了。
至于后面增加安全性,可以新增一个git用户,设置其不能登录shell,并采用证书登录等等,可以参考网上的教程。例如: 廖雪峰的官方网站:搭建Git服务器
手上有个远古时代的上网本,华硕(ASUS) EeePC 900。删掉原来的Windows XP,装上Lubuntu 16.10。原电池废了,淘宝换了个新的,续航能达到5小时(大概吧)。但是一般用来远程ssh到raspberry pi,没必要开启图形界面(特别是发现用screen可以同一界面打开多个shell)。需要解决的问题是中文的显示和输入。Google过后,最终的解决方案是fbterm(完美显示中文) + fcitx-fbterm(实现中文输入)。
fbterm的安装参考这个(英文):https://fcitx-im.org/wiki/Fbterm
中文版本的完整安装教程,参考这个:http://ikuduku.com/blog/fbterm-display-and-input-Chinese-in-tty
关于中文输入法,我选择google拼音(fcitx-googlepinyin)。记录一下相关操作:
1)安装
#安装相关软件
sudo apt-get install fbterm fcitx fcitx-fbterm fcitx-googlepinyin fcitx-configtool
#让fbterm可以设置快捷键,主要是切换输入法
sudo setcap 'cap_sys_tty_config+ep' /usr/bin/fbterm
#把当前用户加入到video组
sudo gpasswd -a <your username> video
2)编辑当前用户的配置
vi ~/.fbtermrc
修改如下:
#设置字体
font-name=Mono
#设置字体大小
font-size=14
#设置输入法
input-method=fcitx-fbterm
3)设置开机启动
#设置开机进入shell界面,这是Ubuntu 16.04及以后版本的设置方法
sudo systemctl set-default multi-user.target
#设置进入图形界面的命令,然后用`sudo startx`命令即可进入图形界面
sudo sh -c "echo \#\!/bin/sh > /usr/local/bin/startx"
sudo sh -c "echo systemctl start lightdm >> /usr/local/bin/startx"
sudo chmod +x /usr/local/bin/startx
#设置进入shell后自动启动fbterm,而图形界面的shell则不会启动fbterm
printf '\nif [ $TERM = 'linux' ]; then\n fcitx-fbterm-helper -l\nfi' >> ~/.bashrc
大概就这样了。使用过程中,还是有一点不习惯。例如快捷键的变换,Ctrl + Alt + F1 ~ F6 不能切换tty,而是切换字符编码,使用 Ctrl + Alt + 1 ~ 0 可以切换10个窗口。
一般一个月一次整理孩子的照片。但是老婆的手机和单反拍出来的照片,文件名都不统一。要统一采用拍照时间做为文件名的话,比较麻烦。本来想用Python3写个脚本处理的,但是官方没有提供获取EXIF信息的方法。找打其它包,也不怎么好用。但是今晚发现原来有个shell命令挺好用的,就是EXIF。
于是就写了个shell脚本,如下:
#!/bin/bash
path=/home/fox/pics
i=$(ls $path/*.JPG)
for j in $i
do
d=$(exif -t "DateTime" $j | grep Value)
d=${d/ Value: /IMG_}
d=${d//:/}
d=${d// /_}
$(mv $j ${d}.jpg)
done
这里采用的统一文件名格式是IMG_yyyyMMdd_HHmmss.jpg。由于采用字符串替换的语法,所以只能用bash运行。
某日发现了提供免费SSL证书的网站——www.sslforfree.com,立马手动申请了个证书来玩。部署以后,非常感动,重点是Chrome和FireFox都支持!曾在某知名网站申请过免费证书,总是申请失败。心灰意冷,本来准备买个廉价的付费版,幸好发现这网站!
免费虽好,但有效期只有3个月,而且到期后只能手动更新证书。不过找到提供该免费证书的网站——Let’s Encrypt(https://letsencrypt.org),以及该网站提供的自动更新证书的开源软件certbot(https://certbot.eff.org)。certbot首页就有安装教程,对应不同HTTP服务和操作系统。安装完毕后,执行以下命令,就可以获取证书了
#验证域名并获取SSL证书
sudo certbot certonly --webroot -w /var/www/example -d example.com -d www.example.com
最后,设置个自动更新,就安枕无忧了。
PS.既然有了免费的证书,何不部署个HTTP 2.0?
简单玩过NodeMCU之后,想获取更多的数据,就是多加几个传感器。但是NodeMCU只有一个ADC接口,于是找到利用Arduino与ESP8266结合的解决方案。Arduino的不同版本的接口数量不同,而手头上的Pro Micro就有4个ADC了,勉强够用。ESP8266就是NodeMCU的核心,相比NodeMCU更少接口,但体积更小,价格更低。于是入手了两个ESP8266来折腾。
First of All,刷固件。
刷固件的官方教程
最新的固件下载
官方入门教程
大概就这些了。话说,计划中的植物环境数据收集平台升级版,都拖好久了……
说起物联网,最早接触的是Arduino。可是入手Arduino Mega后,一直没做出什么好玩的东西,以致Mega丢在角落里好几年。近来在部门经理的怂恿下,入手了NodeMCU,做了个检测盆栽的土壤湿度。本来想在Github开个项目,但是这第一版太简单了,就随便记录一下。
NodeMCU的特点,在于自带WiFi(还可以使用AP模式),而且价格便宜。当然,缺点也在WiFi,比较耗电。为了省电,可以设置网卡的硬件参数(wifi.setphymode()),关闭WiFi(wifi.sleeptype()),甚至是整块板进入深度睡眠模式(node.dsleep(), rtctime.dsleep())。其开源、基于Lua的开发简单、尺寸迷你等优点,也是其好玩之处。
这个项目很简单,就是NodeMCU连个土壤湿度检测模块,定时(10分钟)获取一次数据,并上传到服务器。服务器是采用树梅派,用Python3,利用Flask框架,写了个HTTP服务,用于保存提交的数据,并做数据展示。数据都保存在MySQL数据库。
NodeMCU上的init.lua
print("\n")
print("ESP8266 Started")
dsleepTime = 630000000
ssid = "my-wifi"
password = "123456"
serverIp = "192.168.1.1"
serverPort = 8080
wifi.setphymode(wifi.PHYMODE_N)
wifi.setmode(wifi.STATION)
wifi.sta.config(ssid, password)
tmr.alarm(0,1000,1,function()
curIp = wifi.sta.getip()
if curIp ~= nil then
print("Current IP:"..curIp)
tmr.stop(0)
sendData(readValue(0, 5))
end
end)
--发送数据到服务器
function sendData(value)
print("sendData start")
conn = net.createConnection(net.TCP, false)
conn:on("receive", function(conn, pl)
print("Send data with value: "..value)
print("Result:\n"..pl)
conn:close()
conn = nil
wifi.sta.disconnect()
node.dsleep(dsleepTime)
end)
conn:connect(serverPort, serverIp)
conn:send("GET /gather/?key=123456&value="..value
.." HTTP/1.1\r\nHost: " + serverIp + "\r\n"
.."Connection: keep-alive\r\nAccept: */*\r\n\r\n")
--connect time out
tmr.alarm(1,5000,1,function()
print("[error]connet to server time out")
--conn:close()
--conn = nil
--wifi.sta.disconnect()
tmr.stop(1)
node.dsleep(dsleepTime)
end)
end
--读取土壤湿度数据
--一次有效的采样,最少取3次数据,去掉最大值和最小值,再计算平均值
function readValue(adcPin, readTimes)
if readTimes <= 2 then
readTimes = 3
end
local curValue = 0
local maxValue = 0
local minValue = 0
local sumValue = 0
for i = 0, readTimes - 1 do
curValue = adc.read(adcPin)
sumValue = sumValue + curValue
if maxValue < curValue then
maxValue = curValue
end
if (minValue == 0) or (minValue > curValue) then
minValue = curValue
end
end
sumValue = sumValue - maxValue - minValue
curValue = math.floor(sumValue / (readTimes - 2))
return curValue
end
服务器上的HTTP服务,文件site.ini
[uwsgi]
socket = 127.0.0.1:8080
processes = 2
threads = 1
plugins = python3
master = true
pythonpath = /opt/work/web_gather
chdir = /opt/work/web_gather
module = site
callable = app
chmod-socket = 777
memory-report = true
服务器上的HTTP服务,文件site.py
#!/bin/python3
from datetime import datetime
from flask import Flask, request, abort, render_template
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy import desc
app = Flask(__name__)
app.config['SECRET_KEY'] = '123456'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@127.0.0.1/web_gather'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['HUMIDITY_MIN'] = 740
db = SQLAlchemy(app)
class Humidity(db.Model):
__tablename__ = 'humidity'
id = db.Column('id', db.Integer, primary_key=True)
createDate = db.Column('create_date', db.DateTime)
sourceValue = db.Column('source_value', db.Integer)
value = db.Column('value', db.Integer)
def __repr__(self):
return '<Humidity % r>' % self.id
@app.route('/', methods=['GET', 'POST'])
def index():
key = request.args.get('key', '')
if key == app.config['SECRET_KEY']:
sourceValue = request.args.get('value', '0')
value = (1024 - int(sourceValue)) / 1024 * 100
curTime = datetime.today()
humidity = Humidity(createDate=curTime, sourceValue=sourceValue, value=value)
db.session.add(humidity)
db.session.commit()
return 'true'
humidities = Humidity.query.order_by(desc(Humidity.createDate)).limit(500)
return render_template('humidity.html', humidities=humidities)
if __name__ == '__main__':
app.run(debug=False, host='127.0.0.1', port=8080)
#app.debug = False
#app.run()
MySQL的表定义
CREATE TABLE `humidity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`create_date` datetime DEFAULT NULL,
`source_value` int(11) DEFAULT NULL,
`value` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2554 DEFAULT CHARSET=utf8
上星期终于搞掂了办公室的CentOS备份。一开始,我们把硬盘A完全复制到硬盘B(用dd命令拷贝整个硬盘),产生了很多误会,也搞出不少问题,差点以为把硬盘A的数据搞丢了。
后来才发现,CentOS挂载硬盘分区时,根据分区的UUID来挂载的。由于两个硬盘的数据完全一致(包括各分区的UUID也一致),所以即使以硬盘A启动电脑,也可能挂载了硬盘B的分区。最后将错就错,按如下步骤解决问题:
参考文章:linux下硬盘uuid查看及修改设置
Ext4的分区可以按照该文章,修改分区UUID:
uuidgen | xargs tune2fs /dev/sdb1 -U
但是swap分区不行,只能格式化一下,让其重新生成UUID:
#操作之前,先取消挂载
swapoff /dev/sdb2
#格式化swap分区
mkswap /dev/sdb2
修改后,可以下命令查看各分区的UUID:
blkid /dev/sdb1
此步骤是为了让硬盘B也能直接启动。就是说硬盘A出了什么故障,直接用硬盘B就可以启动服务器了。
a)修改分区挂载文件/etc/fstab,把对应分区的UUID改为新的。
b)修改grub配置文件/boot/grub/grub.conf,把根目录的分区UUID改为最新的。
这里采用rsync命令,把硬盘A的数据自动同步到硬盘B上。
a)把硬盘B的根目录挂载到/media/sdb3
b)创建文件/media/rsync_exclude文件,把要排除的文件夹或文件录进去,一行一个,参考内容如下:
/boot/*
/dev/*
/media/*
/lost+found
/proc/*
/sys/*
/tmp/*
/etc/fstab
c)执行以下命令,立即同步文件(以root用户执行):
rsync -avzP --delete --exclude-form=/media/rsync_exclude / /media/sdb3 >> /media/rsync.log
参考:
后面考虑把硬盘B做成USB移动硬盘,这样可以在需要时才接上电源。再考虑接上硬盘B后自动执行同步命令。
终于还是入手了Kindle3,200RMB的二手货,成色很新。由于带键盘,也有比较成熟的软件,所以非常喜欢。记录一下入手后的折腾经历吧。
1)升级最新固件(fireware)
从官网下载最新固件(目前最新是3.4.2):
升级固件时,按照所需版本,一个一个地升。升级到最新版,最大的作用是可以注册美国亚马逊账号。其它的功能,包括阅读PDF(自动切除白边)、漫画等,都很方便。
2)越狱(Jailbreak)
详细操作,上面会详细记录。简单来说,就是下载对应的版本,然后刷进系统。本链接还包括修改默认屏保(ScreenSavers)、修改字体(Fronts)、USB有线网(USBNetwork)、Python等等。
3)快捷键(launchpad)
一个热键管理程序,可以把shell脚本,包括启动程序的脚本,做成热键,非常好用!
4)命令窗口(Terminal)
用launchpad启动,即可进入shell终端,然后就可用编写shell脚本、修改系统文件、ssh远程到其它机器等等。总之就是非常强大。
5)音乐播放器(MPlayer)
一边播放音乐,一边看书,也是不错的。特别要说的是,Kindle3自带的喇叭,音质比预想的好很多。
6)字典(Dictionary)
下载其它字典,并且可以替换系统默认的字典。
7)中文输入法
8)其它
这里都有汇总了几乎所有的软件,包括上面提到的。
曾经在“闲鱼”(淘宝二手)上看到有人卖NodeMCU的开发板,查了发现这东西很便宜(30RMB以下可以买到),而且自带WiFi,非常适合打开“物联网”的大门。直到前几天,跟经理说起关于怎样控制窗户的开关,才又提起这个,并买了个来玩。

官方网站(http://www.nodemcu.com/)上没有找到官方的入门教程,但是找这一些比较好的:
1)一个比较全面的教程(针对Windows) http://nodemcu-dev.doit.am/ 2)NodeMCU 物联网开发快速上手(适合Linux用户) http://tinylab.org/nodemcu-kickstart/
官方论坛([http://bbs.nodemcu.com/][8])上也有一个系列的入门教程:
关于NodeMCU上使用的Lua,这里有个不错的教程 https://moonbingbing.gitbooks.io/openresty-best-practices/content/lua/main.html