Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
Anodynous committed Mar 21, 2021
2 parents 3d16bf6 + 0fc333a commit 41c1c93
Show file tree
Hide file tree
Showing 23 changed files with 905 additions and 533 deletions.
48 changes: 48 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
### Changed
### Fixed
### Removed

## [0.0.4] - 2021-03-21
### Added
- This CHANGELOG file.
- User configurable bluetooth device name using main.plugins.plover_link.bt_device_name.
- User configurable list of bluetooth mac addresses, in order of priority, to auto-connect to using main.plugins.plover_link.bt_autoconnect_mac.
- User configurable option to clear eINK display at shutdown using ui.display.clear_at_shutdown.
- User configurable wpm calculation method using main.plugins.plover_link.wpm_method.
- User configurable wpm update frequency and calculation window in seconds using main.plugins.plover_link.wpm_timeout.
- More variety in mood indicators on common events.
- Requirements file.

### Changed
- Improved installation guide and documentation in README.
- All functionality in buttonshim plugin reworked into class for better integration with the project.
- More consistent logging messages.
- Stenogotchi_link version upgrade to v0.0.4.

### Fixed
- Reboot after initial setup or hostname change not working.
- Wifi status not showing as [OFF] if wifi is disabled at boot.
- Mode not changing to STENO when Plover becomes operational.
- All button press events not producing logging messages.
- Dependencies for stenogotchi_link Plover plugin corrected in setup.cfg.

## [0.0.3] - 2021-03-18
### Added
- First public pre-release version on GitHub.
- Stenogotchi, portable stenography using Plover and bluetooth keyboard emulation on a Raspberry Pi Zero W. With support for Waveshare 2.13 v2, ButtonSHIM and UPS-Lite v1.2 modules.
- Plover plugin stenogotchi_link for communicating between Plover and Stenogotchi.
- README now includes tested installation guide no longer requiring building PyQt5 from source.
- README now includes basic configuration and usage documentation.
- LICENSE file.

[Unreleased]: https://github.com/Anodynous/stenogotchi/compare/v0.0.4...dev
[0.0.4]: https://github.com/Anodynous/stenogotchi/compare/v0.0.3...v0.0.4
[0.0.3]: https://github.com/Anodynous/stenogotchi/releases/tag/v0.0.3
75 changes: 42 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,38 +38,38 @@ All commands should be executed as root. The installation process can be complet

3. [5min] Install additional dependencies

apt-get install xserver-xorg-video-fbdev libtiff5 libopenjp2-7 bluez python3-rpi.gpio python3-gi screen rfkill -y
pip3 install file_read_backwards flask flask-wtf flask-cors evdev python-xlib pillow spidev jsonpickle pydbus dbus-python
apt-get install xserver-xorg-video-fbdev libtiff5 libopenjp2-7 bluez python3-rpi.gpio python3-gi screen rfkill -y
pip3 install file_read_backwards flask flask-wtf flask-cors evdev python-xlib pillow spidev jsonpickle pydbus dbus-python

4. Clone the Plover repository and comment out PyQt5 and SIP from requirements_distribution. They will fail to install and need to be compiled from source, an 8+ hour process on the rpi0, if you want access to the Plover GUI. Luckily, they are redundant in our setup as the Stenogotchi runs headless.
4. Clone the Plover repository and comment out PyQt5 and SIP from requirements_distribution. They will fail to install and need to be compiled from source, an 8+ hour process on the RPI0w, if you want access to the Plover GUI. Luckily, they are redundant in our setup as the Stenogotchi runs headless.

git clone https://github.com/openstenoproject/plover.git
nano ./plover/requirements_distribution.txt
...
#PyQt5-sip==4.19.13
#PyQt5==5.11.3
...
git clone https://github.com/openstenoproject/plover.git
nano ./plover/requirements_distribution.txt
...
#PyQt5-sip==4.19.13
#PyQt5==5.11.3
...

5. [5min] Install Plover and plover-plugins

pip3 install --user -r ./plover/requirements.txt
pip3 install --user -e ./plover -r ./plover/requirements_plugins.txt --no-build-isolation
pip3 install --user -r ./plover/requirements.txt
pip3 install --user -e ./plover -r ./plover/requirements_plugins.txt --no-build-isolation

6. Clone the Stenogotchi repository and install the stenogotchi_link plover plugin

