<commit_before># pydPiper ![splash](displays/images/pydPiper_splash.png)
A python program written for the Raspberry Pi that controls small LCD and OLED screens for music distributions like Volumio, MoodeAudio, and Max2Play.

![Playing Example](displays/images/example_playing_album.png)![Time Temp Example](displays/images/example_time.png)

## Features
  * Supports multiple music distributions including Volumio (v1 and v2), MoodeAudio, and Max2Play
	* Runs inside a Docker container to increase stability.  This decouples pydPiper from the distribution you run it on.
  * Screens are fully user definable
  * Supports a rich set of system and environmental variables including local weather
  * Compatible with the Winstar WEH and WEG OLED displays
  * Compatible with HD44780 style LCD displays (both I2C and Parallel interface)
	* Compatible with SSD1306 style displays (I2C only)
  * Fully graphics based in its backend allowing any arbritrary font, character set, or image to be displayed if the hardware supports it.
	* For LCD character based displays will dynamically generate custom characters to support characters missing from the font table.  This feature can also be used to display some graphical content on character-based displays though this is limited by the small amount of memory available for customer characters on HD44780 based displays.
  * NEW! A configure function is not included to allow pydPiper to easily be set up for different displays and music distributions

## Display configuration

pydPiper now has standard page files for the displays that it supports.  If the standard display configurations do not meet your needs, you can create your own.  You will need to understand how the pages file system works to accomplish this.

pydPiper displays are configured based upon three key concepts.  The first concept is the widget.  Widgets are used to draw a particular type of content on onto the screen.  There are widgets for displaying text, drawing lines and rectangles, displaying images, or showing a progress bar.  The next concept is the  canvas.  Canvases are collections of widgets where each widget is placed at a particular place within the canvas.  You will typically create a set of canvases that are the same size as your display with each canvas dedicated to a particular display purpose (e.g. show artist, display time).  The last concept is sequences.  A sequence is an ordered list of canvases that are displayed in turn when the sequence is activated.  There should be a sequence for each mode that the music player uses (e.g. play, stop).  Sequences are controlled through conditional expressions which are boolean logic statements.  If the statement evaluates to True, the sequence is activated.  If it is false, the sequence remains dormant.  In addition, each canvas within a sequence can also have a conditional statement to control whether the canvas gets displayed when its turn within the sequence occurs.  Here is a short example.

FONTS = {
	'normal': { 'default':True, 'file':'latin1_5x8_fixed.fnt','size':(5,8) },
}

WIDGETS = {
	'artist': { 'type':'text', 'format':'{0}', 'variables':['artist'], 'font':'normal' },
	'title': { 'type':'text', 'format':'{0}', 'variables':['title'], 'font':'normal' },
  'time': { 'type':'text', 'format:Time\n{0}', 'variables':['utc|timezone+US/Eastern|strftime+%-I:%M'], 'just':'center', 'size':(80,16) }
 }

CANVASES = {
	'playingsong': { 'widgets': [ ('artist',0,0), ('title',0,8) ], 'size':(80,16) },
}

SEQUENCES = [
	{
		'name': 'seqPlay',
		'canvases': [ { 'name':'playingsong', 'duration':15 } ],
		'conditional': "db['state']=='play'"
	},
	{
		'name': 'seqStop',
		'canvases': [ { 'name':'time', 'duration':9999 } ],
		'conditional': "db['state']=='stop'"
  }
]

This simple example will display the artist on the top line and the title on the bottom line of the display if the system is playing a song.  If the player is stopped, it will display the current time centered on the display.  Full documentation for configuring the display will be found in docs/display.md once I've written it.

Standard display configurations are available

| page file           | Appropriate for       |
| ------------------- | --------------------- |
| pages_weh_80x16.py  | Winstar WEH displays  |
| pages_weg_100x16.py | Winstar WEG displays  |
| pages_lcd_16x2.py   | HD44780 16x2 displays |
| pages_lcd_20x4.py   | HD44780 20x4 displays |

## Installation Instructions

These instructions provide a general description of what you need to do in order to get pydPiper up and running on your system.  Instructions specific to individual music distributions will eventually be provided in the docs directory.

#### Step 1.  Download pydPiper to your system
Log in to your system and issue the following commands to download the software and place it within your home directory.  If you prefer to place it somewhere else, modify the location you untar it from accordingly.

