printer troubleshooting etc

This commit is contained in:
trav
2026-01-28 16:42:11 -08:00
parent e1f9417684
commit cafd4b6084
26 changed files with 408 additions and 132 deletions

View File

@ -43,6 +43,12 @@ class Screen10(tk.Frame):
self.running = True
self._update_frame()
# Sticker tip - only show when a sticker was printed
if GlobalVars.print_type == "sticker":
RoundedLabel(container,
text="You might like to add some packing tape on top\nof your sticker to make it more permanent",
bg='white', font=('Georgia', 16)).pack(pady=(10, 0))
# Button container for side-by-side layout
button_frame = tk.Frame(container, bg=BG_COLOR)
button_frame.pack(pady=10)

View File

@ -51,7 +51,7 @@ class Screen4(tk.Frame, DrawingMixin):
# Initialize drawing via mixin (grid_size=1 for stickers)
self.init_drawing(597, 360, grid_size=1)
self.draw_size = 3 # Override default size for stickers
self.draw_size = 4 # Override default size for stickers
self.imported_img = None
# QR size positions and defaults
@ -217,6 +217,7 @@ class Screen8(tk.Frame, DrawingMixin):
# Initialize drawing via mixin
self.init_drawing(width, height, grid_size=scale_factor)
self.draw_size = 4 # Second-from-largest pen size
# Right panel: Pen tools (grid layout) + action buttons
right_panel = tk.Frame(main_container, bg=BG_COLOR)

View File

