Skip to content

Commit bbb9dad

Browse files
authored
Merge branch 'next' into peblar-hardware-conditional-entities
2 parents c2f2947 + 7431154 commit bbb9dad

834 files changed

Lines changed: 42432 additions & 6062 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/create-blog-post/SKILL.md

Lines changed: 94 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ Automates conversion of a draft markdown file with metadata into a production-re
3030
## Required Files in `create-blog-post/` Directory
3131

3232
1. **Draft markdown file** (any .md filename)
33-
2. **`art.webp`** - Hero/OG image (required)
34-
3. **`image2.png`, `image3.png`, etc.** - Additional images (optional, will be converted to WebP)
33+
2. **`art.*`** - Hero/OG image (required, any common image format: `.webp`, `.png`, `.jpg`, `.jpeg`)
34+
3. **`image2.*`, `image3.*`, etc.** - Additional images (optional, any common image format)
3535

3636
## Draft File Format
3737

@@ -84,32 +84,63 @@ Creates a production-ready blog post at:
8484

8585
## Conversion Process
8686

87-
### 1. Parse Metadata
87+
### 1. Pre-process Draft
88+
89+
Before doing anything else, strip out embedded base64 image data from the draft file using a shell command. **Do not read the draft file before this step** — the base64 data can make the file extremely large.
90+
91+
Google Docs markdown exports include image references like `![][image1]` in the content body, with corresponding base64 definitions at the bottom of the file in the format:
92+
93+
```text
94+
[image1]: <data:image/png;base64,iVBORw0KGgo... (potentially megabytes of data)>
95+
```
96+
97+
Run this `sed` command via the Bash tool to strip them in-place:
98+
99+
```shell
100+
sed -i '/^\[image[0-9]*\]: <data:/d' "create-blog-post/draft.md"
101+
```
102+
103+
- This removes all lines matching the base64 image definition pattern
104+
- The `![][image1]` references in the content body are preserved — they will be replaced with proper image paths later
105+
- Only after this command completes should you read the draft file
106+
107+
### 2. Parse Metadata
88108

89109
- Extract blog title, author, publish date, category (convert to YAML list), Social/OpenGraph title and description
90110
- Auto-generate URL slug from blog title (lowercase, hyphens for spaces, remove special characters)
91111
- Remove "# Blog notes/preparations" section and all content under it (up to "# Blog content")
92112
- Remove all lines that start with ☝️ emoji (instruction lines)
93113
- Convert `### **– Summary break / Read more –**` marker to `<!--more-->`
94114

95-
### 2. Process Images
115+
### 3. Process Images
116+
117+
Before processing images, ensure the `cwebp` tool is installed. If not, install it:
118+
119+
```shell
120+
# Check if cwebp is available, install if missing
121+
which cwebp || sudo apt-get install -y webp
122+
```
96123

97-
**Hero image (`art.webp`):**
124+
**Hero image (`art.*`):**
98125

99-
- Move to `source/images/blog/YYYY-MM-slug/art.webp`
126+
- Find the `art` image in `create-blog-post/` (any extension: `.webp`, `.png`, `.jpg`, `.jpeg`)
127+
- If the source is already `.webp`, copy it to `source/images/blog/YYYY-MM-slug/art.webp`
128+
- If the source is any other format, convert to WebP: `cwebp -resize 1200 630 -q 85 input -o source/images/blog/YYYY-MM-slug/art.webp`
129+
- The OG image must be exactly 1200x630 pixels — the source image should already be this size, so use `-resize 1200 630` to ensure correctness
100130
- Replace `![][image1]` reference in "# Blog content" section with: `<img src="/images/blog/YYYY-MM-slug/art.webp" alt="Blog Title" style="border: 0;box-shadow: none;">`
101131
- CRITICAL: Use double quotes for all HTML attributes (prevents breaking on apostrophes in alt text)
102132
- Alt text uses the Social/OpenGraph title or blog title
103133
- No wrapper tags (no `<p>` tag)
104134

105135
**Additional images (if any):**
106136

107-
- Find `image2.png`, `image3.png`, etc. in `create-blog-post/` directory
108-
- Convert to WebP: `cwebp -resize 900 0 -q 85 input.png -o output.webp`
109-
- Move to `source/images/blog/YYYY-MM-slug/`
137+
- Find `image2.*`, `image3.*`, etc. in `create-blog-post/` (any extension: `.webp`, `.png`, `.jpg`, `.jpeg`)
138+
- Convert to WebP with a max width of 900px: `cwebp -resize 900 0 -q 85 input -o output.webp` (the `0` for height preserves the aspect ratio)
139+
- If the source is already `.webp`, still re-encode it with the resize: `cwebp -resize 900 0 -q 85 input.webp -o output.webp`
140+
- Output to `source/images/blog/YYYY-MM-slug/image2.webp`, `image3.webp`, etc.
110141
- Update references in content
111142

112-
### 3. Transform Links
143+
### 4. Transform Links
113144

114145
**External links** (different domains/subdomains):
115146