```
sudo wget https://github.com/dhrone/pydPiper/archive/v0.3-alpha.tar.gz
sudo tar zxvf v0.3-alpha.tar.gz
cd pydPiper-0.3-alpha<commit_msg>[README] formatting for example configuration<commit_after># pydPiper ![splash](displays/images/pydPiper_splash.png)
A python program written for the Raspberry Pi that controls small LCD and OLED screens for music distributions like Volumio, MoodeAudio, and Max2Play.

![Playing Example](displays/images/example_playing_album.png)![Time Temp Example](displays/images/example_time.png)

## Features
  * Supports multiple music distributions including Volumio (v1 and v2), MoodeAudio, and Max2Play
	* Runs inside a Docker container to increase stability.  This decouples pydPiper from the distribution you run it on.
  * Screens are fully user definable
  * Supports a rich set of system and environmental variables including local weather
  * Compatible with the Winstar WEH and WEG OLED displays
  * Compatible with HD44780 style LCD displays (both I2C and Parallel interface)
	* Compatible with SSD1306 style displays (I2C only)
  * Fully graphics based in its backend allowing any arbritrary font, character set, or image to be displayed if the hardware supports it.
	* For LCD character based displays will dynamically generate custom characters to support characters missing from the font table.  This feature can also be used to display some graphical content on character-based displays though this is limited by the small amount of memory available for customer characters on HD44780 based displays.
  * NEW! A configure function is not included to allow pydPiper to easily be set up for different displays and music distributions

## Display configuration

pydPiper now has standard page files for the displays that it supports.  If the standard display configurations do not meet your needs, you can create your own.  You will need to understand how the pages file system works to accomplish this.

pydPiper displays are configured based upon three key concepts.  The first concept is the widget.  Widgets are used to draw a particular type of content on onto the screen.  There are widgets for displaying text, drawing lines and rectangles, displaying images, or showing a progress bar.  The next concept is the  canvas.  Canvases are collections of widgets where each widget is placed at a particular place within the canvas.  You will typically create a set of canvases that are the same size as your display with each canvas dedicated to a particular display purpose (e.g. show artist, display time).  The last concept is sequences.  A sequence is an ordered list of canvases that are displayed in turn when the sequence is activated.  There should be a sequence for each mode that the music player uses (e.g. play, stop).  Sequences are controlled through conditional expressions which are boolean logic statements.  If the statement evaluates to True, the sequence is activated.  If it is false, the sequence remains dormant.  In addition, each canvas within a sequence can also have a conditional statement to control whether the canvas gets displayed when its turn within the sequence occurs.  Here is a short example.

```
FONTS = {
	'normal': { 'default':True, 'file':'latin1_5x8_fixed.fnt','size':(5,8) },
}

WIDGETS = {
	'artist': { 'type':'text', 'format':'{0}', 'variables':['artist'], 'font':'normal' },
	'title': { 'type':'text', 'format':'{0}', 'variables':['title'], 'font':'normal' },
  'time': { 'type':'text', 'format:Time\n{0}', 'variables':['utc|timezone+US/Eastern|strftime+%-I:%M'], 'just':'center', 'size':(80,16) }
 }

CANVASES = {
	'playingsong': { 'widgets': [ ('artist',0,0), ('title',0,8) ], 'size':(80,16) },
}

SEQUENCES = [
	{
		'name': 'seqPlay',
		'canvases': [ { 'name':'playingsong', 'duration':15 } ],
		'conditional': "db['state']=='play'"
	},
	{
		'name': 'seqStop',
		'canvases': [ { 'name':'time', 'duration':9999 } ],
		'conditional': "db['state']=='stop'"
  }
]
```

This simple example will display the artist on the top line and the title on the bottom line of the display if the system is playing a song.  If the player is stopped, it will display the current time centered on the display.  Full documentation for configuring the display will be found in docs/display.md once I've written it.

Standard display configurations are available

| page file           | Appropriate for       |
| ------------------- | --------------------- |
| pages_weh_80x16.py  | Winstar WEH displays  |
| pages_weg_100x16.py | Winstar WEG displays  |
| pages_lcd_16x2.py   | HD44780 16x2 displays |
| pages_lcd_20x4.py   | HD44780 20x4 displays |

## Installation Instructions

These instructions provide a general description of what you need to do in order to get pydPiper up and running on your system.  Instructions specific to individual music distributions will eventually be provided in the docs directory.

#### Step 1.  Download pydPiper to your system
Log in to your system and issue the following commands to download the software and place it within your home directory.  If you prefer to place it somewhere else, modify the location you untar it from accordingly.

```
sudo wget https://github.com/dhrone/pydPiper/archive/v0.3-alpha.tar.gz
sudo tar zxvf v0.3-alpha.tar.gz
cd pydPiper-0.3-alpha
{'fraction_non_alphanumeric': 0.0897560975609756, 'fraction_numerical': 0.016390243902439025, 'mean_word_length': 4.403795466526094, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7091135', 'n_tokens_mistral': 2919, 'n_tokens_neox': 2744, 'n_words': 1317}