X.K.e-Paper —— 驱动电子墨水屏

简介

XingKong e-Paper 基于树莓派和微雪电子墨水屏实现,可以显示时间、天气、温度以及系统状态,支持编写APP扩展功能。

GitHub地址:https://github.com/XingKongSync/X.K.e-Paper

关键组件

名称说明
AppLoader 程序主入口,提供了用于加载 App 的基础环境,启动后会自动加载 SystemUI
SystemUI一个特殊的 App,用于显示程序主界面
RemoteController可以广播并发现局域网中的 X.K.e-paper 并支持向其发送按键消息
XingKongForm提供了一系列 UI 交互控件,封装了底层的绘制操作
XingKongFormGenerator一个帮助 App 开发者用可视化的方式来生成界面的工具
AppBaseApp 的基类
RemoteSerialPort串口服务器,用于接收网络上发来的 TCP 数据,并转发到本机指定的串口

目录结构

程序的目录结构示例如下:

└── X.K.e-Paper
    ├── AppBase.dll
    ├── AppForm.json
    ├── AppLoader.exe
    ├── AppLoader.exe.config
    ├── Apps
    │   ├── PhotoLibrary
    │   │   ├── test_image.jpg
    │   │   ├── MainForm.json
    │   ├── PhotoLibrary.dll
    │   ├── RemotePlayer
    │   │   ├── album.png
    │   │   └── RemotePlayerForm.json
    │   └── RemotePlayer.dll
    ├── asciiLogo.txt
    ├── Config.json
    ├── MainForm.json
    ├── Newtonsoft.Json.dll
    ├── Newtonsoft.Json.xml
    ├── ShutdownForm.json
    ├── StartingForm.json
    ├── SystemUI
    │   ├── APP.BMP
    │   └── 省略其他资源图片
    ├── SystemUI.dll
    ├── XingKongForm.dll
    └── XingKongUtils.dll

App 应当放入 Apps 文件夹中,dll 在 Apps 目录下,该 App 所要使用的资源放在 App 同名目录中

配置文件

程序的配置保存在 Config.json 中,示例如下:

{
    "PortName": "/dev/ttyUSB0",
    "BackupPortName": "/dev/ttyUSB1"
}

PortName 是程序连接屏幕所使用的串口名称,如果在 Windows 环境中则类似于 COM1

有些情况下,由于某些原因,串口号可能会变化(比如硬件性能不稳定导致断开后又自动连上),此时可以通过指定 BackupPortName 来设置一个备用串口名称,当主串口无法打开时,会自动切换到备用串口

远程调试

AppLoader 启动时可以远程连接另一台主机的 e-paper,这样方便开发和调试,具体步骤如下:

  1. 在连接了 e-paper 的计算机中启动 RemoteSerialPort,命令行参数中传入串口名称
  2. 在开发机上启动 AppLoader,命令行中传入 -ip xxx.xxx.xxx.xxx,其中 xxx.xxx.xxx.xxx 请替换为上一步中计算机中的 IP 地址

用户交互

目前程序仅支持模拟按键式的交互方式。在 XingKongForm 中提供的 Keyboard 对象会在本机监听 UDP 9849 端口,并接收长度为 4 个 byte 的消息,这 4 bytes 会被转换为 .Net 中的 System.Windows.Forms.Keys 枚举

App 开发者可以通过绑定 KeyPressed 事件来处理按键消息

注意:当 App 挂起时,需要开发者手动取消绑定 KeyPressed 事件

界面生成

1. 在 XingKongFormGenerator 中新建一个 Form,并继承于 XingKongFormBase

2. 借助 WinForm 的图形化界面设计器,使用 Label、Button、ListBox、PictureBox、Panel 来构建你的界面

3. 在 Program 中将 Form 替换为你的 Form

借助 WinForm 的图形化界面设计器,使用 Label、Button、ListBox、PictureBox、Panel 来构建你的界面

在 Program 中将 Form 替换为你的 Form

