Blog: Latest Entries (15):


Linux im Alltag und auf älterer Hardware

Ich benutze Linux jetzt seit über einem halben Jahr bei der Arbeit und auch privat läuft auf einem Notebook Linux. Meine letzten Entwicklungen mit PHP und Java habe ich so entwickelt, dass sie sowohl unter Windows als auch unter funktionieren. Java und PHP machen es auch mehr als einfach, wenn man nicht auf irgendwelche DLLs angewiesen ist. Die RFID-Reader werden über Ethernet angesprochen und zum Glück gibt es beide SDKs nativ für Java.

bbcode-image


Für Windows spricht eigentlich nur noch die Adobe Software. In allen anderen Fällen gibt es kaum einen Unterschied mehr. Das sehe wohl nicht nur ich so sondern fast alle. Linux Software wie Openshot 2.0 gibt es jetzt auch für Windows. Microsoft bringt den SQL-Server und jetzt auch die PowerShell für Linux raus. Die Bash gibt es ja auch für Windows.

Und seit es Windows 10 nicht mehr kostenlos gibt, ist der Vorteil von Linux, dass es kostenlos ist, wieder bedeutender geworden. Bei Entwicklern hat man den Vorteil, dass diese sowie so lieber ihre Rechner selbst Administrieren wollen und somit keine weiteren Kosten entstehen durch höheren Administrationsbedarf bei den Benutzern.

Aber auch bei den normalen Benutzern sollte Linux eigentlich eine gute Alternative sein. Die meisten Anwendungen wandern oder sind schon in der Cloud und damit reduziert sich das Betriebssystem schon fast auf einen Luncher für den Webbrowser. Firefox/Chrome und Thunderbird sind auf Windows sowie schon sehr verbreitet und somit ist eine Umgewöhnung fast nicht mehr nötig. Linux Mint sieht fast genau so aus wie ein Windowssystem und das Updaten der Software ist sehr viel zentraler und einfacher zu managen.

Linux ist wie auch Windows 10 sehr sparsam was die Hardware-Resourcen betrifft. Ein altes Notebook mit Pentium Dual-Core und 2GB RAM läuft mit Linux sehr gut und auch Probleme wegen veralteter Windows-Treiber sind gelöst.

bbcode-image


Mit gebrauchter Hardware und Linux Mint sollte sich eine komplette IT-Infrastruktur für kleine Büros bauen lassen. Alte aber wieder aufbereitete Hardware ist günstig zu bekommen und Geräte von HP oder Dell auch oft in entsprechenden Stückzahlen an gleichen Geräten, so das man ein paar mehr Geräte kaufen kann, um bei Hardwareausfall gleich Ersatz zur Hand zu haben. Man kann ein Installationsimage erstellen und so Installationen in wenigen Minuten durchführen. Die Kosten sollten sich damit auf vielleicht 40% der Kosten von Neugeräten belaufen und für Internet, Email und Office reicht die Hardware immer noch mehr als aus. Die Leistung eines 10 Jahre alten PCs ist heute immer noch ausreichend. Ich habe meinen PC von 2006 nur gewechselt, weil HyperV darauf nicht lief.. was ich aber trotz neuen PC immer noch nicht verwende und einfach bei VirtualBox geblieben
bin.
Bei VirtualBox wären wir auch schon beim nächsten Punkt: Virtualisierte Server. Ein gebrauchter Server ist nicht teuer und wenn man die Server an sich in VMs laufen lässt, kann man auch immer mal schnell auf einen größeren Server upgraden ohne längere Ausfallzeiten der Systeme zu haben. Bei guter Planung sollte so ein Umzug auf einen neuen Server in 10 Minuten durch geführt sein. Für die meisten Server-Anwendungen braucht man nur eine einfache LAMP-Umgebung. Groupware wie Tine 2.0 bieten Email-Client, Kalender, Adressbuch und alles mögliche und lassen sich auch mit dem Smartphone nutzen. Wer komplette Office-Umgebungen wie Office 365 braucht findet bei OwnCloud und LibreOffice eine Alternative, die leider etwas kostet aber noch relativ günstig ist.

Aber genau wie auch bei Windowsumgebungen und neuer Hardware braucht man jemanden der alles einrichtet und installiert. Wer glaubt diese Kosten mit Windows umgehen zu können, wird sich schnell wundern. Deswegen würde ich keine höheren Administrationskosten bei Linux sehen im Vergleich zu Windows.