@@ -120,13 +151,28 @@ Creates a production-ready blog post at:
120151

121152
- Keep as Markdown links: `[text](/path)`
122153

123-
### 4. Clean Content
154+
### 5. Device List (Works with Home Assistant posts only)
155+
156+
If the blog post category is `Works-with-Home-Assistant`, look for a section that lists certified/supported devices. Replace any manually written device list with the dynamic device list shortcode:
157+
158+
```liquid
159+
{% include integrations/device_list.html brand="brandname" %}
160+
```
161+
162+
- The `brand` value must match a brand in `source/_data/wwha_devices.json` (for example: `"eve"`, `"heatit"`, `"shelly"`, `"zooz"`)
163+
- The brand name is typically the lowercase company/brand name from the draft
164+
- If the draft contains a manually listed set of devices (often as a bullet list or table), replace that list with the shortcode
165+
- Keep any introductory or closing text around the device list — only replace the list itself
166+
167+
### 6. Clean Content
124168

125169
- **Headings**: Remove bold formatting (`## **Title**``## Title`)
126170
- **Heading levels**: If content starts with H1 (`#`), demote all headings one level (content should start at H2)
127171
- **Backticks**: Strip erroneous `\`` characters (preserve code blocks/inline code)
172+
- **Text content**: Do not change the author's wording, phrasing, or writing style. The blog text should stay as-is. If you spot obvious typos or locale spelling issues (such as British English instead of American English), do not fix them silently — collect them and ask the user for confirmation before applying any changes.
173+
- **Emojis**: Preserve all emojis that appear in the blog content. Do not strip them out.
128174

129-
### 5. Build Blog Post
175+
### 7. Build Blog Post
130176

131177
- Create `source/_posts/YYYY-MM-DD-slug.markdown`
132178
- Jekyll front matter (layout, title, description, date, date_formatted, author, categories, og_image)
@@ -153,21 +199,29 @@ This would create:
153199

154200
**Image references:**
155201

156-
- Draft: `![][image1]` (at start of "# Blog content" section) → Output: `art.webp` hero image
157-
- Draft: `![][image2]` → Look for `image2.png`, convert to `image2.webp`
158-
- Draft: `![][image3]` → Look for `image3.png`, convert to `image3.webp`
202+
- Draft: `![][image1]` (at start of "# Blog content" section) → Output: `art.webp` hero image (1200x630, OG image)
203+
- Draft: `![][image2]` → Look for `image2.*` (any format), convert to `image2.webp` (max 900px wide)
204+
- Draft: `![][image3]` → Look for `image3.*` (any format), convert to `image3.webp` (max 900px wide)
205+
- Source images can be any common format (`.webp`, `.png`, `.jpg`, `.jpeg`) — all are converted/re-encoded to `.webp`
159206

160207
**Requirements:**
161208

162209
- Hero image reference should appear at the start of the "# Blog content" section
163-
- `cwebp` tool required for PNG→WebP conversion (install: `sudo apt-get install -y webp`)
210+
- `cwebp` tool is required — the skill will auto-install it via `sudo apt-get install -y webp` if not already present
164211

165212
**Content processing:**
166213

167214
- Remove "# Blog notes/preparations" section entirely
168215
- Remove all lines starting with ☝️ emoji (instruction lines)
169216
- Convert `### **– Summary break / Read more –**` to `<!--more-->`
170217

218+
**Device lists (Works with Home Assistant posts):**
219+
220+
- WWHA blog posts (category `Works-with-Home-Assistant`) typically include a list of certified devices in the draft (as bullet points, tables, or similar)
221+
- Strip out the manually written device list entirely and replace it with: `{% include integrations/device_list.html brand="brandname" %}`
222+
- The `brand` value must match an entry in `source/_data/wwha_devices.json` — verify the brand exists in that file before using it
223+
- Keep any surrounding text that introduces or follows the device list (for example "Here's what's made the cut from Heatit:") — only replace the device list itself
224+
171225
**Output format:**
172226

173227
- Filename: `YYYY-MM-DD-slug.markdown`
@@ -178,3 +232,27 @@ This would create:
178232

179233
- Only `www.home-assistant.io` and `home-assistant.io` stay as Markdown links
180234
- All other domains/subdomains → HTML `<a>` tags with `target="_blank" rel="noopener"`
235+
236+
## Post-processing summary
237+
238+
After the blog post has been created, output a summary to the user covering:
239+
240+
**Metadata:**
241+
- Title, author (and whether they were verified in `people.yml`), date, category
242+
243+
**Images:**
244+
- Each source image, its original dimensions/format, and where it was output (with the conversion applied)
245+
246+
**Content transformations:**
247+
- A bulleted list of every notable transformation applied, such as:
248+
- Sections/content removed (base64 data, blog template, notes, instruction lines)
249+
- Image references replaced
250+
- Summary break conversion
251+
- Device list replacement (if WWHA, including brand used and number of devices)
252+
- Link conversions (external to HTML, internal to relative markdown)
253+
- Quote/blockquote formatting
254+
- Heading changes (reformatted, promoted/demoted, bold removed)
255+
- Escape character cleanup
256+
257+
**Proposed text changes (requires user approval):**
258+
- If any typos or locale spelling issues were spotted (such as British to American English), list each one and ask the user whether to apply them. Do not apply these changes until the user confirms.

