跳转至

博客

实现 VSCodeVim 中支持中文分词的单词移动

最近用 VS Code 写中文 LaTeX 比较多,但是编辑起来总是比较麻烦,不能用各种带 w 的 motion,不然整行都没了。于是 @xalanq 提出能不能拿一个 JS 的分词库,魔改一下 VSCode Vim 来得到同样效果?答案是可以的。

最后代码在 jiegec/VSCodeVimChinese 里,还没有合并到上游的打算。不定期根据上游发版本同步更新,在 Github Release 里发布 vsix 文件,目前版本为 v1.0.1。在 VS Code 里 Extensions: Install from VSIX... 即可安装。

经过对代码的研究,发现对 motion w 的处理都是通过 getWordLeft getWordRightgetCurrentWordEnd 完成的。于是我修改了这三个函数,根据原来的返回值把字符串喂给分词器,再返回的新的位置。一开始用的是 nodejieba ,但是因为需要用到 node-gyp 遇到了 Node 版本不兼容的问题,于是换了一个纯 Node 的实现 node-segment ,就完成了这个功能。

Grafana 中可视化 Ping 时把 Timeout 显示为指定值

刚遇到一个需求,就是用 Telegraf 收集 ping 信息,然后在 Grafana 里可视化当前的延迟,如果超时了,就显示一个指定值,如 999,这样就可以放到一个 Gauge 里面可视化了。但是,问题在于,Telegraf 的 ping input 在超时的时候只会在 result_code 里写一个 2 ,其他项都是空的,因而如果直接用 GROUP BY time(interval) fill(999) 会导致最新的一个数据经常得到 999。这意味着需要根据 "result_code" 来进行区分 Timeout 的情况。最后捣腾了很久,得到了这个方案:

 select "average_response_ms" * (2 - "result_code") / 2 + "result_code" / 2 * 999 from (select "average_response_ms", "result_code" from ping where $timeFilter fill(0))

最后的方法很粗糙:当 "result_code" 是 0 也就是成功的时候,得到延迟,而当 "result_code" 是 2 也就是超时的时候,直接得到 999。这样就解决了这个问题。

域名已经迁移到 jiege.ch

从买新域名到迁移大概用了一个多小时,现在已经恢复访问。原有的地址也会直接 301 到新的域名上来。