Deswegen auch nicht einfach alte Hardware in den Müll werfen! Mit Linux kann die Hardware noch einige Jahre gut weiter verwendet werden und man spart nicht nur sich Kosten sondern schon auch etwas die Umwelt damit. Wer es noch nicht versucht hat, sollte Linux mal eine Chance geben. Ich werde jedenfalls mal Collabora testen. Es wäre sicher eine Lösung, die gerade kleineren Firmen viele Kosten sparen kann.

Die erste Komponente für den 100 Euro Office Server ist schon angekommen. Die CPU hat 7 Euro gekostet. Der wird nur aus gebrauchten Teilen bestehen.. ich werde berichten.

bbcode-image

Projekt: Mein Online Adventskalender

Eine Website wo jeder sich einen Online Adventskalender mit eigenen Bildern und Videos erstellen kann. Es wurde auch alles so angepasst, dass auch Firmen es nutzen können und ihre Weihnachtsaktionen und Gewinnspiele darüber abwickeln können.
Einfach mal ausprobieren. Es ist alles in der normalen Ausführung kostenlos und es existiert eine ausführliche Anleitung. Sollte eine speziellere Integration als der IFrame benötigt werden, kann auch hier eine spezielle Lösung auf Anfrage entwickelt werden.

bbcode-image


Man kann sich hier einen Online Adventskalender bauen, der sich so konfigurieren lässt, um verschiedene Einsatzgebiete abzudecken. So kann man dann nicht nur einen einfachen Kalender erstellen, bei dem an jedem Tag ein neues Bild, GIF oder Video angezeigt wird, sondern auch spezielle Texte für den aktuellen Tag setzen und Links auf externe Seiten setzen.

Damit kann man also auch für jeden Tag z.B. einen Gutscheincode oder eine spezielle Gewinnspiel-Frage setzen. Dieser Text ist dann nur am vorgesehenen Tag sichtbar ohne das man händisch eingreifen muss.

Den Kalender kann man dann teilen in dem man den Link auf mit anderen teilt oder sich den Code für den IFrame kopiert und den Kalender in seine eigene Homepage einbinden.

bbcode-image

Warnings und Deprecated

Elastica ist sehr radikal was deprecated Methoden angeht. Es werden nicht einfach nur Warnings angezeigt sondern gleich Exceptions geworfen. Deprecated Warning ignoriert man gerne. Besonders wenn man aus dem Java-Bereich kommt, weil dort ist man gewohnt (Beispiel die Date-Klasse), dass Methoden zwar deprecated sind, aber ewig weiter existieren und dass meistens auch weiterhin fehlerfrei- Die wurden meistens nur deprecated, weil die Funktionalität in eine andere Klasse verschoben wurde oder es eine neue Funktionalität gibt, die mehr kann und die alte voll umfassend ersetzen kann.
Das werfen von Exceptions, die man mit Try-Catch auffangen könnte motiviert aber ungemein, gleich alles auf das neue Vorgehen umzubauen. Warnings sind ok.. Exception dürfen aber nicht sein. Das Warning ignoriert oder gleich ganz abgeschaltet werden führt auch immer wieder zu "lustigen" Vorkommnissen. "Wieso hast du einfach die Methode gelöscht.. die hab ich an mehreren Stellen verwendet!" - "1. war sie fast 10 Monate als Deprecated markiert.." - "... Warning hab ich abgeschaltet.. waren zu viele.." - ".. und 2. soll bitte die Service-Schnittstelle des Modules genutzt werden,weil dort wurde schon vor 11 Monaten auf die neue und schnellere Methode umgestellt"

Man sollte seinen Code immer Warning-frei halten und nicht einfach Warning ignorieren, weil man ein paar einfach nicht entfernen kann, weil z.B. der Code-Parser der IDE glaubt er könnte das SQL-Statement, dass aus mehreren Strings zusammen gebaut wird brauchbar auf Fehler untersuchen.

GitKraken... jetzt der Gewinner

Ich habe jetzt längere Zeit GitKraken benutzt. Ich sagte ja schon, dass wenn die noch etwas nachlegen werden, dann auch SourceTree überholen können. Seit der 1.6er Version ist es dann auch passiert. Übersichtlich, Pulls ohne Checkout, Konflikte direkt in GitKraken bearbeiten... und die Console sieht auch interessant aus.
Ich bin jetzt jedenfalls schneller mit GitKraken als mit SourceTree. UND es läuft unter Linux und Windows. Damit wird es noch "egaler" welches Betriebssystem man verwendet.


Masseinheiten in Produktionssystemen und Gedanken