.github/ISSUE_TEMPLATE/feedback.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ body:
3838
label: Version
3939
placeholder: "e.g., 2022.7.0"
4040
description: >
41-
Latest stable version version of Home Assistant available
41+
Latest stable version of Home Assistant available
4242
(which does not have to match the version you are using).
4343
- type: textarea
4444
attributes:

.github/copilot-instructions.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,8 @@ Some other rules:
8888
- Don’t use semicolons, commas, or conjunctions (like and or or) at the end
8989
of list items.
9090
- If at least one item in a list is a complete sentence, use periods at the end
91-
of all items in that list.
92-
- Don’t use a period at the end of list items if none of the items are complete
93-
sentences.
91+
of all items in that list, even if not all items are complete sentences.
92+
- Don’t use a period at the end of list items if none of the items in the list are complete sentences.
9493

9594
## Terminology
9695

@@ -245,24 +244,22 @@ Timeframe:
245244

246245
## Supported functionality
247246

248-
### Entities
249-
250247
The **My integration** integration provides the following entities.
251248

252-
#### Buttons
249+
### Buttons
253250

254251
- **Start backflush**
255252
- **Description**: Starts the backflush process on your machine. You got 15 seconds to turn the paddle after activation.
256253
- **Available for machines**: all
257254

258-
#### Numbers
255+
### Numbers
259256

260257
- **Dose**
261258
- **Description**: Dosage (in ticks) for each key
262259
- **Available for machines**: GS3 AV, Linea Mini.
263260
- **Remarks**: GS3 has this multiple times, one for each physical key (1-4), and the entities are disabled by default.
264261

265-
#### Sensors
262+
### Sensors
266263

267264
- **Current coffee temperature**
268265
- **Description**: Current temperature of the coffee boiler.
@@ -274,7 +271,7 @@ The **My integration** integration provides the following entities.
274271
- **Available for machines**: Linea Micra, GS3 AV, GS3 MP.
275272
- **Remarks**: -
276273

277-
#### Selects
274+
### Selects
278275

279276
- **Prebrew/-infusion mode**
280277
- **Description**: Whether to use prebrew, preinfusion, or neither.
@@ -286,7 +283,7 @@ The **My integration** integration provides the following entities.
286283
- **Options**: 1, 2, 3
287284
- **Available for machines**: Linea Micra
288285

289-
#### Updates
286+
### Updates
290287

291288
- **Gateway firmware**
292289
- **Description**: Firmware status of the gateway.

.github/workflows/restrict-task-creation.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
if: github.event.issue.type.name == 'Task'
1313
steps:
1414
- name: Check if user is authorized
15-
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
15+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1616
with:
1717
script: |
1818
const issueAuthor = context.payload.issue.user.login;

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
- name: Check out files from GitHub
1111
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
1212
- name: Setting up Node.js
13-
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
13+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
1414
with:
1515
node-version: 20
1616
cache: "npm"
@@ -37,7 +37,7 @@ jobs:
3737
- name: Check out files from GitHub
3838
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3939
- name: Setting up Node.js
40-
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
40+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
4141
with:
4242
node-version: 20
4343
cache: "npm"

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ source/.jekyll-metadata
2626
!.vscode/tasks.json
2727
*.suo
2828
tags*
29-
create-blog-post
29+
/create-blog-post

.textlintrc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"homeassistant:",
99
"homekit:",
1010
"led:",
11+
"mqtt:",
1112
"sms:",
1213
"sql:",
1314
"ssl:",

CODEOWNERS

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,6 @@ source/_integrations/qnap.markdown @disforw
792792
source/_integrations/qnap_qsw.markdown @Noltari
793793
source/_integrations/quadrafire.markdown @jeeftor
794794
source/_integrations/quantum_gateway.markdown @cisasteelersfan
795-
source/_integrations/qube_heatpump.markdown @MattieGit
796795
source/_integrations/qvr_pro.markdown @oblogic7
797796
source/_integrations/qwikswitch.markdown @kellerza
798797
source/_integrations/rabbitair.markdown @rabbit-air

Gemfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ source 'https://rubygems.org'
33
ruby '> 2.5.0'
44

55
group :development do
6-
gem 'rake', '13.3.1'
6+
gem 'rake', '13.4.2'
77
gem 'jekyll', '4.4.1'
88
gem 'stringex', '2.8.6'
9-
gem 'sass-embedded', '1.98.0'
10-
gem 'rubocop', '1.86.0'
9+
gem 'sass-embedded', '1.99.0'
10+
gem 'rubocop', '1.86.1'
1111
gem 'ruby-lsp', '0.26.9'
1212
gem 'rackup', '2.3.1'
1313
end

0 commit comments

Comments
 (0)