dietpi镜像有时无法使用pishrink脚本缩小的原因

记录以备查

一般使用Win32DiskImager在windows系统上备份树莓派的镜像,这种方式备份出来的镜像为sd卡容量的大小,若在16g卡上安装了一个4g不到的系统,备份出来不仅占空间,刷入时也更花时间,最尴尬的是都是16g的卡也有可能出现略微的容量差异,导致容量小一点的就没法刷入。

在看Raspberrypi 3 系统备份还原, 基于最小系统镜像实现一文时,注意到以下这句话,才意识到dietpi镜像使用pishrink脚本缩小报ERROR: Image already shrunk to smallest size的原因。

经搜索,发现dietpi系统应该是只在第一次启动时会扩展分区,这被写成一个service而不是像raspberry系统中可以在raspi-config命令后找到,推测运行一次就被mask(注销unit)了。而在工作过程中,16g的卡,我可能用pishrink脚本将初始的dietpi镜像缩小成了4g的dietpi-shrink.img,再把dietpi-shrink.img写入到新的sd后,扩展分区的服务(dietpi-fs_partition_resize.service)并不会运行了,所以/root分区的大小可能就只有3.7g,若再把这个新sd卡上的镜像备份出来(16g),那就无法使用pishrink缩小了。

DietPi-Drive_Manager | Expand file system button, in case of changed storage
以上链接给出了解决方法,不需要手动扩展,比较方便,只需把扩展分区服务unmask。

1
2
3
systemctl unmask dietpi-fs_partition_resize.service
systemctl enable dietpi-fs_partition_resize.service
reboot

重启后备份这个新sd卡上的镜像出来,就又可以使用pishrink缩小了。

node-red代码版本控制

记录以备查

之前对于node-red代码的备份都是复制~/.node-red/flows_xxx.json文件并保存n个版本,很烦,即使使用Beyond Compare这种对比软件去对比未美化格式的json文件查看更改内容也是一团糟,搜索时发现可以通过更改~/.node-red/settings.js中的设置使flows_xxx.json文件保存时就美化格式。

1
2
sudo nano ~/.node-red/settings.js
# ctrl+w 搜索 flowFilePretty 找到该行并取消注释

复制文件并不是一个好的版本控制解决方案,发现官方在0.18版本开始就有projects一说并支持版本控制,只是在设置里默认不开启。详见projects

  1. 开启projects支持
1
2
sudo nano ~/.node-red/settings.js
# 找到projects: {enabled: false} 改为 enabled: true
  1. 重启node-red
1
2
ls -ll ~/.node-red/
# 会发现多了projects/目录
  1. 重新访问node-red网页服务地址如127.0.0.1:1880
    根据提示创建或者克隆项目

  2. 侧边栏信息

    上图中info页显示当前的项目名


上图中history页中,Local Changes下的Local files显示当前变更的文件,点击文件名可以看到具体节点的变化内容,按+就相当于git add filename的意思;Changes to commit显示已经add还没commit的文件,按commit后会让你输入描述,确定后就是git commit -m “description”。


上图中,Commit History可以看到提交的历史。若设置了远程仓库地址,在这里还能看到本地比远程ahead了几个commit之类的信息,也可以push或者pull操作。

Raspbian Stretch Lite设置wifi及静态IP

记录以备查

  1. 设置要连接的wifi名称和密码
1
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

添加内容

1
2
3
4
network={
ssid="wifi_name"
psk="wifi_password"
}

  1. 设置wifi连接下的静态ip
1
sudo nano /etc/dhcpcd.conf

按照上面的例子添加内容,这里假设所在网段为192.168.8.1

1
2
3
4
interface wlan0
static ip_address=192.168.8.111/24
static routers=192.168.8.1
static domain_name_servers=192.168.8.1 8.8.8.8

如果要设置有线网的静态ip,把interface wlan0改为interface eth0即可。

  1. 以上前提为ssh已连接
    在现在的版本镜像中,将image刷入microsd卡后,新建一个没有后缀的ssh文件开启功能。
1
touch ssh