Oft hat man das Problem, dass man verschiedene Einheiten verarbeiten muss und nicht alle sich an Standardeinheiten (SI) halten. Mag es daran liegen, dass die Person historisch gewachsene Einheiten wie Liter oder Pfund verwendet oder auch einfach daran, dass diese Person Amerikaner ist. Natürlich gibt es genug Frameworks, die einen helfen mit allen möglichen Einheiten klar zu kommen, aber es ist an sich gar nicht schwer sich so etwas selber zu schreiben.

Man muss nur die Basis-Einheit (SI) bestimmen und alle anderen Einheiten sich darauf beziehen lassen. Ein gutes Beispiel ist hier Inch/Zoll um das ganze zu demonstrieren.
Wir befinden uns in der Gruppe der Einheiten zur Bestimmung von Längen. Die Basiseinheit ist laut SI der Meter. Wir bauen uns jetzt 3 Einheiten Entitäten (die man am Besten in einer Datenbank anlegen sollte).


{
"name":"meter",
"nameshort":"m",
"base":true,
"group":"length",
"conversionfactor":1
}



{
"name":"inch",
"nameshort":"in",
"base":false,
"group":"length",
"conversionfactor":0.0254
}



{
"name":"centimeter",
"nameshort":"cm",
"base":false,
"group":"length",
"conversionfactor":0.01
}


Wie kommen wir jetzt ganz einfach von Inch auf Zentimeter? Wir nehmen den Inch-Wert und multiplizieren ihn mit dem Conversionfactor. Dann haben wir bei 1 Inch einen Wert von 0,0254 Meter. Nun nehmen wir uns unseren Zentimeter und teilen den Meter-Wert durch den Conversionfactor des Zentimeter. 0,0254 / 0.01 = 2.54 damit haben wir Inch in Centimeter umgerechnet. Einfacher Dreisatz. Wenn wir nun Einheitenwerte zu irgendwas speichern wollen, ist es eine gute Idee, diese vor dem Speichern immer auf die Basis-Einheit umzurechnen.

Das vereinfacht die Ausgabe, weil eine Methode sich so direkt die Einheit bilden kann, die sie gerne hätte.

In dem Zusammenhang ist auch eine Methode gut, die eine ideale Maßeinheit für einen Wert bestimmt. Wenn wir nun 0,001cm haben sollte diese Methode uns sagen können, dass die Repräsentation 1m für den Benutzer sehr viel einfacher zu lesen ist und uns den Wert und die Einheit liefern können.

Auch praktisch ist, dass man so dem Benutzer es überlassen kann in welcher Einheit er Ausgaben gerne sehen würde. Würden wir uns im Bereich der Flächeneinheiten befinden und die Fernsehsendung Galileo über die Größe der Flächen von bestimmten Dingen berichten wollen, können wir für sie direkt die Einheit "Fußballfeld" definieren und sie ihnen als Ausgabemöglichkeit anbieten.

Weitere Gedanken zu Einheiten/Units

Bei Bestellsystemen bereitet oft die Pseudo-Einheit "Stück" Probleme. Aber hier muss man sich einfach von der Vorstellung von Stück als eigene Einheit trennen. Maßeinheiten werden gemessen.. Stück werden einfach gezählt. Am Ende wird alles auf eine Verpackungseinheit herunter gebrochen und diese ist alleinstehend "1 Stück". Wenn ich 5L Wasser bestellen möchte ist es weiterhin sehr wichtig wie dieses Verpackt ist. 5x 1L oder 10x 0,5L. Verpackungseinheiten können auch rein virtuell sein. 100L = 100x 1L wobei nicht gesagt ist, dass dieses "verpackt" sein muss und nicht einfach direkt von einem Tank in einen anderen umgefüllt werden kann. Also.. Stück ist keine Maßeinheit sondern existiert parallel dazu um beschreibt nur eine Portionierung der in der Maßeinheit gemessenen Sache, die so geliefert werden kann.

Wo ist der Unterschied zwischen einer 1L Flasche Wasser und einem Stuhl? Beides ist "1 Stück" wobei man bei der Flasche den Inhalt in eine Maßeinheit fassen kann und bei einem Stuhl nicht. Ok.. man könnte.. es ergibt aber einfach keinen Sinn sich 25kg Stuhl zu bestellen.

Für Produktionssysteme ist der obige Ansatz sogar ohne solche Überlegungen einfach direkt umsetzbar und funktioniert sehr gut.

Passwort-Migration weich und hart

