ה-Mac מצלם מסך וירטואלי אחד, הופך כל frame ל-PNG בגווני אפור ומגיש אותו ב-HTTP. לולאת shell על Kobo Libra 2 מושכת אותו ומציירת אותו על ה-e-ink. מה זה עושה, מה היה צריך לעקוף, ומה המגבלות. הן לא קטנות.
רציתי טרמינל על e-ink. זה נראה כמו קונסולה של חללית.
אז ככה. ה-Mac מצלם מסך וירטואלי אחד. כל frame הופך ל-PNG בגווני אפור, 1264 על 1680, ויוצא ב-HTTP. על Kobo Libra 2 לולאת shell מושכת את ה-PNG ומציירת אותו על מסך ה-e-ink. זה כל הפרויקט.
הוא נמצא ב-GitHub, והמגבלות שלו כתובות שם. רוב הפוסט הזה עוסק במגבלות.
1. ה-pipeline
שני חצאים, ורשת Wi-Fi אחת ביניהם.
Mac Kobo Libra 2virtual display NickelMenu -> start.shscreen-server.py loop.sh, each cycle: screencapture -D<n> Wi-Fi GET /cmd.sh, run on change -> grayscale PNG 1264x1680 HTTP GET /screen.png GET /screen.png fbink -g file=screen.png GET /cmd.sh POST /report
ב-Mac, screen-server.py מצלם את המסך ארבע פעמים בשנייה כברירת מחדל ושומר בזיכרון את ה-frame האחרון. כל בקשה מקבלת אותו מיד.
ב-Kobo, פריט תפריט בשם "Screen push" מפעיל את start.sh. הוא מעתיק את FBInk ואת הלולאה ל-/tmp, מצייר שורת בדיקה אחת, שולח diagnostics ל-Mac ומשאיר את הלולאה רצה. הלולאה מושכת את ה-PNG, משווה את ה-checksum שלו לקודם, ומציירת רק אם הוא השתנה. אחר כך היא ממתינה 0.3 שניות.
2. למה Screen Sharing לא התאים
ל-macOS כבר יש דרך להציג מסך על מכשיר אחר. Screen Sharing מגיש את כל המסכים כ-framebuffer אחד גדול. פאנל e-ink במצב לאורך לא צריך את כל המסכים. הוא צריך אחד.
אז השרת מצלם מסך אחד לפי האינדקס שלו, עם screencapture -D<n>. שני פרטים הפכו להערות בקוד.
בגרסאות חדשות של macOS, מצב ה-stdout של screencapture לא מחזיר כלום כשנותנים לו אינדקס של מסך. השרת כותב לקובץ זמני וקורא אותו בחזרה.
סמן העכבר לא נכנס לצילום כברירת מחדל. צריך בשבילו דגל, -C.
המסך עצמו וירטואלי. סקריפט ההתקנה מחפש את DeskPad ומוצא איזה אינדקס צילום קיבל המסך הווירטואלי. מסלול ה-VNC הישן עדיין בריפו, כסקריפט fallback. ה-pipeline שלמעלה לא משתמש בו.
3. איך שולחן עבודה נהיה קריא
הממשק של macOS אפור בהיר, עם ניגודיות נמוכה. על e-ink הוא כמעט בלתי נראה.
השרת עושה חמישה דברים לכל frame.
ממיר אותו ל-grayscale של 8 ביט. FBInk עושה dithering לרמות של הפאנל עצמו.
מסובב אותו ב-90 מעלות נגד כיוון השעון, כשמבקשים. צילום לרוחב בתוך פאנל לאורך יוצא פס דק באמצע. אחרי סיבוב, צילום של 1680 על 1264 ממלא 1264 על 1680.
משנה את הגודל שלו כך שיתאים לפאנל, וממרכז אותו על רקע לבן.
מפעיל מפת levels קבועה. כל מה שב-90 ומטה הופך לשחור. כל מה שב-205 ומעלה הופך ללבן. האמצע עובר דרך gamma של 2.2, וטקסט אפור בכותרות של חלונות נהיה כהה.
מחדד קצוות עם unsharp mask.
המפה קבועה, לא אוטומטית. ניגודיות אוטומטית מותחת את האפור האחיד של שולחן עבודה כמעט ריק לפס שחור מלא.
בצד של ה-Kobo, ה-frames מצוירים כברירת מחדל עם ה-waveform GL16. אחת ל-16 frames יש רענון מלא עם הבהוב, שמנקה ghosting. ה-interval, ה-waveform וקצב ה-polling יושבים בקובץ config אחד, והלולאה קוראת אותו מחדש בכל סבב.
4. ערוץ הפקודות
את החלק הזה כדאי לקרוא לפני שמתקינים משהו.
SSH נכנס ל-Kobo לא אמין. ה-README אומר להשתמש במקומו בערוץ הפקודות. אז מה זה ערוץ הפקודות?
בכל סבב ה-Kobo מבקש מה-Mac את /cmd.sh. כשהתוכן שונה ממה שהלולאה הריצה בפעם האחרונה, היא מריצה אותו עם sh, כ-root, ושולחת את הפלט בחזרה ל-/report. הבקשה הראשונה אחרי שהלולאה עולה מריצה גם את מה שכבר נמצא בקובץ.
לשרת אין אימות, אין הצפנה ואין בקרת גישה. מתוך ה-README:
כל host שמגיע לפורט יכול לקרוא את המסך המצולם
אותו host יכול למשוך את קובץ הפקודות
אותו host יכול להוסיף נתונים בכל גודל לקובץ הדוח ב-Mac
מי שיכול לכתוב את קובץ הפקודות, או ליירט או לזייף את ה-HTTP הלא מוצפן בין שני המכשירים, יכול להריץ פקודות כ-root על ה-Kobo
ברירת המחדל היא האזנה בכל הממשקים.
העצה של ה-README קצרה. להריץ את השרת רק ברשת פרטית שסומכים עליה. לקשור אותו לממשק אחד עם --bind. לעצור אותו כשלא משתמשים בו. למחוק אחר כך את kobo-cmd.sh.
ערוץ הפקודות הוא root shell מרוחק על HTTP לא מוצפן. ב-README יש פסקה שמבקשת מאנשים להיזהר איתו. שניהם בריפו.
5. מה לא עובד
ניהול השינה של המכשיר לא גמור. ה-firmware מרשה לכל היותר 255 דקות עד שינה אוטומטית, אז ה-Kobo נרדם אחרי בערך ארבע שעות בלי פעילות. השינה עוצרת את הלולאה ומנתקת את ה-Wi-Fi. נגיעה מעירה את המכשיר. אין מנגנון שמשאיר אותו ער בעזרת הזרקת אירועי קלט.
את "Screen push" צריך להפעיל ידנית אחרי כל אתחול. אין הפעלה אוטומטית.
התעבורה רק ב-Wi-Fi. רשת דרך USB לא מומשה.
הגדרות ה-waveform והכיוון לא כוונו.
שרת שהופעל דרך launchd עלול להיות בלי הרשאת הקלטת מסך. ואז ה-frames ריקים.
אין סקריפט teardown. עוצרים את הלולאה מהתפריט, את השרת עם kill, ומחזירים את הגדרות החשמל מהגיבוי שההתקנה כתבה ליד הקובץ המקורי.
FBInk לא נמצא בריפו. את הבינארי fbink ואת הספרייה שלו מתקינים לבד, מה-releases של פרויקט FBInk.
רק firmware 4.38 על Libra 2 היה בשימוש. מדגם בגודל אחד.
6. התקנה, בקצרה
צריך Kobo Libra 2 עם firmware מקורי ו-NickelMenu, עותק משלכם של FBInk עם תמיכה בתמונות, DeskPad או כלי אחר למסך וירטואלי, ו-Python 3 עם Pillow על ה-Mac. הטרמינל שמפעיל את השרת צריך הרשאת הקלטת מסך.
מגדירים את הכתובת של ה-Mac ב-kobo-files/config.sh. אחר כך, על ה-Mac:
./provision.sh --mac
הפקודה גם מפעילה ב-macOS את Screen Sharing עם sudo, אם הוא כבוי. רק מסלול ה-VNC הישן משתמש בו. אם אתם לא משתמשים במסלול הזה, כבו את Screen Sharing שוב בהגדרות המערכת.
כשה-Kobo מחובר ב-USB:
./provision.sh --kobo --mac-ip 192.0.2.10 --eject
הכתובת היא דוגמה, מהטווח שנשמר לתיעוד. שימו במקומה את הכתובת של ה-Mac שלכם. הפקודה השנייה מעתיקה את הקבצים למכשיר, מתקינה את פריטי התפריט וקובעת שלוש הגדרות חשמל, עם גיבוי. מפעילים מחדש את ה-Kobo ובוחרים "Screen push".
ב-README יש את טבלת ההגדרות ואת רשימת ה-troubleshooting.
הערה על האתר
התנאים של האתר עודכנו ב-11 בנובמבר 2026: סעיף סמכות השיפוט מציין עכשיו את בתי המשפט בחיפה.