参考

  1. 树莓派3B命令行配置wifi,远程桌面连接,扩展存储
  2. Raspberry PI 3静态IP配置

Raspbian Stretch Lite安装kivy并运行demo显示在触摸屏上

记录下在Raspbian Stretch Lite安装kivy的过程以备查

准备工作

  1. 从树莓派官网下载Raspbian Stretch Lite镜像
  2. windows通过Win32DiskImager(macos可通过Etcher或者命令行)将.img刷入microsd卡(此处使用的是3b)。Stretch Lite的话,4g的卡即可,但现在一般不会买4g了。。。
  3. 在/boot/目录新建不含后缀的文件ssh,开启ssh功能
1
touch ssh
  1. 上电,ssh连接。

在树莓派上安装kivy

官方安装指南Installation on Raspberry Pi

此处想要安装的是python3版本,将官方教程的pip和python改为pip3和python3

1.

1
sudo apt-get update

2.

1
2
3
4
5
6
7
8
# 这里如果说没有获取某些包让apt-get update或者--fix-missing那就再后面加上--fix-missing

sudo apt-get install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev \
pkg-config libgl1-mesa-dev libgles2-mesa-dev \
python3-setuptools libgstreamer1.0-dev git-core \
gstreamer1.0-plugins-{bad,base,good,ugly} \
gstreamer1.0-{omx,alsa} python3-dev libmtdev-dev \
xclip xsel python3-pip

3.

1
sudo pip3 install -U Cython==0.28.2

4.

1
sudo pip3 install git+https://github.com/kivy/kivy.git@master

太慢了,就直接浏览器下载了1.10.x的stable版本,再通过WinSCP传到树莓派。

5.

1
cd kivy-stable-1.10

6.

1
make

make这里会报错,后面再一起记录下

7.

1
echo "export PYTHONPATH=$(pwd):\$PYTHONPATH" >> ~/.profile

8.

1
source ~/.profile

  1. 运行demo

遇到的问题

  1. make报错Cython is missing, it’s required for compiling kivy !
    这里通过改变Makefile的PYTHON值解决
1
sudo nano Makefile

把第一行PYTHON=python改为PYTHON=python3,因为之前依赖所安装的都是python3的,Cython也是。
经过很长时间的等待,编译就通过了。
这个时候运行demo

1
python3 kivy-stable-1.10/examples/demo/showcase/main.py

会继续报错

  1. 运行main.py报错ImportError: No module named ‘pygments’
1
sudo pip3 install pygments

不得不提下面这个issue里有个comment简直道出了我的心声
Unable to run kivy on raspberry pi with

aleksandaratanasov commented on 4 May 2016
Shouldn’t this dependency be actually listed as such? I find it rather annoying that following the official guide on installing Kivy on the RPi you have to dig into the issues on GitHub to find a solution for this problem. After all the demos should be the ones that run without any issues WITH the things that are listed as requirements to get Kivy installed on the system. Please consider adding at least a warning if the required packages for the showcase are not met.

  1. 这个时候运行python3 kivy-stable-1.10/examples/demo/showcase/main.py这个demo不会报错了,但是如果不连接显示屏就看不到效果。
  2. 树莓派连接显示屏显示no signal
1
sudo nano /boot/config.txt


1
#hdmi_force_hotplug=1

的注释去掉,变为

1
hdmi_force_hotplug=1

参考HDMI monitors says NO SIGNAL (solved)

  1. 重启后运行demo应该有显示了,但是发现触摸好像没反应。
    参考官方安装指南中Using Official RPi touch display
1
sudo nano ~/.kivy/config.ini

更改[input]模块为

1
2
3
mouse = mouse
mtdev_%(name)s = probesysfs,provider=mtdev
hid_%(name)s = probesysfs,provider=hidinput

到这里就正常显示及操作了。

buildozer打包kivy应用程序为安卓apk时卡在refreshing resources

按照kivy官方教程Create a package for Android

在ubuntu虚拟机下运行到以下命令时卡在Refresh Sources: Fetching https://dl-ssl.google.com/android/repository/addons_list-2.xml

1
buildozer android debug deploy run