Wenn man von einem alten Hash-Algorithmus auf einen moderneren wechselt gibt es ja zwei Wege. Einmal kann man einfach bei jedem Login prüfen, ob noch die alte Version verwendet wird und dann mit dem gerade im Klartext vorhandenen Passwort updaten oder man erklärt alle vorhandenen Passwörter für ungültig (man ersetzt sie durch Zufallscode, die schon mit dem neuen Algorithmus gehasht sind) und verschickt Emails, dass jeder ein neues Passwort eingeben soll.

bbcode-image


Problem bei Variante 1 ist, dass inaktive Benutzer ihr altes Passwort behalten, wenn sie sich nicht neu einloggen. Bei Variante 2.. ja.. paar Hundert Emails mit Links zum Passwortwechseln, da weiß man dass es bei ein paar nicht klappen wird und ein paar einfach die Email nicht bekommen werden.

Deswegen wäre das Ideale vorgehen, 1-2 Wochen lang die Passwörter sanft zu migrieren und bei jedem Login das Passwort zu updaten. Nach dieser Zeit wird dann ein Script ausgeführt, das jedem der noch ein altes Passwort hat eine Erinnerungsemail zuschickt und das vorhandene Passwort ungültig macht.

Damit hat man insgesamt wohl am wenigstens Probleme.

MySQL Update und Probleme

Beim Umstieg von einer alten PHP Version auf PHP7.0 werden viele sicher gleich sich daran machen auch den ganzen Rest mal auf eine aktuelle Version zu migrieren. Dazu gehört dann oft auch eine aktuelle MySQL-Version.

bbcode-image


Aber manchmal laufen dann ältere Queries nicht mehr. Das Beste ich dann natürlich das Query anzupassen. Wenn man aber nicht so viel Zeit hat oder sich erst später mit den Problem beschäftigen möchte, hilft es oft die problematischen neuen Modes zu deaktivieren.

Besipiel wäre hier der ONLY_FULL_GROUP_BY-Mode

SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));


Bei PDO kann man das Stament direkt als PDO::MYSQL_ATTR_INIT_COMMAND setzen, so dass es bei jeder neuen Verbindung gleich gesetzt wird.

3 Monitore an einem PC

3 Monitore anzuschließen, wenn schon 2 dran sind, klingt jetzt erst einmal nicht nach einem Problem.. dachte ich auch. Das Setup sollte folgendes sein: Über HDMI ist der Fujitsu Haupt-Monitor angeschlossen. Über einen eine DVI auf VGA Adapter läuft noch ein älterer Medion Monitor. Nun sollte ein Wacom Cintiq 13HD angeschlossen werden, das nur einen HDMI-Stecker angeschlossen werden kann. Dafür wurde ein Mini-Displayport auf HDMI Adapter verwendet.

Das Problem ist, dass man den ersten Monitor nicht darauf spiegeln kann, weil der Monitor 1920x1200 und das Grafik-Tablett nur 1920x1080. Das Erweitern des Desktops klappte nicht, da sich dann immer einer der beiden anderen Monitore abschaltete.

bbcode-image


Das Problem war am Ende der passive DisplayPort Adapter. Mit diesem aktiven Adapter klappte dann alles. Bei einer AMD Radeon 7950 und anderen der Serie kann man wohl nur 3 Monitore oder mehr betreiben, wenn alles über 2 Monitor über native DisplayPort Verbindungen angebunden sind. Ein passiver HDMI Adapter erfüllt das wohl nicht und wird wie eine HDMI Verbindung behandelt und nicht wie eine DisplayPort Verbindung.

GitKraken vs SourceTree

Ok ein vs ist jetzt übertrieben, dann leider gibt es SourceTree nicht für Linux. Würde es SourceTree für Linux geben, hätte ich GitKraken wohl nie ausprobiert und hätte direkt wieder SourceTree verwendet. Auch jetzt würde ich wohl noch direkt wieder Wechseln, sollte SourceTree für Linux verfügbar werden. Man merkt das Atlassian sehr viel Erfahrungen im Entwicklungsbereich hat und SourceTree läuft einfach super und ich hatte bis jetzt nie Probleme. GitKraken ist noch sehr neu und hat kleine Probleme. Bei mir bleiben leider oft Konflikte bestehen auch wenn ich diese in der IDE behoben habe. SourceTree erkennt externe Änderungen sehr viel zu verlässiger. Aber eines muss man GitKraken lassen.. optisch ist es echt super und man kann Merges, Branches und alles extrem gut verfolgen und auch bei Problemen allein durch die Betrachtung der Darstellung schnell heraus bekommen, wo Probleme in den Code rein kamen oder eben Konflikte falsch gelöst wurden.