[STAThread]
static void Main(string[] args)
{
    Args = args;
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new YourForm());
}

4. 在你的 Form 的 Load 事件中执行如下代码

private void YourForm_Load(object sender, EventArgs e)
{
    PortName = "COM4";

    XingKongWindow window = GetXingKongWindow();
    LocalShow();//在 e-paper 上预览效果,支持远程调试,方法类似于 AppLoader
    ShowCode();
}

5. 运行 XingKongFormGenerator 后会生成界面的 json 代码,保存此 json 并在你的 App 中进行加载

效果演示

HiWiFiAPI —— 极路由后台API封装

简介 / Introduction

用C#代码模拟了极路由网页版登陆路由后台的过程,支持获取全局网速、设备网速、设备连线消息、设备断线消息

GitHub地址:https://github.com/XingKongSync/HiWiFiAPI

示例 / Usage

class Program
{
	static HiWiFiService service = null;
	static void Main(string[] args)
	{
		string ip = "192.168.199.1";
		string pwd = "123456";

		service = new HiWiFiService(ip, pwd);
		service.DeviceOnlineStatusChanged += Service_DeviceOnlineStatusChanged;

		while (true)
		{
			service.DoHeartBeat();
			Print(service.DeviceMap.Values);
			Task.Delay(2000).Wait();
		}
	}

	private static void Service_DeviceOnlineStatusChanged(DeviceInfo obj)
	{
		string _mesasge = "Device: " + obj.name + (obj.online == 1 ? " connected." : " disconnected.");
		Console.WriteLine("Recent Message: " + _mesasge);
	}

	static void Print(IEnumerable<DeviceInfoEx> devExList)
	{
		Console.Clear();
		//输出局域网整体速度
		string totalUploadSpeed = (int)(service.UploadSpeed / 8000f) + "KB/S";
		string totalDownloadSpeed = (int)(service.DownloadSpeed / 8000f) + "KB/S";
		Console.WriteLine($"Total Upload: {totalUploadSpeed}, Download: {totalDownloadSpeed}\r\n");

		//输出设备网速
		int lineLimit = 25;
		for (int i = 0; i < lineLimit && i < devExList.Count(); i++)
		{
			var devEx = devExList.ElementAt(i);

			string devName = string.IsNullOrWhiteSpace(devEx.Info.name) ? "<Unkown>" : devEx.Info.name;
			string txSpeed = (int)(devEx.UploadSpeed / 8000f) + "KB/S";
			string rxSpeed = (int)(devEx.DownloadSpeed / 8000f) + "KB/S";

			if (devName.Length > _padLeft) _padLeft = devEx.Info.name.Length;

			Console.WriteLine($"Device: {devName}\t up: {txSpeed}\t down: {rxSpeed.}");
		}
	}
}

安装了WordPress

主站重建,之前说好的“自豪地不使用WordPress”的呢?!

总之现在要把之前的主页内容搬过来,而且需要找个好看的主题,其实WP的功能我也不是很熟悉(虽然之前用过),还需要摸索一下。

之前的网站计划中本来还打算自己做后端渲染,做SEO来着,咕了!

网站升级计划


网站升级计划

有个大胆的想法,把这个服务器一方面作为博客服务器,另一方面作为家庭物联网的中枢。
目前的构想的架构如下:

简单解释一下就是,网站后端放弃ASP.NET,改用我自己的一个简易的WebAPI服务,前端使用React来实现,在后期为了SEO可能还需要使用Next.js做SSR

在云端架设FRP服务,在家里的电脑、树莓派等等设备上搭建服务,提供一些API,通过FRP透传到云端,然后云端的后端服务再与这些API对接

                                         User
    _______________________________________↑______________________
   | Cloud                                 |                      |
   |                                     HTTPS                    |
   |                                       ↑                      |
   |                                     Nginx                    |
   |                                 ______↑______                |
   |                                |             |               |   
   |                     XingKongWebApiServer  Next.js            |
   |                               ↑          (Optional)          |
   |       |-Dev1-API  ----------| |              |               |
   | FRPs -|-Dev2-API  ----------|-|            React             |
   |       |-Dev3-API  ----------|                                |
   |  ↑                                                           |
   |__|___________________________________________________________|
    __|_____________________
   |  |     IOT Device      |
   |  ↑                     |
   | FRPc        Service    |
   |  |             |       |
   |  |----------- API      |
   |________________________|