VMWare虚拟机通过主机shadowsocks代理上网开启了代理后,即使可以在浏览器访问该链接也还是无法进行下去。

翻了好多帖子后,在How to build Python for Android with Ubuntu and Buildozer的回复下发现有一条写

Moved forward by following below .cfg solution.
http://stackoverflow.com/questions/10634202/android-sdk-manager-proxy-settings-in-linux

按最高赞的回复解决。

1
nano ~/.android/androidtool.cfg

根据个人实际情况按以下格式修改:

1
2
3
4
5
6
7
http.proxyPort=1080  # 宿主机上shadowsocks的代理端口
sdkman.monitor.density=108
http.proxyHost=192.168.2.xxx # 宿主机的ip,这里为192.168.2.xxx
sdkman.show.update.only=true
sdkman.ask.adb.restart=false
sdkman.force.http=true
sdkman.show.updateonly=true

后续又卡在了

1
Downloading hostpython2 from https://python.org/ftp/python/2.7.2/Python-2.7.2.tar.bz2

报错为

IOError: [Errno socket error] [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)

未能找到解决方案,转而使用kivy提供的虚拟机The Kivy Android Virtual Machine,同样进行了SDK Manager代理设置后,成功打包了apk文件,在四儿子上测试安装可运行。

运行Node-RED官方docker后安装serial节点

在ubuntu上安装docker

Ubuntu 安装 Docker CE

在docker下运行Node-RED

Running under Docker

1
docker run -it -p 1880:1880 --name mynodered nodered/node-red-docker

参数解释

查看镜像

1
docker image ls

查看所有容器

1
docker container ls -a

访问127.0.0.1:1880后,发现没有所需的serial节点,要在容器中自行安装。

在容器中安装serial节点

利用 commit 理解镜像构成

进入该名为mynodered的容器

1
docker exec -it mynodered bash

终端就会从user@ubuntu之类的变成node-red@container_id这种:
安装serial节点

1
2
3
npm i node-red-node-serialport
# ... 等待安装完成
exit

查看具体改动:

1
docker diff mynodered

提交为镜像

暂略

树莓派刷LEDE(OpenWrt)后开机自启frpc

树莓派安装LEDE实现翻墙后,总想搞点事情比如远程下载之类。
因为租房的联通网并没有公网IP也懒得折腾,之前用过ngrok,最近无意中发现frp就用上了。
参考OpenWrt Init Scripts设置未果,一直苦于树莓派上的frpc服务没能开机自启,远程时就不敢瞎折腾。
最终参考deploy-frp-on-openwrt得以解决,似乎是启动顺序问题,在frpc脚本运行到的时候仍有需要的服务未开启。
救命语句

1
sleep 30

PyQt5程序用PyInstaller打包依赖后运行报错could not find or load the Qt platform plugin windows

用PyQt5写了个简单的程序,PyInstaller打包依赖后在两个同事电脑上运行正常,但另一同事使用后发现报错,内容为:

This application failed to start because it could not find or load the Qt platform plugin “windows” in “”.

Reinstalling the application may fix this problem.

谷歌到的相关问题很多,参考Qt 5.1.1: Application failed to start because platform plugin “windows” is missing进行了一系列的尝试,比如:

  1. 在.exe同目录下添加Qt目录下的platforms\qwindows.dll
  2. 在.exe通路录下添加Qt目录下的libEGL.dll
  3. 。。。

均无果。

最后无意中发现U盘直接拷贝过去的可以进行,而区别在于目录名一个为中文(❌)一个为英文(✔)。

对于我这种情况的解决方案:把程序放在纯英文目录下。

在Kivy中自定义MyCheckBox改变显示尺寸

Kivy是一个用于快速开发交互界面应用程序的开源python库,如多点触控应用。
跨平台,支持 Linux, Windows, OS X, Android, iOS, Raspberry Pi。
更多请移步前辈们翻译的Kivy中文编程指南

工作原因,已使用Kivy4个多月,期间遇到了很多问题,大多能通过stackoverflow等平台解决,难解决的也已另辟蹊径或折衷个方法。最终还是决定记录下这些过程。