bbcode-image


bbcode-image


Die Darstellung ist auch nicht ganz fehlerfrei und manchmal gehen die Linien dabei der Hälfte der Ansicht verloren und man muss den Branch einmal kurz wechseln, damit die Darstellung wieder stimmt.

bbcode-image


Aber die Tabs und die Seitenansicht bei SourceTree sorgt gerade bei mehreren Projekten, die man parallel bearbeitet, sorgen für sehr viel mehr Übersicht. Ich kann direkt sehen, wo ich noch was commiten oder pushen muss und auch wird mir direkt angezeigt wo ich mal wieder pullen muss und wie viele Commits mir fehlen.

bbcode-image


bbcode-image


Fazit: Wenn man kein SourceTree hat sollte man GitKraken eine Chance geben. Ich gehe auch davon aus, dass GitKraken in den nächsten Monaten auch viele der Probleme beheben wird und es mit der Zeit zu SourceTree aufschließen könnte. Die Darstellung der Merges und Branches ist aber jetzt schon wirklich sehr gut!


Projekt FAMICOM.. eine kleine Odysse

Mal etwas, was nichts mit Programmieren oder IT an sich zu tun hat :-)

Man mag es kaum glauben, aber ich habe nie einen NES besessen. Ich hatte einen Gameboy, einen SNES, einen Megadrive 1, einen Megadrive 2, sogar mal einen Atari 2600, natürlich auch einen C64, C16, Plus4, Atari 800(!), TI 99/4A, Atari ST 520, Atari ST 1024, Amiga 1200, und im PC-Bereich alles von einem Commodore PC20 (8088) über einen Bull Unix-Server hin zu Xeon Workstations (und bin dabei geblieben). Später kam Gamecube, N64, Wii, Wii U und sogar eine PS3 hinzu.. wobei ich die PS3 bis immer noch nicht wirklich mag. Aber eines hatte ich nie: einen NES.

Ich kann mich noch gut an den NES eines Freundes erinnern. Super Mario 3 und Probotector waren super Spiele und wir haben ganze Tage in diese Spiele investiert.

Was mich am meisten davon abgehalten hat mir einen NES zu kaufen waren immer die sehr hohen Gebrauchtpreise, die gerade Händler dafür haben wollten. Eine Konsole, mit Controller und einem Spiel kostete ohne Probleme mal 80 Euro oder mehr. Für eine Konsole, die mal Millionen-fach gab, fand ich diese Preise nicht wirklich gerecht fertig. Ein Mega Drive kostete gerade mal die Hälfte und ein Mega Drive war seltener anzutreffen und der Zustand der Konsole meistens sehr viel besser als bei den NES-Konsolen, die ich so gesehen hab. Fehlende Klappe, abgeriebene Beschriftungen und gebrochene Gehäuse schien nie ein Problem zu sein und es wurde immer noch ein hoher Preis verlangt.

Aber vor ungefähr 3 Monaten begann mein Projekt "Famicom".

bbcode-image


Auf Ebay fand ich ein Angebot für gerade mal 80 Euro inkl. Versand für einen Famicom mit 5 Spielen, Verpackung, Anleitung und er sollte auch noch funktionsgetestet sein. Er kam direkt aus Japan, aber die Lieferzeit war jetz kein Problem. Ich wusste, dass man den originalen Famicom nur über den Antennen-Eingang an den Fernseher anchließen konnte, aber ich sah da jetzt kein Problem darin. NTSC sollte jeder moderne Fernseher ja hinbekommen und sonst würde ich mir eben eine TV-Karte kaufen. Meine letzte TV-Karte, die ich besaß war eine FAST Movie Machine 2, die noch einen ISA-Slot brauchte und in einem Pentium 60 Rechner unter Windows 95 lief. Die Movie Machine hatte einen TV-Tuner, Video-In, S-Video-In und konnte jeden TV-Standard, der überhaupt mal jemanden auf der Welt nur in Sinn gekommen war. Also war ich der Meinung, wenn das damals alles schon kein Problem war, sollte es heute ja noch einfacher sein.

bbcode-image


