Setup DevTerm to be a cool non-GUI device

Related tags

Hardware linux devterm
Overview

DevTerm hobby project

I bought this amazing device: DevTerm A-0604. It has a beefy ARM processor, runs a custom version of Armbian, embraces Open Source / Open Hardware philosophy and looks dope!

It also has LightDM + xfce as a GUI but it's kinda boring to use this awesome retro-looking device with any kind of a graphical interface. Let's try to set it up for a serious business and a maximum entertainment without any GUI - just how it was in the good old days.

Last Linux distro I've touched (not counting servers) was Red Hat Linux 9 (not RHEL!). I know nothing about modern linuxes + I always forget all the voodoo you have to do to make them work. So here I'll be storing my notes and useful scripts as I go with this hobby project

Roadmap

  • disable GUI
  • enable ssh connection
  • connect to home wifi
  • basic scripts (battery charge and brightness control)
  • render UTF, Cyrillic, Japanese in TTY
  • battery indicator in zsh prompt
  • nice setup for tmux (themes, plugins)
  • email client (gmail, protonmail)
  • games: nethack
  • games: dcss
  • twitter client
  • hckrnews client
  • reddit client
  • stonks
  • IDE / code editor
  • text editor
  • rust
  • can I see pictures in the TTY?
  • what about video?
  • music / spotify player
  • gamepad to scroll text in terminal
  • soluiton for browser
  • start fdterm+fcitx on load
  • bg image in fbterm
  • japanese input in tty
  • google translate in terminal
  • auth by usb stick
  • plug a mini cassette recorder, do some magic to let me store data using cute tiny mini audio-cassettes.. yum!

