Skip to content

Commit a8576d9

Browse files
author
fwmone
committed
First release
1 parent a52fc8a commit a8576d9

11 files changed

Lines changed: 787 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/).
7+
8+
## [0.1.0] - 2026-02-03
9+
10+
### Added
11+
12+
- Initial release of the paperlesspaper Push custom integration.

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2026 Falk
3+
Copyright (c) 2026 F. Müller
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
# 📖 Table of content
2+
3+
- [📖 Table of content](#-table-of-content)
4+
- [Features](#features)
5+
- [📦 Installation](#-installation)
6+
- [Option A: Installation via HACS (recommended)](#option-a-installation-via-hacs-recommended)
7+
- [Option B: Manual installation](#option-b-manual-installation)
8+
- [Configuration](#configuration)
9+
- [Folder Setup](#folder-setup)
10+
- [Input directory](#input-directory)
11+
- [Publish directory (optional)](#publish-directory-optional)
12+
- [Entities](#entities)
13+
- [Sensor](#sensor)
14+
- [State:](#state)
15+
- [Attributes:](#attributes)
16+
- [Services](#services)
17+
- [Automation Examples](#automation-examples)
18+
- [API / Upload Method](#api--upload-method)
19+
- [Troubleshooting](#troubleshooting)
20+
- [Upload succeeds but frame shows old image](#upload-succeeds-but-frame-shows-old-image)
21+
- [Blocking calls in logs](#blocking-calls-in-logs)
22+
- [Roadmap / Ideas](#roadmap--ideas)
23+
- [Support / Issues](#support--issues)
24+
- [License](#license)
25+
- [🙏 Note](#-note)
26+
27+
# Features
28+
29+
A small Home Assistant custom integration to **upload images from the Home Assistant server to a Paperlesspaper e-paper frame** using the WireWire API. The integration is designed to work well with Home Assistant automations (e.g. upload a new image twice a day), and provides a *“varied random”* image selection that avoids repeating the same images too often.
30+
31+
- Upload a random image from an input folder to a Paperlesspaper frame via API
32+
- "Varied random" selection:
33+
- remembers recently used images
34+
- recent-window size = **50% of available images** (min 5, max 50)
35+
- avoids repetition until the pool is exhausted
36+
- Optional publish/copy of the selected image into `/config/www/...` for preview/debugging
37+
- Optional cleanup of the publish directory before publishing
38+
- Robust upload retries with exponential backoff
39+
- Home Assistant sensor showing:
40+
- last upload timestamp
41+
- current file name
42+
- last result (success/failed/dry_run)
43+
- last HTTP status / error
44+
45+
# 📦 Installation
46+
47+
## Option A: Installation via HACS (recommended)
48+
49+
1. Open **HACS → Integrations**
50+
2. Click on **“Custom Repositories”**
51+
3. Add this repository: https://github.com/fwmone/paperlesspaper_push, Category: **Integration**
52+
4. Install **paperlesspaper Push**
53+
5. Restart Home Assistant
54+
55+
## Option B: Manual installation
56+
57+
1. Download this repository
58+
2. Copy the custom_components/paperlesspaper_push folder to: <config>/custom_components/paperlesspaper_push (this is usually /config)
59+
3. Restart Home Assistant
60+
61+
# Configuration
62+
63+
This integration currently uses YAML configuration.
64+
65+
Add this to your `configuration.yaml`:
66+
67+
```yaml
68+
paperlesspaper_push:
69+
api_key: !secret paperlesspaper_api_key
70+
paper_id: !secret paperlesspaper_paper_id
71+
72+
# optional:
73+
base_url: https://api.memo.wirewire.de/v1
74+
input_dir: /media/picture-frames/paperlesspaper
75+
publish_dir: /config/www/picture-frames/paperlesspaper
76+
timeout: 30
77+
max_attempts: 4
78+
publish: true
79+
```
80+
81+
Add the secrets to secrets.yaml:
82+
83+
```yaml
84+
paperlesspaper_api_key: "YOUR_API_KEY"
85+
paperlesspaper_paper_id: "YOUR_PAPER_ID"
86+
```
87+
88+
Restart Home Assistant after changing YAML.
89+
90+
## Folder Setup
91+
### Input directory
92+
93+
Place images in ```/media/picture-frames/paperlesspaper```.
94+
95+
Supported formats:
96+
- .png
97+
- .jpg / .jpeg
98+
99+
### Publish directory (optional)
100+
101+
If enabled, the integration copies the chosen image to: ```/config/www/picture-frames/paperlesspaper```.
102+
103+
This is useful for debugging or previewing the selected image from Home Assistant (served under /local/...).
104+
105+
# Entities
106+
## Sensor
107+
108+
```sensor.paperlesspaper_push_status```
109+
110+
### State:
111+
112+
- never or last upload timestamp (UTC ISO format)
113+
114+
### Attributes:
115+
116+
- current_filename
117+
- last_result
118+
- last_http_status
119+
- last_error
120+
- published_name
121+
122+
## Services
123+
```paperlesspaper_push.upload_random```
124+
125+
Uploads a (varied) random image.
126+
127+
Example:
128+
129+
```yaml
130+
service: paperlesspaper_push.upload_random
131+
data:
132+
dry_run: false
133+
publish: true
134+
```
135+
136+
Fields:
137+
- dry_run (bool, optional): select/publish only, do not upload
138+
- publish (bool, optional): publish/copy the chosen file to publish_dir
139+
- force_file (string, optional): force a specific file name from the input folder
140+
141+
```paperlesspaper_push.reset_recent```
142+
143+
Clears the internal "recent images" history list.
144+
145+
Example:
146+
147+
```yaml
148+
service: paperlesspaper_push.reset_recent
149+
```
150+
151+
## Automation Examples
152+
153+
Upload twice per day:
154+
155+
```yaml
156+
alias: Paperlesspaper Upload Morning
157+
trigger:
158+
- platform: time
159+
at: "05:45:00"
160+
action:
161+
- service: paperlesspaper_push.upload_random
162+
163+
---
164+
165+
alias: Paperlesspaper Upload Afternoon
166+
trigger:
167+
- platform: time
168+
at: "16:45:00"
169+
action:
170+
- service: paperlesspaper_push.upload_random
171+
```
172+
173+
# API / Upload Method
174+
175+
The upload is performed using a multipart form-data request similar to:
176+
177+
```bash
178+
curl -X POST "https://api.memo.wirewire.de/v1/papers/uploadSingleImage/<PAPER_ID>" \
179+
-H "x-api-key: <API_KEY>" \
180+
-F "picture=@/path/to/image.png;type=image/png"
181+
```
182+
183+
# Troubleshooting
184+
## Upload succeeds but frame shows old image
185+
186+
The Paperlesspaper frame pulls images from the cloud in configurable intervals.
187+
Make sure the device is configured to wake up and fetch images.
188+
189+
## Blocking calls in logs
190+
191+
This integration avoids blocking filesystem operations inside the event loop by using Home Assistant's executor helpers.
192+
193+
If you still see blocking call warnings, please open an issue with logs.
194+
195+
# Roadmap / Ideas
196+
- Config Flow (UI-based configuration)
197+
- Additional sensors (e.g. success/failure binary sensor)
198+
- Optional "keep last N published images" instead of cleaning publish_dir fully
199+
- Support multiple Paper IDs
200+
201+
# Support / Issues
202+
203+
Please open issues on GitHub if you encounter bugs or have feature requests.
204+
205+
# License
206+
207+
This project is licensed under the terms of the MIT License.
208+
209+
# 🙏 Note
210+
211+
This integration has no official connection to the manufacturer of paperlesspaper frames.

0 commit comments

Comments
 (0)