Ein kleiner Sprung zurück in der Zeit. Jeder kennt es wohl noch, dass man seine Konsole irgendwo mithin nehmen durfte, meistens dass man dort beschäftigt war.. man schloss die Konsole an und dann begann das nervigste am Ganzen: Der Sendersuchlauf. Oft hing das Signal irgendwo zwischen zwei Senderplätzen und man musste noch mit der manuellen Feinabstimmung ran. SNES brauchte einen festen Senderplatz und man mußte immer umstecken. Der Megadrive mit seinem Umschalter ersparte einen das Umschalten aber auch brauchte man den Senderplatz. Es war nervig, doof und die Signal-Qualität war meistens auch alles andere als gut.
Warum hat man das gemacht? Die alten Fernser hatten nur einen TV-Tuner und keine Video-Eingänge. Später hätte man Video-Kabel nachkaufen müssen, aber deren Existenz war den wenigstens bekannt und Antennenkabel waren den Eltern bekannt und ein Cinch-Kabel.. nee.. zu modern, zu seltsam.. man blieb lieber beim bekannten.

bbcode-image


Deswegen haben viele ein Problem alte Konsolen an modernen TV-Geräten zum Laufen zu bekommen. Antenen-Kabel ran und dann wird die Konsole nicht gefunden. Selbst der alte NES hat einen stink-normalen Video-Ausgang. Ein einfaches Kabel ran und es läuft. Wer noch versucht mit einem Antennenkabel etwas anzuschließen, liebt es wohl einfach sich selbst zu quälen.

bbcode-image


Sega-Konsolen können sogar sauberes RGB ausgeben, das auch dazu benutzt wird z.B. die Mega-CD Erweiterung mit dem Video-Signal der Konsole zu versorgen und dann mit Overlays zuarbeiten, wenn die Erweiterung zum Einsatz kommt.

Um es kurz zu machen.. der Famicom kam an und ich bekam ihn an keinen meiner TV-Geräte zum laufen. Ich wusste aber auch nicht, ob der Famicom überhaupt richtig lief (jeder kennt ja das Problem mit den Modulen und dem Pusten, damit die Konsole mit dem Modul startete). Eine LED hat der Famicom nicht. Hat der Strom? Sieht man nicht. Ich war aufgeschmissen. Also wollte ich dann die Lösung mit der TV-Karte ausprobieren. Also einfach schnell eine TV-Karte bestellen.. dachte ich. Nach 2 Tagen suchen hatte ich genau eine TV-Karte gefunden die NTSC-J unterstützte und bei EBay bezahlbar war. Es war eine FAST Movie Machine 2... FAST war wohl einfach die einzige Firma, die mal etwas weiter gedacht hatte... leider ja nicht mehr existent.

Eine Woche später hatte ich mich dann durch Angebote für einen AV-Mod gearbeitet. Selber löten wollte ich nicht, weil so ein Famicom doch nicht einfach zu ersetzen ist und ich wenig Erfahrung im Löten habe. Ein Stecker an ein Kabel löten bekomme ich noch hin, aber auf Platinen rumlöten wollte ich dann doch nicht.

Ich hatte ein Angebot für einen RGB-Umbau für 170 Euro. Micro-Controller gesteuert und mit haufenweise Zusatzfunktionen. Ich brauch keinen Micro-Controller der mehr Leistung hat als die CPU der Konsole und der Preis war mir einfach zu hoch. Ein normaler AV-Umbau würde man nicht mehr machen hieß es. Also suchte ich weiter. Beim nächsten gab es wieder keinen normalen einfachen AV-Umbau mehr, aber dafür kein RGB oder so, sondern einfaches Video-Signal und es würde auch die Stromversorgung ausgetauscht. Das mit der Stromversorgung hat mich doch sehr überzeugt, da ich den alten Bauteilen nach den Jahren nicht mehr ganz traute und man hat eine LED! Auch war der Umbau optisch wirklich toll. Der alte RF-Modulator wird ausgebaut, dann ein Teil des Gehäuse entfernt und mit einer passenden Blende versehen. Es gibt einen Aufkleber der perfekt zur Optik des Famicom passt. Das alles dann auch zu einem Preis von 69 Euro. Ich überlegte nicht lange.

bbcode-image


bbcode-image


Nach ein paar Emails war klar, dass sobald der neue AV-Umbau verfügbar sei, ich die Konsole einschicken würde. Es dauerte ein paar Wochen aber dann ging die Konsole auf die Reise. Und war dann auch schnell wieder da. Angeschlossen.. und.. nur ein grünes Bild. Nichts zu machen. Überall nur ein grünes Bild. Laut Internet lag es wohl am Modul, aber jedes Modul zeigte diesen Effekt. Zwei Emails später ging der Famicom wieder auf die Reise. Wie sich herausstellte, war es wohl ein Problem mit dem Modul-Slot. Noch mal Reinigen und dabei fiel auch auf, dass das Microphone des zweiten Controller ein Rauschen im Ton verursachte. Also wurde das Micro kurzer Hand auch gleich einfach gekappt. Sinnvoll nutzen kann ich es sowie so nicht.
Eine Woche später kam der Famicom wieder bei mir an. Super toller Kontakt, hat mich nicht extra gekostet und dann noch mal alles gecheckt wurde, ist wirklich super.