仍然 Host 在 Github Pages 上。还会继续更新,不会跑路的(逃

每周分享第 6 期

今天刚迁移了域名到 jiege.ch,原来的 jiegec.me 会自动跳转过来,链接什么的都不用变。

  1. Rust 的 cfg! 宏只是返回 bool 而不会影响内部是否被编译 如果需要 if constexpr 的效果需要用 cfg-if
  2. 基于 HTML5 canvas 的图表库 Chart.js
  3. Endianness MATTERS! -- Harry Chen
  4. 各数据库的带补全的 CLI https://www.dbcli.com/
  5. 边开发边测试 k8s 部署 tilt
  6. Github unlimited free private repos 于是称为了 PRO 用户 https://blog.github.com/2019-01-07-new-year-new-github/
  7. Github 美食博主还行 https://github.com/hendricius/pizza-dough
  8. 一个用于本地化的库 https://github.com/dustin/go-humanize
  9. Vim Verilog 补全 https://github.com/vhda/verilog_systemverilog.vim
  10. homebridge 网页前端 https://github.com/oznu/homebridge-config-ui-x
  11. Zigbee 2 MQTT Bridge 需要额外的设备 https://github.com/Koenkk/zigbee2mqtt
  12. gdb 的网页 gui https://github.com/cs01/gdbgui
  13. Rust 一键 par iter https://github.com/rayon-rs/rayon
  14. 挺好看的 hex viewer https://github.com/sharkdp/hexyl 可以配合 bat 滚屏
  15. gitalk 基于 Github issues 的评论系统 类似 Disqus https://github.com/gitalk/gitalk
  16. 根据蓝牙连接键盘与否改变键盘布局 https://github.com/jwilm/alacritty/wiki/Automatic-MacOS-Keyboard-layout-change-for-Bluetooth
  17. 8.8.8.8 加入 DoT 家庭 https://security.googleblog.com/2019/01/google-public-dns-now-supports-dns-over.html
  18. 恢复损坏的 QRCode 工具箱 https://merricx.github.io/qrazybox/
  19. 通过同时修改两个芯片的 PLL 达成了非标准的 Wi-Fi 通信还行 https://hackaday.com/2019/01/04/underclocking-the-esp8266-leads-to-wifi-weirdness/
  20. inline x86 asm in go https://github.com/mmcloughlin/avo#readme

调整 Alacritty 的 Powerline 字体显示偏移

今天体验了一下 Alacritty,以前一直在用 iTerm2,但是它的高级功能我都没用到。于是现在用了下 Alacritty,把 Solarized Dark 配置了,发现 Inconsolata for Powerline 字体显示有点偏差,于是调整了一下:

# Font configuration (changes require restart)
font:
  # Normal (roman) font face
  normal:
    family: Inconsolata for Powerline
    # The `style` can be specified to pick a specific face.
    #style: Regular

  # Bold font face
  bold:
    family: Inconsolata for Powerline
    # The `style` can be specified to pick a specific face.
    #style: Bold

  # Italic font face
  italic:
    family: Inconsolata for Powerline
    # The `style` can be specified to pick a specific face.
    #style: Italic

  # Point size
  size: 18.0

  # Offset is the extra space around each character. `offset.y` can be thought of
  # as modifying the line spacing, and `offset.x` as modifying the letter spacing.
  offset:
    x: 0
    y: 0

  # Glyph offset determines the locations of the glyphs within their cells with
  # the default being at the bottom. Increasing `x` moves the glyph to the right,
  # increasing `y` moves the glyph upwards.
  glyph_offset:
    x: 0
    y: 3

主要是这里的 glyph_offset 设置为 3(2 也可以,我更喜欢 3) ,这样箭头就基本对齐了不会突出来。

然后按照官方 Wiki,配置了 Solarized Dark 配色:

## Colors (Solarized Dark)
colors:
  # Default colors
  primary:
    background: '0x002b36' # base03
    foreground: '0x839496' # base0

  # Normal colors
  normal:
    black:   '0x073642' # base02
    red:     '0xdc322f' # red
    green:   '0x859900' # green
    yellow:  '0xb58900' # yellow
    blue:    '0x268bd2' # blue
    magenta: '0xd33682' # magenta
    cyan:    '0x2aa198' # cyan
    white:   '0xeee8d5' # base2

  # Bright colors
  bright:
    black:   '0x002b36' # base03
    red:     '0xcb4b16' # orange
    green:   '0x586e75' # base01
    yellow:  '0x657b83' # base00
    blue:    '0x839496' # base0
    magenta: '0x6c71c4' # violet
    cyan:    '0x93a1a1' # base1
    white:   '0xfdf6e3' # base3

真香

Grafana Variable 的 regex 过滤方式

用 InfluxDB 收集到 Mountpoint 数据的时候,经常会掺杂一些不关心的,如 TimeMachine,KSInstallAction 和 AppTranslocation 等等。所以,为了在 Variables 里过滤掉他们,需要用 Regex 进行处理。网上有人提供了方案,就是通过 Negative Lookahead 实现:

/^(?!.*TimeMachine)(?!.*KSInstallAction)(?!.*\/private)/

这样就可以把不想看到的这些 mountpoint 隐藏,节省页面空间了。当然了,这里其实也可以用白名单的方法进行处理,直接写 regex 就可以了。

Rust 获取 Linker Script 中的地址

在 Linker Script 中可以记录下一个地址到一个变量中,大概这样:

.text: {
    PROVIDE(__text_start = .);
    *(.text .text.* .gnu.linkonce.t*)
    PROVIDE(__text_end = .);
}

这里的 PROVIDE() 是可选的。这样,代码里就可以获取到 .text 段的地址了。在 C 中,直接 extern 一个同名的变量就可以了,但在 Rust 中,需要这样获取:

extern "C" {
    fn __text_start();
    fn __text_end();
}

// __text_start as usize
// __text_end as usize

这样就可以拿到地址了。

每周分享第 5 期

2019 年第一篇博文,祝大家新年快乐。最近忙于期末,没怎么搞事情,所以暂时没有关于别的内容的博文。

  1. 发现一个很好看的 http web server index 就是不再更新了 h5ai
  2. 录制 DOM 变化并且重放 rrweb
  3. C++ 中的 Lazy Sequence 实现 lazyCode
  4. 来自 Berrysoft 的 Windows UWP 校园网认证解决方案 TsinghuaNetUWP
  5. 中科大老运维的笔记 ITTS
  6. Go 源码研究电子书 目测还在编写,不过读来挺有收获的 go-under-the-hood
  7. 第一次了解到 ELF Aux Vectors auxv
  8. 发现了 C99 的参数列表里 static 数组大小语法 static array indicies
  9. 发现一个有趣的包装了 socket 的消息库 支持一些消息分发方法 nanomsg
  10. 找到一个可视化 YUV 和视频解码的一些内部信息的工具 YUVView
  11. 通过动态 QRCode 传输数据 txqr qr-transfer
  12. 发现一些很好看的 CSS 动画 10-stunning-css-3d-effect-must-see 其中最神奇也最复杂的是 这个
  13. Android runtime 中动态获取权限的库 Dexter
  14. 来自 Berrysoft 的 Stream operators in C++ CppLinq
  15. Squirrel (Rime for macOS) 在两年以后终于出了 0.10.0 新版本 有了好看的新皮肤
  16. 神奇的 v8 漏洞利用 实在是太复杂了 exploting math expm1 in v8
  17. JWT How-to 发现 Koa 和 Flask 的 session 默认实现也是同样的原理 learn-json-web-tokens
  18. 配置 DNS CAA 的在线工具 限制 CA 签证书的方案 sslmate caa
  19. 又一个 Python 的 Parser 库 配合有趣的 decorator 语法 sly
  20. 自动配置 webpack 的库 Jetpack jetpack
  21. eBPF tutorial learn ebpf tracing
  22. 图片 xkcd-ify 太有趣了 xkcd-style plots
  23. 又一个 Vue 的 rich text 控件 tiptap

每周分享第 4 期

咕了更长的时间。

  1. Header only JIT assembler https://github.com/herumi/xbyak 想找个时间玩玩 JIT
  2. Rust 实现的 Babel 转译 https://github.com/swc-project/swc
  3. 又一个瀑布流实现 https://github.com/e-oj/Magic-Grid
  4. 马上可以体验 HTTP/3 的库 https://github.com/djc/quinn
  5. Logitech Spotlight Presentation 挺好用的 配套软件的安装过程和使用都挺好的
  6. Server side canvas https://github.com/Automattic/node-canvas
  7. 边看 youtube tutorial 边写代码 https://yourepl.tumblr.com/post/180936303347/announcing-yourepl
  8. 又一个 PostgreSQL 网页版客户端 https://github.com/sosedoff/pgweb
  9. 有趣的 CSS Layout 学习方法 http://cssgridgarden.com/#en http://flexboxfroggy.com/
  10. pipenv 也有过 easter egg https://github.com/pypa/pipenv/issues/786 不过影比 antd 这个事情好多了
  11. Web 太强了 啥都能做 https://whatwebcando.today/
  12. 来自娄晨耀的清真 DNS 解决方案 https://github.com/Chenyao2333/freedns-go
  13. 快速的 tldr 实现 https://github.com/dbrgn/tealdeer
  14. MongoDB Data Source for Grafana 可以用 就是 aggregation 不大容易写对 https://github.com/JamesOsgood/mongodb-grafana
  15. Fish 3.0 发布“fish now supports && (like and), || (like or), and ! (like not), for better migration from POSIX-compliant shells (#4620).”

《加速奔向 2019》小程序编写和运营回顾

前言

关注清华的同学可能知道,昨天,“清华大学”公众号发了一篇名为《2018,我们共芳华丨@THUers 致相伴一年的你,请查收这份心意》的推送,内容大概就是,有那么 100 个新年台历礼品要送出去,大家如果想要的话,就扫描小程序。小程序模仿了火车抢票的病毒式营销的模式,要求大家分享到群聊或者朋友圈,让别人给自己加速,加速到 2019 的前 100 名即可填写信息领取奖品。

然后大家就在推送里看到了我。就酱。

开始

这件事情据说策划了有一段时间了,只是因为各种原因一直没有做,最后这个锅就路由到了我的头上。一开始说就是个加速小程序,逻辑很简单,但后来逐渐发现需求越来越多,主要是界面上的,动画上的,还有一些非技术因素的功能,嗯。这其实算是一个不大好的软件工程案例。

过程

线上的问题与解决方案

然后就是上线了。大概是昨天(2018-12-27)中午的时候推送发出去,很快流量就开始来了。很快,在朋友圈看到有同学在转发了,也有人反映说,网络有点卡,加载资源有点多。我去机器上用 iftop 看了下,流量大概是 250Mb/s,没打到千兆。我一开始看了下,CPU 和内存占用都良好,以为是网络出口限制的问题,就想着没办法了,就这样吧,扛过去再说。不过,忽然有了转机。

TUNA 技术群里,忽然有人在讨论 SOMAXCONN 的问题,我想到,会不会是有些参数没开够大,导致了性能瓶颈,又受到啊荣的点拨,立马调整了这些变量:

net.core.somaxconn
fs.file-max
net.core.netdev_max_backlog
net.ipv4.tcp_max_syn_backlog
nginx: worker_rlimit_nofile
nginx: event.worker_connections

很快带宽从 200Mb/s 左右打到了 400Mb/s 多,在 iftop 中看到的峰值接近 600Mb/s,见下图:

事后回来看,发现配置一套科学的监控系统真的很有用,如 TCP 连接的状态图:

这里最高的黄线代表的是 TIME_WAIT,意味着很多的 TCP 连接都卡在了等待资源上,而一当我修改参数以后,立刻就降了下来,ESTBALISHED 的连接有了显著的提升。这个问题从另一个图也可以明地看出:

这个图是 TCP Handshake Issues,可以看到无论是 activeopen 还是 passiveopen,都很高,意味着这里无论是发还是收都遇到了问题。而修改参数以后,这些问题立马得到了很好的改善。

其实这些本应该在上线前做好的,但我低估了清华大学的影响力,没有做好相应的准备,还是在优秀的运维人员的指点下得到了较好的效果。

用户数据分析

当然了,除了 Grafana+InfluxDB+Telegraf 这一套监控系统,我们也部署了 ElasticSearch+Logstash+Kibana,只不过我们还是用 Grafana 做了 ElasticSearch 的前端了。通过对 Nginx 日志的分析,我们得到了这些关键的数据(从 12-26 12:00 到 12-27 12:00 一天时间):

除了这些,还有很多有趣的数据,例如用户里北京的最多,也可以大致地看出各个地方网络和手机的普及程度;用户使用的手机的机型里前几名都是苹果的,从单项占领了排名的前很多位,之后则是华为小米 OPPO 等,但总体上反而是安卓用户更多。

微信小程序官方也提供了一些数据统计可供参考。例如页面的访问次数信息,一共大约有二十多万次,打开小程序有十三万多次,访问人数是五万多,还有女性用户比男性用户多等等。这个时代,有数据确实能够得到许多有价值的判断。

反思

这次学到了很多东西,验证了监控系统的必要性,它能够实时看到服务的运行状态并进行调优,事后也可以回过头来进行进一步的分析和总结。不足的是,遇到大客户量的时候,静态资源就应该用 CDN 服务而不应该自己搭建,成本不高而且用户体验会很好。这次后端在数据库操作都用了原子操作,没有出现大的问题,但如果以后遇到更复杂的需求的时候就没有这么容易了。

每周分享第 3 期

因为 DDL,咕了一小会。

  1. 被 Windows 保存为 Unicode 文件坑了 BOM 配上 UTF-16 太难受了
  2. Github 最近添加了很多 Issue 方面的更新,如 Pin 和 Delete
  3. Grafana 真的很好看很好用 推荐大家自己配一套监控系统
  4. Microsoft Remote Desktop Beta 新增了 AVC Codec 有意思 不知道啥时候上 HEVC
  5. 发现一个很好玩的用 Rust 写的网页游戏 https://sandspiel.club/#
  6. Python Pattern Matching https://github.com/santinic/pampy
  7. 大新闻:MIPS Open Source 了 https://www.eetimes.com/document.asp?doc_id=1334087
  8. GRPC 调试的 GUI https://github.com/uw-labs/bloomrpc 对标 Postman
  9. 酷炫的屏幕保护 for Mac https://github.com/JohnCoates/Aerial
  10. WPF 开源了 不知道啥时候支持 *nix https://github.com/dotnet/wpf
  11. 分享欢乐 https://github.com/dotnet/wpf
  12. 分享欢乐 x2 https://lore.kernel.org/patchwork/patch/628142/
  13. 谷歌近日到处上线了 Material Design 2.0 感觉风格不大习惯
  14. veonim/veonim 的 Tag 里有 #meme-driven-development 太好笑了
  15. 巨硬开源了自己的 UEFI 和 TianoCore EDK 竞争 https://blogs.windows.com/buildingapps/2018/12/19/%e2%80%afintroducing-project-mu/
  16. Github 的 GDPR 完全体上线 https://blog.github.com/2018-12-19-download-your-data/
  17. ZFSonLinux 要统治 ZFS 世界的节奏 https://lists.freebsd.org/pipermail/freebsd-current/2018-December/072422.html
  18. VBScript 真的是太多漏洞了 满目疮痍 https://googleprojectzero.blogspot.com/2018/12/on-vbscript.html
  19. 原来取名真的这么草率的吗 我也想买一个了 https://www.solidot.org/story?sid=59028

每周分享第 2 期

继续,继续。

  1. 用代码呈现硬件实现对性能的影响,值得一读 链接
  2. 发现了一个蛮少见的编码标准 AVS2,才发现是中国主导的 编码器
  3. linux.org 的 DNS 被篡改了,认准 kernel.org 即可
  4. 一个处理器的电路的在线可视化 ARM1 visualized
  5. WASM 家庭现已加入 Nginx 链接
  6. 用 .bat 编写汇编语言 mnnip/BOOTSTRA
  7. Gitlab 挺香的,兹瓷 git-lfs,还可以自己给自己的项目配一个 ci runner
  8. LaTeX 的 subfigure 之间如果有空行,就真的换了一行,所以同一行的 subfigure 不要换行
  9. Rocket 4.0 出了,看起来不错,要是作者更新一下 CS140e 就好了 链接
  10. 装机必备,查询 Arch Wiki arch-wiki-man
  11. LaTeX 里 \newcommand 时,如果文件名有多个 '.' ,要特殊处理 链接
  12. RunAsDate for *nix wolfcw/libfaketime
  13. 用数据库做数据分析似乎是个不错的选择
  14. Canvas 配合 globalCompositionOperation 能做到不少东西
  15. 才知道有 Time Machine over SMB 这种操作 链接
  16. mDNS repeater 把两个子网的 mDNS 打通 kennylevinsen/mdns-repeater
  17. Office 2019 for Mac 的 December 2018 release 添加了 Dark Mode,并且也支持了 Continuity Camera,直接从手机拍照导入
  18. Gitlab serverless 发布,期待 链接
  19. 用 NAS 作为 Time Machine 备份盘的方法 链接
  20. 研究了一下,Time Machine over SMB 在 macOS 里的表现形式是 apfs 里写了一个 sparse bundle,bundle 里面是 HFS+ 。

配置 homebridge-mi-aqara 并添加为 telegraf 的数据源

最近有了设备,想把设备拿到的数据都导一份存到 influxdb 里,但是目前找到的只有 homebridge-mi-aqara 可以访问并拿到数据,然后它又提供了 mqtt 的数据获取方案,于是自己写了个脚本去读取这些数据。

首先当然是配置一下 homebridge-mi-aqara,按照网上的教程来,这个不难。然后本地开一个 MQTT Broker(如 mosquitto),配置为本地监听,然后我编写了脚本 telegraf-mi-aqara.py ,使用前需要 pip install paho-mqtt,并且按照实际路径修改一下内容。验证能够跑起来后,写一个 telegraf 配置:

[[inputs.exec]]
        commands = ["/usr/bin/python3 /path/to/telegraf-mi-aqara.py"]
        timeout = "5s"
        data_format = "influx"

现在就可以读取到各项信息,如温度,湿度,是否开门,开关用电情况等等。

2018-12-16 更新:

研究了一下绿米网关局域网通信协议,得到了第二个版本 telegraf-mi-aqara-v2.py,它与第一版的区别是,第一版是主动向网关读取信息,而这一版则是监听组播包,等待网关发消息。这个脚本负责把读取到的组播信息发送到 MQTT,再让 telegraf 从 MQTT 里解析 JSON 消息,写入数据库。Telegraf 配置如下:

[[inputs.mqtt_consumer]]
        servers = ["tcp://127.0.0.1:1883"]
        qos = 0
        connection_timeout = "30s"
        topics = [
                "/telegraf-mi-aqara"
        ]
        persistent_session = true
        client_id = "Telegraf"
        data_format = "json"
        json_string_fields = ["model", "sid", "status"]
        tag_keys = ["model", "sid", "short_id"]

由于设备不全,有些字段可能不完整。如果大家自己要用的话,可能需要自行修改一下。

每周分享第 1 期

向阮一峰学习,把自己在一周里看到的有趣的事情分享一下。不过形式就比较随意了。

  1. 最近写 MongoDB + NodeJS 学到的新操作:$addToSet $nin $ne Mongoose 的 setDefaultsOnInsert
  2. Promise 真香,真好用
  3. 几天前惠老师还在说 "IE, The best Chrome Downloader Downloader, ever" 今天 EdgeHTML 就宣告死亡了
  4. WPF, Windows Forms 和 WinUI 开源了,mono 这是要凉? 链接
  5. 有人逆向了 FPGA 的 bitstream 格式,希望 FPGA 有朝一日可以进入 开源时代? 链接
  6. 造机的 baseline 就决定是
  7. 根据 AST 炼丹判相似度还行,好奇它跨语言的预测水准 链接
  8. 可视化 h264 nalu 的软件 H264Naked (做的好糙啊,想交 pr)
  9. ffprobe -show_packets 和 ffprobe -show_frame 真好用
  10. 发现一个解决 ArchLinux 滚内核后无法 modprobe 的方案
  11. 010 Editor 和 Hex Fiend 是二进制分析的神器啊... Kaitai 还有待加油
  12. CSS-in-JS for ClojureScript 真香 有空可以试试用 ClojureScript 写前端
  13. Safari Technology Preview 71 加入了 Web Authentication 这是要支持 U2F 的节奏?
  14. Grafana+InfluxDB+Telegraf 真科学,随手写了一些简单的 Telegraf 的 input plugin
  15. 给 010 Editor 写了俩 .bt 文件,见我上一篇博客
  16. 海思 cc 居然支持 ASan : /opt/hisi-linux/x86-arm/arm-hisiv600-linux/arm-hisiv600-linux-gnueabi/lib/a7/libasan.so
  17. 遇到了 设备名有空格导致 telegraf 读取 S.M.A.R.T. 信息失败 的锅,不过似乎没人修
  18. 看到了一个很有意思的 Interview Pass Rate 关于使用的编辑器的调查,很有意思 链接
  19. 发现一个 JSX 的替代品,用了 Template literal syntax,挺好的 链接

也不知道能不能坚持下来,就这样了,发布(逃

Grafana 可视化实践:清华大学 2018 年度人物评选

最近这段时间,清华内部正在投票选出今年的年度人物,想到最近刚好在学习使用 Grafana+InfluxDB+Telegraf 全家桶,于是想着能不能写个爬虫把数据都拿下来,然后用 Grafana 画出来,就可以得到一个投票随时间变化的趋势。爬虫很简单,就是登录,获取页面信息,然后按照 InfluxDB 的输入格式进行输出即可。代码放在了 jiegec/student-tsinghua-vote18 下。

接着就是用 Grafana 进行可视化,大概得到了这样一个曲线:

为保护隐私,把名字隐去了。实际上的投票时间是从 12-3 号开始到 12-7 号结束,但由于宿舍停电的原因所以采样的点在半夜的时候都没有,所以看起来有点奇怪,但还是能够反应总体的趋势的。比如可以看到前两名很早就一马当先,而后一直遥遥领先,下面的选手则排名变动很大,特别是截止前最后一段时间,大家都在拼命拉票,可见大家都是 DDL 选手啊。如果对上面这个图求个导,看看变化率的话:

这显现出了很有意思的一个趋势,就是每天十二点左右都有一个高峰期,然后在零点前大概熄灯附近的时间也是一个高峰期,另外就是截止前最后的抢票阶段,大家都在疯狂拉票,从中午拉到最后时刻。由于停电的原因,在零点附近的数据都比较的鬼畜,不过影响不大,趋势一目了然。

Grafana 真香!期望可以学到更多高端的查询语法和可视化的骚操作,现在有很多东西不知道该怎么可视化,比较苦恼,不知道大家有没有什么经验可以分享。

编写 010 Editor 的 FLV Template

最近在做 FLV 和 H264 方面的研究,研究了很多标准和文档,然后用 010 Editor 对着文件进行分析。这个软件真的很好用,对研究二进制结构用处特别大。不过它自带的 FLV.bt 功能不是很好,我对它加上了 H264(AVC) 的部分支持,放在了 myFLV.bt 里。我也写了 H264 的解析,不过效率不高,大文件要卡好一会。

除此之外,很多格式,010 editor 都有支持,特别好用,它的解析器语法也很好写。

强制启用 Google Chrome 原生的 Dark Mode

Mojave 的 Dark Mode 真香,但是 Google Chrome 并不会随着系统的 Dark Mode 设置变化,所以 NightOwl 只能让部分软件按照时间变更 Dark/Light Mode。一番搜索,发现其实 Google Chrome 其实已经支持了 Dark Mode,但只能设置,不能按照系统的状态自动切换,命令如下:

$ open -a Google\ Chrome --args --force-dark-mode

然后就可以看到 Google Chrome 已经是 Dark Mode 了。但可惜并不能自动切换。

配置 Grafana+InfluxDB+Telegraf 并添加 MIIO 数据来源

之前一直想配一个监控系统,现在有机会了,就简单配了一下。发现真的特别简单,用 Homebrew 安装这三个软件并且都跑起来,然后稍微动一下配置,就可以得到可观的效果了。

然后想利用 miio 配置一下,把宿舍的空气净化器各项参数拿到,以 Telegraf 的插件形式定时上报,然后通过 Grafana 进行可视化。插件放在了 jiegec/tools 下,就是一个简单的 Python 脚本。配置方法如下:

编辑 /usr/local/etc/telegraf.d/miio.conf

[[inputs.exec]]
    commands = ["/usr/local/bin/python3 /Volumes/Data/tools/telegraf/miio.py MIID_HERE"]
    timeout = "5s"
    data_format = "influx"

默认了 miio 路径为 /usr/local/bin/miio

Mac 上安装 Arch Linux,ZFS 真香

最近在 Mac 上装了 Arch Linux,按照 Mac - Arch Linux Wiki 一路一路走,创建单独的一个 EFI 分区给 Arch Linux 放 GRUB 和内核,一个 ext4 作为根分区。由于 Arch ISO 不支持 Broadcom 的无线网卡,于是先拿 Apple Ethernet Adapter 连到路由器上装机。然后把一些需要的驱动装上了,桌面用的 KDE Plasma,Trackpad 用的 xf86-input-mtrack-git,HiDPI 设置为 2x Scale,各种体验都还可以,就是 Wi-Fi 的 802.1X 没配置好,然后 kwalletd5 老是崩没找到原因。常见的应用除了微信基本都有,也终于可以体验 Steam Play,利用 Proton 在 Linux 上跑一些只支持 Windows 的游戏,不过我已经很少玩游戏了。

然后我就想,怎么做 macOS 和 Linux 之间的文件共享。典型的操作可能是 exFAT,但是作为数据盘的话,这还是不大适合。或者就直接用 ext4,配合 extFS For Mac by Paragon 使用,也可以,最后我选择了 ZFS。

在 macOS 上安装 OpenZFS on OSX ,在 Linux 上安装 ZFS on Linux 。具体命令就是:

$ brew cask install openzfs # macOS
$ yay zfs-dkms-git # Arch Linux

由于硬盘空间所限,我只用了一个分区作为 vdev,没有采用 mirror、raidz 等方案。我首先在 macOS 上创建了一个 zpool,参考 Creating a pool - OpenZFS on OSX

$ sudo zpool create -f -o ashift=13 Data diskxsy

此时应该能够看到 /Volumes/Data 上已经挂载了一个 ZFS Dataset。我采用 cbreak-black/ZetaWatch 在菜单栏里查看 ZFS 信息。此时回到 Arch Linux 上,通过 zfs import 可以找到并且挂载这个 ZFS Dataset 到 /Data 处。

我还尝试创建了一个加密的 ZFS Dataset,对加密的部分的粒度控制可以很细。另外,我参考 Time Machine Backups - OpenZFS on OSX 也在移动硬盘上划出一个新的分区作为 ZFS,在上面创建了一个加密的 Sparse Bundle,把它作为 Time Machine 的目标。之后还会尝试一下 zfs send 作为替代的备份方案。

USB/IP 实践

之前一直想玩 USB/IP,但是一直没有找俩 Linux 设备然后共享,今天终于尝试了一下,没有什么大问题。这次采用的设备是 Raspberri Pi 3 和 SaltedFish Pi。一开始尝试从后者向前者共享,但总是出现这个错误:

libusbip: error: udev_device_get_sysattr_value failed
usbip: error: open vhci_driver

然后我反过来做就好了,比较神奇。

主要过程如下:

  • pacman -S usbip 安装用户态软件
  • systemctl enable --now usbipd 启动 USB/IP 的端口监听 daemon
  • usbip list -l 查看本地有哪些 USB 设备可以共享
  • usbip bind -b [BUS_ID] 把指定的 USB 设备共享出去,其中 BUS_ID 从上个命令中查看
  • usbip list -r [IP] 在另一个设备上查看这个设备共享的 USB 设备,可以看到许多信息
  • usbip attach -r [IP] -b [BUS_ID] 把对方共享的 USB 设备 attach 到本地

效果:把一个 U 盘成功映射到了本地:

$ lsusb -t
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=vhci_hcd/8p, 480M
    |__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 480M
$ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda           8:0    1 14.9G  0 disk
`-sda1        8:1    1 14.9G  0 part /tmp/mnt

尝试 mount 什么的,也都没有问题。以后可以考虑把本地的 LicheeTang 通过这种方式穿透到远端,然后在远端用它的 IDE 进行编程。

UPDATE: LicheeTang 烧写有一些问题,直接 JTAG 写上去没有作用,但是 SPI Flash 是可以成功写入并且有作用的,虽然需要强制打断。感觉还是网络延迟导致了一些问题。

超过 100 篇博文了!

今天看了下,发现算上这一篇,这个博客已经有 103 篇文章了,这个数量还是蛮多的,特此庆祝一下。我也顺带做了一下简单的数据处理,得到这么一张图:

graph

目测数量与干活的频率相关性很高啊。

向咸鱼派写入 ArchlinuxARM

之前由于我的 macOS 上不知道为啥不能把我的 TF 卡设备放到我的虚拟机里,所以之前就没能刷 ArchLinuxARM 上去。今天我想到了一个方法,完成了这件时期:

$ wget https://mirrors.tuna.tsinghua.edu.cn/archlinuxarm/os/ArchLinuxARM-armv7-latest.tar.gz
$ dd if=/dev/zero of=archlinuxarm.img bs=1M count=1024
$ mkfs.ext4 archlinuxarm.img
$ sudo mkdir -p /mnt/archlinuxarm
$ sudo mount -o loop archlinuxarm.img /mnt/archlinuxarm
$ sudo bsdtar -xpf ArchLinuxARM-armv7-latest.tar.gz -C /mnt/archlinuxarm
$ sudo umount /mnt/archlinuxarm

这样就获得了一个 ext4 的 ArchlinuxARM 镜像。刚好解压出来不到 1G,所以开了 1G 的镜像刚好放得下。然后把 archlinuxarm.img 拷回 macOS,然后用 dd 写进去:

$ sudo dd if=archlinuxarm.img of=/dev/rdisk4s2 bs=1048576

这时候可以确认,我们确实是得到了一个正确的 ext4fs:

$ sudo /usr/local/opt/e2fsprogs/sbin/tune2fs -l /dev/disk4s2

不过,我们实际的分区大小可能不止 1G,所以可以修改一下大小:

$ sudo /usr/local/opt/e2fsprogs/sbin/resize2fs -p /dev/disk4s2

这样就成功地把 ArchlinuxARM 写进去了。默认的用户名和密码都是 root,可以成功通过串口登录。

咸鱼派的启动配置

最近刚拿到了一个咸鱼派的测试板子,准备自己把 U-Boot 和 Linux 内核这一套东西跑通,都用主线的东西,尽量减少魔改的部分。首先是编译 u-boot,我用的是现在的 master 分支的最新版 99431c1c:

$ # Archlinux
$ sudo pacman -Sy arm-none-eabi-gcc
$ make LicheePi_Zero_defconfig
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- -j24

这时候会得到一个 u-boot-sunxi-with-spl.bin 的文件。我们只要把它写到 SD 卡的 8192 偏移处,就可以把 U-Boot 跑起来了:

$ diskutil unmountDisk /dev/disk4
$ sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/disk4 bs=1024 seek=8

接着我们做一下分区。我采用的是 MBR 分区,这样保证不会和 U-Boot 冲突。使用 fdisk 进行分区,我从 1M 处开始分了一个 10M 的 FAT-32 分区作为启动分区,然后之后都是 EXT4 的系统盘分区。接着就是编译内核。

我用的是八月份时候的 4.18.2 内核,虽然不是很新但也足够新了。一番调整内核参数后,得到了一个可用的内核,然后把 zImage 和 sun8i-v3s-licheepi-zero.dtb 都复制到刚才创建的 FAT-32 启动分区,然后进入 U-Boot 进行启动:

$ setenv bootcmd 'fatload mmc 0 0x41000000 zImage; fatload mmc 0 0x41800000 sun8i-v3s-licheepi-zero.dtb; setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait; bootz 0x41000000 - 0x41800000'
$ saveenv # optional
$ boot

这里一开始遇到了很多坑,比如一直看不到 console,这个是找了 @gaoyichuan 拿到的一份 Kernel Config 进行修改修好的。另一个是进去以后找不到 root,我先是搞了一个有 busybox 的 initrd,进去看发现是能找到 mmc 的,但是有延迟,那么添加上 rootwait 就好了。进去以后就差 rootfs。由于我缺少一个写 ext4 的工具,又发现手上有一个 Raspbian 的镜像,它里面也正好是两个分区,而且架构也同样是 armv7l,我就直接把它烧到 SD 卡中,把 U-Boot 写进去,然后往 boot 分区里写内核和 dtb,然后就成功进去,并且跑起来了。最喜感的就是,进去以后是个 pi@raspberrypi,实际上确是另一个东西。不过,只有当我 apt update 发现用了半小时的时候,我才想起来这其实是是一个嵌入式系统。。

进去以后发现,没有识别到网卡驱动。网上找了 LicheePi Zero 的一个解决方案,但是并不能用,还出现了神奇的 Kernel Oops,怀疑是内核版本太新的问题。我又找到 @icenowy 的一个 Patch ,它终于是解决了这个问题,成功地找到了网卡,并且愉快地 ssh pi@raspberrypi.local 。之后会在咸鱼派那边公布一下我们做的修改。

现在的想法是,把 HomeBridge 搭建到它上面,不过目前来看硬件资源有点紧张,放着会有点慢。可能还是用树莓派做这个事情比较合适。

使用 HomeBridge 把小米空气净化器加入到 HomeKit 中

受 @NSBlink 安利,自己部署了一下 HomeBridge ,然后在 iOS 的家庭上就可以看到它。然后,通过 homebrdige-mi-airpurifiermiio 按照教程进行配置。然后就可以在家庭里看到小米空气净化器,包括空气质量,湿度,睡眠模式,温度,打开状态。然后我就可以做一些配置,如离开宿舍的时候自动关闭空气净化器,回来的时候自动打开。不过由于自己没有一个一直放在宿舍的 iPad、Apple TV 或者 HomePod,失去了中枢,这个功能可能会打折扣。

后续想买一些智能的灯啊,然后就可以用 Siri 进行打开 / 关闭了。

此外,我又试了下,可以用 homebridge-camera-ffmpeg 把摄像头配置到 HomeKit 中。这样,就可以远程查看视频流了。

部署 adminMongo 的 Docker 镜像

之前在软工的平台上部署了一个 MongoDB,但是自然是仅内网访问,想要浏览内容只能通过网页上的 Console 进去看,体验特别不好。所以想着能不能找一个在线的 MongoDB 浏览器。由于软工平台只能部署 Docker 镜像,所以我找到了mongo-expressadicom/admin-mongo。但软工平台现在还没实现环境变量的配置,所以我选了后者。

首先本地创建一个 app.json,让它监听 0.0.0.0:80,通过 deployer 传到平台上的配置,然后再把配置 mount 到 /app/config 路径上。现在就可以成功地在网页上浏览 MongoDB 了。