git clone https://github.com/Anodynous/stenogotchi.git
pip3 install ./stenogotchi/plover_plugin/
git clone https://github.com/Anodynous/stenogotchi.git
pip3 install ./stenogotchi/plover_plugin/

7. Add configuration file for the service used to communicate over D-Bus between Plover and Stenogotchi

cp ./stenogotchi/plover_plugin/stenogotchi_link/com.github.stenogotchi.conf /etc/dbus-1/system.d/
cp ./stenogotchi/plover_plugin/stenogotchi_link/com.github.stenogotchi.conf /etc/dbus-1/system.d/

8. Remove the input bluetooth plugin so that it does not grab the sockets we require access to. We make this the default behaviour by appending '-P input' to the pre-existing line in below service file.

nano /lib/systemd/system/bluetooth.service
nano /lib/systemd/system/bluetooth.service

#----------
ExecStart=/usr/lib/bluetooth/bluetoothd -P input
#----------
ExecStart=/usr/lib/bluetooth/bluetoothd -P input


9. Configure Plover and Stenogotchi to start at boot
Expand Down Expand Up @@ -122,7 +122,19 @@ All commands should be executed as root. The installation process can be complet
[Plugins]
enabled_extensions = ["stenogotchi_link"]

11. Significantly reduce boot time
11. Launch Stenogotchi manually for initial setup. Configure settings after reboot completes.

python3 ./stenogotchi/stenogotchi.py
nano /etc/stenogotchi/config.toml
#----------modify the config as you see fit----------#
main.plugins.buttonshim.enabled = true
main.plugins.upslite.enabled = true
main.plugins.evdevkb.enabled = true
main.plugins.plover_link.bt_autoconnect_mac = '00:DE:AD:BE:EF:00,11:DE:AD:BE:EF:11'
#----------

12. Significantly reduce boot time
* Set ARM initial turbo to the max (60s) under dietpi-config > performance options to reduce boot time. You can also play around with overclocking, throttling and cpu governor to find a suitable balance between performance and power draw.
* Disable dietpi and apt update check at boot:

Expand All @@ -132,30 +144,27 @@ All commands should be executed as root. The installation process can be complet
CONFIG_CHECK_DIETPI_UPDATES=0
CONFIG_CHECK_APT_UPDATES=0