需求: CheckBox显示的尺寸太小,在10.1寸的显示屏上操作时需要小心翼翼,要将其尺寸改大

参考https://www.reddit.com/r/kivy/comments/424m2o/checkbox_size_scale/, 就知道可以通过自定义一个MyCheckBox来改变其在normal状态(inactive)和down状态(avtive)的背景图片以达到目的。

因Kivy源码checkbox.py中为

1
2
class CheckBox(ToggleButtonBehavior, Widget):
pass

查看文档中ToggleButtonBehavior处,Kivy已给出很直观的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# main.py

from kivy.app import App
from kivy.uix.image import Image
from kivy.uix.behaviors import ToggleButtonBehavior


class MyButton(ToggleButtonBehavior, Image):
def __init__(self, **kwargs):
super(MyButton, self).__init__(**kwargs)
self.source = 'atlas://data/images/defaulttheme/checkbox_off'

def on_state(self, widget, value):
if value == 'down':
self.source = 'atlas://data/images/defaulttheme/checkbox_on'
else:
self.source = 'atlas://data/images/defaulttheme/checkbox_off'


class SampleApp(App):
def build(self):
return MyButton()


SampleApp().run()

对于我个人的需求,只需找两张合适大小的图片对应两个不同的状态就行(未考虑disabled状态),此处我将图片放在项目的main.py同目录下,为对比显示添加了部分代码,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# main.py

from kivy.app import App
from kivy.uix.image import Image
from kivy.uix.behaviors import ToggleButtonBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.checkbox import CheckBox


class MyButton(ToggleButtonBehavior, Image):
def __init__(self, **kwargs):
super(MyButton, self).__init__(**kwargs)
self.source = './mycheckbox_off.png'

def on_state(self, widget, value):
if value == 'down':
self.source = './mycheckbox_on.png'
else:
self.source = './mycheckbox_off.png'


class MyLayout(BoxLayout):
def __init__(self, **kwargs):
super(MyLayout, self).__init__(**kwargs)
kivy_checkbox = CheckBox()
my_checkbox = MyButton()
self.add_widget(kivy_checkbox)
self.add_widget(my_checkbox)


class SampleApp(App):
def build(self):
return MyLayout()


SampleApp().run()

一次跳闸引起的ubuntu命令学习记录

ubuntu命令行学习记录

公司有个ubuntu12.04系统的samba文件服务器。一次意外跳闸后,就无法进入系统了。文件检测卡在checking battery之类,可以ctrl+alt+F1然后登陆。

经多次推测排查,认为是意外断电导致的文件系统丢失等问题。
/usr/lib/x86_64-linux-gnu/目录下的共享动态链接库等都消失了。即使dpkg -i libapt-pkg.deb后也没用。

定位某个库文件

1
locate libapt-pkg.so.5.0
1
sudo fdisk -l;  # 查看硬盘和分区情况

Disk /dev/sda doesn’t contain a valid partition table这种提示是正常的!!如果没分区直接挂载使用当然没有分区表!!

1
sudo df -h; # 查看挂载的设备的大小
1
sudo du -h --max-depth=1 /fileDirectory; # 查看单个目录的大小,最后一项会显示为./大小。
1
2
3
4
sudo mount /dev/sdb /mnt;
ls /mnt; # 为/dev/sdb/下内容
sudo umount /mnt;
ls /mnt; # 为空

用ultralISO制作U盘启动盘

用U盘启动盘try ubuntu,查看其他硬盘状态;
必须先取消挂载

1
sudo umount /media/uuid/;
1
sudo fsck /dev/sdb/;

ubuntu分区问题
/: 4g,系统所在分区,boot可以不单独分区直接放/下
/home: 其他所有
swap区: 2G,一般按物理内存大小分配?

##设置静态ip

1
sudo vim /etc/network/interfaces

关于防火墙配置

一个相对iptables简单很多的防火墙配置工具:ufw,默认不启用。也就是说,ubuntu的端口默认都是开放的。
启动ufw:

1
2
$ sudo ufw default deny
$ sudo ufw enable