@ -77,12 +77,32 @@ It can print stickers and ribbons to affix to an item you care about."""
wraplength=500, justify='left', padx=20, pady=20)
text_label.pack(expand=True)
# Bottom: Forward button only
# Bottom: Forward button only (delayed)
nav_frame = tk.Frame(self, bg=BG_COLOR)
nav_frame.grid(row=1, column=0, columnspan=2, sticky='ew', pady=20)
tk.Button(nav_frame, text="Forward →", command=lambda: master.switch_frame(InfoPage2),
height=2, width=15, bg='peach puff', font=GlobalVars.BUTTON_FONT).pack(side='right', padx=40)
# Dot progress indicator
self.dots_label = tk.Label(nav_frame, text="", font=GlobalVars.TEXT_FONT, bg=BG_COLOR)
self.dots_label.pack(side='left', expand=True)
self.dot_count = 0
def add_dot():
self.dot_count += 1
self.dots_label.config(text="." * self.dot_count)
if self.dot_count < 8:
self.after(1000, add_dot)
self.after(1000, add_dot)
self.forward_btn = tk.Button(nav_frame, text="Forward →", command=lambda: master.switch_frame(InfoPage2),
height=2, width=15, bg='peach puff', font=GlobalVars.BUTTON_FONT)
def show_forward():
self.dots_label.pack_forget()
self.forward_btn.pack(side='right', padx=40)
# Show forward button after 8 second delay
self.after(8000, show_forward)
class InfoPage2(tk.Frame):
@ -123,14 +143,35 @@ by tagging an item you are saying to it, 'you matter, I will take care of you'""
wraplength=500, justify='left', padx=20, pady=20)
text_label.pack(expand=True)
# Bottom: Back and Forward buttons
# Bottom: Back and Forward buttons (forward delayed)
nav_frame = tk.Frame(self, bg=BG_COLOR)
nav_frame.grid(row=1, column=0, columnspan=2, sticky='ew', pady=20)
tk.Button(nav_frame, text="← Back", command=lambda: master.switch_frame(InfoPage1),
height=2, width=15, bg='peach puff', font=GlobalVars.BUTTON_FONT).pack(side='left', padx=40)
tk.Button(nav_frame, text="Forward →", command=lambda: master.switch_frame(InfoPage3),
height=2, width=15, bg='peach puff', font=GlobalVars.BUTTON_FONT).pack(side='right', padx=40)
# Dot progress indicator (centered)
self.dots_label = tk.Label(nav_frame, text="", font=GlobalVars.TEXT_FONT, bg=BG_COLOR)
self.dots_label.pack(side='left', expand=True)
self.dot_count = 0
def add_dot():
self.dot_count += 1
self.dots_label.config(text="." * self.dot_count)
if self.dot_count < 8:
self.after(1000, add_dot)
self.after(1000, add_dot)
self.forward_btn = tk.Button(nav_frame, text="Forward →", command=lambda: master.switch_frame(InfoPage3),
height=2, width=15, bg='peach puff', font=GlobalVars.BUTTON_FONT)
def show_forward():
self.dots_label.pack_forget()
self.forward_btn.pack(side='right', padx=40)
# Show forward button after 8 second delay
self.after(8000, show_forward)
class InfoPage3(tk.Frame):
@ -147,14 +188,14 @@ class InfoPage3(tk.Frame):
All generated items are stored permanently and replicated across the Scuttlebutt network. Once published, it cannot be deleted.
Please do not create imaginary items or shitpost.
Please post with care and with positive and constructive intentions.
The QR codes contain a Scuttlebutt messageID, scanning it works best at www.cust.ooo or any Scuttlebutt client.
"""
text_label = RoundedLabel(container, text=mindful_text,
font=GlobalVars.TEXT_FONT, bg='white',
wraplength=700, justify='center', padx=30, pady=30)
font=("Helvetica", 20), bg='white',
wraplength=900, justify='center', padx=30, pady=30)
text_label.pack()
# Deferred import
@ -162,11 +203,32 @@ The QR codes contain a Scuttlebutt messageID, scanning it works best at www.cust
from kiosk.screens.ssb_selection import Screen1
master.switch_frame(Screen1)
# Bottom: Back and Forward buttons
# Bottom: Back and Forward buttons (forward delayed)
nav_frame = tk.Frame(self, bg=BG_COLOR)
nav_frame.place(relx=0.5, rely=0.9, anchor='center')
tk.Button(nav_frame, text="← Back", command=lambda: master.switch_frame(InfoPage2),
height=2, width=15, bg='peach puff', font=GlobalVars.BUTTON_FONT).pack(side='left', padx=40)
tk.Button(nav_frame, text="Forward →", command=go_to_screen1,
height=2, width=15, bg='peach puff', font=GlobalVars.BUTTON_FONT).pack(side='right', padx=40)
# Dot progress indicator (centered)
self.dots_label = tk.Label(nav_frame, text="", font=GlobalVars.TEXT_FONT, bg=BG_COLOR)
self.dots_label.pack(side='left', expand=True)
self.dot_count = 0
def add_dot():
self.dot_count += 1
self.dots_label.config(text="." * self.dot_count)
if self.dot_count < 8:
self.after(1000, add_dot)
self.after(1000, add_dot)
self.forward_btn = tk.Button(nav_frame, text="Forward →", command=go_to_screen1,
height=2, width=15, bg='peach puff', font=GlobalVars.BUTTON_FONT)
def show_forward():
self.dots_label.pack_forget()
self.forward_btn.pack(side='right', padx=40)
# Show forward button after 8 second delay
self.after(8000, show_forward)

View File