傲腾导致资源管理器CPU占用高


现象:explorer.exe持续占用cpu10%
解决方法:卸载Intel Optane Pinning Explorer Extensions

我回来啦!

为期19天的宁波出差生活告一段落,Home, Sweet Home!

捷径测试

这是通过iOS12捷径发布的一篇日志

备案号被撤啦!

因为原先是通过阿里云进行备案的,现在由于域名指向了非阿里云国内节点,所以阿里云给我把备案撤了。

Advanced Installer 踩坑总结


这几天用Advanced Installer给公司的软件制作安装包,本来以为只是一项很简单的工作,却不幸地踩到了好几个坑,在此记录下来备忘。

一、两个Code了解一下
UpgradeCode:同一软件的UpgradeCode必须一样,否则无法通过安装包升级安装。墙裂建议在别的地方把UpgradeCode保存一份,否则一旦手贱把UpgradeCode给覆盖了,那请参考本文后节。
ProductCode:同一软件的不同版本,ProductCode必须不一样,否则在安装时会提示“已安装此产品的另一个版本balabala”

二、允许降级安装
Product Information -> Upgrades,选中Allow side by side installs of different product versions

三、安装前卸载旧版本
Product Information -> Upgrades,选中Uninstall old version first and then install new version
参考:https://www.advancedinstaller.com/user-guide/upgrades.html

四、版本号
MSI只认版本号前三位!!!!
如果你的旧版版本号是1.0.0.1,新版是1.0.0.2,那么你在安装新版的时候,即使安装目录与旧版选择的是一致的,安装程序不会卸载旧版本,于是你会在控制面板里发现两个软件,而且新版的不一定会覆盖掉旧版的文件(大概吧,没详细测)

五、找回UpgradeCode和ProductCode
前提是你要有之前版本的安装包,或者已经安装过之前版本
要找到UpgradeCode必须先找到ProductCode

找回ProductCode的两种方法:
1、打开注册表编辑器,定位到
HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall
搜索你的ProductName,然后左侧的那个GUID就是你的ProductCode了

2、打开CMD,输入
wmic product where "Name like \'你的产品名称\'" get Name, Version, IdentifyingNumber

找回UpgradeCode的方法:
1、打开CMD,输入 msiexec /i {你的ProductCode} REINSTALL=ALL REINSTALLMODE=omus /l*v log.txt
2、此时安装程序会对你的软件进行修复安装,等待安装结束
3、打开刚刚生成的log.txt文件
4、搜索“UpgradeCode”

六、执行PowerShell脚本
Custom Behavior -> Custom Actions,在 Add Custom Action 选项卡中,找到 Run PowerShell inline script,添加然后调整执行顺序

附上一个结束进程PowerShell脚本示例
# Block for declaring the script parameters.
Param()

# Your code goes here.
Get-Process -Name TR.VideoSurveillance Stop-Process Get-Process -Name WuhanSanZhan Stop-Process

MySQL内存占用


看了一下VPS的控制台,发现内存使用量爆表,swap空间也用了不少

在终端输入top,按下大写M,查看内存使用量排名,发现mysql占了58%内存

于是决定对mysql的配置进行修改,以节约内存,参考网上的文章,配置文件最终修改如下

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M
thread_concurrency = 8
log-bin=mysql-bin
binlog_format=mixed
server-id = 1

# Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0
# Recommended in standard MySQL setup sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
[mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid
[mysqldump] quick max_allowed_packet = 16M
[mysql] no-auto-rehash
[myisamchk] key_buffer_size = 128M sort_buffer_size = 128M read_buffer = 2M

修改之后内存瞬间富裕了好多