Notes

  1. Terminal. Standard TTY has a very limited capabilities to render fonts. Had troubles to render Japanese characters (kanji, hirogana and katakana). Got success with using fdterm with Iosevka Term and Noto Sans JP fonts. Downloaded them and copied into /usr/share/fonts/(truetype|opentype) and update ~/.fbtermrc. If the first font doesn't contain the glyph for the rendering character, it will try second font and etc (1). (Still need to try to figure out how to autostart fdterm)

  2. To connect to WiFi I've tried wpa_cli but you need to be really smart to use it. Not my case. Fallbacked to use nmcli and it works like a charm

  3. Browser. Had some hopes for Browsh but it's super slow (uses headless Firefox behind the scenes) and rendering getting borked in fdterm. Have to use lynx for now, and my Macbook

  4. Translations. After quick search was able to find libtranslate-bin but there were no builds for ARM64 and I was about to start building it from sources. However, looked for alternatives in the apt repo and found translate-shell. Works amazingly well for my needs

  5. There is a cool zsh plugin as part of oh-my-zsh called battery. To make it work you need to install acpi and update your prompt. Works flawlessly but I want to use battery indicator in tmux

  6. Games. DCSS is a cool roguelike crawler. Doesn't have ARM64 binary, got the source, followed the instructions and built it without any problems. However attempting to start it throws an error Terminal too small because it needs min height of 24 lines (DevTerm is only 19). Can try to change this but will that make it unplayable?

  7. Used this guide to change the way gamepad on DevTerm keyboard works

  8. Installed gpm (using this) to enable mouse in tty. Didn't need to setup anything. It just works

  9. Software - Reddit client. Although rtv is discontinued - it still works better than alternatives. Can't log in under my user but it doesn't matter much.

  10. Games. Nethack just works!

  11. CPU scaling. Clockworkpi made a script to adjust CPU/GPU cores dynamically

  12. Spotify. You can get spotifyd complied from sources without a problem, just follow the official docs - that allows to play spotify on a devterm. Now, there is spotify-tui to control it via the terminal (to register correctly I had to tunnel the dev server as lynx wasn't able to render the spotify auth page. App itself works but still missing a lot of features.

Japanese input method in terminal

I stumbled upon this good video where Brodie Robertson talks about input method frameworks, input method engines and shows how to setup fcitx with fcitx-moz to enable Japanese input method for Arch linux.

However we need to make all of it working in our terminal. Luckily for us there is fbterm support and as a double win - we have all needed packages in Armbian repo. So I've installed sudo apt install fcitx fcitx-mozc fcitx-frontend-fbterm fcitx-ui-classic.

Configuration in ~/.config/fcitx/config seems pretty odd. I wasn't able to make it work with any other trigger key except for the default one (Ctrl+Space). However I changed SwitchKey to be L_ALT (instead of defaule L_SHIFT) and it made my life better.

To be able to use Ctlr+Space combination I had to update permissions for fbterm by executing setcap 'cap_sys_tty_config+ep' /usr/bin/fbterm

Then to start fbterm with fcitx you simply run fcitx-fbterm-helper -l. Press Ctrl+Space to enable it and then Alt to switch between US and JA input methods.

Set background image in terminal

We have this good guide that I followed to make the magic happen. We need to build fbv from sources and for that we need to:

  • get stock libjpeg dev by using sudo apt-get install libjpeg-dev
  • build libungif from sources:
git clone https://github.com/Distrotech/libungif.git
autoreconf -f -i
./configure
make 
sudo make install
  • build old libpng (1.2) because fbv doesn't like the latest one Armbian repo has
# get .tar.gz from https://sourceforge.net/projects/libpng/
tar xfv 
   
    
./configure
make 
sudo make install
sudo ldconfig

   

Now it's time to get and build fbv:

wget http://s-tech.elsat.net.pl/fbv/fbv-1.0b.tar.gz
tar xfv fbv-1.0b.tar.gz
./configure
sudo checkinstall

Now according to the fbterm manual, this is the script we can create to run fbterm with the background image:

#!/bin/bash

# fbterm-bi: a wrapper script to enable background image with fbterm
# usage: fbterm-bi /path/to/image fbterm-options

echo -ne "\e[?25l" # hide cursor

fbv -ciuker "$1" << EOF
q
EOF

shift
export FBTERM_BACKGROUND_IMAGE=1
exec fbterm "$@"

I've slightly modified it and put in this repo as ./scripts/fbstart. Remember, we actually don't start fbterm directly but run it via fcitx-fbterm-helper instead. If you are doing the same thing, you would also would like to edit /usr/bin/fcitx-fbterm-helper to comment all echo lines there. Otherwise those messages will become the part of your background.

One more thing: for some reason my fbterm requires a counter clockwise rotation to render itself correctly, so I had to rotate the image as well.

At the end it looks like this:

Login & sudo via Yubikey (USB Security Key)

I have Yubikey 5 NFC so it was logical to set it up with DevTerm.

First you need to generate One Time Password (OTP) and upload it to Yubikey Cloud, then you have to generate API keys - store it somewhere secure.

For the same step you can download and use Yubikey Manager app on your other machine. I used it to setup long button press on a key to return the OTP

Then you will have to get yubico-pam. I've built it myself following the instruction in the README. But to do that you will have to build a fee other dependencies first. Namely yubico-c and yubico-c-client

And to build them I had to install quite a few libraries (maybe even missing something):

sudo apt-get install libcurl4-openssl-dev libpam-dev help2man libxslt1-dev docbook-xsl xsltproc libxml2-utils asciidoc

After that follow the configuration instructions for yubico-pam, add to /etc/pam.d/sudo and /etc/pam.d/login this (you can remove debug later after you verify that it works:

auth sufficient pam_yubico.so id=[Your API ID] debug

then create ~/.yubico/authorized_yubikeys with your username and Yubikey ID (that's the info from "Public identity" field when you generate your OTP password)

username:
   

   

then move pam_yubico.so to /lib/security/

mv /usr/local/lib/security/pam_yubico.so /lib/security/

and that's it! Next time you login/sudo you will prompted by YubiKey for 'USERNAME': and you just need to simply touch your key. You should see something like this:

debug: pam_yubico.c:943 (parse_cfg): called.
debug: pam_yubico.c:944 (parse_cfg): flags 32768 argc 2
debug: pam_yubico.c:946 (parse_cfg): argv[0]=id=00000
debug: pam_yubico.c:946 (parse_cfg): argv[1]=debug
debug: pam_yubico.c:947 (parse_cfg): id=00000
debug: pam_yubico.c:948 (parse_cfg): key=(null)
debug: pam_yubico.c:949 (parse_cfg): debug=1
debug: pam_yubico.c:950 (parse_cfg): debug_file=1
debug: pam_yubico.c:951 (parse_cfg): alwaysok=0
debug: pam_yubico.c:952 (parse_cfg): verbose_otp=0
debug: pam_yubico.c:953 (parse_cfg): try_first_pass=0
debug: pam_yubico.c:954 (parse_cfg): use_first_pass=0
debug: pam_yubico.c:955 (parse_cfg): always_prompt=0
debug: pam_yubico.c:956 (parse_cfg): nullok=0
debug: pam_yubico.c:957 (parse_cfg): ldap_starttls=0
debug: pam_yubico.c:958 (parse_cfg): ldap_bind_as_user=0
debug: pam_yubico.c:959 (parse_cfg): authfile=(null)
debug: pam_yubico.c:960 (parse_cfg): ldapserver=(null)
debug: pam_yubico.c:961 (parse_cfg): ldap_uri=(null)
debug: pam_yubico.c:962 (parse_cfg): ldap_connection_timeout=0
debug: pam_yubico.c:963 (parse_cfg): ldap_bind_user=(null)
debug: pam_yubico.c:964 (parse_cfg): ldap_bind_password=(null)
debug: pam_yubico.c:965 (parse_cfg): ldap_filter=(null)
debug: pam_yubico.c:966 (parse_cfg): ldap_cacertfile=(null)
debug: pam_yubico.c:967 (parse_cfg): ldapdn=(null)
debug: pam_yubico.c:968 (parse_cfg): ldap_clientcertfile=(null)
debug: pam_yubico.c:969 (parse_cfg): ldap_clientkeyfile=(null)
debug: pam_yubico.c:970 (parse_cfg): user_attr=(null)
debug: pam_yubico.c:971 (parse_cfg): yubi_attr=(null)
debug: pam_yubico.c:972 (parse_cfg): yubi_attr_prefix=(null)
debug: pam_yubico.c:973 (parse_cfg): url=(null)
debug: pam_yubico.c:974 (parse_cfg): urllist=(null)
debug: pam_yubico.c:975 (parse_cfg): capath=(null)
debug: pam_yubico.c:976 (parse_cfg): cainfo=(null)
debug: pam_yubico.c:977 (parse_cfg): proxy=(null)
debug: pam_yubico.c:978 (parse_cfg): token_id_length=12
debug: pam_yubico.c:979 (parse_cfg): mode=client
debug: pam_yubico.c:980 (parse_cfg): chalresp_path=(null)
debug: pam_yubico.c:981 (parse_cfg): mysql_server=(null)
debug: pam_yubico.c:982 (parse_cfg): mysql_port=0
debug: pam_yubico.c:983 (parse_cfg): mysql_user=(null)
debug: pam_yubico.c:984 (parse_cfg): mysql_database=(null)
debug: pam_yubico.c:1020 (pam_sm_authenticate): pam_yubico version: 2.28
debug: pam_yubico.c:1035 (pam_sm_authenticate): get user returned: ido
debug: pam_yubico.c:222 (authorize_user_token): Dropping privileges
debug: util.c:351 (check_user_token): Authorization line: ido:***********
debug: util.c:356 (check_user_token): Matched user: ido
debug: util.c:362 (check_user_token): Authorization token: :***********
debug: util.c:362 (check_user_token): Authorization token: (null)
debug: pam_yubico.c:1157 (pam_sm_authenticate): Tokens found for user
YubiKey for `ido':
debug: pam_yubico.c:1220 (pam_sm_authenticate): conv returned 44 bytes
debug: pam_yubico.c:1234 (pam_sm_authenticate): Skipping first 0 bytes. Length is 44, token_id set to 12 and token OTP always 32.
debug: pam_yubico.c:222 (authorize_user_token): Dropping privileges
debug: util.c:351 (check_user_token): Authorization line: ido::***********
debug: util.c:356 (check_user_token): Matched user: ido
debug: util.c:362 (check_user_token): Authorization token: :***********
debug: util.c:366 (check_user_token): Match user/token as ido/:***********
debug: pam_yubico.c:1276 (pam_sm_authenticate): OTP: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ID: :***********
debug: pam_yubico.c:1277 (pam_sm_authenticate): Token is associated to the user. Validating the OTP...
debug: pam_yubico.c:1279 (pam_sm_authenticate): ykclient return value (0): Success
debug: pam_yubico.c:1280 (pam_sm_authenticate): ykclient URL used: https://api.yubico.com/wsapi/2.0/verify?id=00000&nonce=aaaaaaaayxnvkpqixgkufyhbxnyxztvg&otp=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&timestamp=1
debug: pam_yubico.c:1348 (pam_sm_authenticate): done. [Success]

Done!

Screenshots

(1) Translations + JA glyph rendering in fbterm

License

MIT unless specified otherwise

You might also like...
This application works with serial communication. Use a simple gui to send and receive serial data from arduino and control leds and motor direction
This application works with serial communication. Use a simple gui to send and receive serial data from arduino and control leds and motor direction

This application works with serial communication. Use a simple gui to send and receive serial data from arduino and control leds and motor direction

A facial recognition device is a device that takes an image or a video of a human face and compares it to another image faces in a database.
A facial recognition device is a device that takes an image or a video of a human face and compares it to another image faces in a database.

A facial recognition device is a device that takes an image or a video of a human face and compares it to another image faces in a database. The structure, shape and proportions of the faces are compared during the face recognition steps.

Launched in 2018 Actively developed and supported. Supports tkinter, Qt, WxPython, Remi (in browser). Create custom layout GUI's simply.  Python 2.7 & 3 Support. 200+ Demo programs & Cookbook for rapid start. Extensive documentation.  Examples using Machine Learning(GUI, OpenCV Integration,  Chatterbot), Floating Desktop Widgets, Matplotlib + Pyplot integration, add GUI to command line scripts, PDF & Image Viewer. For both beginning and advanced programmers .
A GUI for Face Recognition, based upon Docker, Tkinter, GPU and a camera device.

Face Recognition GUI This repository is a GUI version of Face Recognition by Adam Geitgey, where e.g. Docker and Tkinter are utilized. All the materia

A Robust Non-IoU Alternative to Non-Maxima Suppression in Object Detection
A Robust Non-IoU Alternative to Non-Maxima Suppression in Object Detection

Confluence: A Robust Non-IoU Alternative to Non-Maxima Suppression in Object Detection 1. 介绍 用以替代 NMS,在所有 bbox 中挑选出最优的集合。 NMS 仅考虑了 bbox 的得分,然后根据 IOU 来

A non-linear, non-parametric Machine Learning method capable of modeling complex datasets
A non-linear, non-parametric Machine Learning method capable of modeling complex datasets

Fast Symbolic Regression Symbolic Regression is a non-linear, non-parametric Machine Learning method capable of modeling complex data sets. fastsr aim

Make nixos usable for non-technical users through a settings / package management GUI.
Make nixos usable for non-technical users through a settings / package management GUI.

Nix-Gui Make nixos usable for non-technical users through a settings / package management GUI. Motives The declarative nature of ni

LinuxHelper - A collection of utilities for non-technical Linux users accessible via a GUI

Linux Helper A collection of utilities for non-technical Linux users accessible via a GUI This app is still in very early development, expect bugs and

A GUI for designing Python GUI's for PySimpleGUI.
A GUI for designing Python GUI's for PySimpleGUI.

SimpleGUIBuilder A GUI for designing Python GUI's for PySimpleGUI. Installation There is none :) just download the file from a release and run it. Don

A GUI love Calculator which saves all the User Data in text file(sql based script will be uploaded soon). Interative GUI. Even For Admin Panel

Love-Calculator A GUI love Calculator which saves all the User Data in text file(sql based script will be uploaded soon). Interative GUI, even For Adm

A gui-script-editor(Based on pyqt5, pyautogui) to writing your gui script.
A gui-script-editor(Based on pyqt5, pyautogui) to writing your gui script.

gui-script-editor A gui-script-editor(Based on pyqt5, pyautogui) to writing your gui script. ##更新说明 版本号:1.0.0 版本说明:实现了脚本编辑器雏形,未实现执行报告,自动化脚本管理(只支持单个脚本运

PyQt5 Sample GUI Program - Python PyQt5 Sample GUI application
PyQt5 Sample GUI Program - Python PyQt5 Sample GUI application

Python PyQt5 Sample GUI application Program work like this Designed GUI using De

Simple Linear 2nd ODE Solver GUI - A 2nd constant coefficient linear ODE solver with simple GUI using euler's method
Simple Linear 2nd ODE Solver GUI - A 2nd constant coefficient linear ODE solver with simple GUI using euler's method

Simple_Linear_2nd_ODE_Solver_GUI Description It is a 2nd constant coefficient li

The GUI application by Python3.8. Using QT Design draw UI and generator UI XML file provides to PySide2 build GUI components
The GUI application by Python3.8. Using QT Design draw UI and generator UI XML file provides to PySide2 build GUI components

The GUI application by Python3.8. Using QT Design draw UI and generator UI XML file provides to PySide2 build GUI components. Total adopt OOD design class, service, and abstract class. OOP implemented this project.

Pardus-flatpak-gui - A Flatpak GUI for Pardus
Pardus-flatpak-gui - A Flatpak GUI for Pardus

Pardus Flatpak GUI A GUI for Flatpak. You can run, install (from FlatHub and fro

Use an air-gapped Raspberry Pi Zero to sign for Bitcoin transactions! (and do other cool stuff)
Use an air-gapped Raspberry Pi Zero to sign for Bitcoin transactions! (and do other cool stuff)

Hello World! Build your own offline, airgapped Bitcoin transaction signing device for less than $35! Also generate seed word 24 or generate a seed phr

A new kind of Progress Bar, with real time throughput, eta and very cool animations!
A new kind of Progress Bar, with real time throughput, eta and very cool animations!

alive-progress :) A new kind of Progress Bar, with real-time throughput, eta and very cool animations! Ever found yourself in a remote ssh session, do

A cool logging replacement for Python.
A cool logging replacement for Python.

Welcome to Logbook Travis AppVeyor Supported Versions Latest Version Test Coverage Logbook is a nice logging replacement. It should be easy to setup,

Checkout some cool self-projects you can try your hands on to curb your boredom this December!

SoC-Winter Checkout some cool self-projects you can try your hands on to curb your boredom this December! These are short projects that you can do you

Owner
Alex Shteinikov
“Beauty is the ultimate defence against complexity”
Alex Shteinikov
How to configure IOMMU device for nested Proxmox hypervisor (PVE) VM - PCIe Passthrough

Configuring PCIe Passthrough for Nested Virtualization on Proxmox Summary: If you are running bare-metal L0 (level 0) Proxmox (PVE) hypervisor with ne

Travis Johnson 6 Aug 30, 2022
Turns a compatible Raspberry Pi device into a smart USB drive for PS4/PS5.

PSBerry A WIP project for Raspberry Pi, which turns a compatible RPI device into a smart USB drive for PS4/PS5. Allows for save management of PS4 game

Filip Tomaszewski 2 Jan 15, 2022
A DiY holiday project to demonstrate how you can send data from adafruitIO cloud to a balena edge device

holiday-star balena ❤️ adafruitIO Introduction A DiY holiday project to demonstrate how you can send data from adafruitIO cloud to a balena edge devic

Ayan Pahwa 3 Dec 20, 2021
Python library to interact with the GCE Electronics IPX800 device

A python library to control a GCE-Electronics IPX800 V4 device through its API.

Marc-Aurèle Brothier 2 Oct 20, 2021
Monitor an EnvisaLink alarm module running Honeywell firmware, and set a Nest device to Home/Away depending on whether the alarm is Disarmed/Away.

Nestalarm Monitor an EnvisaLink alarm module running Honeywell firmware, and set a Nest device to Home/Away depending on whether the alarm is Disarmed

null 1 Dec 30, 2021
This tool emulates an EMV-CAP device, to illustrate the article "Banque en ligne : à la decouverte d'EMV-CAP" published in MISC

About This tool emulates an EMV-CAP device, to illustrate the article "Banque en ligne : à la decouverte d'EMV-CAP" published in MISC, issue #56 and f

Philippe Teuwen 28 Nov 21, 2022
Sticklog2heatmap - Draw a heatmap of RC sticks from OpenTX logs or USB HID device

sticklog2heatmap Draw a heatmap of RC sticks from OpenTX logs or USB HID device

null 2 Feb 2, 2022
A simple non-official manager interface I'm using for my Raspberry Pis.

My Raspberry Pi Manager Overview I have two Raspberry Pi 4 Model B devices that I hooked up to my two TVs (one in my bedroom and the other in my new g

Christian Deacon 21 Jan 4, 2023
GUI wrapper designed for convenient service work with TI CC1352/CC2538/CC2652 based Zigbee sticks or gateways. Packed into single executable file

ZigStar GW Multi tool is GUI wrapper firtsly designed for convenient service work with Zig Star LAN GW, but now supports any TI CC1352/CC2538/CC2652 b

null 133 Jan 1, 2023
A script and GUI for controlling stepper motors from an arduino

A script and GUI for controlling stepper motors from an arduino (nema 23 in my case but should work for others in general)

Pip 2 Aug 1, 2022