@ -110,15 +110,20 @@ class Screen13(tk.Frame):
# Load and rotate scan-tag 90 degrees clockwise
scan_tag = Image.open("scan-tag.png").convert("L")
scan_tag_rotated = scan_tag.rotate(-90, expand=True) # -90 = clockwise
scan_tag_rotated = scan_tag.rotate(-90, expand=True) # -90 = clockwise, 53×357
merged_image = Image.new('L', (675, 375), "white")
# 300 DPI printer, 2.25" label = 675 dots
# Drawing: 597px, scan-tag rotated: 53px = 650px total (no gap)
sticker_width = 650
sticker_height = 375
merged_image = Image.new('L', (sticker_width, sticker_height), "white")
merged_image.paste(drawing, (0, 8))
merged_image.paste(qr_img, (QRX, QRY + 8))
# Paste rotated scan-tag right after drawing, vertically centered
scan_tag_x = 597 # Right edge of drawing
scan_tag_y = (375 - scan_tag_rotated.height) // 2 # Center vertically
scan_tag_y = (sticker_height - scan_tag_rotated.height) // 2 # Center vertically
merged_image.paste(scan_tag_rotated, (scan_tag_x, scan_tag_y))
merged_image.save("merged_image.png")
@ -161,7 +166,10 @@ class Screen13(tk.Frame):
print_width=ribbon_width,
label_length=total_height)
else:
zpl_code = tozpl.print_to_zpl("merged_image.png")
# Sticker: specify dimensions for proper positioning on 2.25" (675 dot @ 300 DPI) label
zpl_code = tozpl.print_to_zpl("merged_image.png",
print_width=sticker_width,
label_length=sticker_height)
# save the zpl
# Open the file in write mode
@ -214,20 +222,21 @@ AND OR
please email maintenance@cust.ooo
thanks!"""
RoundedLabel(container, text=troubleshoot_text, bg='white', font=('Georgia', 22),
RoundedLabel(container, text=troubleshoot_text, bg='white', font=('Georgia', 18),
wraplength=900, justify='left').pack(pady=10)
# Re-print button
tk.Button(container, text="Re-print", command=self._reprint,
height=2, width=30, bg='peach puff', font=GlobalVars.BUTTON_FONT).pack(pady=5)
# Done button
# Button container for side-by-side layout
def go_home():
from kiosk.screens.home import Screen0
master.switch_frame(Screen0)
tk.Button(container, text="Done", command=go_home,
height=2, width=30, bg='light gray', font=GlobalVars.BUTTON_FONT).pack(pady=5)
button_frame = tk.Frame(container, bg=BG_COLOR)
button_frame.pack(pady=10)
tk.Button(button_frame, text="Re-print", command=self._reprint,
height=2, width=20, bg='peach puff', font=GlobalVars.BUTTON_FONT).pack(side='left', padx=10)
tk.Button(button_frame, text="Done", command=go_home,
height=2, width=20, bg='light gray', font=GlobalVars.BUTTON_FONT).pack(side='left', padx=10)
def _reprint(self):
"""Re-send the last print job."""

View File

@ -54,6 +54,7 @@ class Screen2(tk.Frame):
tk.Frame.__init__(self, master, bg=BG_COLOR)
self.selected_label = None
self.filtered_users = []
self._search_after_id = None # For debouncing search input
# Create a new frame at the top for the label and text box
self.top_frame = tk.Frame(self, bg=BG_COLOR)
@ -61,7 +62,7 @@ class Screen2(tk.Frame):
# Add a label with text wrapping
self.label = RoundedLabel(self.top_frame,
text="slowly type your public key or alias one letter at a time to find yourself in the list then click on your key to select it.",
text="Type your public key or alias to find yourself in the list, then click on your key to select it.",
font=GlobalVars.TEXT_FONT,
wraplength=800,
bg='white')
@ -69,7 +70,7 @@ class Screen2(tk.Frame):
# Add text box to the top frame
self.entry = tk.Entry(self.top_frame, font=GlobalVars.TEXT_FONT)
self.entry.bind('<KeyRelease>', lambda e: self.update_users_list())
self.entry.bind('<KeyRelease>', self._debounced_search)
self.entry.pack(side="top", fill="x", padx=20)
# Focus on the entry box
@ -113,20 +114,51 @@ class Screen2(tk.Frame):
from kiosk.screens.camera import Screen3
master.switch_frame(Screen3)
def cancel_selection():
GlobalVars.selected_user = None
go_to_screen3()
# The 'Cancel' button to skip without selecting a user
self.cancel_button = tk.Button(self.button_frame, text="Cancel", command=cancel_selection,
height=2, width=20, bg='peach puff', font=GlobalVars.BUTTON_FONT)
self.cancel_button.pack(side="left", padx=(10, 10))
# The 'Done' button to navigate to next screen
self.done_button = tk.Button(self.button_frame, text="Done", command=go_to_screen3,
height=2, width=20, bg='peach puff', font=GlobalVars.BUTTON_FONT)
self.done_button.pack(side="right", padx=(10, 20))
# Initialize users list from users.json
self.users = self.get_users_from_file()
self.update_users_list()
# Loading label (shown during initial load)
self.loading_label = tk.Label(self.scrollable_frame, text="Loading...",
font=GlobalVars.TEXT_FONT, bg=BG_COLOR)
self.loading_label.pack(pady=20)
# Defer loading to allow UI to render first
self.users = []
self.after(10, self._load_users)
master.add_home_button(self)
def _debounced_search(self, event=None):
"""Debounce search input - wait 250ms after last keystroke before searching."""
if self._search_after_id:
self.after_cancel(self._search_after_id)
self._search_after_id = self.after(250, self.update_users_list)
def _load_users(self):
"""Load users from file and display them."""
self.users = self.get_users_from_file()
self.loading_label.destroy()
self.update_users_list()
def update_users_list(self):
search_text = self.entry.get().lower()
self.filtered_users = [user for user in self.users if search_text in user['id'].lower() or search_text in self.unescape_unicode(user.get('alias', '')).lower()]
# Use cached _search_alias and _search_id for fast filtering
self.filtered_users = [
user for user in self.users
if search_text in user.get('_search_id', user['id'].lower())
or search_text in user.get('_search_alias', '')
]
self.display_users()
# Preserve selection after filtering
@ -148,7 +180,8 @@ class Screen2(tk.Frame):
frame = tk.Frame(self.scrollable_frame, bg=BG_COLOR)
frame.pack(fill='x', expand=True, pady=2)
alias = self.unescape_unicode(user.get('alias', ''))
# Use cached _display_alias if available, otherwise compute it
alias = user.get('_display_alias', self.unescape_unicode(user.get('alias', '')))
id = user.get('id', '')
alias_label = tk.Label(frame, text=alias, font=('Georgia', 14, 'bold'), width=20, anchor='w', bg='white')
@ -221,14 +254,28 @@ class Screen2(tk.Frame):
return False
def refresh_users(self):
# Show loading state
self.refresh_button.configure(state="disabled", text="Loading...")
self.update_idletasks()
try:
self.users = self.get_scuttlebutt_users()
users = self.get_scuttlebutt_users()
# Pre-process aliases for the new users
for user in users:
display_alias = self.unescape_unicode(user.get('alias', ''))
user['_display_alias'] = display_alias
user['_search_alias'] = display_alias.lower()
user['_search_id'] = user['id'].lower()
self.users = users
self.update_users_list()
self.save_users_to_file(self.users)
self.save_users_to_file(users)
messagebox.showinfo("Success", "User list has been refreshed and updated with aliases.")
except Exception as e:
print(f"An error occurred while refreshing the user list: {e}")
messagebox.showerror("Error", "An error occurred while refreshing the user list. Please try again later.")
finally:
# Restore button state
self.refresh_button.configure(state="normal", text="Refresh List")
def get_scuttlebutt_users(self):
try:
@ -253,6 +300,12 @@ class Screen2(tk.Frame):
try:
with open('users.json') as f:
users = json.load(f)
# Pre-process and cache unescaped aliases for fast search and display
for user in users:
display_alias = self.unescape_unicode(user.get('alias', ''))
user['_display_alias'] = display_alias
user['_search_alias'] = display_alias.lower()
user['_search_id'] = user['id'].lower()
return users
except FileNotFoundError:
return []

View File

@ -1,8 +0,0 @@
^XA
^PW675
^LL375
^LH0,0
^LT0
^LS0
^JUS
^XZ

View File

@ -1,8 +0,0 @@
^XA
^PW675
^LL375
^LH10,10
^LT0
^LS0
^JUS
^XZ

View File

@ -1,8 +0,0 @@
^XA
^PW675
^LL375
^LH5,5
^LT0
^LS0
^JUS
^XZ

View File

@ -1,7 +0,0 @@
^XA
^FO0,0^GB50,50,50^FS
^FO605,0^GB50,50,50^FS
^FO0,305^GB50,50,50^FS
^FO605,305^GB50,50,50^FS
^FO280,155^A0N,30,30^FDCENTER^FS
^XZ

View File

@ -1,7 +0,0 @@
^XA
^FO0,0^GB40,40,40^FS
^FO625,0^GB40,40,40^FS
^FO0,325^GB40,40,40^FS
^FO625,325^GB40,40,40^FS
^FO290,160^A0N,30,30^FDCENTER^FS
^XZ

View File

@ -1,7 +0,0 @@
^XA
^FO0,0^GB40,40,40^FS
^FO605,0^GB40,40,40^FS
^FO0,305^GB40,40,40^FS
^FO605,305^GB40,40,40^FS
^FO285,155^A0N,30,30^FDCENTER^FS
^XZ

View File

@ -1,3 +0,0 @@
^XA
~HQ
^XZ

View File

@ -1,6 +0,0 @@
^XA
^LT0
^LS0
^LH0,0
^JUS
^XZ

View File

@ -1,4 +0,0 @@
^XA
^LH50,50
^JUS
^XZ

View File

@ -1,5 +0,0 @@
^XA
^LT50
^LS50
^JUS
^XZ

View File

@ -1,6 +0,0 @@
^XA
^FO10,10
^GB200,100,3^FS
^FO30,50
^A0N,30,30^FDTest^FS
^XZ

View File

@ -1,7 +0,0 @@
^XA
^LH50,50
^FO0,0
^GB100,100,3^FS
^FO50,50
^A0N,30,30^FDCenter Test^FS
^XZ

View File

@ -1,8 +0,0 @@
^XA
^LT50
^LS50
^FO0,0
^GB200,200,3^FS
^FO20,80
^A0N,40,40^FDShift Test^FS
^XZ

View File

@ -0,0 +1,129 @@
# Zebra Printer Darkness Troubleshooting
## Understanding Darkness Settings
The Zebra GX430t has **two darkness settings that add together**:
| Command | Type | Range | Persists? |
|---------|------|-------|-----------|
| `~SD##` | Absolute base darkness | 0-30 | Yes (with `^JUS`) |
| `^MD##` | Relative offset | -30 to +30 | Yes (with `^JUS`) |
**Effective darkness = ~SD value + ^MD offset**
### Critical Warning: ^MD Stacks!
The `^MD` command is **relative** - it adds/subtracts from the current saved offset. If you run:
```bash
echo "^XA^MD-5^JUS^XZ" | lp -d printer # offset now -5
echo "^XA^MD-2^JUS^XZ" | lp -d printer # offset now -7 (not -2!)
```
This can quickly result in an extremely low effective darkness, causing blank labels even at high `~SD` values.
### How to Reset
To fix stacked ^MD issues:
```bash
# Option 1: Factory reset (WARNING: loses all calibration)
echo "^XA^JUF^XZ" | lp -d printer
# Option 2: Try setting high ~SD to compensate
# If prints are blank at ~SD15, try ~SD25 or ~SD30
echo "^XA~SD25^JUS^XZ" | lp -d printer
```
## Symptoms and Solutions
### Checkerboard/dithered areas print DARKER than solid black
**Cause:** Too much heat - solid areas need sustained heat, but you're overheating
**Solution:** DECREASE darkness (counterintuitive!)
```bash
echo "^XA~SD10^JUS^XZ" | lp -d printer # try lower values
```
### Ribbon tears or sticks to labels
**Cause:** Way too much heat
**Solution:** Significantly decrease darkness
```bash
echo "^XA~SD5^JUS^XZ" | lp -d printer
```
### Text edges dark but centers are gray/muddled
**Cause:** Slightly too much heat
**Solution:** Decrease darkness incrementally
### Prints are faint/gray overall
**Cause:** Not enough heat (or extreme overheat causing poor transfer)
**Solution:** Increase darkness, but if you've been adjusting ^MD, the offset may be very negative
### Completely blank labels
**Cause:**
1. Darkness too low (check for stacked ^MD issue)
2. Wrong print mode (direct thermal vs thermal transfer)
3. Ribbon not making contact
**Solution:**
```bash
# Ensure thermal transfer mode
echo "^XA^MTT^JUS^XZ" | lp -d printer
# Try high darkness to rule out ^MD stacking
echo "^XA~SD25^JUS^XZ" | lp -d printer
```
## Finding the Right Darkness
Start low and work up - it's easier to recover from too-light than too-dark:
1. Set a known baseline:
```bash
echo "^XA~SD5^JUS^XZ" | lp -d printer
```
2. Print test pattern (see test-prints/ directory)
3. If too light, increment by 2-3:
```bash
echo "^XA~SD8^JUS^XZ" | lp -d printer
```
4. Stop when black is solid black and gray is distinguishable
**For full resin ribbon on this setup, ~SD25 worked well (after ^MD offset issues).**
**Originally, ~SD2-6 was optimal before ^MD commands corrupted the offset.**
## Printing ZPL Files
Always use `-o raw` flag:
```bash
lp -d printer -o raw /path/to/file.zpl
```
Without `-o raw`, large ZPL files may not print.
## Quick Reference
```bash
# Set absolute darkness (0-30)
echo "^XA~SD15^JUS^XZ" | lp -d printer
# Check thermal transfer mode is enabled
echo "^XA^MTT^JUS^XZ" | lp -d printer
# Set print speed (1=slowest, higher=faster)
echo "^XA^PR2^JUS^XZ" | lp -d printer
# Factory reset (last resort - loses calibration!)
echo "^XA^JUF^XZ" | lp -d printer
```
## Session Log: 2026-01-28
Started with checkerboard-darker-than-solid symptom. Discovered:
- Original darkness was way too high
- Optimal was around ~SD2-6
- Accidentally used ^MD-5 and ^MD-2 which stacked to create large negative offset
- Even after power cycle, blank labels persisted (saved to EEPROM)
- Had to use ~SD25 to compensate for the negative ^MD offset
- Lesson: Avoid ^MD commands, stick to ~SD for absolute control

View File

@ -3,5 +3,5 @@
^FO625,0^GB50,50,50^FS
^FO0,325^GB50,50,50^FS
^FO625,325^GB50,50,50^FS
^FO300,170^A0N,30,30^FDCENTER^FS
^FO280,160^A0N,40,40^FDCENTER^FS
^XZ

View File

@ -0,0 +1,12 @@
^XA
^FO30,20^A0N,30,30^FDSolid Black:^FS
^FO30,55^GB120,60,60^FS
^FO200,20^A0N,30,30^FDCheckerboard:^FS
^FO200,55^GFA,480,480,8,AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA5555^FS
^FO400,20^A0N,30,30^FD50% Gray:^FS
^FO400,55^GFA,480,480,8,F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0^FS
^FO30,140^A0N,40,40^FDTest Text Here^FS
^FO30,200^A0N,24,24^FDIf checkerboard is darker than solid = too hot^FS
^FO30,230^A0N,24,24^FDIf everything is gray = too cold^FS
^FO30,260^A0N,24,24^FDIdeal: solid=black, checker=medium gray^FS
^XZ

View File

@ -0,0 +1,3 @@
^XA
^FO50,50^A0N,50,50^FDTest^FS
^XZ

BIN
qr.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 993 B

After

Width:  |  Height:  |  Size: 709 B

View File

@ -0,0 +1,63 @@
# SSB Troubleshooting Notes - January 27, 2026
## Problem
Kiosk ssb-server posts were not propagating to the pub over the internet.
## Environment
- Kiosk: `custo-kiosk-2` running ssb-server 15.3.0 as a user systemd service
- Kiosk key: `@apIwMs+ElLT6h4d9nUqqFSWUXAHII1d+Wz9SopR26Lo=.ed25519`
- Pub: `69.61.19.149:8807`
- Pub key: `@jmnz08i4tzykqJ57B3BduqabcYSuDxTukOvihPlLkec=.ed25519`
## Findings
### 1. ekata.social pub is down
The original pub at `ssb.ekata.social:8008` is not accepting connections:
```
Error: connect ECONNREFUSED 64.190.63.222:8008
```
- Server pings fine, but port 8008 refuses connections
- The ssb-server process on that pub is likely not running
### 2. Personal pub at 69.61.19.149:8807 is reachable
- Port 8807 confirmed open via netcat
- Friends relationship confirmed (hops=1)
### 3. Manual gossip.connect triggered sync
Running this command forced a connection and posts synced:
```bash
ssb-server gossip.connect 'net:69.61.19.149:8807~shs:jmnz08i4tzykqJ57B3BduqabcYSuDxTukOvihPlLkec='
```
## Possible Root Causes (not fully diagnosed)
- Wrong port cached in gossip table (8008 vs 8807)
- Exponential backoff after failed connection attempts
- Gossip scheduler not prioritizing the peer
## Useful Diagnostic Commands
```bash
# Check ssb-server status
systemctl --user status ssb-server
# View user-level logs
journalctl --user -u ssb-server --no-pager -n 100
# Check identity
ssb-server whoami
# List all gossip peers (large output)
ssb-server gossip.peers
# Check friend relationship
ssb-server friends.hops '@PUBKEY.ed25519'
# Manually trigger connection to a pub
ssb-server gossip.connect 'net:HOST:PORT~shs:PUBKEY_WITHOUT_@_AND_.ed25519'
# Test if pub port is reachable
nc -zv HOST PORT -w 5
```
## Resolution
Manually running `gossip.connect` triggered the sync. If this happens again, try forcing a connection with the command above.

View File

@ -85,14 +85,23 @@ echo "^XA^PW675^LL375^JUS^XZ" | lp -d sticker
### Step 5: Configure Darkness
Full resin ribbon needs moderate heat. Start with MD18:
**Use `~SD` (absolute) instead of `^MD` (relative) to avoid stacking issues.**
Full resin ribbon heat requirements vary. Start LOW and work up:
```bash
echo "^XA^MD18^JUS^XZ" | lp -d sticker
# Start with low darkness
echo "^XA~SD5^JUS^XZ" | lp -d sticker
```
If prints are too light/gray, increase to MD20 or MD22.
If resin sticks to labels when peeling, decrease to MD15.
Test print and adjust:
- If too light/gray: increase (`~SD8`, `~SD10`, etc.)
- If resin sticks or ribbon tears: decrease
- **If checkerboard prints darker than solid black: DECREASE darkness (counterintuitive!)**
See `printer-troubleshooting/darkness-troubleshooting.md` for detailed guidance.
**WARNING:** Avoid `^MD` commands - they stack and can corrupt saved settings. Stick to `~SD` for absolute control.
### Step 6: Physical Calibration
@ -111,13 +120,13 @@ The printer will feed several labels as it calibrates the gap sensor.
Simple text test:
```bash
echo "^XA^PW675^LL375^MD18^FO50,50^ADN,36,20^FDTest Print^FS^XZ" | lp -d sticker
echo "^XA^PW675^LL375~SD10^FO50,50^ADN,36,20^FDTest Print^FS^XZ" | lp -d sticker
```
Border alignment test:
```bash
echo "^XA^PW675^LL375^MD18^FO10,10^GB655,355,5^FS^XZ" | lp -d sticker
echo "^XA^PW675^LL375~SD10^FO10,10^GB655,355,5^FS^XZ" | lp -d sticker
```
This prints a 5-dot border around the label edge. If misaligned, adjust with:
@ -135,26 +144,38 @@ lp -d sticker your_file.zpl
### Troubleshooting
See `printer-troubleshooting/` directory for detailed guides and test prints.
**Problem: Ribbon pools/doesn't wind onto uptake spool**
- Solution: Make sure you ran `^MNN,Y` (uptake enabled)
- Factory reset and reconfigure if needed
**Problem: Checkerboard/dithered areas darker than solid black**
- Solution: DECREASE darkness (too much heat!)
- See `printer-troubleshooting/darkness-troubleshooting.md`
**Problem: Prints are fuzzy or gray**
- Solution: Increase darkness (`^MD20` or higher)
- Solution: Increase darkness with `~SD` command (not `^MD`)
- Check print head cleanliness (wipe with isopropyl alcohol)
**Problem: Printing across multiple labels**
- Solution: Re-run physical calibration (2-blink method)
- Verify label length matches actual label+gap size
**Problem: Resin sticks to label when peeling**
- Solution: Decrease darkness (`^MD15` or lower)
**Problem: Resin sticks to label or ribbon tears**
- Solution: Decrease darkness significantly
- Ensure print speed isn't too slow: `echo "^XA^PR4^JUS^XZ" | lp -d sticker`
**Problem: ZPL file doesn't print (but simple commands work)**
- Solution: Use `-o raw` flag: `lp -d sticker -o raw file.zpl`
**Problem: ZPL commands print as literal text**
- Solution: Printer isn't configured as raw queue
- Reconfigure: `sudo lpadmin -p sticker -m raw`
**Problem: Blank labels after adjusting darkness**
- Solution: May have corrupted ^MD offset - see darkness troubleshooting guide
### Complete Configuration Script
Save this as a shell script for easy re-setup:
@ -175,12 +196,12 @@ echo "Setting label dimensions (2.25\" x 1.25\")..."
echo "^XA^PW675^LL375^JUS^XZ" | lp -d $PRINTER_NAME
sleep 2
echo "Setting darkness to 18..."
echo "^XA^MD18^JUS^XZ" | lp -d $PRINTER_NAME
echo "Setting darkness to 10 (adjust as needed)..."
echo "^XA~SD10^JUS^XZ" | lp -d $PRINTER_NAME
sleep 2
echo "Configuration complete. Run physical calibration (2-blink method) now."
echo "Test with: echo \"^XA^PW675^LL375^MD18^FO50,50^ADN,36,20^FDTest^FS^XZ\" | lp -d $PRINTER_NAME"
echo "Test with: echo \"^XA^PW675^LL375~SD10^FO50,50^ADN,36,20^FDTest^FS^XZ\" | lp -d $PRINTER_NAME"
```
### Quick Reference: Common ZPL Commands
@ -188,7 +209,8 @@ echo "Test with: echo \"^XA^PW675^LL375^MD18^FO50,50^ADN,36,20^FDTest^FS^XZ\" |
- `^XA` / `^XZ` - Start/end ZPL command block
- `^PW###` - Print width in dots
- `^LL###` - Label length in dots
- `^MD##` - Darkness (0-30)
- `~SD##` - Darkness absolute (0-30) - USE THIS
- `^MD##` - Darkness relative (-30 to +30) - AVOID (stacks!)
- `^FO###,###` - Field origin (X,Y position in dots)
- `^ADN,H,W` - Font: N=default, H=height, W=width
- `^FD` - Field data (the actual text/content)