* Disable waiting for network and time sync at boot (unless you always will have wifi available or need reliable timestamps in logs):
* Disable waiting for network and time sync at boot. Doing this you should be aware that the RPI0w does not have a hardware clock. It will lose track of real world time as soon it is powered off, making log timestamps or any time based action you may set up unreliable. None of this is important for the core functionality of the Stenogotchi and disabling time-sync at boot can shave up to a minute off the boot process. By adding a cheap I2C hardware clock you can completely remove the need for network sync. Many modules are small enough to fit in the empty space of the UPS-Lite or under the eINK screen [and are easy to wire](https://www.pishop.us/product/ds3231-real-time-clock-module-for-raspberry-pi/) and [set up](https://learn.adafruit.com/adding-a-real-time-clock-to-raspberry-pi/set-rtc-time). Just don't forget to isolate it with some tape.

nano /boot/dietpi.txt

#----------
CONFIG_BOOT_WAIT_FOR_NETWORK=0
CONFIG_NTP_MODE=0

12. Launch Stenogotchi once for initial setup (unless you already rebooted in previous step). Configure settings and reboot.

python3 ./stenogotchi/stenogotchi.py
nano /etc/stenogotchi/config.toml
#----------modify the config as you see fit----------#
main.plugins.evdevkb.enabled = true
main.plugins.buttonshim.enabled = true
main.plugins.plover_link.bt_autoconnect_mac = 'DE:AD:BE:EF'
#----------

reboot

## Configuration
- Configuration files are placed in /etc/stenogotchi/
- Create a file called config.toml with overrides to the defaults. Don't edit default.toml directly as it is overridden on version updates
* Configuration files are placed in /etc/stenogotchi/
* Create a file called config.toml with overrides to the defaults. Don't edit default.toml directly as it is overwritten on version updates.
* Define your bluetooth devices in main.plugins.plover_link.bt_autoconnect_mac for auto-connect upon boot. Multiple comma separated devices in order of preference can be given. If no connection attempts are successful, the device will fall back to listening for incoming connection attempts.
* Issues with pairing or connecting after changes in bluetooth configurations can usually be fixed by unpairing the devices and re-pairing. On the Stenogotchi this is handled through bluetoothctl.

bluetoothctl
[bluetooth]# paired-devices
Device 00:DE:AD:BE:EF:00 Anodynous' Ipad
[bluetooth]# remove 00:DE:AD:BE:EF:00
[bluetooth]# exit


## Usage
![stenogotchi_2](https://user-images.githubusercontent.com/17461433/107883149-d5539680-6ef5-11eb-86fe-41f0b6293eed.jpg)
Expand Down
7 changes: 4 additions & 3 deletions plover_plugin/setup.cfg
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[metadata]
name = stenogotchi_link
version = 0.0.3
description = A plugin for exposing Plover events and transmitting output to Stenogotchi
version = 0.0.4
description = A plugin for exposing Plover events and communicating with Stenogotchi over D-Bus
long_description =
author = Anodynous
author_email =
Expand All @@ -21,9 +21,10 @@ keywords = plover plover_plugin stenogotchi
zip_safe = True
install_requires =
plover>=4.0.0.dev8
jsonlib-python3
jsonpickle
dbus-python
textstat
PyGObject
packages =
stenogotchi_link

Expand Down
16 changes: 9 additions & 7 deletions plover_plugin/stenogotchi_link/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def _setup_object(self):
dbus_interface=SERVER_DBUS,
signal_name='signal_to_plover')
except dbus.exceptions.DBusException as e:
logging.error(f'Failed to initialize D-Bus object: {str(e)}')
logging.error(f'[stenogotchi_link] Failed to initialize D-Bus object: {str(e)}')

def _exit(self):
self._mainloop.quit()
Expand Down Expand Up @@ -75,15 +75,17 @@ def plover_strokes_stats(self, s):
def stenogotchi_signal_handler(self, dict):
# Enable and disable wpm/strokes meters
if 'start_wpm_meter' in dict:
logging.debug('Starting WPM meter')
wpm_method = dict['wpm_method']
wpm_timeout = int(dict['wpm_timeout'])
logging.info('[stenogotchi_link] Starting WPM meter')
if dict['start_wpm_meter'] == 'wpm and strokes':
self._engineserver.start_wpm_meter(enable_wpm=True, enable_strokes=True)
self._engineserver.start_wpm_meter(enable_wpm=True, enable_strokes=True, wpm_method=wpm_method, wpm_timeout=wpm_timeout)
elif dict['start_wpm_meter'] == 'wpm':
self._engineserver.start_wpm_meter(enable_wpm=True, enable_strokes=False)
self._engineserver.start_wpm_meter(enable_wpm=True, enable_strokes=False, wpm_method=wpm_method, wpm_timeout=wpm_timeout)
elif dict['start_wpm_meter'] == 'strokes':
self._engineserver.start_wpm_meter(enable_wpm=False, enable_strokes=True)
self._engineserver.start_wpm_meter(enable_wpm=False, enable_strokes=True, wpm_method=wpm_method, wpm_timeout=wpm_timeout)
if 'stop_wpm_meter' in dict:
logging.debug('Stopping WPM meter')
logging.info('[stenogotchi_link] Stopping WPM meter')
if dict['stop_wpm_meter'] == 'wpm and strokes':
self._engineserver.stop_wpm_meter(disable_wpm=True, disable_strokes=True)
elif dict['stop_wpm_meter'] == 'wpm':
Expand Down Expand Up @@ -170,7 +172,7 @@ def send_plover_keycode(self, keycode, modifiers=0):
# if (modifiers & (1 << n))
#]
if modifiers > 1:
logging.debug("Modifier received: " + str(modifiers) +" keycode" + str(keycode))
logging.debug("[stenogotchi_link] Modifier received: " + str(modifiers) +" keycode" + str(keycode))
# Update modifier keys
#for mod_keycode in modifiers_list:
# self.update_mod_keys(plover_modkey(mod_keycode), 1)
Expand Down
34 changes: 17 additions & 17 deletions plover_plugin/stenogotchi_link/stenogotchi_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def __init__(self, engine: StenoEngine) -> None:
def start(self):
""" Starts the server. """
self._connect_hooks()
logging.debug("Plover_link started")
logging.info("[stenogotchi_link] Plover_link started")
self._stenogotchiclient.plover_is_running(True)

# Called when Plover exits or user disables the extension
Expand All @@ -47,13 +47,13 @@ def stop(self):
self._disconnect_hooks()
self._stenogotchiclient.plover_is_running(False)

def start_wpm_meter(self, enable_wpm=False, enable_strokes=False, method='ncra'):
def start_wpm_meter(self, enable_wpm=False, enable_strokes=False, wpm_method='ncra', wpm_timeout=60):
""" Starts WPM and/or Strokes meters
"""
if enable_wpm:
self._wpm_meter = PloverWpmMeter(stenogotchi_link=self, wpm_method=method)
self._wpm_meter = PloverWpmMeter(stenogotchi_link=self, wpm_method=wpm_method, timeout=wpm_timeout)
if enable_strokes:
self._strokes_meter = PloverStrokesMeter(stenogotchi_link=self, strokes_method=method)
self._strokes_meter = PloverStrokesMeter(stenogotchi_link=self, strokes_method=wpm_method, timeout=wpm_timeout)

def stop_wpm_meter(self, disable_wpm=True, disable_strokes=True):
if disable_wpm:
Expand All @@ -64,12 +64,12 @@ def stop_wpm_meter(self, disable_wpm=True, disable_strokes=True):
self._strokes_meter = None

def _on_wpm_meter_update_strokes(self, stats):
""" Sends strokes stats from past 1 min to stenogotchi as a string """
self._stenogotchiclient.plover_strokes_stats(stats['strokes60'])
""" Sends strokes stats to stenogotchi as a string """
self._stenogotchiclient.plover_strokes_stats(stats['strokes_user'])

def _on_wpm_meter_update_wpm(self, stats):
""" Sends wpm stats from past 1 min to stenogotchi as a string """
self._stenogotchiclient.plover_wpm_stats(stats['wpm60'])
""" Sends wpm stats to stenogotchi as a string """
self._stenogotchiclient.plover_wpm_stats(stats['wpm_user'])

def get_server_status(self):
"""Gets the status of the server.
Expand All @@ -82,7 +82,7 @@ def _connect_hooks(self):
"""Creates hooks into all of Plover's events."""

if not self._engine:
logging.debug(ERROR_MISSING_ENGINE)
logging.error(f'[stenogotchi_link] {ERROR_MISSING_ENGINE}')
raise AssertionError(ERROR_MISSING_ENGINE)

for hook in self._engine.HOOKS:
Expand Down Expand Up @@ -138,7 +138,7 @@ def _on_output_changed(self, enabled: bool):
"""

data = {'output_changed': enabled}
logging.debug(data)
logging.debug(f'[stenogotchi_link] _on_output_changed data: {data}')
self._stenogotchiclient.plover_output_enabled(enabled)


Expand All @@ -152,7 +152,7 @@ def _on_config_changed(self, config_update: Config):
config_json = jsonpickle.encode(config_update, unpicklable=False)

data = {'config_changed': json.loads(config_json)}
logging.debug(data)
logging.debug(f'[stenogotchi_link] _on_config_changed data: {data}')

def _on_dictionaries_loaded(self, dictionaries: StenoDictionaryCollection):
"""Broadcasts when all of the dictionaries get loaded.
Expand Down Expand Up @@ -187,39 +187,39 @@ def _on_send_key_combination(self, combination: str):
"""

data = {'send_key_combination': combination}
logging.debug(data)
logging.debug(f'[stenogotchi_link] _on_send_key_combination data: {data}')

def _on_add_translation(self):
"""Broadcasts when the add translation tool is opened via a command."""

data = {'add_translation': True}
logging.debug(data)
logging.debug(f'[stenogotchi_link] _on_add_translation data: {data}')

def _on_focus(self):
"""Broadcasts when the main window is focused via a command."""

data = {'focus': True}
logging.debug(data)
logging.debug(f'[stenogotchi_link] _on_focus data: {data}')

def _on_configure(self):
"""Broadcasts when the configuration tool is opened via a command."""

data = {'configure': True}
logging.debug(data)
logging.debug(f'[stenogotchi_link] _on_configure data: {data}')

def _on_lookup(self):
"""Broadcasts when the lookup tool is opened via a command."""

data = {'lookup': True}
logging.debug(data)
logging.debug(f'[stenogotchi_link] _on_lookup data: {data}')

def _on_quit(self):
"""Broadcasts when the application is terminated.
Can be either a full quit or a restart.
"""

data = {'quit': True}
logging.debug(data)
logging.debug(f'[stenogotchi_link] _on_quit data: {data}')
self._stenogotchiclient.plover_is_running(False)


Expand Down
Loading

0 comments on commit 41c1c93

Please sign in to comment.