Check whether your feed is valid. For more information about JSON Feed, see the specification.
{ "version": "https://jsonfeed.org/version/1.1", "title": "fboës - Der Blog | Startseite", "home_page_url": "https://journal.3960.org/", "feed_url": "https://journal.3960.org/feed.json", "description": "Programmierung, Luft- & Raumfahrt, Kurioses: Der Blog von und mit Frank Boës.", "icon": "https://cdn.3960.org/favicon-192x192.png", "favicon": "https://cdn.3960.org/images/tile-128x128.png", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org" } ], "language": "de-DE", "_rss": { "about": "http://cyber.harvard.edu/rss/rss.html", "copyright": "© 2008-2023 Creative Commons BY" }, "items": [ { "id": "user/posts/2025-04-15-marathon-trailer/index.md", "url": "https://journal.3960.org/posts/2025-04-15-marathon-trailer/", "title": "Marathon – Der Trailer", "content_html": "<div class=\"video-player video-player--youtube\"><iframe allowfullscreen=\"allowfullscreen\" title=\"https://www.youtube.com/watch?v=fvbEnWLRo1s\" src=\"https://www.youtube-nocookie.com/embed/fvbEnWLRo1s?enablejsapi=1\" srcdoc=\"<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href="https://www.youtube.com/embed/fvbEnWLRo1s?autoplay=1"><img src="https://img.youtube.com/vi/fvbEnWLRo1s/hqdefault.jpg" alt=""><span>▶</span></a>\"></iframe><!-- img src=\"https://img.youtube.com/vi/fvbEnWLRo1s/hqdefault.jpg\" --></div>\n<p>Schnitt, Ästhetik, Voice Acting, Choreographie, Musik, Sound, Story, <em>Atmosphäre</em> – der Trailer zu „Marathon“ ist ein Stück Kunst.</p>\n<p>Von mir aus kann Bungie statt einem Extraction Shooter auch einen Kinofilm aus dem Setting machen.</p>\n<p>Der Stil erinnert nicht von ungefähr an die ebenfalls sehr eindringliche Folge <a href=\"https://www.imdb.com/title/tt20239442/\">„Jibaro“ aus der Serie „Love, Death & Robots“</a>.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Marathon%20%E2%80%93%20Der%20Trailer&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2025-04-15-marathon-trailer%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Schnitt, Ästhetik, Voice Acting, Choreographie, Musik, Sound, Story, Atmosphäre – der Trailer zu „Marathon“ ist ein Stück Kunst.\nVon mir aus kann Bungie statt…", "date_published": "2025-04-15T18:03:29+02:00", "date_modified": "2025-04-15T19:13:47+02:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://img.youtube.com/vi/fvbEnWLRo1s/hqdefault.jpg", "language": "de-DE", "image": "https://img.youtube.com/vi/fvbEnWLRo1s/hqdefault.jpg", "tags": [ "Raumfahrt", "Spiel", "Technologie", "The Cool" ] }, { "id": "user/posts/2025-01-08-es-kann-nicht/index.md", "url": "https://journal.3960.org/posts/2025-01-08-es-kann-nicht/", "title": "Es kann nicht sein…", "content_html": "<blockquote><p>Es kann nicht sein, dass „Es kann nicht sein“ als Argument verwendet wird!</p></blockquote>\n<p>Wenn man genau drüber nachdenkt, ist „Es kann nicht sein“ eigentlich auch gar kein Argument, sondern eher ein Gefühlsausdruck. 🤔</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Es%20kann%20nicht%20sein%E2%80%A6&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2025-01-08-es-kann-nicht%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Es kann nicht sein, dass „Es kann nicht sein“ als Argument verwendet wird!\n\nWenn man genau drüber nachdenkt, ist „Es kann nicht sein“ eigentlich auch gar kein…", "date_published": "2025-01-08T17:38:35+01:00", "date_modified": "2025-01-08T18:55:59+01:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://cdn.3960.org/favicon-192x192.png", "language": "de-DE", "image": "https://cdn.3960.org/favicon-192x192.png", "tags": [ "Geckobar", "Lustiges", "Meinung", "Philosophie" ] }, { "id": "user/posts/2025-01-01-new-trailer-for-long-dark-2/index.md", "url": "https://journal.3960.org/posts/2025-01-01-new-trailer-for-long-dark-2/", "title": "New trailer for „The Long Dark 2“", "content_html": "<div class=\"video-player video-player--youtube\"><iframe allowfullscreen=\"allowfullscreen\" title=\"https://www.youtube.com/watch?v=4wlttElgLg4\" src=\"https://www.youtube-nocookie.com/embed/4wlttElgLg4?enablejsapi=1\" srcdoc=\"<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href="https://www.youtube.com/embed/4wlttElgLg4?autoplay=1"><img src="https://img.youtube.com/vi/4wlttElgLg4/hqdefault.jpg" alt=""><span>▶</span></a>\"></iframe><!-- img src=\"https://img.youtube.com/vi/4wlttElgLg4/hqdefault.jpg\" --></div>\n<p>One of my all-time favorite games „The Long Dark“ gets a sequel. <a href=\"https://store.steampowered.com/app/1586260/BLACKFROST_The_Long_Dark_2/\">BLACKFROST: The Long Dark 2</a> is supposed to have the same survival setting as well as all core game mechanics (like crafting and taking care of sleep and nutrition) of its predecessor, but also gets multi-player mode and more social interaction.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=New%20trailer%20for%20%E2%80%9EThe%20Long%20Dark%202%E2%80%9C&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2025-01-01-new-trailer-for-long-dark-2%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "One of my all-time favorite games „The Long Dark“ gets a sequel. BLACKFROST: The Long Dark 2 is supposed to have the same survival setting as well as all core…", "date_published": "2025-01-01T15:21:16+01:00", "date_modified": "2025-01-08T22:16:27+01:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://img.youtube.com/vi/4wlttElgLg4/hqdefault.jpg", "language": "en-GB", "image": "https://img.youtube.com/vi/4wlttElgLg4/hqdefault.jpg", "tags": [ "The Long Dark", "Outdoor", "Spiel" ] }, { "id": "user/posts/2024-08-28-chatgpt-does-flight-plans/index.md", "url": "https://journal.3960.org/posts/2024-08-28-chatgpt-does-flight-plans/", "title": "ChatGPT does flight plans", "content_html": "<p>A brilliant conversation with ChatGPT for proposing a flight plan:</p>\n<!-- more -->\n<p id=\"more\">Please propose a short flight from Martha's Vineyard airport to a nearby airport with a Cessna 172</p>\n<blockquote><p>A great short flight from Martha's Vineyard Airport (MVY) in a Cessna 172 would be to Nantucket Memorial Airport (ACK). The flight covers about 30 nautical miles, which takes roughly 20–30 minutes depending on conditions. This route offers stunning views of the Atlantic Ocean and the islands, making it a scenic and enjoyable flight.</p><p>Given the relatively short distance and straightforward navigation over open water, it's a perfect trip for a short hop in a Cessna 172.</p></blockquote>\n<p>Could you give me a flight plan recommendation?</p>\n<blockquote><p>Certainly! Below is a suggested VFR (Visual Flight Rules) flight plan for a Cessna 172 from Martha's Vineyard Airport (KMVY) to Nantucket Memorial Airport (KACK).</p><h2 id=\"flight-plan-overview\">Flight Plan Overview:</h2><ul><li><strong>Departure:</strong> Martha's Vineyard Airport (KMVY)</li><li><strong>Destination:</strong> Nantucket Memorial Airport (KACK)</li><li><strong>Distance:</strong> ~30 NM</li><li><strong>Estimated Flight Time:</strong> 20–30 minutes</li><li><strong>Cruising Altitude:</strong> 3,000 feet (VFR recommended altitude)</li><li><strong>Flight Type:</strong> VFR</li></ul><h2 id=\"flight-plan-details\">Flight Plan Details:</h2><ul><li><p><strong>Pre-Flight:</strong></p><ul><li><strong>Weather:</strong> Check METAR/TAF for both MVY and ACK, as well as en route weather.</li><li><strong>Weight & Balance:</strong> Ensure your Cessna 172 is within weight and balance limits.</li><li><strong>Fuel:</strong> Verify adequate fuel for the flight, including reserves.</li><li><strong>Navigation:</strong> Set up your navigation radios and GPS if available.</li></ul></li><li><p><strong>Departure from KMVY:</strong></p><ul><li><strong>Runway:</strong> Depending on the wind, likely Runway 24 or 06.</li><li><strong>Climb Out:</strong> After takeoff, climb to a cruising altitude of 3,000 feet.</li><li><strong>Heading:</strong> After departure, fly a south-eastern heading towards Nantucket. The initial heading will be approximately 120°.</li></ul></li><li><p><strong>En Route:</strong></p><ul><li><strong>Direct Route:</strong> Fly direct from MVY to ACK.</li><li><strong>Landmarks:</strong> You’ll be over water most of the way, with limited landmarks. However, keep an eye out for the following:<ul><li><strong>Edgartown</strong> on Martha's Vineyard, off to your left shortly after departure.</li><li><strong>Tuckernuck Island</strong> before reaching Nantucket.</li></ul></li></ul></li><li><p><strong>Arrival at KACK:</strong></p><ul><li><strong>Communication:</strong> Contact Nantucket Tower as you approach the Class D airspace.</li><li><strong>Descent:</strong> Begin your descent to pattern altitude (1,000 feet AGL) as you near the airport.</li><li><strong>Pattern Entry:</strong> Depending on the active runway, enter the appropriate traffic pattern.</li><li><strong>Runway:</strong> Likely Runway 24 or 06, depending on wind conditions.</li></ul></li><li><p><strong>Landing:</strong></p><ul><li>Perform a standard landing, taxi to the ramp, and shut down.</li></ul></li></ul><h2 id=\"communication-frequencies\">Communication Frequencies:</h2><ul><li><strong>MVY ATIS:</strong> 118.12 MHz</li><li><strong>MVY Ground:</strong> 121.90 MHz</li><li><strong>MVY Tower:</strong> 119.70 MHz</li><li><strong>ACK ATIS:</strong> 133.45 MHz</li><li><strong>ACK Tower:</strong> 118.30 MHz</li></ul><h2 id=\"considerations\">Considerations:</h2><ul><li><strong>Wind:</strong> Check the wind direction and adjust your runway choice and headings accordingly.</li><li><strong>Traffic:</strong> Nantucket can be busy, especially in the summer, so stay alert for other traffic.</li><li><strong>Alternate:</strong> If weather deteriorates or there's an issue, you could divert back to Martha's Vineyard or head to Cape Cod (Hyannis, KHYA).</li></ul><p>This is a straightforward flight, but it offers stunning views and a good practice opportunity for navigation over water and handling short cross-country flights. Safe flying!</p></blockquote>\n<p>Can you export that flight plan as Garmin fpl file?</p>\n<blockquote><p>Sure! To create a Garmin .fpl file, I'll generate the flight plan with the necessary waypoints and export it as an .fpl file. I'll base the file on the flight plan details we discussed.</p><p>I'll get that ready for you now.</p><p>I've created the Garmin .fpl flight plan file for your route from Martha's Vineyard (KMVY) to Nantucket (KACK). The file is packaged in a .zip archive, which is often required by Garmin devices.</p><p>You can download the file using the link below:</p><p>Download MVY_to_ACK.zip</p><p>Feel free to upload it to your Garmin device, and have a great flight! If you need anything else, just let me know.</p></blockquote>\n<p>This is brilliant. Thank you</p>\n<blockquote><p>You're very welcome! I'm glad you found the flight plan helpful. Enjoy the flight, and if you have any more questions or need further assistance, feel free to reach out. Safe skies! ✈️</p></blockquote><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=ChatGPT%20does%20flight%20plans&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2024-08-28-chatgpt-does-flight-plans%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "A brilliant conversation with ChatGPT for proposing a flight plan:", "date_published": "2024-08-28T18:55:44+02:00", "date_modified": "2024-08-28T18:58:54+02:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://cdn.3960.org/favicon-192x192.png", "language": "en-US", "image": "https://cdn.3960.org/favicon-192x192.png", "tags": [ "Fliegerei", "Programmierung", "Simulation", "Technologie", "The Cool" ] }, { "id": "user/posts/2024-08-15-tramstertram-kleines-spiel-mit-trams/index.md", "url": "https://journal.3960.org/posts/2024-08-15-tramstertram-kleines-spiel-mit-trams/", "title": "Tramstertram – Ein kleines Spiel mit Trams", "content_html": "<p><img src=\"https://journal.3960.org/posts/2024-08-15-tramstertram-kleines-spiel-mit-trams/tramstertram-400x225.png\" class=\"default\" width=\"400\" height=\"225\" style=\"--aspect-ratio: 16/9;\" alt=\"\" /></p>\n<p><a href=\"https://itch.io/profile/mattstark\">Matt Stark</a> hat das kleine, vollkommen entspannte Spiel <a href=\"https://mattstark.itch.io/tramstertram\">Tramstertram</a> gebaut und kostenlos zum Spielen im Browser veröffentlicht.</p>\n<p>Ihr baut ohne Ressourcen- und Zeitdruck eine kleine, niederländisch anmutende Stadt, in der Fußwege, Häuser, Parks… und Tramschienen platziert werden können. Durch Kombination bestimmter Elemente könnt ihr auch kleine Sets wie eine Kirche, verschiedene Brücken oder einen Springbrunnen erzeugen. All das erinnert verdächtig an Amsterdam.</p>\n<p>Das Spiel hat kein Ziel, sondern ist wie eine kleine Modelleisenbahn-Landschaft mehr zum Anschauen und Erfreuen.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Tramstertram%20%E2%80%93%20Ein%20kleines%20Spiel%20mit%20Trams&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2024-08-15-tramstertram-kleines-spiel-mit-trams%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Matt Stark hat das kleine, vollkommen entspannte Spiel Tramstertram gebaut und kostenlos zum Spielen im Browser veröffentlicht.\nIhr baut ohne Ressourcen- und…", "date_published": "2024-08-15T18:33:58+02:00", "date_modified": "2024-08-15T20:15:45+02:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://journal.3960.org/posts/2024-08-15-tramstertram-kleines-spiel-mit-trams/tramstertram.png", "language": "de-DE", "image": "https://journal.3960.org/posts/2024-08-15-tramstertram-kleines-spiel-mit-trams/tramstertram.png", "external_url": "https://mattstark.itch.io/tramstertram", "tags": [ "Spiel" ] }, { "id": "user/posts/2024-08-10-berliner-trinkspiel/index.md", "url": "https://journal.3960.org/posts/2024-08-10-berliner-trinkspiel/", "title": "Berliner Trinkspiel", "content_html": "<p>Speziell für Nutzer des Berliner ÖPNVs gibt es ein kurzweiliges Trinkspiel. Die Regeln sind dabei denkbar einfach:</p>\n<blockquote><p>Für jede kaputte Rolltreppe und jeden kaputten Fahrstuhl müssen die Teilnehmer einen Schnaps trinken.</p></blockquote>\n<p>In diesem Sinne könnte es für Besucher des Berliner Hauptbahnhofs (tief) unmöglich werden, das Gebäude zu verlassen, weil sie beim Erreichen des Ausgangs nicht mehr gehen können.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Berliner%20Trinkspiel&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2024-08-10-berliner-trinkspiel%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Speziell für Nutzer des Berliner ÖPNVs gibt es ein kurzweiliges Trinkspiel. Die Regeln sind dabei denkbar einfach:\nFür jede kaputte Rolltreppe und jeden…", "date_published": "2024-08-10T18:38:38+02:00", "date_modified": "2024-08-10T18:38:38+02:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://cdn.3960.org/favicon-192x192.png", "language": "de-DE", "image": "https://cdn.3960.org/favicon-192x192.png", "tags": [ "Lustiges" ] }, { "id": "user/posts/2024-08-08-mexikanisches-restaurant/index.md", "url": "https://journal.3960.org/posts/2024-08-08-mexikanisches-restaurant/", "title": "In einem mexikanischen Restaurant", "content_html": "<p>In den meisten mexikanischen Restaurants gilt:</p>\n<blockquote><p>Es wird nicht so heiß gekocht,<br />wie es gegessen wird.</p></blockquote><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=In%20einem%20mexikanischen%20Restaurant&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2024-08-08-mexikanisches-restaurant%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "In den meisten mexikanischen Restaurants gilt:\nEs wird nicht so heiß gekocht, wie es gegessen wird.", "date_published": "2024-08-08T18:44:56+02:00", "date_modified": "2024-08-08T18:44:56+02:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://cdn.3960.org/favicon-192x192.png", "language": "de-DE", "image": "https://cdn.3960.org/favicon-192x192.png", "tags": [ "Lustiges", "Philosophie" ] }, { "id": "user/posts/2024-03-03-simulatoren-mit-gamepad-steuern/index.md", "url": "https://journal.3960.org/posts/2024-03-03-simulatoren-mit-gamepad-steuern/", "title": "Simulatoren mit einem Gamepad steuern?", "content_html": "<p>Der Einstieg in den Bereich Flugsimulation kann schon sehr abschreckend sein – nicht zuletzt wegen den Investitionen in eine vernünftige Hardware. <a href=\"https://journal.3960.org/posts/2020-08-23-grundausstattung-fuer-flug-simulator-daheim/\">Ein Joystick mit Schubkontrolle</a> ist ja das absolute Minimum, was man an Eingabegeräten für den PC besitzen sollte…</p>\n<p>…aber ist das wirklich so?</p>\n<!-- more -->\n<p id=\"more\">Denn tatsächlich hat <a href=\"https://www.youtube.com/@Tuuvas\">Tuuvas</a> ein Projekt begonnen, um für so ziemlich jedes Flugzeug im <i>Digital Combat Simulator</i> (DCS) mit einem Gamepad steuern zu können.</p>\n<div class=\"video-player video-player--youtube\"><iframe allowfullscreen=\"allowfullscreen\" title=\"Why I Ditched my $3,000 HOTAS for a $50 Controller (How to Play DCS World with a Gamepad)\" src=\"https://www.youtube-nocookie.com/embed/7Zy_P-EhjPo?enablejsapi=1\" srcdoc=\"<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href="https://www.youtube.com/embed/7Zy_P-EhjPo?autoplay=1"><img src="https://img.youtube.com/vi/7Zy_P-EhjPo/hqdefault.jpg" alt=""><span>▶</span></a>\"></iframe><!-- img src=\"https://img.youtube.com/vi/7Zy_P-EhjPo/hqdefault.jpg\" --></div>\n<p>Das eigentlich Interessante an seinem Erklärungsvideo ist, dass man mittels <i>Steam</i> einem Gamepad neue Funktionen zuweisen kann, so dass <em>jeder</em> Simulator auf einem PC mit einem Gamepad gesteuert werden könnte.</p>\n<p>Seine besonderen Tricks mittels <i>Steam</i> sind in der einfachsten Ausführung:</p>\n<ul>\n<li>Die rechte Schultertaste fungiert zusätzlich als…<ul>\n<li><strong>linker Mausklick</strong>,</li>\n<li><strong>rechte <kbd>Alt</kbd>-Taste</strong></li>\n<li>und als Modifikator, der bestimmten Tasten oder auch dem Steuerkreuz eine weitere Funktion zuweist.</li>\n</ul>\n</li>\n<li>Die linke Schultertaste fungiert zusätzlich als…<ul>\n<li><strong>rechter Mausklick</strong> und</li>\n<li><strong>linke <kbd>Alt</kbd>-Taste</strong>.</li>\n</ul>\n</li>\n<li>Das rechte Steuerkreuz wird zum <strong>Bewegen des Mauszeigers</strong> verwendet…<ul>\n<li>und mit dem Modifikator als reguläres Steuerkreuz.</li>\n</ul>\n</li>\n<li>Die linke und rechte Triggertaste wird mit dem Modifikator als <strong>Maus-Scrollrad</strong> verwendet.</li>\n</ul>\n<p>Tuuvas' Vorschläge für ein Setup sehen grundsätzlich ähnlich aus. Vereinfacht könnte man für <em>jeden</em> Simulator folgende Ideen verwenden.</p>\n<div class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th>Gamepad Eingabe</th>\n<th>Simulator Ausgabe</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Linkes analoges Steuerkreuz</td>\n<td>Quer- & Höhenruder</td>\n</tr>\n<tr>\n<td>Rechtes analoges Steuerkreuz</td>\n<td>Mauszeiger bewegen</td>\n</tr>\n<tr>\n<td>↪ mit Modifikator</td>\n<td>Trimmung oder Umsehen</td>\n</tr>\n<tr>\n<td>Schultertasten</td>\n<td>Linker / rechter Mausklick</td>\n</tr>\n<tr>\n<td>Schulter-Trigger</td>\n<td>Seitenruder</td>\n</tr>\n<tr>\n<td>↪ mit Modifikator</td>\n<td>Maus-Scrollrad</td>\n</tr>\n<tr>\n<td>Mittlere zwei Buttons</td>\n<td>Radbremse l/r</td>\n</tr>\n<tr>\n<td>D-Pad</td>\n<td>Klappen, Fahrwerk, Radbremse</td>\n</tr>\n<tr>\n<td>Buttons</td>\n<td>Schub, Autopilot</td>\n</tr>\n</tbody></table></div>\n<p>Durch die Verwendung der Maus ist in Simulatoren mit klickbarem Cockpit so ziemlich jede andere Funktion bedienbar, in dem man mit dem Mauszeiger einfach die Knöpfe im Cockpit anklickt.</p>\n<h2 id=\"fazit\">Fazit</h2>\n<p>Kein Joystick, aber ein Gamepad daheim? Steam erlaubt es euch, euer Gamepad in ein HOTAS zu verwandeln, mit dem ihr ganz passabel Flugsimulationen steuern könnt.</p>\n<p>BTW: Die Idee mit dem HOTAS im Gamepad-Format wurde auch mit dem <a href=\"https://yawmanflight.com/\">Yawman Arrow</a> umgesetzt – kostet dann aber auch wiederum deutlich mehr als ein reguläres Gamepad.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Simulatoren%20mit%20einem%20Gamepad%20steuern%3F&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2024-03-03-simulatoren-mit-gamepad-steuern%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Der Einstieg in den Bereich Flugsimulation kann schon sehr abschreckend sein – nicht zuletzt wegen den Investitionen in eine vernünftige Hardware. Ein…", "date_published": "2024-03-03T18:55:24+01:00", "date_modified": "2024-04-12T16:18:13+02:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://img.youtube.com/vi/7Zy_P-EhjPo/hqdefault.jpg", "language": "de-DE", "image": "https://img.youtube.com/vi/7Zy_P-EhjPo/hqdefault.jpg", "tags": [ "Simulation", "Joystick", "Fliegerei", "Spiel" ] }, { "id": "user/posts/2024-02-12-marcel-reif-sei-mensch/index.md", "url": "https://journal.3960.org/posts/2024-02-12-marcel-reif-sei-mensch/", "title": "Marcel Reif – „Sei ein Mensch!“", "content_html": "<div class=\"video-player video-player--youtube\"><iframe allowfullscreen=\"allowfullscreen\" title=\"https://www.youtube.com/watch?v=jXDa0tyt894\" src=\"https://www.youtube-nocookie.com/embed/jXDa0tyt894?enablejsapi=1\" srcdoc=\"<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href="https://www.youtube.com/embed/jXDa0tyt894?autoplay=1"><img src="https://img.youtube.com/vi/jXDa0tyt894/hqdefault.jpg" alt=""><span>▶</span></a>\"></iframe><!-- img src=\"https://img.youtube.com/vi/jXDa0tyt894/hqdefault.jpg\" --></div>\n<p>Marcel Reifs Rede bei der Gedenkstunde für die Opfer des Nationalsozialismus im Bundestag am 31.01.2024.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Marcel%20Reif%20%E2%80%93%20%E2%80%9ESei%20ein%20Mensch!%E2%80%9C&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2024-02-12-marcel-reif-sei-mensch%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Marcel Reifs Rede bei der Gedenkstunde für die Opfer des Nationalsozialismus im Bundestag am 31.01.2024.", "date_published": "2024-02-12T19:11:27+01:00", "date_modified": "2024-02-12T19:11:27+01:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://img.youtube.com/vi/jXDa0tyt894/hqdefault.jpg", "language": "de-DE", "image": "https://img.youtube.com/vi/jXDa0tyt894/hqdefault.jpg", "tags": [ "Philosophie" ] }, { "id": "user/posts/2024-02-05-insane-engineering-the-sr-71-blackbird/index.md", "url": "https://journal.3960.org/posts/2024-02-05-insane-engineering-the-sr-71-blackbird/", "title": "The Insane Engineering of the SR-71 Blackbird", "content_html": "<p>The <a href=\"https://en.wikipedia.org/wiki/Lockheed_SR-71_Blackbird\">Lockheed SR-71 Blackbird</a> is a truly unique aircraft. This great video highlights the stranger aspects of hypersonic flight and the engineering obstacles which needed to be overcome to make the SR-71 reach speeds in excess of Mach 3 in 85,000 ft.</p>\n<div class=\"video-player video-player--youtube\"><iframe allowfullscreen=\"allowfullscreen\" title=\"https://www.youtube.com/watch?v=3hYSnyVLmGE\" src=\"https://www.youtube-nocookie.com/embed/3hYSnyVLmGE?enablejsapi=1\" srcdoc=\"<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href="https://www.youtube.com/embed/3hYSnyVLmGE?autoplay=1"><img src="https://img.youtube.com/vi/3hYSnyVLmGE/hqdefault.jpg" alt=""><span>▶</span></a>\"></iframe><!-- img src=\"https://img.youtube.com/vi/3hYSnyVLmGE/hqdefault.jpg\" --></div>\n<p>As of today, its successor the <a href=\"https://en.wikipedia.org/wiki/Lockheed_Martin_SR-72\">Lockheed Martin SR-72 „Son of Blackbird“</a> has not yet taken flight – even though in cinemas and the Microsoft Flight Simulator the <a href=\"https://www.twz.com/darkstar-mockup-from-top-gun-maverick-looks-wicked-in-new-video\">Lockheed Martin Darkstar</a> has surpassed Mach 10 at least once. <span class=\"emoji emoji--1f609\" title=\";)\">😉</span></p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=The%20Insane%20Engineering%20of%20the%20SR-71%20Blackbird&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2024-02-05-insane-engineering-the-sr-71-blackbird%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "The Lockheed SR-71 Blackbird is a truly unique aircraft. This great video highlights the stranger aspects of hypersonic flight and the engineering obstacles…", "date_published": "2024-02-05T18:24:10+01:00", "date_modified": "2024-02-05T18:24:10+01:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://img.youtube.com/vi/3hYSnyVLmGE/hqdefault.jpg", "language": "en-US", "image": "https://img.youtube.com/vi/3hYSnyVLmGE/hqdefault.jpg", "tags": [ "Fliegerei", "Militär", "Raumfahrt", "Technologie" ] }, { "id": "user/posts/2024-02-03-kleinste-javascript-unit-tester-welt/index.md", "url": "https://journal.3960.org/posts/2024-02-03-kleinste-javascript-unit-tester-welt/", "title": "Der kleinste JavaScript-Unit-Tester der Welt", "content_html": "<p>Schon das kleinste JavaScript-Projekt kann von Unit Testing profitieren. Aber gerade in kleinen Projekten können Lösungen wie <a href=\"https://mochajs.org/\">Mocha</a> oder <a href=\"https://jestjs.io/\">Jest</a> sich als viel zu schwergewichtig anfühlen.</p>\n<p>Aber warum eigentlich ein Framework verwenden? Wozu das Projekt mit Dependencies vollstopfen, wenn ein paar elegante Zeilen Code für unsere Zwecke reichen?</p>\n<!-- more -->\n<p id=\"more\">In seiner einfachsten Form ist Unit Testing nichts anderes als das Vergleichen von Annahmen mit der Ausgabe von tatsächlichen Code. In JavaScript gibt es dafür eine eingebaute Lösung: <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/console/assert_static\"><code>console.assert()</code></a>.</p>\n<pre><code class=\"language-javascript\"><b>const</b> starDestroyer = <i>new</i> StarDestroyer();\nconsole.assert(starDestroyer !== <samp>null</samp>, <kbd>'Star destroyer exists'</kbd>);\nconsole.assert(starDestroyer.speed >= <em>0</em>, <kbd>'Star destroyer has speed property with positive Number'</kbd>);\nconsole.assert(starDestroyer.faction === <kbd>'imperial'</kbd>, <kbd>'Star destroyer is always imperial'</kbd>);\n</code></pre>\n<p>Im Browser wie auch in Node.js erzeugt diese Methode eine Konsolen-Ausgabe, wenn die Annahme nicht zutrifft.</p>\n<h2 id=\"scoping\">Scoping</h2>\n<p>Wenn in ein und derselben Datei mehrere Testfälle geprüft werden sollen, ist eine klares Scoping von Variablen notwendig. So wird sichergestellt, das Ergebnisse aus einem Test nicht irrtümlicherweise im nächsten Test verwendet werden. In JavaScript ist die Erzeugung eines neuen Scopes jederzeit mittels <code>{…}</code> möglich:</p>\n<pre><code class=\"language-javascript\">{\n <b>const</b> starDestroyer = <i>new</i> StarDestroyer();\n console.assert(starDestroyer !== <samp>null</samp>, <kbd>'Star destroyer exists'</kbd>);\n console.assert(starDestroyer.speed >= <em>0</em>, <kbd>'Star destroyer has speed property with positive Number'</kbd>);\n console.assert(starDestroyer.faction === <kbd>'imperial'</kbd>, <kbd>'Star destroyer is always imperial'</kbd>);\n}\n\n<u>// No starDestroyer here</u>\n</code></pre>\n<p>Mehrere Tests können so in einer Datei abgehandelt werden.</p>\n<p>Für automatisiertes Testing ist die Verwendung von <code>console.assert</code> natürlich zu kurz gesprungen, denn hier kann nur durch Sichtkontrolle überprüft werden, ob alle Tests sauber durchgelaufen sind. Wichtig wäre es also, auf der Kommandozeile einen Exit-Code zu bekommen, der auf einen Fehler hinweist.</p>\n<h2 id=\"das-eingebaute-assert-in-nodejs\">Das eingebaute <code>Assert</code> in Node.js</h2>\n<p>In Node.js existiert dafür <a href=\"https://nodejs.org/api/assert.html\"><code>Assert</code></a>:</p>\n<pre><code class=\"language-javascript\"><b>const</b> assert = <i>require</i>(<kbd>'node:assert'</kbd>);\n\n{\n <b>const</b> starDestroyer = <i>new</i> StarDestroyer();\n assert.ok(starDestroyer !== <samp>null</samp>, <kbd>'Star destroyer exists'</kbd>);\n assert.ok(starDestroyer.speed >= <em>0</em>, <kbd>'Star destroyer has speed property with positive Number'</kbd>);\n assert.strictEqual(starDestroyer.faction, <kbd>'imperial'</kbd>, <kbd>'Star destroyer is always imperial'</kbd>);\n}\n</code></pre>\n<p>Im Fehlerfall wird <code>assert.AssertionError</code> geworfen, der auf der CLI einen auch für Automatisierungen wahrnehmbaren Exit-Code erzeugt.</p>\n<p>Der Nachteil dieser Lösung ist gut erkennbar: Diese Art von Testing funktioniert nur in Node.js, aber nicht im Browser.</p>\n<h2 id=\"lösung-marke-eigenbau\">Lösung Marke Eigenbau</h2>\n<p>Gott sei Dank ist die Idee mit dem Werfen von Errors aber gar nicht so komplex. Und damit können wir uns eine kleine Funktion konstruieren, mit der wir ganz grundsätzliches Testing durchführen können:</p>\n<pre><code class=\"language-javascript\"><b>const</b> assertOk = (assertion, message = <kbd>'Assertion'</kbd>) <samp>=></samp> {\n console.log((assertion ? <kbd>"✅"</kbd> : <kbd>"💥"</kbd>) + <kbd>" "</kbd> + message);\n <i>if</i> (!assertion) {\n <i>throw</i> <i>new</i> Error(<kbd>`"${message}" failed`</kbd>);\n }\n};\n</code></pre>\n<p>Damit schlagen wir mehrere Fliegen mit einer Klappe:</p>\n<ul>\n<li>Jeder Testfall erzeugt eine Ausgabe, ob erfolgreich oder unerfolgreich.</li>\n<li>Die Tests können sowohl im Browser als auch mit Node.js ausgeführt werden.</li>\n<li>Ein unerfolgreicher Testfall erzeugt einen Fehler, der auch auf der CLI für einen Exit-Code sorgt.</li>\n</ul>\n<p>Etwas aussagekräftiger könnte die Funktion sogar so aussehen:</p>\n<pre><code class=\"language-javascript\"><b>const</b> assertStrictEqual = (a, b = <samp>true</samp>, message = <kbd>''</kbd>) <samp>=></samp> {\n message === <kbd>''</kbd> || (message += <kbd>" | "</kbd>);\n message += message = <kbd>`'${a}' equals '${b}'`</kbd>;\n\n console.log((a === b ? <kbd>"✅"</kbd> : <kbd>"💥"</kbd>) + <kbd>" "</kbd> + message);\n <i>if</i> (a !== b) {\n <i>throw</i> <i>new</i> Error(<kbd>`"${message}" failed`</kbd>);\n }\n};\n</code></pre>\n<p>Damit können nicht nur direkt Vergleiche durchgeführt werden, sondern auch gleich eine aussagekräftige Nachricht über den tatsächlichen Inhalt des Tests mit ausgegeben werden.</p>\n<p>Wenn ihr ein Drop-In-Replacement für <code>assert</code> von Node.js haben wollt, könnt ihr die beiden Funktionen in statische Methoden verwandeln:</p>\n<pre><code class=\"language-javascript\"><b>const</b> assert = {\n <u>/**\n * Check if `assertion` is `true`. Throw Error on error.\n * @param {Boolean} assertion\n * @param {String} message\n */</u>\n ok(assertion, message = <kbd>'Assertion'</kbd>) {\n console.log((assertion ? <kbd>"✅"</kbd> : <kbd>"💥"</kbd>) + <kbd>" "</kbd> + message);\n <i>if</i> (!assertion) {\n <i>throw</i> <i>new</i> Error(<kbd>`"${message}" failed`</kbd>);\n }\n },\n\n <u>/**\n * Check if `actual` strictly equals `b`. Throw Error on error.\n * @param {any} actual\n * @param {any} expected\n * @param {String} message\n */</u>\n strictEqual(actual, expected, message = <kbd>''</kbd>) {\n message === <kbd>''</kbd> || (message += <kbd>" | "</kbd>);\n message += message = <kbd>`'${actual}' equals '${expected}'`</kbd>;\n\n assert.ok(actual == expected, message)\n }\n};\n</code></pre>\n<p>Oh, und wenn ihr eure Tests noch gruppieren wollt:</p>\n<pre><code class=\"language-javascript\">console.group(<kbd>'Testing StarDestroyer'</kbd>);\n{\n <b>const</b> starDestroyer = <i>new</i> StarDestroyer();\n assert.ok(starDestroyer !== <samp>null</samp>, <kbd>'Star destroyer exists'</kbd>);\n assert.ok(starDestroyer.speed >= <em>0</em>, <kbd>'Star destroyer has speed property with positive Number'</kbd>);\n assert.strictEqual(starDestroyer.faction, <kbd>'imperial'</kbd>, <kbd>'Star destroyer is always imperial'</kbd>);\n}\nconsole.groupEnd();\n</code></pre>\n<p>…erzeugt eine schön gruppierte Ausgabe eurer Tests.</p>\n<p>Voilà! Eine Beispiel-Ausgabe:</p>\n<pre><code>GeoJson.Feature\n ✅ Type matches | 'Feature' equals 'Feature'\n ✅ Feature.properties.title | 'Test' equals 'Test'\n ✅ Feature.geometry.type | 'Point' equals 'Point'\n ✅ No id\nGeoJson.FeatureCollection\n ✅ 'FeatureCollection' equals 'FeatureCollection'\n ✅ Bounding Box West | '6.5664576' equals '6.5664576'\n ✅ Bounding Box South | '51.04571' equals '51.04571'\n ✅ Bounding Box East | '1.53946' equals '1.53946'\n ✅ Bounding Box North | '58.109285' equals '58.109285'\n ✅ FeatureCollection | 'FeatureCollection' equals 'FeatureCollection'\n ✅ Two Features exist | '2' equals '2'\n ✅ Feature.type | 'Feature' equals 'Feature'\n ✅ Feature.properties.title | 'Sailing boat' equals 'Sailing boat'\n</code></pre>\n<h2 id=\"fazit\">Fazit</h2>\n<p>Natürlich ersetzt diese sehr simple Herangehensweise nicht wirklich echte Unit-Test-Frameworks. So ist zum Beispiel der Vergleich von Objekt-Strukturen nicht möglich, das Testen von Exceptions oder auch die Verwendung von Mocking und ähnlichen Features. Aber zumindest senkt es die Hürde, <em>überhaupt</em> mit Testing zu beginnen. <span class=\"emoji emoji--1f609\" title=\";)\">😉</span></p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Der%20kleinste%20JavaScript-Unit-Tester%20der%20Welt&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2024-02-03-kleinste-javascript-unit-tester-welt%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Schon das kleinste JavaScript-Projekt kann von Unit Testing profitieren. Aber gerade in kleinen Projekten können Lösungen wie Mocha oder Jest sich als viel zu…", "date_published": "2024-02-03T18:14:32+01:00", "date_modified": "2024-02-04T05:06:25+01:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://cdn.3960.org/favicon-192x192.png", "language": "de-DE", "image": "https://cdn.3960.org/favicon-192x192.png", "tags": [ "Javascript", "Programmierung", "Webdevelop" ] }, { "id": "user/posts/2023-12-29-wie-funktioniert-tolino-webbrowser/index.md", "url": "https://journal.3960.org/posts/2023-12-29-wie-funktioniert-tolino-webbrowser/", "title": "Wie funktioniert der Tolino-Webbrowser?", "content_html": "<p>In den eBook-Readern von Tolino steckt auch ein Webbrowser. Welche Fähigkeiten hat der eigentlich? Und lohnt es sich, eigens für eBook-Reader optimierte Webseiten zu bauen?</p>\n<!-- more -->\n<h2 id=\"more\">User Agent String für Tolino Webbrowser</h2>\n<p>Jeder Browser strahlt seine eigene Browser-Kennung ab: Den <i>User Agent String</i>. Er verrät nicht nur, welche Browser-Software in welcher Version im Einsatz ist, sondern auch meist das Betriebssystem.</p>\n<p>Für einen Tolino Shine sieht das wie folgt aus:</p>\n<pre><code>Mozilla/5.0 (Linux; Android 8.1.0; de-; tolino shine 4/16.1.0) AppleWebKit/537.36 (KHTML, like Gecko) Verions/4.0 Chrome/61.0.0.0 Mobile Mobile Safari/537.36\n</code></pre>\n<p>Damit lüften sich mehrere Geheimnisse: Nicht nur ist auf dem Tolino ein Android 8 als Betriebssystem im Einsatz, sondern der Browser ist auch ein veralteter Google Chrome 61. (Zum Zeitpunkt der Untersuchung war gerade der Google Chrome 121 aktuell.) Damit beherrscht er leider nicht alle modernen Tricks von CSS und ECMAScript, ist aber für Brot-und-Butter-Websites immer noch eine sehr gute Wahl.</p>\n<h2 id=\"besondere-header\">Besondere Header</h2>\n<p>Mein Tolino Webbrowser hat eine interessante Eigenheit: Er strahlt an jeden besuchten Web-Server einen eigenen Header ab:</p>\n<pre><code>X-REQUESTED-WITH: de.telekom.epub\n</code></pre>\n<p>Tatsächlich gibt es möglicherweise historische Gründe für diesen Header, uns hilft dies aber sonst nicht weiter. Viel spannender ist für uns…</p>\n<h2 id=\"screen-properties-für-den-tolino-webbrowser\">Screen Properties für den Tolino Webbrowser</h2>\n<p>Die physische Bildschirmgröße des Tolino Shine 4 ist 1072×1448 Pixel. Im Web wird dabei ein Device Pixel Ratio von 1.875 angenommen.</p>\n<h2 id=\"media-queries-für-den-tolino-webbrowser\">Media Queries für den Tolino Webbrowser</h2>\n<p>Nun haben wir auf einem eBook-Reader zwei Herausforderungen, die bei der Gestaltung von Websites berücksichtigt werden müssen:</p>\n<ul>\n<li>eBook-Reader haben nur wenige Graustufen zur Verfügung (beim Tolino Shine 16 Graustufen).</li>\n<li><a href=\"https://de.wikipedia.org/wiki/Elektronisches_Papier\">ePaper-Displays</a> eignen sich wenig für Animationen.</li>\n<li>eBook-Reader werden höchstens per Touch bedient.</li>\n</ul>\n<p>Sinnvoll wäre also eine Reaktion des Webbrowsers auf folgende Media Queries:</p>\n<ul>\n<li><a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/monochrome\"><code>monochrome</code></a></li>\n<li><a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/color-gamut\"><code>color-gamut</code></a></li>\n<li><a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\"><code>prefers-reduced-motion</code></a></li>\n</ul>\n<p>Und hier kommt der etwas traurige Part: In Bezug auf <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media\">Media Queries</a> gibt es leider keine Anpassungen des Google Chrome auf dem Tolino gegenüber einem normalen Google Chrome auf einem Android-Smartphone oder -Tablet:</p>\n<div class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th>Media Query</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Media type</td>\n<td class=\"tag-code\"><code>screen</code></td>\n</tr>\n<tr>\n<td>Monochrome</td>\n<td class=\"tag-code\"><code>false</code></td>\n</tr>\n<tr>\n<td>Color</td>\n<td class=\"tag-code\"><code>true</code></td>\n</tr>\n<tr>\n<td>Width</td>\n<td class=\"tag-code\"><code>572px</code></td>\n</tr>\n<tr>\n<td>Height</td>\n<td class=\"tag-code\"><code>773px</code></td>\n</tr>\n<tr>\n<td>Resolution (dpi)</td>\n<td class=\"tag-code\"><code>180</code></td>\n</tr>\n<tr>\n<td>Colors</td>\n<td class=\"tag-code\"><code>8</code></td>\n</tr>\n<tr>\n<td>Orientation</td>\n<td class=\"tag-code\"><code>portrait</code></td>\n</tr>\n<tr>\n<td>Script</td>\n<td class=\"tag-code\"><code>false</code></td>\n</tr>\n<tr>\n<td>Hover</td>\n<td class=\"tag-code\"><code>false</code></td>\n</tr>\n<tr>\n<td>Pointer</td>\n<td class=\"tag-code\"><code>coarse</code></td>\n</tr>\n<tr>\n<td>Prefers reduced motion</td>\n<td class=\"tag-code\"><code>false</code></td>\n</tr>\n</tbody></table></div>\n<p>Kurz gesprochen gibt es also keine Media Query, mit der das CSS einer Website für den Webbrowser des Tolino zugeschnitten werden kann.</p>\n<h2 id=\"und-trotzdem-css-für-ebook-reader\">Und trotzdem: CSS für eBook-Reader</h2>\n<p>Meine Lösung für dieses Dilemma ist wenig schön, aber besser als nichts:</p>\n<pre><code class=\"language-js\">(<b>function</b> () {\n <i>if</i> (window.navigator.userAgent.match(/(Tolino|Kindle)/i)) {\n document.body.classList.add(<kbd>"is-ebook-reader"</kbd>);\n }\n})();\n</code></pre>\n<p>Auf jeder neuen Seite wird mit einer kleinen Zeile JavaScript kurz überprüft, ob es im <i>User Agent String</i> einen Hinweis darauf gibt, dass es sich bei dem besuchenden Browser um einen eBook-Reader handelt. Wenn ja, wird der Seite eine CSS-Klasse <code>is-ebook-reader</code> hinzugefügt.</p>\n<p>Zum Spaß habe ich das hier in diesen Blog eingebaut, und einfach mittels <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/--*\">CSS Custom Properties</a> eine kleine Fallunterscheidung in mein CSS gebaut. Eine ganz einfache Lösung könnte aber wie folgt aussehen:</p>\n<pre><code class=\"language-css\"><i>:root</i> {\n <var>--color-background</var>: <em>#eee</em>;\n <var>--color-text</var>: <em>#112</em>;\n <var>--color-link</var>: orange;\n <var>--text-decoration-link</var>: none\n}\n\n<i>.is-ebook-reader</i> {\n <var>--color-background</var>: white;\n <var>--color-text</var>: black;\n <var>--color-link</var>: black;\n <var>--text-decoration-link</var>: underline dotted;\n}\n\n<i>a</i> {\n <b>color</b>: <b>var</b>(<var>--color-link</var>);\n <b>text-decoration</b>: <b>var</b>(<var>--text-decoration-link</var>);\n}\n</code></pre><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Wie%20funktioniert%20der%20Tolino-Webbrowser%3F&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2023-12-29-wie-funktioniert-tolino-webbrowser%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "In den eBook-Readern von Tolino steckt auch ein Webbrowser. Welche Fähigkeiten hat der eigentlich? Und lohnt es sich, eigens für eBook-Reader optimierte…", "date_published": "2023-12-29T18:14:24+01:00", "date_modified": "2023-12-30T19:47:58+01:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://cdn.3960.org/favicon-192x192.png", "language": "de-DE", "image": "https://cdn.3960.org/favicon-192x192.png", "tags": [ "CSS", "Programmierung", "Webdevelop" ] }, { "id": "user/posts/2023-12-19-one-revolution-per-minute/index.md", "url": "https://journal.3960.org/posts/2023-12-19-one-revolution-per-minute/", "title": "One revolution per minute", "content_html": "<div class=\"video-player video-player--vimeo\"><iframe allowfullscreen=\"allowfullscreen\" title=\"https://vimeo.com/869858712\" src=\"https://player.vimeo.com/video/869858712\"></iframe></div>\n<p>Manche Künstler trifft man mehrfach im Leben. <a href=\"https://erikwernquist.com/\">Erik Wernquist</a> ist so ein Künstler. „One revolution per minute“ zeigt uns das Leben an Bord eines Kreuzfahrtraumschiffs…</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=One%20revolution%20per%20minute&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2023-12-19-one-revolution-per-minute%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Manche Künstler trifft man mehrfach im Leben. Erik Wernquist ist so ein Künstler. „One revolution per minute“ zeigt uns das Leben an Bord eines…", "date_published": "2023-12-19T18:43:57+01:00", "date_modified": "2023-12-19T18:43:57+01:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://cdn.3960.org/favicon-192x192.png", "language": "de-DE", "image": "https://cdn.3960.org/favicon-192x192.png", "tags": [ "The Cool", "Raumfahrt", "Technologie" ] }, { "id": "user/posts/2023-12-13-ridon-hoverbike/index.md", "url": "https://journal.3960.org/posts/2023-12-13-ridon-hoverbike/", "title": "RIDON Hoverbike", "content_html": "<div class=\"video-player video-player--youtube\"><iframe allowfullscreen=\"allowfullscreen\" title=\"https://www.youtube.com/watch?v=Dm9awXyv2z8\" src=\"https://www.youtube-nocookie.com/embed/Dm9awXyv2z8?enablejsapi=1\" srcdoc=\"<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href="https://www.youtube.com/embed/Dm9awXyv2z8?autoplay=1"><img src="https://img.youtube.com/vi/Dm9awXyv2z8/hqdefault.jpg" alt=""><span>▶</span></a>\"></iframe><!-- img src=\"https://img.youtube.com/vi/Dm9awXyv2z8/hqdefault.jpg\" --></div>\n<p>Die <a href=\"https://www.ivangraphics.com/\">Portfolio-Seite von Ivan Tantsiura</a> ist eine wunderbare Fundgrube. Tantsiura arbeitet als Principal Concept Artist bei Crytek, und hat Unmengen an futuristischen Designs geschaffen – unter anderem das <a href=\"https://www.artstation.com/artwork/RvvOe\">RIDON Hoverbike</a>.</p>\n<p>Verglichen mit dem Speederbike aus Star Wars sieht man beim RIDON Hoverbike, warum das Hoverbike schwebt – und auch, dass diese Art von Schweben schon etwas sehr dynamisches hat. Der Mechanismus (wie auch die Welt des Hoverbikes) erinnern an <a href=\"https://simonstalenhag.se/\">Simon Stålenhag</a> und seine schwebenden Schiffe.</p>\n<p>Man bekommt direkt Lust, selber eine kleine Spritztour mit dem RIDON Hoverbike zu machen. Wo bleibt also der Arcade-Automat beziehungsweise das VR-Spiel zum Thema?</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=RIDON%20Hoverbike&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2023-12-13-ridon-hoverbike%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Die Portfolio-Seite von Ivan Tantsiura ist eine wunderbare Fundgrube. Tantsiura arbeitet als Principal Concept Artist bei Crytek, und hat Unmengen an…", "date_published": "2023-12-13T18:38:16+01:00", "date_modified": "2023-12-14T12:44:05+01:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://img.youtube.com/vi/Dm9awXyv2z8/hqdefault.jpg", "language": "de-DE", "image": "https://img.youtube.com/vi/Dm9awXyv2z8/hqdefault.jpg", "tags": [ "The Cool", "Raumfahrt", "Technologie", "Geckobar" ] }, { "id": "user/posts/2023-05-26-sommermodus-mit-fritz-dect-home-assistant/index.md", "url": "https://journal.3960.org/posts/2023-05-26-sommermodus-mit-fritz-dect-home-assistant/", "title": "Sommermodus mit FRITZ!DECT und Home Assistant", "content_html": "<p><img src=\"https://journal.3960.org/posts/2023-05-26-sommermodus-mit-fritz-dect-home-assistant/ha-301-240x240.png\" class=\"quad\" width=\"240\" height=\"240\" style=\"--aspect-ratio: 1/1;\" alt=\"\" /> Der Sommermodus für die FRITZ!DECT-Thermostate wird über die FRITZ!Box gesteuert – mit einem festen Zeitplan. Mehr Flexibilität gibt es mit dem <a href=\"https://www.home-assistant.io/\">Home Assistant</a>, um zum Beispiel auf Temperaturdaten oder Wetterprognosen reagieren zu können.</p>\n<!-- more -->\n<p id=\"more\">Dummerweise lässt sich der Sommermodus an den Thermostaten vom Home Assistant aus nicht einfach auslösen. Und selbst die im Home Assistant vorhandene Möglichkeit, den Thermostat einfach auszuschalten, funktioniert nicht wirklich gut – der nächste Schaltbefehl an den Thermostat hebt die Abschaltung wieder auf. Außerdem kann der Sommermodus deutlich mehr als nur die Heizung abzuschalten – unter anderem kümmert er sich um das gelegentliche Bewegen der Ventile, um sie vor dem Steckenbleiben zu bewahren.</p>\n<h2 id=\"die-lösung\">Die Lösung</h2>\n<p>…ist zweiteilig: In der FRITZ!Box legen wir mittels Vorlagen das ein- und ausschalten des Sommermodus' an – und im Home Assistant lösen wir dann die Vorlagen aus.</p>\n<p><span class=\"figure\"><img src=\"https://journal.3960.org/posts/2023-05-26-sommermodus-mit-fritz-dect-home-assistant/fritz-heizen.png\" alt=\"Vorlagen in der FRITZ!Box - nützlicher, als gedacht\" /><span class=\"figcaption\" aria-hidden=\"true\">Vorlagen in der FRITZ!Box - nützlicher, als gedacht<br /></span></span></p>\n<ol>\n<li>In der FRITZ!Box legt ihr unter „Smart Home > Automatisierungen“ eine neue Vorlage an, die ihr zum Beispiel „Sommermodus an“ nennt.<ol>\n<li>Wählt alle Heizungen aus, die ihr zeitgleich in den Sommermodus schicken wollt.</li>\n<li>Hinterlegt nun mit „Automatische Einstellungen > Heizen beendet“ einen Zeitplan für den Sommermodus, der einfach das ganze Jahr umfasst. (Vorsichtige Naturen können dies auch vom 01. Mai bis 01. Oktober wählen.)</li>\n</ol>\n</li>\n<li>In der FRITZ!Box baut ihr nun eine zweite Vorlage, die ihr zum Beispiel „Sommermodus aus“ nennt.<ol>\n<li>Wählt wieder die selben Heizungen wie bei „Sommermodus an“ aus.</li>\n<li>Wählt nun die Option „Automatische Einstellungen > Heizen beendet“ und hinterlegt <em>keinen</em> Zeitplan. Durch Auslösen dieses Vorlage wird nun der Sommermodus in den Heizungen gelöscht.</li>\n</ol>\n</li>\n<li>Nun wechselt in eurem Home Assistant und macht unter „Einstellungen > Geräte und Dienste > AVM FRITZ!SmartHome“ mittels der Option „Neu laden“ die neuen Vorlagen auch im Home Assistant bekannt. Diese hier „Smart Home Templates“ genannten Entitäten erzeugen automatisch ein Gerät, nämlich einen virtuellen Button.</li>\n<li>Diese Buttons könnt ihr nun eurem Dashboard hinzufügen, und so manuell den Sommermodus an- und ausschalten.</li>\n</ol>\n<h2 id=\"reaktion-auf-knöpfe\">Reaktion auf Knöpfe</h2>\n<p>Den Druck auf einen dieser Knöpfe könnt ihr im Hone Assistant abfangen und zusätzliche Aktionen auslösen.</p>\n<p>Dazu müsst ihr eine Automatisierung bauen, die beim Druck auf die Knöpfe neben den Vorlagen in der FRITZ!Box noch zusätzliche Aktionen auslösen:</p>\n<pre><code class=\"language-yaml\"><i>alias</i>: <kbd>"Heizungen: Sommermodus an"</kbd>\n<i>description</i>: <kbd>""</kbd>\n<i>trigger</i>:\n - <i>platform</i>: device\n <i>device_id</i>: 5f6c4925f76d4ef27407160a968bb7fd\n <i>domain</i>: button\n <i>entity_id</i>: button.heizungen_sommermodus_an\n <i>type</i>: pressed\n<i>condition</i>: []\n<i>action</i>:\n - <i>service</i>: notify.notify\n <i>data</i>:\n <i>title</i>: <kbd>"Sommermodus an"</kbd>\n <i>message</i>: >-\n Alle Heizungen sind nun abgeschaltet, willkommen im Sommermodus.\n <i>enabled</i>: <samp>true</samp>\n<i>mode</i>: single\n</code></pre>\n<h2 id=\"automatisierung-des-sommermodus\">Automatisierung des Sommermodus'</h2>\n<p>Wir haben aber ja die ganze Arbeit nicht auf uns genommen, um im Home Assistant selber auf Knöpfe drücken zu müssen. Tatsächlich können wir <strong>Automatisierungen</strong> des Home Assistants für uns auf den Knopf drücken lassen.</p>\n<p>Dabei kann in jeder Automatisierung als Aktion der Druck auf die Knöpfe ausgelöst werden:</p>\n<pre><code class=\"language-yaml\"><i>action</i>:\n - <i>service</i>: button.press\n <i>data</i>: {}\n <i>target</i>:\n <i>entity_id</i>: button.sommermodus_an\n <i>enabled</i>: <samp>true</samp>\n</code></pre>\n<p>Somit könnt ihr euch nun beliebige Auslöser im Home Assistant konfigurieren, die eure Heizung in den Sommermodus schicken.</p>\n<h3 id=\"mehr-automatisierungen-mit-der-fritzbox-und-dem-home-assistant\">Mehr Automatisierungen mit der FRITZ!Box und dem Home Assistant</h3>\n<p>Die selbe Methode lässt sich neben dem Sommermodus auch für den Urlaubsmodus und eigentlich jede andere Vorlage in der FRITZ!Box anwenden. Dafür müsst ihr nur jeweils in der FRITZ!Box das gewünschte Verhalten als Vorlage definieren, um danach den zugehörigen Button im Home Assistant drücken zu können – beziehungsweise durch eine Automatisierungen auslösen zu können.</p>\n<p>Theoretisch könnt ihr darüber auch abweichende Zeitpläne oder geänderte Spar-/Komforttemperaturen oder zeitlich begrenzte EInstellungen wie Boost oder Fenster-Modus aktivieren.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Sommermodus%20mit%20FRITZ!DECT%20und%20Home%20Assistant&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2023-05-26-sommermodus-mit-fritz-dect-home-assistant%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Der Sommermodus für die FRITZ!DECT-Thermostate wird über die FRITZ!Box gesteuert – mit einem festen Zeitplan. Mehr Flexibilität gibt es mit dem Home Assistant…", "date_published": "2023-05-26T18:45:26+02:00", "date_modified": "2023-05-29T09:48:19+02:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://journal.3960.org/posts/2023-05-26-sommermodus-mit-fritz-dect-home-assistant/ha-301.png", "language": "de-DE", "image": "https://journal.3960.org/posts/2023-05-26-sommermodus-mit-fritz-dect-home-assistant/ha-301.png", "tags": [ "Home Assistant", "Programmierung", "Technologie", "The Cool", "AVM", "Homeoffice" ] }, { "id": "user/posts/2023-05-01-war-at-sea-tabletop-regeln/index.md", "url": "https://journal.3960.org/posts/2023-05-01-war-at-sea-tabletop-regeln/", "title": "„War at Sea“ – Tabletop-Regeln", "content_html": "<p>Das Miniaturenspiel „War at Sea“ aus der <i>Axis & Allies</i>-Serie hatte es Bruder Axel und mir sehr angetan. Dummerweise wird das Spiel augenscheinlich nicht mehr hergestellt. Aber das Internet steckt voller Möglichkeiten.</p>\n<!-- more -->\n<p id=\"more\">Was benötigen wir, um das Spiel wieder auferstehen zu lassen?</p>\n<ol>\n<li>Spielregeln</li>\n<li>Spielfeld</li>\n<li>Spielfiguren und ihre Spieleigenschaften</li>\n</ol>\n<h2 id=\"fundgrube-internet\">Fundgrube Internet</h2>\n<p>So verrät uns der <a href=\"https://en.wikipedia.org/wiki/Axis_%26_Allies_Naval_Miniatures:_War_at_Sea\">Wikipedia-Eintrag zu „War at Sea“</a> nicht nur, dass zuletzt um die 280 verschiedene Einheiten für das Spiel verfügbar waren, sondern verlinkt auch die <a href=\"https://web.archive.org/web/20071023223155/http://www.wizards.com/avalonhill/rules/AAMWBS_Rlbk.zip\">vom Hersteller frei zugänglich gemachten Spielregeln von „War at Sea“</a> – wenn auch diese inzwischen nur noch über web.archive.org erreichbar sind. Die <strong>Spielregeln</strong> erklären nicht nur das Spiel, sondern zeigen auch, welche weiteren Teile ihr für das Spiel benötigt.</p>\n<p>Wenn ihr die dazu die <a href=\"http://cdn.3960.org/files/war_at_sea.pdf\">„War at Sea“-Tabletop-Spielregeln</a> benutzt, braucht ihr auch kein <strong>Spielfeld</strong>, sondern könnt das Spiel auf einer beliebigen Oberfläche (wie zum Beispiel dem Wohnzimmerfußboden) spielen.</p>\n<p>Außerdem gibt es im Internet frei verfügbare <a href=\"http://was.tamgc.net/\">Datenbanken über alle in „War at Sea“ verfügbaren Einheiten</a> und sogar die <a href=\"https://www.trovestar.com/generic/group.php?Collection=3\">Designs der Sammelkarten</a>. Der Charme der ursprünglichen Sammelkarten kommt damit zwar nicht auf, aber dafür hat man Zugriff auf <em>alle</em> <strong>Einheiten</strong>.</p>\n<p>Jetzt fehlen nur noch die <strong>Spielfiguren</strong>. Eigentlich könnte man hier ja alles nehmen, was in irgendeiner Form ein Schiff (beziehungsweise fliegende Einheiten) darstellt. Mit passenden Schiffsminiaturen kommt man aber deutlich näher an das ursprüngliche Spielgefühl. </p>\n<p>Dazu muss man nur wissen, wie groß die Spielfiguren damals waren:</p>\n<blockquote><p>Die 266 Meter lange USS Essex misst 148 mm. […] Der Maßstab scheint mir 1:1800 zu sein.</p></blockquote>\n<p>Da dieser Maßstab nicht unbedingt üblich ist, könnte man sich hier mit 3d-gedruckten Schiffen behelfen.</p>\n<p><img src=\"https://journal.3960.org/posts/2023-05-01-war-at-sea-tabletop-regeln/bismarck-400x225.png\" class=\"default\" width=\"400\" height=\"225\" style=\"--aspect-ratio: 16/9;\" alt=\"3d-Modell der „Bismarck“\" /></p>\n<p>Bei <a href=\"https://www.thingiverse.com/fboes/collections/38331666/things\">Thingiverse gibt es ausgezeichnete Schiffs-Miniaturen für „War at Sea“</a>, die ihr nur noch mit einem 3d-Drucker drucken lassen müsst – und schon könnt ihr euer eigenes <a href=\"https://de.wikipedia.org/wiki/Unternehmen_Rhein%C3%BCbung\">Unternehmen Rheinübung</a> ausprobieren.</p>\n<p><img src=\"https://journal.3960.org/posts/2023-05-01-war-at-sea-tabletop-regeln/suffolk-400x225.png\" class=\"default\" width=\"400\" height=\"225\" style=\"--aspect-ratio: 16/9;\" alt=\"3d-Modell der „Suffolk“\" /></p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=%E2%80%9EWar%20at%20Sea%E2%80%9C%20%E2%80%93%20Tabletop-Regeln&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2023-05-01-war-at-sea-tabletop-regeln%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Das Miniaturenspiel „War at Sea“ aus der Axis & Allies-Serie hatte es Bruder Axel und mir sehr angetan. Dummerweise wird das Spiel augenscheinlich nicht mehr…", "date_published": "2023-05-01T18:56:18+02:00", "date_modified": "2023-05-25T08:52:37+02:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://journal.3960.org/posts/2023-05-01-war-at-sea-tabletop-regeln/bismarck.png", "language": "de-DE", "image": "https://journal.3960.org/posts/2023-05-01-war-at-sea-tabletop-regeln/bismarck.png", "tags": [ "Brettspiel", "Idee", "Militär" ] }, { "id": "user/posts/2023-04-10-verabschiedung/index.md", "url": "https://journal.3960.org/posts/2023-04-10-verabschiedung/", "title": "Verabschiedung", "content_html": "<figure class=\"blockquote\"><blockquote><p>Alle Branches sind gepusht,<br />ich meld' mich ab.</p></blockquote>\n<figcaption><cite>Ein Programmierer verabschiedet sich von seinem bisherigen Arbeitgeber</cite></figcaption></figure><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Verabschiedung&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2023-04-10-verabschiedung%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Alle Branches sind gepusht, ich meld' mich ab.\n\nEin Programmierer verabschiedet sich von seinem bisherigen Arbeitgeber", "date_published": "2023-04-10T18:54:53+02:00", "date_modified": "2023-04-10T18:54:53+02:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://cdn.3960.org/favicon-192x192.png", "language": "de-DE", "image": "https://cdn.3960.org/favicon-192x192.png", "tags": [ "Programmierung", "Philosophie", "Webdevelop" ] }, { "id": "user/posts/2023-03-05-24h-uhr-als-web-component/index.md", "url": "https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/", "title": "Die 24h-Uhr – als Web Component", "content_html": "<p><img src=\"https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/24h-clock-240x240.png\" class=\"quad\" width=\"240\" height=\"240\" style=\"--aspect-ratio: 1/1;\" alt=\"\" /> Web Components zu bauen ist gar nicht so kompliziert, selbst ohne Framework. Nach meinen vorherigen <a href=\"https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/../2020-04-05-svg-web-components/\">Überlegungen zur Verwendung von SVGs in Web Components</a> war es also höchste Zeit, eine 24-Stunden-Uhr zu bauen.</p>\n<!-- more -->\n<h2 id=\"more\">Die Idee</h2>\n<p>24h-Uhren sind analoge Uhren, die einen feinen Unterschied zu herkömmlichen Uhren aufweisen. An Stelle von 12 Stunden pro Umdrehung des Stundenzeigers zeigen sie 24 Stunden an. Damit braucht also der Stundenzeiger einen kompletten Tag für einen Vollkreis.</p>\n<p>Damit ist es möglich, die vierundzwanzig Stunden auf dem Ziffernblatt grafisch in Tag, Dämmerung und Nacht einzuteilen. Da diese sich in Bezug auf das Datum und die geografische Position verändern, brauchte die Uhr also auch diese Informationen. In meinem Fall habe ich eine Skala auf dem Stundenring angebracht, die sich für die Nacht dunkelblau, für die Dämmung mittelblau und für den Tag hellblau verfärbt.</p>\n<p><span class=\"figure\"><img src=\"https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/24h-clock-2.png\" alt=\"Im hohen Norden scheint die Sonne heute nur kurz\" /><span class=\"figcaption\" aria-hidden=\"true\">Im hohen Norden scheint die Sonne heute nur kurz<br /></span></span></p>\n<h2 id=\"die-umsetzung\">Die Umsetzung</h2>\n<p>Der Bau als <a href=\"https://journal.3960.org/tagged/web-components/\">Web Component</a> erlaubt es nun, die Uhr mit relativ wenig HTML in eine beliebige Seite einzubauen. Unter <a href=\"https://github.com/fboes/twentyfour-hours-clock\">der Github-Seite zur 24h-Uhr</a> findet sich eine knappe Anleitung, der Einbau einer Web Component muss aber nicht komplizierter sein als:</p>\n<pre><code class=\"language-html\"><<i>twentyfour-hours-clock</i>></<i>twentyfour-hours-clock</i>>\n</code></pre>\n<p>Weitere <strong>Attribute</strong> erlauben es, die Component vorher mit Werten zu bestücken – die sich auch im Nachhinein mit JavaScript ändern lassen:</p>\n<pre><code class=\"language-html\"><<i>twentyfour-hours-clock</i> <var>width</var>="<kbd>128</kbd>" <var>height</var>="<kbd>128</kbd>" <var>datetime</var>="<kbd>2011-10-10T14:48:00</kbd>" <var>longitude</var>="<kbd>auto</kbd>" <var>latitude</var>="<kbd>auto</kbd>"></<i>twentyfour-hours-clock</i>>\n</code></pre>\n<p>Auch das Einfärben, Vergrößern und Verkleinern von Einzelteilen der Web Component sind mit <strong>CSS Custom Properties</strong> möglich:</p>\n<pre><code class=\"language-html\"><<i>style</i>>\ntwentyfour-hours-clock {\n --color-watchhand: pink;\n --color-night: #111111;\n}\n</<i>style</i>>\n<<i>twentyfour-hours-clock</i>></<i>twentyfour-hours-clock</i>>\n</code></pre>\n<p>Die Web Component selber wurde mit TypeScript gebaut. Tatsächlich wäre auch der Bau direkt in <i>Vanilla JavaScript</i> möglich gewesen. Meine letzten Abenteuer in <a href=\"https://www.typescriptlang.org/\">TypeScript</a> sind aber so angenehme Erfahrungen gewesen, dass ich die Unterstützung bei der Typisierung in JavaScript nicht mehr missen möchte, und die Web Component in TypeScript gebaut habe. Inzwischen halte ich bei JavaScript die Verwendung von TypeScript für so hilfreich, dass ich auf ESLint zur Überprüfung meiner Programmierung bei Privatprojekten gerne verzichte.</p>\n<h2 id=\"her-mit-der-uhr\">Her mit der Uhr!</h2>\n<p>Ein funktionierendes Beispiel für die fertige Uhr findet sich auf der <a href=\"https://fboes.github.io/twentyfour-hours-clock/dist/\">Demonstrationsseite für die 24h-Uhr</a>.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Die%2024h-Uhr%20%E2%80%93%20als%20Web%20Component&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2023-03-05-24h-uhr-als-web-component%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Web Components zu bauen ist gar nicht so kompliziert, selbst ohne Framework. Nach meinen vorherigen Überlegungen zur Verwendung von SVGs in Web Components war…", "date_published": "2023-03-05T18:56:12+01:00", "date_modified": "2023-03-05T18:56:12+01:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/24h-clock.png", "language": "de-DE", "image": "https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/24h-clock.png", "tags": [ "Webdevelop", "Web-Components", "SVG", "Javascript", "CSS", "Geografie", "Outdoor", "Programmierung", "Technologie" ] }, { "id": "user/posts/2023-02-14-pragmatische-heizungssteuerung-home-office/index.md", "url": "https://journal.3960.org/posts/2023-02-14-pragmatische-heizungssteuerung-home-office/", "title": "Pragmatische Heizungssteuerung im Home-Office", "content_html": "<p><img src=\"https://journal.3960.org/posts/2023-02-14-pragmatische-heizungssteuerung-home-office/ha-301-240x240.png\" class=\"quad\" width=\"240\" height=\"240\" style=\"--aspect-ratio: 1/1;\" alt=\"\" /> Mein neuestes Abenteuer mit dem <a href=\"https://www.home-assistant.io/\">Home Assistant</a> in Verbindung mit <a href=\"https://avm.de/produkte/fritzdect/fritzdect-301/\">FRITZ!DECT 301</a> beschäftigt sich mit einer smarten Heizungssteuerung für das Home-Office.</p>\n<!-- more -->\n<h2 id=\"more\">Wie es lief</h2>\n<p>Ach, was habe ich alles gebaut und gebastelt. Los ging es mit einem einfachen Zeitplan in der FRITZ!Box, der <strong>jeden Montag bis Freitag</strong> in der Arbeitszeit die Heizung ein- und danach wieder ausschaltete. Ich war's zufrieden.</p>\n<p>Aber an <strong>Feiertagen</strong>, die zwischen Montag und Freitag lagen, lief die Heizung immer noch. Höchste Zeit, den <a href=\"https://www.home-assistant.io/integrations/workday/\">Werktags-Sensor</a> über den Home Assistant zu verbauen und in die Heizungssteuerung mit einzubeziehen. Dafür musste ich dann den Zeitplan aus der FRITZ!Box entfernen und ebenfalls in den Home Assistant übertragen.</p>\n<p>Und im Urlaub? Urlaube sind ja keine Feiertage. Also noch einen Kalender in den Home Assistant integriert, der an <strong>Urlaubstagen</strong> die Heizung ebenfalls ausgeschaltet hält.</p>\n<p>Oha, <strong>Gleitzeit und Überstunden</strong>: Mal starte ich früher, mal höre ich später auf. Also diesen Teil von Hand steuern? Und wie ist es am Wochenende, wenn man im Arbeitszimmer am privaten PC etwas bastelt?</p>\n<p>Wie man es auch dreht und wendet – der Plan hatte inzwischen viel zu viele Variablen bekommen. Eigentlich wollte ich doch nur, dass die Heizung läuft, wenn ich im Raum bin! Aber wie kann ich das dem Home Assistant beibringen?</p>\n<h2 id=\"wie-es-läuft\">Wie es läuft</h2>\n<p>Ganz einfach! Ob im Büro jemand arbeitet kann man daran erkennen, dass einer der PCs im Büro eingeschaltet ist. Ein super-simples Rezept kann also prüfen, ob mindestens einer der Rechner dort an und im Netzwerk sichtbar ist, und schaltet entsprechend die Heizung an. Wenn <em>keiner</em> der Rechner im Netzwerk ist, wird die Heizung entsprechend ausgeschaltet.</p>\n<h3 id=\"teil-1-status-der-pcs-überwachen\">Teil 1: Status der PCs überwachen</h3>\n<p><img src=\"https://journal.3960.org/posts/2023-02-14-pragmatische-heizungssteuerung-home-office/network-240x240.png\" class=\"quad\" width=\"240\" height=\"240\" style=\"--aspect-ratio: 1/1;\" alt=\"\" /> Dazu bauen wir uns einen Zustand, der eingeschaltet ist, wenn irgendeiner der PCs angeschaltet und im Netzwerk ist – und erst ausgeschaltet ist, wenn <em>alle</em> PCs ausgeschaltet sind. Das funktioniert wie folgt:</p>\n<ol>\n<li>Wenn ihr im Home Assistant und „Einstellungen > Geräte & Dienste > FRITZ!Box“ die Liste der Geräte aufmacht, seht ihr die Liste aller von eurer FRITZ!Box erkannten Netzwerkteilnehmer. In meinem Beispiel nennen wir die zwei PCs <code>arbeitspferd</code> und <code>daddelkiste</code>.</li>\n<li>Merkt euch die Namen der Netzwerkteilnehmer, die beim Einschalten eure Heizung einschalten sollen. Unter „Entwicklerwerkzeuge > Zustände“ findet ihr dazu den passenden Zustand, der mit <code>device_tracker</code> beginnt. In meinem Beispiel gehen wir von zwei PC-Trackern aus, <code>device_tracker.arbeitspferd</code> und <code>device_tracker.daddelkiste</code>.</li>\n<li>Mit dem <a href=\"https://community.home-assistant.io/t/home-assistant-community-add-on-visual-studio-code/107863\">Home Assistant Community Add-on: Visual Studio Code</a> kann die <code>configuration.yaml</code> nun so erweitert werden, dass die beiden Tracker (oder beliebig viele Tracker) zu einem Sammel-Tracker zusammengefasst werden.</li>\n</ol>\n<pre><code class=\"language-yaml\">- <i>name</i>: <kbd>"Home-Office PCs"</kbd>\n <i>unique_id</i>: device_tracker_homeoffice\n <i>state</i>: <kbd>"{{ is_state('device_tracker.arbeitspferd', 'home') or is_state('device_tracker.daddelkiste', 'home') }}"</kbd>\n <i>icon</i>: <kbd>"mdi:lan-connect"</kbd>\n <i>device_class</i>: presence\n</code></pre>\n<p>Nach einmaligem Neustart sollte unter „Entwicklerwerkzeuge > Zustände“ der neue Tracker sichtbar sein. Er heißt dann wahrscheinlich <code>binary_sensor.device_tracker_homeoffice</code>.</p>\n<p>Unser neuer kleiner Device-Tracker „Home-Office PCs“ kann nun zum Beispiel auf dem Dashboard verbaut werden. Sobald eines der Geräte eingeschaltet wird, wird auch der Tracker eingeschaltet – beim Ausschalten gibt es knapp zwei Minuten Verzögerung, bis der Home Assistant das Gerät wirklich als offline annimmt.</p>\n<h3 id=\"teil-2-heizung-steuern\">Teil 2: Heizung steuern</h3>\n<p>Der Home Assistant kann nun die Programmierung der FRITZ!Box verbessern. Dafür wird in der FRITZ!Box die Heizung zu 100% in den Spar-Modus geschickt, weil ab sofort der Home Assistant die Heizung zwischen Spar- und Komfort-Modus hin- und herschaltet. Die Verbindung ist dabei einfach:</p>\n<ol>\n<li>Wenn auch nur einer der PCs an ist, soll die Heizung im Komfort-Modus sein.</li>\n<li>Wenn keiner der PCs an ist, soll die Heizung im Spar-Modus sein.</li>\n</ol>\n<p>Unter „Einstellungen > Automatisierungen & Szenen“ fügen wir dazu ein einfaches Rezept hinzu:</p>\n<pre><code class=\"language-yaml\"><u># Replace all occurences of `office` with your thermostat's identifier</u>\n<u># `device_id` has to be assigned via GUI</u>\n<i>alias</i>: <kbd>"Office: Someone is there"</kbd>\n<i>description</i>: <kbd>"Be nice, and turn on the heating if someone is using a PC in the office"</kbd>\n<i>trigger</i>:\n - <i>platform</i>: state\n <i>entity_id</i>:\n - binary_sensor.device_tracker_homeoffice\n <i>from</i>: <kbd>"on"</kbd>\n - <i>platform</i>: state\n <i>entity_id</i>:\n - binary_sensor.device_tracker_homeoffice\n <i>to</i>: <kbd>"on"</kbd>\n<i>action</i>:\n - <i>if</i>:\n - <i>condition</i>: state\n <i>entity_id</i>: binary_sensor.device_tracker_homeoffice\n <i>state</i>: <kbd>"on"</kbd>\n <i>then</i>:\n - <i>device_id</i>: b46c4851235fb8c90f4a659b6e9a953d\n <i>domain</i>: climate\n <i>entity_id</i>: climate.office\n <i>type</i>: set_preset_mode\n <i>preset_mode</i>: comfort\n <i>else</i>:\n - <i>device_id</i>: b46c4851235fb8c90f4a659b6e9a953d\n <i>domain</i>: climate\n <i>entity_id</i>: climate.office\n <i>type</i>: set_preset_mode\n <i>preset_mode</i>: eco\n<i>mode</i>: single\n</code></pre>\n<p>Erst mit der Zusammenfassung der beiden Zustände zu einem Tracker ist es sauber möglich, zwischen Spar- und Komfort-Modus hin- und herzuschalten. Wenn wir die Tracker trennen würden könnte es ansonsten passieren, dass das Ausschalten eines Rechners die Heizung deaktiviert, obwohl der andere Rechner eigentlich noch läuft.</p>\n<h2 id=\"wie-es-laufen-könnte\">Wie es laufen könnte</h2>\n<p>Tatsächlich kann man diese Idee auch auf andere Geräte ausdehnen, wie zum Beispiel Fernseher und Spielekonsolen, die ebenfalls im Internet hängen. Eine kleine Automatisierung könnte also abends die Heizung noch etwas länger an lassen, solange der Fernseher läuft.</p>\n<p>Oder wie wäre es mit einem Sammel-Tracker, der die Smartphones aller Haushaltsteilnehmer als Schalter verwendet?</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Pragmatische%20Heizungssteuerung%20im%20Home-Office&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2023-02-14-pragmatische-heizungssteuerung-home-office%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Mein neuestes Abenteuer mit dem Home Assistant in Verbindung mit FRITZ!DECT 301 beschäftigt sich mit einer smarten Heizungssteuerung für das Home-Office.", "date_published": "2023-02-14T19:04:06+01:00", "date_modified": "2023-02-21T10:37:45+01:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://journal.3960.org/posts/2023-02-14-pragmatische-heizungssteuerung-home-office/ha-301.png", "language": "de-DE", "image": "https://journal.3960.org/posts/2023-02-14-pragmatische-heizungssteuerung-home-office/ha-301.png", "tags": [ "Home Assistant", "Programmierung", "Technologie", "The Cool", "AVM", "Homeoffice" ] }, { "id": "user/posts/2023-01-31-nothing-else-matters/index.md", "url": "https://journal.3960.org/posts/2023-01-31-nothing-else-matters/", "title": "Nothing else matters", "content_html": "<div class=\"video-player video-player--youtube\"><iframe allowfullscreen=\"allowfullscreen\" title=\"Chris Stapleton – "Nothing Else Matters"\" src=\"https://www.youtube-nocookie.com/embed/jzN9rdvXmS4?enablejsapi=1\" srcdoc=\"<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href="https://www.youtube.com/embed/jzN9rdvXmS4?autoplay=1"><img src="https://img.youtube.com/vi/jzN9rdvXmS4/hqdefault.jpg" alt=""><span>▶</span></a>\"></iframe><!-- img src=\"https://img.youtube.com/vi/jzN9rdvXmS4/hqdefault.jpg\" --></div>\n<p>Einige Lieder sollte man nicht covern… bis jemand vorbei kommt, der einem Klassiker die Krone aufsetzt.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Nothing%20else%20matters&url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2023-01-31-nothing-else-matters%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />", "summary": "Einige Lieder sollte man nicht covern… bis jemand vorbei kommt, der einem Klassiker die Krone aufsetzt.", "date_published": "2023-01-31T18:40:08+01:00", "date_modified": "2023-01-31T18:40:08+01:00", "author": { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" }, "authors": [ { "name": "Frank Boës", "url": "mailto:info@3960.org", "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca" } ], "banner_image": "https://img.youtube.com/vi/jzN9rdvXmS4/hqdefault.jpg", "language": "de-DE", "image": "https://img.youtube.com/vi/jzN9rdvXmS4/hqdefault.jpg", "tags": [ "Musik" ] } ] }