bbcode-image


Also der Famicom war wieder bei mir und gleich an den TV angeschlossen. Strom ran, Video-Kabel ran.. einschalten.. und.. ein wirklich gutes Bild. Scharf, nicht verwaschen... wieso hat man sich so lange nur die RF-Signale angetan?

bbcode-image


Ach ja.. ich habe ja damit angefangen, dass ich nie einen NES besessen habe.. ich hab mir dann doch zwischendurch noch mal einen gekauft. Ist wie man auf den Fotos sieht leicht beschädigt, aber läuft ohne Probleme und war relativ günstig.
Für die Mühen mit meinem Famicom und den Umbau möchte Andreas König von Donkings's Konsolen-Service danken. Echt super Arbeit und sehr günstig. Kann ich nur empfehlen. Als nächstes steht dann bei mir an die DBZ-Spiele
für den Famicom zu spielen und zu hoffen, dass es auch ohne Japanischkenntnisse geht.

Entwickler in der freien Natur (für den Job)

Auch wenn sich immer noch das Gerücht hält Entwickler würden Tag für Tag vor ihrem Rechner in schlecht beleuchteten und belichteten Räumen sitzen.. NEIN.. das stimmt nicht, manchmal findet man sie auch mit ihrem Notebook unter Regenschirmen im strömenden Regen auf Marktplätzen oder Rennstrecken. Spätestens wenn ein System das erste Mal wirklich benutzt wird, sind auch die Entwickler dabei.

bbcode-image


Dabei sollte man auf einige Dinge achten:


  • Eigenes und schnelles Notebook mit IDE dabei haben. Denn wenn etwas Probleme macht, kann es gleich direkt Bugfixen und da man nie genug Zeit hat, sollte es ein schnelles Notebook sein.

  • Regenschirm, Regenjacke und alles dabei haben um sich und das Notebook vor Regen zu schützen

  • 25m-50m Netzwerkkabel, weil man nie weiß, ob man wirklich mit dem Notebook an der richtigen Stelle sitzt oder man andere Hardware doch vom Notebook entfernt aufbauen muss

  • Kabeltrommel und Verlängerungskabel, sowie Stift und Papier dabei haben. Schnelle Notizen sind immer mal nötig.



Wenn man darauf achtet überlebt der gemeine Entwickler auch ohne Probleme die oben beschriebene Zeit.

Das tollste wäre natürlich ein Notebook, dass einfach Regen übersteht und keinen extra Schutz bräuchte!

PHP7 und die Session

Das Verhalten von Sessions haben sich in PHP7 etwas geändert. Jedenfalls hatte ich das Problem jetzt schon mehrfach, wobei es lokal mit einer älteren 7.0.0 noch nicht auftrat. Mit einer 7.0.7 und einer 7.1 trat es dagegen immer auf.

Es kommt ja vor, dass man während session_start() z.B. durch einen eigenen Class-Loader schon versucht auf Daten aus der Session zu zugreifen. Hier wird man schnell merken, dass zwar die Einträge in der Session schon sichtbar sind, aber alle vom Typ UNKOWN sind. Ein Array oder Boolean aus der Session zu lesen, funktioniert
also noch nicht.
Bei meinem ClassLoader habe ich es einfach so gemacht, dass er nicht die schon gespeicherten Pfade aus der Session verwendet, solange die Session nicht komplett rekonstruiert wurde (unserialized). Sobald die Session wieder da ist, kann ich wieder auf die schon hinterlegten Einträge zugreifen und muss nicht mehr im Dateisystem meine Klassen suchen, sondern habe wieder mein Array mit Klassen/Pfad Zuordnungen.

bbcode-image

MySQL: DDL und Transactions

Das ist jetzt nicht wirklich eine große Entdeckung und ist eigentlich klar, aber auch wenn in der Beschreibung von MySQL nur steht, dass einige Statements nicht mehr mit einem Rollback zurück genommen werden können, wenn man ein DDL-Statement nach einem start transaction; ausführt, bedeutet es einfach, dass die Transaction danach einfach commited wird und alles danach nicht in einer Transaction läuft.

Wenn man sich als bei größeren Imports oder Datenverarbeitungen eine Tabelle zum Auslagern von Daten erzeugt, sollte man das immer zuerst und außerhalb der Transaction machen. Auch wenn man mit PDO arbeitet, muss man darauf achten.