打开ssh服务的22端口:

1
$ sudo ufw allow 22

由于在/etc/services中, 22端口对应的服务名是ssh。所以下面的命令是一样的:

1
$ sudo ufw allow ssh

禁用22端口:

1
$ sudo ufw delete allow 22

查看防火墙状态:

1
$ sudo ufw status

关闭防火墙:

1
$ sudu ufw disable

更多用法可以通过以下命令查看

1
$ man ufw

关于开启ssh登陆

新安装的ubuntu系统,默认是不支持ssh登录的。
SSH分客户端openssh-client和openssh-server
如果只是想登陆别的机器的SSH只需要安装openssh-client(ubuntu有默认安装,如果没有则sudoapt-get install openssh-client),如果要使本机开放SSH服务就需要安装openssh-server。
这里根据需求只安装了服务端。

1
2
$ sudo apt-get update
$ sudo apt-get install openssh-server

开启和停止ssh服务端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#启动
$ /etc/init.d/ssh start

#停止
$ /etc/init.d/ssh stop

#重新启动
$ /etc/init.d/ssh restart

#利用service命令
#启动
$ sudo service ssh start

#停止
$ sudo service ssh stop

#重新启动
$ sudo service ssh restart

查看ssh是否在运行:

1
2
#如果没有任何显示,是没有运行ssh服务的。反之,出现sshd字样,表示ssh服务已运行。
$ sudo ps -e |grep ssh

ssh配置文件地址:/etc/ssh/sshd_config

到这里就不得不提一下安全性。。因为我有个鲨鱼的小机只用来搭$$居然也有1000+次尝试登录失败的提醒。
(1)改ssh的默认端口为其他如2333
改之前先将2333端口打开,配置文件中的port从22改为2333,然后service ssh restart重启服务,命令行指定端口号为

1
$ ssh -p 2333 userName@ip

(2)在配置里禁止root登陆,创建密钥对登陆,详见使用密钥认证服务器但是当你需在不同机器上登录时还是会有点麻烦,而且万一丢失了私钥也会比较麻烦。

关于linux系统下的挂载

详见Ubuntu - 硬盘分区、格式化、自动挂载配置

根据UUID自动挂载要修改/etc/fstab 文件,一般不重新分区UUID号不会变化。

1
sudo blkid # 查看设备uuid

关于samba文件服务器

Samba的配置文件为‘/etc/samba/smb.conf’。
开启smbd服务后有时候还是无法连接,可能是防火墙的原因,通过关闭防火墙来验证。如果是,只用文件和打印共享服务的话,开启139(TCP)端口就可以。

1
$ sudo service smbd restart
1
2
# 测试工具。比如设置的限定用户无效。
$ sudo testparm
1
2
# 查看已添加的sabd用户
$ sudo pdbedit -L

scp跨机远程拷贝

  1. 从远处复制文件到本地目录
1
$ scp root@10.6.159.147:/opt/soft/demo.tar /opt/soft/
  1. 从远处复制到本地
1
$ scp -r root@10.6.159.147:/opt/soft/test /opt/soft/
  1. 上传本地文件到远程机器指定目录
1
$ scp /opt/soft/demo.tar root@10.6.159.147:/opt/soft/scptest
  1. 上传本地目录到远程机器指定目录
1
$ scp -r /opt/soft/test root@10.6.159.147:/opt/soft/scptest

其他

因为服务器文件夹和文件名都为中文,ls -ll 后看到的都是???无法区分内容,按某宗师给的建议,ls -ll > /seeFileName.txt 拷贝到U盘,在windows上查看中文名称。
从ubuntu的utf-8拷贝到windows机器上文件名会乱码且无法更改编码方式情况下,一种不严谨的做法:格式化一个ntfs的硬盘挂载上去,拷贝出来就不会,因为linux会自动转换ntfs能识别的格式。

参考文档:
Ubuntu的防火墙配置-ufw-iptables

Ubuntu开启SSH登录

Ubuntu环境下SSH的安装及使用

Linux添加/删除用户和用户组

samba服务器配置