bbcode-image


Sich extra Tabellen anlegen ist gut für Dinge, die länger laufen und besonders wenn sie länger laufen als die Timeout-Zeit von PHP oder des DB-Treibers. Den gerade MySQL locked alle Rows, die während einer Transaction geschrieben und auch gelesen werden. Wenn nun jemand in so eine Row schreiben möchte, die in einer langen Transaction auch nur gelesen wurde,kann es schnell zu Problemen kommen.
Erst einmal sollte man sowie so Stammdaten und Bewegungsdaten trennen. Damit minimiert sich das Problem schon mal etwas.

Am Ende kann man auch das Isolation-Level ändern, aber das sollte immer das letzte sein, was man versuchen sollte.

Eigenes Lightweight Logging (PHP)

Wenn ich eine Lib oder ein Framework sehe, kommt bei mir immer die Frage auf: "Wie macht man so etwas?" Das gipfelte heute darin, dass ich ein kleines Logging-Framework geschrieben habe. Etwas an
Log4j erinnernd aber erst einmal nur mit Output in eine Datei. Andere Outputs könnte man noch integrieren durch Appender-Types.

bbcode-image


Die LoggerFactory

class XWLoggerFactory{
private static $config=[];
private static $appenderCache=[];

/**
* @return XWLogger
* @param string $clazz
*/
public static function getLogger($clazz){
if(count(self::$config)==0 && file_exists("system/config/log.json")){
self::$config=json_decode(file_get_contents("system/config/log.json"),true);

foreach(self::$config["appenders"] as $appender){
self::$appenderCache[$appender["name"]]=$appender;
}
}

$appenders=[];
$levels=[];

foreach(self::$config["classes"] as $cla){
if(preg_match("/^".$cla["name"]."/i", $clazz)){
foreach($cla["appenders"] as $app){
$appenders[]=self::$appenderCache[$app["name"]];
$levels[]=$app["level"];
}
}
}

return new XWLogger($clazz, $appenders, $levels);
}
}


Der Logger

class XWLogger{
const ALERT="alert";
const CRITICAL="critical";
const ERROR="error";
const WARNING="warning";
const INFO="info";
const NOTICE="notice";
const DEBUG="debug";

private $clazz="";
private $appenders=[];
private $levels=[];

private $values=[
"alert" => 6,
"critical" => 5,
"error" => 4,
"warning" => 3,
"info" => 2,
"notice" => 1,
"debug" => 0,
];

public function __construct($clazz, $appenders, $levels){
$this->clazz=$clazz;
$this->appenders=$appenders;
$this->levels=$levels;
}

/**
*
* @param string $type
* @param string $msg
* @param \Exception $e
*/
public function log($type, $msg, \Exception $e=null){
foreach($this->appenders as $key => $app){
if($this->values[$this->levels[$key]] >= $this->values[strtolower($type)]){
$dateFormat="Y-m-d h:i:s";
if(isset($app["dateformat"])){
$dateFormat=$app["dateformat"];
}
$ip="";
if(isset($app["remoteip"]) && ($app["remoteip"]===true || $app["remoteip"]=="true")){
$ip=" [".$_SERVER["REMOTE_ADDR"]."]";
}
$content = strtoupper($type).$ip." [".date($dateFormat)."]: ".$msg;
if($e!=null && $app["exceptionFullStackTrace"]){
$content.="\n".$e->getTraceAsString();
}
if(!file_exists($app["filename"])){
if(!file_exists(preg_replace("/[a-zA-Z0-9_.]+$/Uis", "", $app["filename"]))){
mkdir(preg_replace("/[a-zA-Z0-9_.]+$/Uis", "", $app["filename"]));
}
}
file_put_contents($app["filename"], $content."\n", FILE_APPEND);
}
}
}
}


Die Config-Datei (system/config/log.json) for den aoop-PageLoader

{
"appenders":[
{
"name":"default",
"filename":"system/log/aoop.log",
"dateformat":"H-m-y h:i:s",
"remoteip":"true"
}
],
"classes":[
{
"name":"XWFastPostProPageLoader",
"appenders":[
{
"name":"default",
"level":"warning"
}
]
}
]
}


Eine Nutzung mit einer einfachen Warning

XWLoggerFactory::getLogger(self:class)->log(XWLogger::Warning, "a warning!");

Older posts:

Möchtest Du AdSense-Werbung erlauben und mir damit helfen die laufenden Kosten des Blogs tragen zu können?