Nach vielen vielen Monden habe ich es am Ende doch mal fertig gebracht mein altes Zeiterfassung-Projekt bei Github hoch zu laden. Wobei das komplizierteste noch war das Framework "hübsch" zu machen. Das Modul ist jetzt auch mehrsprachig.
Agil arbeiten ist voll in und jeder will es machen. Klingt eben cool, wenn man sagen kann, dass man Scrum macht und UserStories entwirft und danach arbeitet. Leider ist agiles Arbeiten nichts, was man den Mitarbeitern einfach mal vorschreiben kann und es dann auch so in Zukunft läuft. Agil ist viel mehr als ein Whiteboard mit ToDos und Sprints mit 2 Wochen Laufzeit, wo am Ende es Sprints alles fertig ist, was man an das Board geklebt hat.
Wenn man wirklich agil arbeiten will, muss man erst einmal sich um die Hierarchie kümmern, weil diese agilen Arbeiten meistens im Weg steht. Wer so arbeitet, dass Aufgaben durch 3-4 Schichten von Oben nach Unten herunter gereicht werden und jeder nur die Infos bekommt, die er gerade braucht, wird das ganze Vorhaben scheitern. Wichtig beim agilen Arbeiten ist, dass die Mitarbeiter, die es umsetzen sollen, auch vollumfänglich informiert sind und nicht nur das wissen, was in dem aktuellen Sprint umgesetzt werden sollen.
Oft läuft es so das der Chef seine Idee mit dem Abteilungsleiter bespricht, der guckt was zu machen ist und stimmt sich mit dem Teamleiter/Scrummaster ab was in einem Sprint abgearbeitet werden soll. Die Mitarbeiter dürfen dann noch mal die Aufwände schätzen für das was sie in der Zeit erledigen sollen. Meistens müssen, dann die Aufwände aber dann auch so geschätzt werden, dass es passt, weil der Inhalt des Sprints ja schon fest gelegt wird. Was im Backlog für die nächsten Sprints steht, wird oft nicht mitgeteilt. Damit wird den Mitarbeitern aber die Möglichkeit genommen schon mal Erkenntnisse und konkretes Wissen für die Zukunft zu sammeln. Weil.. man ist ja agil und wenn sich die Arbeit des Sprints leider als nicht zukunftssicher heraus stellt, macht man es eben nochmal. Aber Hauptsache man wird am Sprintende mit den Aufgaben fertig.
Im Grunde kennt man dieses Vorgehen schon lange. Man bekommt die Anforderungen diktiert, dann werden diese umgesetzt und am Ende wird geguckt, ob es das ist was man haben wollte. Wenn nicht fängt man wieder von vorne an. Das ist das klassische Wasserfall-Model.
Nur eben auf 2 Wochen herunter gebrochen. Das ist nicht Agil. Man blickt nicht über den Tellerrand und passt sich ändernden Anforderungen an. Wenn sich mitten drin was ändert wird es oft nicht mitgeteilt, wenn dann heißt es man müsse das Sprintziel um jeden Preis erreichen und im nächsten Sprint würde man es eben dann nochmal machen.
Planung und Konzeption wird weiterhin von der "Führungsebene" gemacht. Die Mitarbeiter arbeiten nur wieder stur nach Vorgaben ihre ToDos ab. Sollte ein ToDo in der Umsetzung nicht genau spezifiziert sein, kann dieses nicht bearbeitet werden. Ein Konzept kann sich nicht mit der Zeit entwickeln, weil es kein Feedback über Erkenntnisse und neue Erfahrungen gibt.
Hier ist aber nicht nur die "Führungsebene" schuld, sondern oft auch Mitarbeiter, die viel lieber nach festen Vorgaben arbeiten und nicht selbst die Lösung für das Problem entwickeln wollen. Die Verantwortung für ein Produkt wird da immer noch nach oben gereicht, weil der Mitarbeiter führt ja nur aus.
Wie macht man es besser. Man braucht eine direkte und vollständige Kommunikation über alle Grenzen hinweg. Die Vision muss allen klar sein und jeder muss auch bereit sein diese selbstverantwortlich um zu setzen. Jeder soll eine Lösung vorschlagen können. Bei klaren Anforderungen muss auch nicht jeder Pups besprochen werden, weil jeder ja daran interessiert ist, das Produkt fertig zu stellen, wird auch jeder die seiner Ansicht nach beste Lösung implementieren. Und wenn man ehrlich ist, kann jede andere Lösung genau so "richtig" oder "falsch" sein, wie die andere. Zu viel diskutieren bringt am Ende nichts, lieber machen und ausprobieren.
Niemand wird dir das Denken dabei abnehmen. Immer mit denken und den Denkprozess und die Entscheidungen dazu immer dicht man Entwicklungsprozess halten. Bei den Meetings können Vorschläge gemacht werden, aber diese sind nicht in Stein gemeißelt sondern wie gesagt nur Vorschläge und mögliche Lösungen. Wenn es sich auf halben Wege heraus stellt, dass es nicht so geht.. abbrechen und direkt neu anfangen. Ein Sprintziel ist nie wichtiger als das Produkt. Was bringt es ein Feature zu Ende zu implementieren, wenn die Implementierung sowie so
wieder verworfen wird? Nichts.. es verbraucht nur Zeit und Kunden könnten glauben, es würde doch schon fertig sein. Wenn man etwas macht, dann richtig und dafür darf man keine Angst haben mal was aus zu probieren und dann mit dem Versuch auch zu scheitern.
Retrospektiven und Meetings sind wichtig, weil da keine nach unten gerichtete Kommunikation stattfindet, sondern alle auf Augenhöhe mit einander reden können. Auf von "unten" muss klar kommuniziert werden, was und wie viel man schafft und schaffen will. Ein Sprint ist kein Zeitraum wo man möglichst viele Aufgaben reindrückt und am Ende Crunchtime erzeugt, damit das Sprintziel auf jeden Fall erreicht wird. Lieber weniger einplanen und dem Sprintende entspannt und zufrieden entgegen sehen. Lieber die Zeit nutzen um Lösungen zu entwickeln und geplante ToDos noch mals zu analysieren und schon mal etwas auszuarbeiten.
Viele leben aber noch zu sehr in ihrer hierarchischen Wasserfall-Welt, wo Kommunikation nur in eine Richtung geht, nur konkrete Ausgaben kommuniziert werden und ein Sprint ein Timeslot ist, in dem man möglichst viel Arbeit erledigt haben will und das Sprintende eher drohend sein soll und nicht erwartet werden soll.
Agil bedeutet für mich, dass Informationen in alle Richtungen fließen und einen beim Denken und Lösungen finden immer zur Verfügung stehen. Agil ist, wenn man schnell austestet, schnell scheitert und schnell mit der mehr Erfahrung von neuen beginnen kann. Wo man neue Fehler machen kann um so zu neuen Lösungen zu kommen. Und für all dieses übernehme ich dann auch gerne die Verantwortung
Die Idee klang erst einmal ganz interessant. Eine ältere SSD im mSATA oder M.2 Format in einen USB 3.0 Adapter einbauen und als schnellen USB-Stick verwenden. Kostet auch so gut wie nichts. Ein Adapter so 3-5 EUR in China und eine 32GB mSATA SSD kostet auch nur etwas über 10 EUR.
Nettes kleines Projekt dachte ich mir. Kann ja nicht viel schief laufen, außer dass der Adapter vielleicht am Ende doch alles aus bremst, weil der schlecht ist.
Und mein vorhaben ist grandios gescheitert. Eines von beiden funktioniert nicht. Formatieren ging nach vielen versuchen. Aber irgendwann bricht die Übertragung ab und Windows meldet einen Timeout.
Was jetzt? SSD neu bestellen? Adapter erneut bestellen?
Ich bestell einen SATA-Adapter (kann man immer mal gebrauchen) und teste mal die SSD. Wenn die defekt ist, wird die zurück geschickt. Ansonsten werde ich mal abwarten, ob man einen neuen Adapter mal für 1 EUR oder so bekommt, der hoffentlich dann richtig funktioniert.
In den letzten Wochen hat sich doch einiges beim meinem XML-Export Plugin getan. Langsam aber zielstrebig geht es in die Bereiche Dropshipping und Bestellung-Konsolidierung. Dadurch wird es zu einem wichtigen B2B-Baustein.
Mit der Version 0.4.1 ist nun viel mehr in dem Bereich möglich (Veröffentlichung folgt in den nächsten Tagen)
Als erstes Beispiel wie man das Plugin nicht nur dafür verwenden kann für das eigene ERP Bestellungen zu exportieren, habe ich hier erotikgrosshandel.de . Deren Schnittstellen-Doku ist ziemlich gut und sie haben ein sehr minimalistisches Format, so dass man relativ schnell zum Ziel kommt. Die Voraussetzung waren:
- Ein eigenes passendes XSLT-Template (nach deren Doku)
- Der ApiClient muss FORM-Data per Post senden können (nicht nur wie bisher JSON)
- CronJob und CLI-Command müssen den Push an eine API auslösen
- Das Model muss die Lieferanten spezifischen Bestellnummern der Artikel enthalten (Puchase-Preise kamen gleich mit dazu...)
Das ganze war dann eigentlich nur viel Kleinkram und der POST als FORM-Data. War also an sich relativ schnell umgesetzt und lies sich gut testen.
Eingestellt muss sein:
- Format: eigene XSLT-Transformation
- Den Pfad zur eigenen XSLT angeben (absoluter Pfad vom /-Root aus!)
- Export-Pfad ist nicht nötig, aber sollte man doch setzen, falls man als Kontrolle die XML-Daten doch selbst noch mal vorhalten möchte (auch hier der absolute Pfad)
- nie automatisch exportieren (nur per CLI, CronJob oder API), man sollte den CronJob verwenden
- CronJob soll nur Bestellungen mit dem Status 0 und 12 (offen und vollständig bezahlt) verarbeiten: "0,!1,!2,!3,!4,!5,!6,!7,!8,!9,!10,!11,12,!13,!14"
- nach dem Export auf Status 1 (in Bearbeitung) setzen
- Host und URL setzen für erotikgrosshandel.de
- Content-Feldname auf "data" ändern
- Post-Format auf "FORM" setzen, damit in "data" die XML-Daten zu finden sind
Damit sendet er per CLI oder CronJob alle 0+12 Bestellungen im Lieferanten eigenen XML-Format an deren Schnittstelle und setzt danach die Bestellung auf 1+12, damit sie beim nächsten Durchlauf kein weiteres mal übertragen wird.
Den CronJob auf 10min stellen und dann sollten alle 10 Minuten alle "offenen" Bestellungen an den Server übertragen.
Über XSLT-Dateien kann man in anderen Fällen natürlich dann auch andere Formate wie GS1 oder OCI implementieren. Um die Daten zu den anderen Systemen übertragen zu können stehen der API-Client, Emails, Abruf über die Shopware-API oder der Export als Datei (und dann Übertragung per FTP oder SCP) zur Verfügung.
In den nächsten Wochen steht bei mir auf dem Plan, Bestellungen konsolidieren zu können, so dass bei einem CronJob-Lauf alle 2h nicht alle Bestellungen einzeln übertragen werden müssen, sondern auch zusammen gefasst werden können, wenn die Bestellungen für den selben Empfänger vorgesehen sind.
Für mein POS-Projekt hatte ich 2 verschiedene RFID-USB-Reader. Einen direkt aus China und einen über Amazon bestellt. Der von Amazon hat den Vorteil, dass er verschiedene Ausgabe-Modi kann.
Der einfache Reader aus China gab von Anfang an direkt die Nummer mit Enter aus.
Der Reader von Amazon war zu Anfang so eingestellt das die Nummer ohne Enter ausgegeben wird. Aber es war eine Karte dabei um die Ausgabe zu konfigurieren.
Das ist auch sehr einfach. Wie man wohl schon direkt vermutet, hält man die Karte über das Lesegerät und es schaltet in den nächsten Modus.
Der Index des aktiven Modus wird ausgeben und man kann direkt mit einer normalen RFID-Karte testen.
Ich habe am Ende den Modus 0e verwendet. Da es der Code ist, der auch auf der Karte steht und mit Enter ausgegeben wird (also wie vorher nur mit Enter).
Ich hatte mal vor längerer Zeit einen Blog-Post darüber gesprochen, dass IT nicht bei Ebay wächst. Also über Firmen, die ihre IT Ausstattung oder was sie so nennen, sich Stückchenweise bei Ebay und so zusammen kaufen und einen wilden Wuchs verschiedenster PCs und Notebooks mit genau so vielen verschiedenen Problemen schaffen.
Das Verlockende an diesem Vorgehen ist einfach der Preis und damit ein gedachter schneller RoI. Nur leider stimmt dieses so einfach nicht. Verschiedene Systeme haben verschiedene Probleme und brauchen verschiedene Lösungen. Die langzeit Administrationkosten sind also sehr hoch und drücken sehr auf den RoI. Oft wären der RoI schneller und höher bei neuen Systemen, die man bei z. B. bei Dell, HP, Fujitsu oder Lenovo in den benötigten Stückzahlen kaufen kann.
Aber es gibt eine 3. Methode, die eher der 2. genannten entspricht, aber auf Preisen der ersten basiert. Refurbished Systeme kaufen. Refurbished Systeme kommen zu meiste aus alten Firmenbeständen. Wenn eine Firma 200 Arbeitsplatz-PCs austauscht, weil der Hersteller nach 5-6 Jahren keinen bezahlbaren Support und Ersatzteile/Austauschgeräte mehr bietet, holt man sich gerne eine externe Firma, die die PCs einen abkauft, wieder in Schuss bringt und dann selbst weiter verkauft. Stückzahlen, Garantie und schon die richtige Art von Systemen für einen sehr günstigen Preis.
Bei dem Preis kauft man sich einfach 10% mehr als benötigt und spart sich teure Support-Verträge.
Konkret ging es bei mir um eine Anfrage, wie man ~12 Arbeitsplätze erneuern könnte. Es gab verschiedene Angebote und ich sollte auch noch mal was raus suchen. Anforderung war, dass sie schneller als die alten sein sollten. Das übersetzt man dann in: leicht administrierbar, alle gleich, solide Hardware, ausreichend Anschlüsse. Da ist das auch Freelance-Ebene neben meinem Job mache, habe ich dabei auch die Freiheit günstig zu sein, auch wenn ich versuche nicht denen, die davon leben, die Preise kaputt zu machen.
Ich hab einen einfachen Office-PC rausgesucht. Ein i5 ist mehr als ausreichend schnell. Denn was machen die Leute im Büro? 80% der Anwendungen sind Cloud-Anwendungen, die im Firefox laufen. Was in Word schreiben. Die Hardcore-Anwender verwenden sogar mal Excel (teilweise für Todo-Listen). PDFs ansehen, Drucken, Scannen (damals noch über SMB-Freigaben *urgs*).. das war es. Ich wurde gewarnt, dass viele ja so viele Daten hätten 10GB-500GB an Daten und die 320GB HDD würde ja nie reichen. Wenn man aber die 600MB Druckertreiber, 150MB Openoffice Installer, etc einmal weg gerechnet hatte blieben meist so 1GB-5GB übrig. Der Arbeitsplatz der Grafikdesignerin war eine eigene kleine ungeplante Baustelle.
Viel konnte man sparen, in dem man die Scans nur noch über Email laufen lies. Weil dann ist alles im Postfach zu finden, was man mal gescannt hat und man findet es dort auch wieder, falls mal die Kopie von der Festplatte verloren geht (defekter PC oder so).
Also i5, 8GB RAM, 320GB HDD und , das war mir wichtig, 2 Displayports. Keiner der dort verwendeten Monitore war mit Displayport angeschlossen, ABER der Wildwuchs an HDMI, DVI und VGA Monitoren, Adaptern und Kabel war zu undurchsichtig um alles irgendwie geordnet aud 1x HDMI, 1x DVI, 1x VGA auszuteilen. An Displayport kann man alles gut und einfach adaptieren und die Adapter sind günstig. Also lieber 8x DP auf HDMI und 6x DP auf DVI ADapter kaufen und sich den Stress mit Kabel und Monitore sortieren und hin und her tauschen sparen.
Etwas was man auch nicht unterschätzen sollte, ist die Stapelbarkeit der PCs. Wenn man die alten einlagert oder neue vorbereitet für den späteren Einsatz, ist man glücklich im Lagerraum nur wenig Platz zu benötigen. Da sind diese Office-PCs auch fast unschlagbar (nur die Kiste für die Netzteile ist nicht ganz optimal).
Das sind dann ca 280 Euro für einen neuen Arbeitsplatz und es können mit Tesafilm zusammen gehaltene PCs ausgetauscht werden :-)
Was neu gekauft wurde, sind die Adapter, ein QNAP NAS (als allgemeiner SMB-Server und Domain-Controller.. was echt super funktioniert), sowie eine Fritzbox. Die Fritzbox ersetzte eine Telekom Digitialisierungbox Business.
Beim Router war der RoI auschlag gebend. Remote-Access, VPN und alles schnell und einfach. Der Preis für die Fritzbox war schon in den 30min wieder drin, die ich damit brauchte alles einzurichten, wobei ich bei der Box 4-5h lang gescheitert bin. Ok.. mir fehlte die Erfahrung mit der Box, aber wenn man die TK-Anlagen Funktion der Box nicht nutzt, ist es kein Verlust und spart direkt Geld (Fallback Lösungen sind auch schnell in 10min umgesetzt).
Selbst die Fritzbox hätte man gut gebraucht kaufen können, wenn man die Zeit gehabt hätte. Bei QNAP Geräten sind die Auswahl und die Preise bei Refurbished Geräten so schlecht, dass neu kaufen genau so gut ist.
Bei anderen Herstellern ist es leider nicht besser (Domain-Controller Funktion lässt leider wenig Auswahl!)
Noch mal zum Grafik-Arbeitsplatz. Momentan ist der Arbeitsplatz nur mit einem Notebook (i7, 16GB, etc) ausgerüstet und soll zu einem Arbeitsplatz mit einer echten Workstation + dem Notebook + VPN-Zugang werden. Der Printserver für den Plotter entpuppte sich als Xeon CAD-Workstation (E3, 16GB, Quadro 4000er, 256GB M.2 SSD). Dafür habe ich eine refurbished 2TB HDD gekauft (ich liebe Shops wo ich 3h nach Bestellung alles einfach direkt abholen kann).
Die Daten für die Workstation und das Notebook sollen auf dem NAS gelagert sein, dass über VPN dann erreichbar ist.
Am Ende war es eine gute Entscheidung das meiste gebraucht oder wenigstens günstig zu kaufen. Beim NAS sind neue Festplatten gut, aber das Gehäuse hätte man genau so gut gebraucht kaufen können. Für Festplatten und SSDs die nicht 24h/7d laufen reichen auch oft refurbished Komponenten, die zumeist aus Demo-Systemen stammen oder bei Aufrüstungen übrigblieben.
Ich habe erst gestern eine 300GB SSD verbaut, um einen PC noch mal etwas mehr schnellen Speicher zu geben. Günstig, funktioniert... da am Ende nur viel davon gelesen wird (da kommt der Steam-Ordner drauf) hält die auch lange. Auch als unempfindliche externe Festplatte sind günstige SSDs echt super. Sie sind sehr viel schneller als USB-Sticks und halten auch mal Stöße sowie Stürze aus, weil keine mechanischen Komponenten verbaut sind. Ein gutes 2,5 USB 3.0 Gehäuse gibt es für 8 Euro.
Seine IT auf refurbished Geräten aufbauen zu lassen ist also ohne Probleme möglich und für kleine Firmen, die nicht viel Geld investieren und auch das schnell wieder drin haben wollen, eine sehr gute Alternative zu Verträgen mit Dell, HP, etc.
So langsam wird aus dem Prototypen, ein echtes und brauchbares Produkt. Auch wenn der Realworld-Test heute leider ausgefallen ist, hat das Plugin wichtige neue Funktionen bekommen:
- Direktes Anlegen eines Kunden beim ersten Login-Versuch (dann muss man bei 4000 Karten nicht 4000 Kunden anlegen sondern, kann direkt loslegen)
- Vorgegebene Freitext-Felder, dadurch muss man weniger konfigurieren und weniger Fehlerquellen
Zusätzlich:
- viele Fixes
- Drucken von Kassenbons ist zu 50% fertig. Ein Thermodrucker zum testen ist bestellt.. und hilft vielleicht bei der Kassenschubladen-Problematik
- 13,6mHz Tags zum Aufkleben und ein passendes Lesegerät sind auch bestellt... damit kann man einfache Eintrittskarten zu Bezahlkarten machen
Es geht also alles in schnellen Schritten voran und ich hoffe, dass es dann schon bald als Cloud-Service für alle verfügbar sein wird.
Da alles andere irgendwie zu groß oder zu teuer ist, habe ich mir mal was einfaches kleines gebaut. Es braucht zwar einen Client als Service auf dem PC (oder starten mit Admin-Rechten), aber dafür läuft alles über HTTP und der Client-PC muss nicht eingeschaltet sein, sondern prüft wenn er angeht oder jede Stunde einmal.
Momentan gibt es noch keine Unterscheidung der Betriebssysteme und eine gute Server-Umgebung fehlt auch. Aber man kann auch alles ganz plain und primitiv auf dem Server ablegen ohne eine extra Software.
Mal gucken was daraus wird. Aber gerade weil es alles so einfach und klein ist, sehe ich da doch etwas Potential, wenn dann eine Server-Software dafür existiert wird.
Mein neues Plugin ist online. Es kann warnen, wenn sich der Preis der eines Artikels um mehr als X% in einem bestimmten Zeitraum (letzte Änderung, 1 Tag, 7 Tage, 30 Tage) ändert. Es kann auch eine Email verschicken oder den Artikel direkt deaktivieren.
Auch kann das Plugin mein anderes Plugin ersetzen und auch 0,00-Preise reagieren.
Manchmal kann es sein, dass man die Email-Adressen von allen die man einer Gruppe hinzu fügen will nicht kennt. Gerade wenn sich diese mit privaten Email-Adressen anmelden.
Nun hat man für jede Gruppe in https://www.mobile-time-tracking.com einen Einladungs-Code den man verschicken oder in Chat-Gruppen teilen kann. Wenn ein Benutzer diesen Code eingibt, wird er automatisch zur Gruppe hinzugefügt.
Nach langer Zeit.. also einigen Monaten gibt es mal wieder einen neuen Bild-Filter für MP4toGIF. Er spiegelt die linke Seite des Bildes an der Mittellinie und ersetzt damit die Rechte Seite des Bildes.
Ist an sich ein sehr alter und schon oft verwendeter Effekt des etwas von 80er Jahre Musikvideos hat. Aber er ist eben auch schön trashig und retro und machte Spaß ihn zu bauen.
Video-Material von Under Siege aka Alarmstufe Rot.. der beste Steven Seagal Film !!!!
Events behandeln wir hier bei wie einen normalen Kunden. Ich werde die Übersetzung noch mal neu machen und dann wird es alles auch auf Deutsch geben und dann werde ich Events direkt mit einbringen.
Zuerst legen wir uns eine Gruppe für unsere Events an. Gruppen haben die Aufgabe ähnliche Kunden und Events zusammen und auch die Zuordnung zu den Benutzern abzubilden. Gruppen sind dafür da wenn man für verschiedene Firmen Kunden als Freelancer bedient oder für Teams und Abteilungen in einer Firma, die alle einzeln ihre Kunden und Zeiten abrechnen.
Wir legen also hier eine Gruppe „Events“ an, damit wir unseren Mitarbeitern und Aushilfen bei den Events die Möglichkeit geben Zeiten auf die Events buchen zu können.
Danach kommt jetzt unser Event No1. Das legen wir direkt an. Wir brauchen dafür nur einen Namen. Kontaktinformationen werden nicht benötigt, helfen aber den Mitarbeiten um zum Kunden oder zur Event-Location zu finden oder sich dort zu melden, falls etwas etwas zu klären ist. Die OpenStreetMap-Integration ist jetzt nicht wirklich toll, aber doch eine Hilfe, um den Weg zu finden, falls man sich dort nicht auskennen sollte. Aber es ersetzt keine "echte" Navi-App.
Ich überlege gerade ob Appointments praktisch wären.. also man Termine für einen Mitarbeiter eintragen kann, so damit der Mitarbeiter weiß, wann er wo sein soll. Also etwas wie „Event No1, Appointment 17:00“. Dann weiß der Mitarbeiter, dass er um 17:00 an der Event-Location von Event No 1 sein soll.
Falls jemand das System benutzt und so etwas gerne hätte.. einfach bei mir melden und ich bauen es ein :-)
Nachdem wir unser Event No1 anlegt haben, können wir Zeiten darauf buchen. Aber wir wollen ja, dass unsere Mitarbeiter ihre Zeiten darauf buchen.
Also gehen wir "edit“ bei der Gruppe und tragen weiter unten den Benutzernamen/ die Emailadresse unseres Mitarbeiter ein. Er muss dafür bei mobile-time-tracking.com registriert sein.
Danach sieht er die Gruppe auch auf seiner Startseite und kann seine Zeiten auf die Events in der Gruppe buchen.
Wenn er also bei der Event-Location ankommt, wählt er das Event aus und drückt auf "Start“. Nachdem er dort fertig ist drückt er auf "Stop“ und geht glücklich und erschöpft nach Hause.
Der Besitzer der Gruppe darf alle Zeiten sehen. Normale Mitarbeiter (also !Besitzer) sehen nur ihre eigenen Buchungen.
Am 24.6. war es wieder so weit und das Bremer Oldtimer-Rennen stand wieder für mich vor der Tür. Wie im Jahr davor sollte meine Aufgabe sein, die Zeitmessungen (jeden Falls einen Teil davon) durch zu führen und am Ende die Gewinner benennen zu können. Klingt erst einmal ganz einfach aber für diese Sache, die an sich voll automatisch laufen sollte, ist immer viel mehr zu tun als man so denken würde.
Dafür muss man das Grund-Setup kennen und verstehen. Bei dem Rennen nehmen 170 Autos teil. Jedes dieser Autos wird mit einem aktiven RFID-Tag ausgestattet der den Tag über die Kennung des Autos aussendet. Die Veranstaltung besteht genau genommen aus 3 Rennen. Da es natürlich unfair wäre, bei Autos von 1920 bis 1970 auf Minimalzeit pro Strecke zu fahren, wird immer auf eine Richtzeit gefahren. Der Fahrer, der am dichtesten an der Zeit dran ist gewinnt. Also kann der zweit etwas langsamer als die Zeit sein und der 3. etwas schneller. Es nur um die absolute Differenz.
Am Anfang und am Ende jeder Strecke steht dabei ein RFID-Reader, der alle Autos erfasst, die vorbei fahren.
RFID sendet aber bei einem aktiven Tag mehr als die Sekunde sein Signal und die Reader decken mit ihren Antennen einen größeren Bereich ab. Es funktioniert also grundlegend anders z.B. eine Lichtschranke. Man bekommt also eine Menge an Messwerten, die vom Auto gesendet werden, während es vorbei fährt. Daraus wird nach dem relativ einfachen Prinzip von Zuerst-Gesehen und Zuletzt-Gesehen der Mittelwert berechnet.
Dabei kann an sich schon genug schief laufen. Gerade wenn man kleine und kurze Strecken hat. Wenn das Auto schon soweit beim Start an den Reader heran fährt und schon Messwerte erfasst werden, aber das Auto noch nicht losfährt. Dann wird die Zeit in der das Auto steht, mit Pech mit in die Zeitberechnung mit hinein gerechnet.
Aber auch die Chips und Sender der Tags sind nicht immer zuverlässig. Auch wenn sie 100 mal die Sekunde senden sollen, kann man nicht immer sicher sein, dass es keine Einbrüche in dieser Frequenz gibt. Autos aus Metall können außerdem sehr gut Abschirmen und so die Sendeleistung stark beeinflussen. Bautechnische Probleme wie schlechte oder defekte Schalter zum Ein- und Ausschalten kommen noch dazu.
Diesmal hatten wir im Vorwege das Problem, dass allein durch die Bewegungen der Tags in der Kiste sich einige einschalteten und anfingen zu senden und so Tags empfangen wurden, die gar nicht zum Rennen gehörten.
Durch einen guten Aufbau und ein wenig mehr Programm-Logik kann man fast alle Probleme unter Kontrolle bringen. Aus der Menge der Messpunkte werden konkrete Werte errechnet. Mehrfachmessungen eines Autos werden entfernt und fehlende Messungen werden herausgesucht. Das benötigt etwas mehr Rechenleistung, weswegen die Messstationen mit etwas Leistungsfähigeren Notebooks ausgestatteten sein müssen.
Damit kommen wir erst einmal wieder zurück an den Anfang. Die Vorbereitung und was diesmal alles zu tun war.
Vorbereitung:
Nachdem im letzten Jahr mehr oder weniger spontan Notebooks mit dem Mess-Client ausgestattet wurden und es zu vielen Problemen kam:
- Fehlende Runtime-Umgebungen
- andere Server-Anwendungen die Ports blockierten
- Notebooks auf denen schon so viel installiert war, dass sie langsam waren
- Akkus die nicht mehr lange durch hielten und deswegen immer Strom nötig war (den es nicht immer gibt)
Ich fing also schon 2 Monate vorher an, das Problem in Angriff zu nehmen. Ich entschied mich die Hardware diesmal komplett selbst zu stellen und somit etwas mehr Sicherheit zu haben. Das Alienware sollte diesmal nicht benutzt werden, da es schwer ist und man es nicht mal schnell zur Seite nehmen kann, wenn es regnet. Außerdem ist es einfach nicht dafür gedacht, über den Akku zu laufen.. jedenfalls nicht langer als 15min.
Da ich für Notfälle aber eine Entwicklungsumgebung haben wollte, damit ein Fehler nicht ein Rennen versauen kann oder die Auswertung unmöglich macht, entschied ich mich mein Surface mit zunehmen. Es ist relativ Wetter-beständig und der Akku hält sehr lange. Die Rechenleistung ist nicht wirklich groß, aber ausreichend.
Damit waren meine eigenen Notebook Vorräte aber erschöpft und extra welche Kaufen würde sich nicht lohnen. Also kam ich auf die Idee meine Kontakte als Mitarbeiter bei Notebooks Wie Neu zu nutzen. Ich konnte mir 2 Lenovo Thinkpad T410 leihen. Mit i5, 4GB RAM waren die mehr als schnell genug und Thinkpads sind auch stabil genug, so das ich mir wegen Regen nicht zu viel Sorgen machen musste. LAN und USB Anschlüsse waren auch vorhanden. Der Akku hielt mehr als genug und am Ende waren die Akkus nicht mal halbleer, obwohl die Thinkpads ca. 2h damit beschäftigt werden durchgehend Daten abzurufen und in eine MySQL-Datebank zu schreiben.
Nur eine Sache störte mich etwas.. das war Windows 7. Egal was viele im Internet so schreiben.. bei der Bedienung ist Windows 10 sehr viel schneller und intuitiver als Windows 7. Aber da alles wie Java 1.8 und MySQL laufen, ist es nicht so schlimm, weil die Client-Software sowie so rein über die CLI bedient wird. Eine GUI Version existiert, ist aber noch auf eine Verbindung zum Server angewiesen, was da nicht gegeben war. Ein portabler UMTS-WLN-Router wäre eine gute Lösung gewesen, aber die Idee kam mir zu spät und ich wollte ja gerne den Server bei Problemen schnell ändern und fixen können. Was mit einer lokalen Instanz, die man direkt in der IDE hat, natürlich sehr viel schneller und einfacher geht als mit einem System das auf einem Server im Internet läuft.
Vielleicht bin ich nächstes Jahr mal mutiger. Es hätte auch noch andere Vorteile für die Veranstalter.. aber dazu später mehr.
Die Liste der Teilnehmer konnte ich am Abend vorher importieren und dabei noch 2 kleine Fixes einbauen. Deswegen wollte ich die Liste gerne schon vorher haben.
170 Autos. 170 importierte Rennteilnehmer am Ende. Alles perfekt.
Ich hatte also 4 Notebooks (das Alienware war als Fallback dann doch dabei), Reader, Netzwerk-Kabel und einen Switch. Was man aber immer dabei haben sollte, ist auch Essen und Trinken. Wasser und Energiedrink. Eines für den Durst und das andere für Energie. IBUs für Notfälle und natürlich das Smartphone für Navigation und Informationsbeschaffung. Beim Essen kann man sich ruhig abends vorher was kochen, denn gutes Essen macht es einen sehr viel einfacher, wenn man morgen um 4:15 aufstehen muss und dann noch kein Frühstück hatte.
Immerhin war das Wetter gut und nicht so verregnet wie im letzten Jahr... jeden Falls am Anfang
Der Tag:
Um 4:45 war ich in Stockeldorf bei "die Halle" wo die Switch GmbH ihren Sitz hat. Die Mitarbeiter wuselten durch die Gegend und packen alles in den VW Bus was man so brauchte. Dann wurde ein Karton mit Tags hochgehalten und gefragt, ob die auch mit sollen. "Nein, das sind die, die nicht funktionierten und ausgewechselt wurden".
Klingt erst einmal nicht so schlimm, aber wenn man bei 170 Teilnehmern 30 Tags für jeweils drei Rennen austauschen muss.. also 90 Einträge per Hand bearbeiten, dann klingt es nicht mehr gut. Am Ende wurden also diese Ausgetauschten alle geöffnet und Batterien getauscht. Am Ende waren es pro Rennen nur jeweils ca. 6 Tags, die per Hand übergetragen werden mussten.
Hier fiel mir auch auf, dass die Tags dieses Jahr gefühlt sehr viel Fehleranfälliger waren. Beim Testen wurden noch 4 ausgetauscht, weil sie nicht vom Reader erkannt wurden. Die Schalter schalteten in den Karton bei jeder kleinen Bewegung wie sie wollten.
Und dann kam der Regen. Viel Regen. Alles wurde unter die offene Heckklappe des VW-Bus gestellt und das Surface wechselte erst einmal in eine Plastiktüte.
Es war zum Glück nicht wirklich kalt. Nur sehr sehr nass. Wer glaubt das Regen und die Nässe nur immer von oben kommt, irrt sich. Tropfen fallen auf Tische und spritzen dann in alle Richtungen. Am Ende ist doch alles nass.
Aber es gab auch positives zu berichten. Weniger Tags streuten in den Messbereich und die Erkennung war dieses mal sehr viel besser. Das andere Team meldete sich schon kurze Zeit später und meldete, dass alles laufen würde. Ich bin immer sehr unruhig wenn ich bei so etwas nicht in der Nähe sein kann, um möglicherweise auftretende Fehler zu beheben. Ich kenne das System zu 100% und einfach unerfahrene Benutzer damit los zu schicken.. dazu gehört sehr viel Vertrauen in die eigene Software dazu.
Am Ende war alles super. Alles hatte beim ersten Rennen funktioniert und das Thinkpad konnte zeigen was es konnte. Beim Surface braucht ich so 15min mit Client in der IDE um die Daten zu übertragen. Dabei liest der Client und schreibt der Server auch in die selbe Datenbank, was auch nochmal bremst. Das Thinkpad brauchte gerade mal 4-5 Minuten. Schnelle CPU, schnelles Lesen von der Festlatte. Das Schreiben in die DB auf dem Surface war dann auch sehr entspannt, weil nebenbei nicht so viel gelesen oder gerechnet werden musste. Also Server und Entwickler-Rechner hat sich das Surface mehr als bewährt. Das selbe gilt auch für die Thinkpads als Messstationen-Clients.
Das 2. Rennen war dann die kritische Phase, die dann aber auf Grund der stabilen Bauweise der Reader und viel Nachrechnen und eliminieren von Fehlmessungen, am Ende doch gut ging. Wir hatten kaum Zeit zum Aufbauen, ein Reader lief an einem Diesel-Generator und 50m Lan-Kabel. Die ersten Autos wurden manuell gemessen mit der eingebauten App vom Time-System, während wir nebenbei den zweiten Reader aufbauten, der dann am Alienware lief. Sturm, Regen und noch mehr Regen. Wir saßen im Bus und nur die Kabel zu den Readern im Regen gingen nach draußen. Ich wüsste zwischendurch nicht ob der Reader am Start noch lebte und Daten sendete. 1,5h später war der Regen vorbei und man ordnete sich und guckte mal wieder auf die Terminal-Ausgaben auf dem Surface. Alles lief super. Es fuhr gerade das letzte Auto vor und der Reader meldete den Tag also ob vorher nicht gewesen wäre. Sein Netzteil hing so im Regen und ein Teil des Kabel lag vorher schon blank. Aber kein Aussetzer bei der Datenerfassung. Ich war wirklich stolz auf den kleinen tapferen Reader.
Das Netzwerk-Kabel wurde auch nebenbei als Streckenbegrenzung verwendet. Von der Planung her eine Katastrophe, aber mit den Fallback-Lösungen konnte man alles retten.
Danach ging es zur Test-Strecke von Mercedes und das 2. Thinkpad übernahm das Rennen dort. 1. Rennen war in 20min fertig. Ich hab bevor Korrektur-Funktionen über die Daten liefen immer lieber noch einmal die Daten gesichert. Berechnen lief schnell.
Das 2. Rennen brauchte mehr Zeit. über eine Stunde, da ich viel bei den Korrektur-Funktionen nacharbeiten musste, die Fehlmessungen eliminierten und ich lieber 3 mal die Liste der gefahrenen Autos durch ging, um sicher zu sein, dass wirklich kein Auto übersehen oder nicht gemessen wurde.
Das 3. Rennen ging dann wieder sehr schnell und es gab keine Überraschungen.
Bestes Frauen-Team musste dann per Hand berechnet werden. Waren aber nur sehr wenige Teams, deswegen ging es. Der Gesamtsieger war aufwendiger, weil man über die gesamten drei rennen Rechnen musste, zum Glück sind es doch immer die selben Fehler die vorne liegen. Damit war es ausreichend die 9 Sieger der 3 Rennen zu nehmen und für diese die Werte der 3 Rennen auszuwerten. Kontrolle bei den 4. und 5. Plätzen zeigten gleich, dass von dort keine Konkurrenz mehr kam.
Auch fiel dabei auf, dass man kein großes Kopf-an-Kopf-Rennen hier hatte. Die ersten Plätze waren immer sehr eindeutig, eher am Ende des ersten Drittels konzentrierten sich die Zeiten auf eine geringe Zeitspanne.
Das Fazit:
Das Event lief sehr viel besser als das letzte Jahr und die Zeiten für die Auswertungen war sehr viel geringer. Die automatischen Analysen und Korrekturen von Fehlmessungen hat viel gebraucht und sehr viel besser und zuverlässiger funktioniert, als es per Hand war.
Trotzdem hätte ich gerne eine andere Lösung für das nächste mal. Die Tag an sich sind eine Fehlerquelle für sich und diese würde ich gerne eliminieren. Eine Lösung wäre eine Kamera gestützte Erfassungsmethode mit QR-Codes. Wie Lichtschranken, gibt es da aber Probleme bei parallel fahrenden Autos. Deswegen müsste man ein Gestell haben, um die Kameras von oben auf die Start- und Ziellinie gucken zu lassen. Dann muss man die Autos erkennen, da man so wirklich von vorderen Punkt des Autos messen kann und nicht nur die Position des RFID-Tags (was viele Teilnehmern nicht klar war, sich aber natürlich auf die Messungen auswirkt).
So ein System ist sicher zu bauen, aber braucht seine Zeit. Am Ende hätte man aber sicher gute Ergebnisse mit Beweisfoto.
Auch sollte alles so aufbaubar sein, dass die Technik die Autos nie verlassen muss. Mehr Schutz vor Regen und man kann schneller aufbauen, wenn nur noch Kabel verlegt werden müssen.
Ein großer Traum wäre es, es wirklich als Cloud-Anwendung laufen zu lassen, so dass die Clients direkt vor Ort über einen WLAN-UMTS-Router ihre Daten direkt an den Server schicken können. Vielleicht sogar kurz nach dem sie gemessen wurden. Damit hätte man auch die Möglichkeit eine Echtzeit Anzeige zu realisieren.
Ich hatte bei der Entwicklung von mein-online-adventskalender.de schon sehr darauf geachtet, dass es sich leicht integrieren lässt. Aber bei meinem Test mit Shopware hat sich gezeigt, dass es auch wirklich gut klappt.
Ich hab es über ein Iframe-Element in einer Einkaufswelt eingebunden. Das Element sollte eine Höhe von 1350 haben auf dem Desktop.
Vielleicht baue ich im Herbst ja noch mal ein richtiges Plugin dafür :-)
Morgen beginnen die Test meiner ersten beiden Shopware Plugins. Teilweise sehen sie auch wirklich wie "die ersten" aus, auch wenn ich nochmal viel nachgebessert habe. Aber gerade optisch ist noch viel Raum nach Oben. Bis Freitag kann man da sicher noch was machen, um auch optisch noch was besseres abliefern zu können.
Weitere und bessere Plugins, aber erst einmal ohne Oberflächen, sondern als Unterstützung für Entwickler und Designer, folgen dann hoffentlich in den nächsten Wochen und Monaten.
Das Surface ist mit dem Pen ideal um sich in OneNote schnell und einfach handschriftliche Notizen zu machen. Zusätzlich zum Text oder auch nur per Hand.
Gerade während man telefoniert, kann man Notizen machen und hat diese dann auch gleich auf dem PC und auf dem Smartphone, ohne das man Dateien kopieren muss.
Die nächsten Wochen und Monate werden sehr stressig. Meine Pläne sind:
- Umziehen und Renovieren (vielleicht mit Blog-Post über Netzwerk, Server und Überwachungskameras)
- Ein einfaches Shopware Plugin in den Community Store zu bekommen (Das Plugin ist so gut wie fertig.. jetzt kommt die Upload-Theorie* .. schlimmer als der App-Store für Firefox OS kann es sicher nicht sein)
- Einen kleinen aber etwas speziellen Shop online bringen (ich werde berichtigen wie es läuft und ob es am Ende erfolgreich war)
- Zwei Termine mit dem Switch GmbH Time-System stehen an, wo ich auch Blog-Post und so liefern werde.. mehr als letztes Jahr
- Ein Video über die manuelle Zeitmessung mit dem Time-System
- Und nach dem Umbau der letzten 3 Monate am aoop PHP-Framework mit MVC, neuer Verzeichnisstruktur, PHP 7, Namespaces, Composer-Autoloader, etc müsste ich wirklich mal eine neue Version releasen.. ich bin doch relativ stolz auf die neue Version ,weil sie doch etwas ist was man als modern bezeichnen kann
Gehen wir mal davon aus wir erstellen eine Homepage für eine Restaurant-Kette mit 3 Restaurants. Die Seite soll so gebaut sein, dass Mitarbeiter der Restaurants einfache Datenänderungen vornehmen können, ohne dafür um Hilfe fragen zu müssen. Auch sollen Änderungen im Layout einfach und schnell möglich sein, dass aber nicht durch die Mitarbeiter, da diese wohl kein HTML beherrschen.
Jedes Restaurant hat eine eigene Unterseite, die vom Aufbau aber immer gleich sind.
Das Problem ist, dass wenn es Änderungen im Layout dieser 3 Seiten geben soll, müssen die Änderungen auch in allen 3 Seiten getätigt werden. Ein einfaches Kopieren geht natürlich nicht, da man sonst ja die individuellen Texte und Bilder überschreiben würde. Die speziellen Öffnungszeiten für Feiertage einzutragen ist nicht ganz so kompliziert, wenn man einen WYSIWYG-Editor hat. Aber einfacher wäre es natürlich, wenn diese Angaben atomar eingegeben werden können und so auch nicht die Gefahr besteht, durch Fehler die gesamte Seite durcheinander zu bringen.
Ich habe für mein Framework/CMS diese Lösung entwickelt. In dem Code der Seite sind Platzhalter eingebaut, die heraus geparst werden und mit individuellen Werten gefüllt werden können. Daher kann man einfach eine vorhandene Seite kopieren und muss nur die im Formular ausgewiesenen Platzhalter neu füllen. Das Layout zu Ändern geht auch einfach weil man den Code wirklich mit Copy und Paste in alle Seiten übernehmen kann, ohne Werte zu überschreiben.
Man hätte natürlich auch Entitäten und Controller mit Templates bauen können. Aber für solche Zwecke ist das oft vom Aufwand her nicht gerechtfertigt, weil die verwendete Zeit nicht entsprechend bezahlt werden würde und mit dieser Lösung es wohl auch schneller geht.
Und für die einfachen Benutzer ist es so auch viel übersichtlicher und sie können dann bestimmt mehr alleine Ändern, weil sie nicht der Content der gesamten Seite erschlägt.
Den ersten Test hat mein Framework schon geschafft. Es hat SMS empfangen und durch die Pipeline an das Dummy-Plugin weiter gegeben. Jetzt muss nur noch mal getestet werden, dass die Patterns und Value-Checks alle richtig greifen.
Dann hoffe ich ein es einem ersten Projekt verwenden zu können.
Mein neustes Projekt ist heute Abend gestartet. Es geht um ein Framework, dass SMS empfangen kann und diese dann anhand verschiedener Regeln wie Absender, Empfänger oder Inhalt an ein oder auch mehrere externe Systeme weiterleiten kann.
Diese Weiterleitung an andere System geschieht über Plugins, die auch dann die Daten aus der SMS aufbereiten sollen, so dass sie vom externen System verarbeitet werden können.
Einfache Plugins wie "in eine DB" schreiben, an einen REST-Service oder meine MessageDriven Bean schicken, werden direkt dann mitgeliefert.
Das Empfangen und Senden von einer SMS mit Java habe ich schon letzten Monat erfolgreich getestet, deswegen glaube ich, dass ich relativ schnell zu ersten Ergebnissen kommen werden. In den nächsten 2 Monaten hätte ich gerne den ersten brauchbaren Prototypen.
Heute ist der neue Stick angekommen und nachdem die Software von der Herstellerseite installiert wurde, wurde er auch problemlos unter Windows 10 erkannt.
Der Stick ist ein 4G Systems XS Stick P10 und bei dem Preis kann man wohl erst einmal nicht viel falsch machen.
Während ich in den letzten 3 Jahren bei aoop immer mehr Framework-Charakter im Vordergrund gesehen habe und den CMS-Teil davon mehr oder weniger komplett vernachlässigt habe (bis auf die Integration von TinyMCE und Code-Mirror), habe ich jetzt mal wieder angefangen in die Richtung etwas zu tun und die ersten Änderungen sind schon aus dem Feature-Branch in den Master gewandert.
Seiten sind nun Grids mit Content-Modulen als Inhalt. Der Vorteil von so einem Grid ist, dass es responsive ist und so die Anpassung für Mobile-Devices sehr vereinfacht wird. Während in der Desktop-Ansicht man das Grid sieht wird bei der Unterschreitung einer gewissen Breite einfach alles untereinander angeordnet. Momentan verwende ich das Grid von Bootstrap, weil man dieses auch allein super in vorhandene Templates integrieren kann ohne Angst haben zu müssen, dass das Design oder Layout Schaden nimmt.
Der Editor nutzt auch das Grid um eine brauchbare Vorschau zu liefern.
Dieses neue Seiten-Model und der dazu gehörige Editor werden nie den Umfang und die Qualität der Shopping Worlds in Shopware. Ich überlege ein Modul zu schreiben, das ähnlich wie das Digital Publishing in Shopware repsonsive Banners ermöglicht, aber auch hier natürlich nicht in dem Umfang, sondern in einer einfachen und grundlegenden Version.
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.
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.
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".
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.
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.
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.
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.
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.
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?
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.
Nach dem ich den Tag mit der Sound API für Java verbracht habe, hab ich dann für heute noch mal eine Verbesserung für MP4toGIF.com in Angriff genommen. Neben den normalen Farbfiltern wird nun noch ein Vignitierungsfilter als Ergänzung zu den Farbfiltern hinzukommen.
Mit dem Canvas sind solche Effekte sehr einfach umzusetzen und sind dabei noch relativ performant.
function createVignetting(ctx){
var x=Math.round(ctx.canvas.width/2);
var y=Math.round(ctx.canvas.height/2);
var grd=ctx.createRadialGradient(x,y,1,x,y,y-5);
Nach 9 Jahren geht es mit aoop doch mal los. Ein weiters Projekt mit meinem Framework startet morgen. Es basiert auf der neusten Version mit dem Blog-Modul.
Ich bin auch technischer Admin und betreue alles auf technischer Ebene. Logos und Design stammen von meiner Frau und sind wirklich toll. Wer es sich mal ansehen möchte findet es unter http://www.tentacle-news.net.
Ich habe den ersten Schritt gemacht und 2 einfache Filter in MP4toGIF.com eingebaut. Man kann nun direkt schwarz/weiß Animationen aus farbigen Ausgangsmaterial erstellen. Auch eine Farbgebung, die etwas "vintage" aussieht.
Die Filter basieren auf dem Code den ich hier schon mal vor einiger Zeit veröffentlicht habe. Alles natürlich HTML5 Canvas basiert.
Mit der Zeit werden noch ein paar mehr Filter folgen.
Bald kommt wieder die Weihnachtszeit. Manch einer könnte auf die Idee kommen seine Familie, Freunde, Kunden, Follower, Fans oder einfach die Welt mit einem Bilder-Adventskalender im Internet zu beglücken. Egal ob es nun Bilder von einem selbst, von den eigenen Kindern, Katzen oder Hunden sein sollen.
Dafür habe ich ein kleines Projekt gestartet, dass es jedem ermöglicht einen solchen Online-Adventskalender zu erstellen und zu teilen.
Neben den Bildern (die man auch in einer Großansicht betrachten kann), kann man jedem Bild einen zusätzlichen Text hinzufügen und auch dem gesamten Kalender neben einem eigenen Titel auch einen Text geben in dem man die Besucher seines Kalenders direkt ansprechen kann.
Wer seine Bilder nicht mit der gesamten Welt teilen möchte, kann den Adventskalender auch mit einem Passwort versehen, so das nur Personen Zugriff erhalten, die die Bilder sehen sollen dürfen.
Jeder Adventskalender ist kostenlos, hat 24 Türchen, kann einen Text und ein zusätzliches Hintergrundbild enthalten und lässt sich jeder Zeit anpassen und ändern. Auch Bilder und Texte schon offener Türchen lassen sich weiterhin bearbeiten. Dadurch kann man den Kalender auch während er schon läuft weiter aufbauen und man muss nicht gleich am Anfang seine 24 Bilder heraus gesucht haben.
Über Videos und Texte die nur am passenden Tag zusehen sind, denke ich momentan noch nach, wobei Video oder animierte Gifs ein komplexeres Thema sind. Wenn man jetzt kommerziell denken würde, wären diese Tages-Texte ideal für Gutschein-Codes und so etwas.
Jeder der es mal ausprobieren möchte ist herzlich dazu eingeladen und ich würde es toll finden, wenn dann doch ein paar Adventskalender wirklich ihrer Bestimmung nach andere Menschen beglücken können. Wenn jemand es testet und auch Fehler stößt oder Verbesserungsvorschläge hat.. immer her damit.
Eine bebilderte Anleitung wie für MP4toGif.com werde ich in den nächsten Tagen zusammen basteln.
Jetzt läuft auch alles im Microsoft Edge. Das Problem war dass das "canplay" Event im Edge nicht bei einem Wechel der Zeit gefeuert wird wie beim Firefox oder Chrome. "timeupdate" löst aus bevor das Bild verfügbar ist und sorgt für ein ruckeliges GIF. Die Lösung war: seeked. Damit läuft MP4toGIF.com jetzt im Edge, Chrome und Firefox.
Früher war es nur möglich URL zu finden, die am Anfang einer Zeile standen und die Zeile für sich allein hatten. Das war für einfache Listen vollkommen ausreichend. Nun wurde es so erweitert, dass auch URLs innerhalb eines Textes gefunden werden könnten. Man kann nun also eine *.txt-Datei laden und die Web-App versucht alle enthaltenen Links zu finden und darzustellen.
Nachdem ich noch bei einem Abschiedsessen mit meinen alten Kollegen, doch noch mal auf der Thema der Entwicklungsgeschwindigkeit und Qualität an dem Abend gekommen bin, werde ich mir dieses Thema hier doch mal annehmen. Es ist ein kompliziertes Thema, dass keine richtige einzelne richtige Lösung kennt, aber dafür Raum für viele Fehler bereit hält. Ich stütze mich jetzt einfach mal auf 10 Jahre Erfahrung in der Softwareentwicklung und der Mitarbeit in Teams, die eben auch mit diesen Problemen zu kämpfen hatten und auch noch haben. Denn auch wenn man Lösungen kennt, muss man den Weg immer noch gehen.
Neben der verlorenen Zeit stellen diese Probleme auch für die Entwickler eine nicht zu unterschätzende Belastung da.
Frameworks vs eigenen Code
Einer der größten Fehler wurde gleich am Anfang gemacht. Es sollte schnell los gehen und da wurde auf Abstraktion und der Suche nach vorhandenen Lösungen verzichtet. Es wurde alles auf der untersten Ebene begonnen. Also keine Kapselung oder ähnliches. Entitäten-Objekte wurden direkt vom Service an den Client geschickt. Eine allgemeine Kommunikationsstruktur zwischen den beiden wurde nicht entwickelt.
Oberflächen und Logik wurden einfach zusammen in eine Klasse geschrieben. DTOs, DAOs und DataBindung waren aber schon da keine neuen Konzepte mehr. Das alles führte dazu, dass man sich mit EJB und SWT jeweils auf der untersten Ebene auseinander setzen muss, selbst um einfache Oberflächen und Service zu implementieren.
Es entwickelte sich zu der Vorgehensweise, dass man es lieber alles schnell selbst machten sollte, als externe Frameworks und Libs zu verwenden. Wenn man nur genug eigene Dinge implementieren würde, würde am Ende schon ein fertiges Frameworks dabei heraus kommen. Das Ein Framework in seiner Gesamtheit durchdacht sein muss und eine gewisse Konsistenz in der Benutzung und im Verhalten zeigt, war dabei egal. Die Idee, jeder Entwickler würde mal so nebenbei für sich ein oder zwei Komponenten entwickeln und wenn man nach einem Jahr alles zusammen wirft, würde ein fertiges GUI-Framework heraus kommen, war zu verlockend und so wurden auch alle komplizierteren Ansätze, die so etwas beachten wollten, als nicht notwendig erachtet.
Wenn man ein auch nicht mehr ganz so neues AngularJS nun betrachtet, dass einmal für die GUI-Elemente auf HTML5 setzen kann und für die Oberflächen eine sehr gute und flexible Template-Engine mitbringt, merkt man erst wie viel Zeit allein mit dem Kampf des SWT-Gridlayouts oder der selbst gebauten Input-Box für Zahlenwerte verbracht wurde.
Das Problem, dass zu viel grundlegende Technologie selbst entwickelt wird und dann alles zu sehr mehr der eigentlichen Anwendungslogik verzahnt wird, ist in so fern ein wirklich großes Problem, als dass hier sehr schnell sehr viel Code produziert wird und durch die fehlende Abstraktion Änderungen mit fortlaufender Zeit immer schwieriger werden. Am Anfang müsste man einige Klassen neu schreiben, aber ein Jahr später, kann man schon die halbe Anwendung weg werfen. Ob man das vielleicht auch tun sollte, werde ich später noch mal ansprechen.
Jedenfalls braucht man entweder jemanden aus dem Team der das Framework für das Team(!) entwickelt und auch die Zeit dafür bekommt oder aber man muss einige Woche am Anfang einplanen, um ein geeignetes Framework zu finden.
Hier lauter schon der nächste Fehler. Oft wird eine Person dazu abgestellt, sich über Frameworks zu informieren und eins oder zwei vorzuschlagen. Da aber viele Entwickler damit arbeiten sollen, sollten auch alle bei dem Findungsprozess mit wirken können. Jeder achtet auf andere Dinge und erkennt Vor- oder Nachteile wo andere nur eine weitere aber nicht so wichtige Komponente sehen. Und auch hier werde ich auf die Probleme,
die hierbei entstehen können, später noch mal eingehen. Es hängt alles zusammen und beeinflusst sich gegenseitig, so führen Probleme zu anderen Problemen.. vielleicht.
Vertrauen in die Technologie muss da sein
Gehen wir mal davon aus, dass wir nun jemanden haben, der das Framework entwickelt oder man eines gefunden hat, das auf dem Papier echt toll aussieht, aber viele Fehler hat und Lösungen dafür kaum zu finden sind.
Das kann an Fehler, einer schlechten Dokumentation oder einem eher ungewöhnlichen Benutzungskonzept liegen. Aber am Ende besteht das Problem, dass die Entwickler dem Framework nicht vertrauen. Das für dann oft auch zu Punkt 1 zurück, in dem dann lieber eine Funktionen und Methoden geschrieben und verwendet werden, weil man diesen mehr traut als dem Framework. Weiter werden dann mindestens 2 Entwickler das Selbe nochmals neu implementieren, aber natürlich dann so verschieden, dass man nicht eines davon wieder abschaffen könnte. Wenn diese mindestens Doppelung an gleicher Funktionalität auffällt, muss das Framework so angepasst werden, dass es mindestens seine und die beiden anderen Funktionsweisen abbilden kann und hoffentlich dabei nichts kaput geht. Dadurch haben wir dann wieder eine große Inkonsistenz Framework, weil es plötzlich Sachen machen soll, die einfach anders sind und anderer Herangehensweisen haben. Weil es inkonsistent geworden ist kommen die Entwickler nicht mehr wirklich damit klar und schreiben sich im besten Falle eine eigene Abstraktionsschicht für das Framework, oder versuchen es wieder zu umgehen, was dann am Ende mindestens die 4. Implementation für die selbe Funktionalität mit sich bringt.
Ich ziehe hier mal wieder AngularJS als positives Beispiel heran. Wenn man ein Problem hat, wird man eine Lösung im Internet finden. Irgendwer hatte das Problem schon und irgendwer hat den Fehler schon behoben, die richtige Vorgehensweise noch mal erklärt oder eine passende Direktive geschrieben. Es stellt sich nicht die Frage, ob etwas an sich möglich ist. Es ist möglich und man versucht es erst einmal und wenn es nicht funktioniert, guckt man eben wie die anderen es gelöst haben. Im Notfall gibt es immer noch das native JavaScript mit document.getElementById().
In Java versuchen Frameworks einen oft komplett in sich gefangen zu nehmen und alle anderen Wege als den eigenen unmöglich zu machen. Durch Interfaces die eingehalten werden müssen, klappt es ganz gut. Das verhindert, dass andere Lösungen entwickelt werden, die das Framework um gehen. Aber es schränkt oft auch mehr ein als es hilft. Das Framework soll dem Entwickler helfen und nicht über ihn bestimmen. Als Entwickler mag man es nicht, nur die Konzepte und Denkweisen eines anderen unterworfen zu sein, der, wie man schnell merkt, das ganze nicht mit dem Anwendungsfall im Hinterkopf entwickelt hat, den man selber gerade umsetzen möchte.
Deswegen muss ein Framework alles bieten und so flexibel sein, dass auch Abweichungen vom Konzept möglich sind und sich direkt ins Framework integrieren lassen, dass es zu einem Teil des Frameworks wird. So wird verhindert, das Entwickler das Framework umgehen oder eigene Lösungen einbauen, die zwar den Anwendungsfall entsprechen aber sich komplett als Fremdkörper im Framework präsentiert. Das wichtigste ist aber eine gute Doku und eine zentrale Stelle wo man Probleme zusammen beheben kann. Für ein eigenes Framework ist daher ein Forum im Intranet vielleicht gar nicht so verkehrt. Man kann suchen, nachlesen und diskutieren. Auch weiß der Entwickler des Frameworks, wo er die Dokumentation verbessern oder nochmal überarbeiten sollte. Auch werden Ansätze etwas neu zu schreiben oder zu umgehen schneller erkannt und es kann mit Aufklärung oder Fehlerbehebung und neuen Features darauf reagiert werden.
Ich habe auch schon erlebt, dass ich von einer Lösung erfahren habe, wie man etwas im Framework bewerkstelligen kann und ein Ergebnis erhält wie man es möchte und das auch schon von einige Entwicklern so eingesetzt wurde und die auch ganz Stolz auf diese Lösung waren. Das Problem war nur, dass das Framework an der Stelle eigentlich genau das liefern sollte, was die über Umwegen dann auch bekommen haben und eine einfache kleine
Meldung bewirkt hätte, dass aufgefallen wäre, dass es ein einfacher Bug im Code war, der dann auch in 5min behoben war. Aber dadurch dass eine alternative Lösung jetzt ein falsches Ergebnis erwartete, war es viel Arbeit alles mit der Fehlerfreien Komponente des Frameworks wieder zum laufen zu bekommen.
Da fehlte dann auch das vertrauen ins Framework. Denn wenn man Vertrauen hat und etwas nicht wie erwartet funktioniert, geht man von einem Bug aus und nicht von einem normalen Verhalten, dem man selbst entgegen wirken muss.
Entscheidungen überdenken und schnell reagieren
Manchmal klingt etwas sehr gut und die Beispiele liefen gut und die Tutorials im Internet ging schnell von der Hand. Entität anlegen, laden, ändern, löschen und eine Liste der vorhandenen Entitäten laden. Alles super.
Aber dann kommt die Komplexität der echten Welt, wo man nicht nur Listen lädt und etwas hinzufügt oder ein Element hinzufügt. Hier beginnen Probleme und manchmal zeigt sich erst hier, ob dass alles wirklich so gut war wie gedacht. Bei JavaFX kann ich einfache DTOs in Tabellen verwenden. Wenn sich aber ein Wert in einem der DTOs ändert wird es nur erkannt, wenn es ein Property ist. Das ist dann plötzlich ein Sprung von "geht ja ganz einfach" zu "jetzt muss alles in Properties umkopiert werden und die normalen Getter und Setter reichen nicht mehr und also doch wieder eine Wrapper-Klasse bauen."
Oder wir treffen auf das Problem aus Punkt 1. Entweder probieren wir es erst einmal weiter und bauen erst einmal eine Version und damit und gucken dann mal oder aber wir haben uns doch am Anfang darauf festgelegt und die Entwickler haben gerade gelernt damit umzugehen.. oder aber ganz radikal: Zusammen setzen, noch mal Alternativen suchen und wenn es was gibt schnellst möglich wechseln. Erstmal mit einer nicht passenden Technologie oder so einem Framework weiter zu arbeiten ist das schlimmste was man machen kann. Denn es müssen Teile neu geschrieben und angepasst werden und dass sollte man machen, wenn noch nicht zu viel davon entstanden ist. Wenn man ein Jahr wartet, wird es zu viel und die Ansicht wird sich durch setzen, dass fertig machen nun doch schneller geht als "neu" machen. Es wird aber mit den Jahren immer langsamer und langsamer entwickelt und es zeigt sich, dass die Annahme falsch war und man doch schon viel weiter wäre, wenn man gewechselt hätte.
Nie mit etwas entwickeln was Probleme macht ohne das die Möglichkeit gegeben ist, das entwickelte später in einem besseren Technologie-Kontext weiter verwenden zu können. Hier Zahlt sich Abstraktion wie MVC/MVVM oder auch einfaches Databinding dann schnell aus, wenn man mit einfachen DTOs und POJOs gearbeitet hat.
Hier ist aber oft die Angst vor dem Mehraufwand und auch vor neuen Technologien das Problem, was die Entwickler daran hindert, schnell und angemessen zu reagieren. Denn die Entwickler kennen fehle Technologien und Frameworks und können bestimmt eine oder zwei Alternativen nennen. Man sollte immer dafür offen sein, dass es etwas besseres gibt und vielleicht ein Umstieg die Zukunft einfacher macht. Auch ohne zu große Probleme sollte so ein Vorschlag immer mal wieder überdacht werden. Es kann auch helfen sich andere Lösungen anzusehen und davon zu lernen in dem man Konzepte übernimmt (wenn diese dann in die alte Struktur passen!)
Ich habe bei meinen Frameworks, die ich so geschrieben habe gelernt, dass man manchmal einfach alte Dinge weg werfen muss, Kompatibilität gut ist aber nicht bis in die Steinzeit reichen muss und man teilweise ein neues Framework anfängt, dass alles besser machen soll und am Ende portiert man es in das alte Framework zurück und wundert sich wie flexibel man das erste doch entwickelt hat, dass man die Konzepte am Ende auch dort in wenigen Stunden komplett implementieren konnte.
Mutig sein und Entwickler dafür abstellen sich auf dem Laufenden zu halten und die Aufgabe zu geben Vorhandenes zu hinterfragen und zu kritisieren.
Die eine zukunftssichere Technologie
Damit kommen wir direkt zum nächsten Problemkomplex. Es wird analysiert und diskutiert und sich für eine Technologie entschieden. Das geht auch erst einmal ganz gut und so lange niemand danach über den Tellerrand schaut bleibt auch alles gut.
Um eine Technologie für ein Projekt, das auch mal mehrere Jahre laufen wird, muss sie stabil sein, gut zu benutzen, es darf sich nichts groß an ihr ändern, damit man nicht dauernd alte Module anpassen muss und sie sollte gut unterstützt werden (also schon viel im Internet darüber zu finden sein). Das alles ist am Anfang gegeben. Aber es soll ja auch so bleiben. Eine Technologie bei der sich in 3 Jahren nichts mehr groß ändern wird ist an sich tot. Was vor paar Jahren noch sehr toll war z.B. SOAP-Webservice über Annotationen zu erzeugen wird heute keiner mehr wirklich benutzen wollen. SOAP war mal komfortabel, wirkt heute aber einfach umständlich im Vergleich zu REST-Services.
Es gibt keine Technologie, die über Jahre hinweg die beste und einfachste Lösung bleibt. Man kann sich aber auch modernen Entwicklungen nicht komplett entziehen. Das Grundsystem wie der Application-Server und das GUI-Framework sollten immer bei neuen Versionen mit geupdatet werden. Es bedeutet nicht, dass die produktiven Server jedes mal ein Update erhalten müssen, aber die Anwendung sollte immer auch auf der aktuellsten Version laufen können. Das kostet den Entwickler natürlich immer etwas Zeit, aber sollt wirklich mal ein Wechsel der Produktivumgebung anstehen, wird dies wenigstens kein Problem mehr sein und es entsteht kein Zeitdruck alles
doch noch schnell auf die neue Version anzupassen. Wir wissen ja das solche Ankündigen nie rechtzeitig vor her kommuniziert werden.
Es muss nicht immer eine neue Technologie sein, aber wenn man bei der Entwicklung der benutzen Technologie nicht mit macht wird man schnell Probleme bekommen und von allen Vorteilen der neuen Versionen nicht profitieren können. Das deprimiert die Entwickler und gibt denen das Gefühl, als würde man ihnen bewusst Steine in den Weg legen. Man siehe nur den Wechsel von EJB2 auf EJB3.
Jeder Entwickler ist anders
Wir brauchen ein Konzept, damit nicht alles wild durch einander geht und jeder so programmiert wie er gerne möchte und kein Modul aussieht wie das anderen. Also soll jemand festlegen, wie der Code-Style, die Packages und die Oberflächen auszusehen haben. Das geht natürlich ganz schnell, es wird programmiert wie man es selber machen, weil man ist überzeugt von seinem vorgehen und man selbst kommt damit ja super zurecht. Oberflächen guckt man sich seine Anwendungsfälle an... andere werden ja wohl keine Anwendungsfälle haben, die sich von der Struktur her groß unterscheiden. Aber leider dreht sich die Welt nicht um einen. Jeder kommt mit seinen Sachen gut zurecht, sonst hätte man es ja schon längst geändert. Also muss man davon ausgehen, dass auch der der die Dinge entwickelt hat, mit denen wir nicht zurecht kommen, damit super zurecht kommt. Also sich im Team zusammensetzen und am Besten mit offenen Standards anfangen. Ein Tab ist fast immer 4 Zeichen lang. Warum sollte man 3 nehmen? Eine persönliche Vorliebe, weil man ein besseres Lesegefühl dabei hat? So etwas hat sich nicht umsonst durchgesetzt und es haben sich Menschen Gedanken gemacht. Wichtig ist zu realisieren, dass vor einem schon andere Leute über solche Dinge nachgedacht haben und diese Leute auch nicht dumm waren oder sind. Wer glaubt er hätte die einzige wahre Lösung gefunden und jegliche kleine Abweichung wäre falsch, der sollte alles wegwerfen und noch mal von vorne beginnen.
Das Framework sollte verschiedene Ansätze von sich auf unterstützen. JavaFX mit Objekten, FXML, HTML im Web-View und auch sonst noch die alte SWT-Variante. Klingt nach viel, aber es gibt für jeden dieser Ansätze einen Anwendungsfall wo er besser als der Rest ist. Das Framework sollte den Entwickler unbemerkt dazu bringen, dass egal wie er an die Aufgabe heran geht, der Code am Ende den der anderen Entwickler ähnelt. Gleich wird der Code nie sein. Es ist schwer so ein flexibles Framework zu entwickeln, wo sich jeder ransetzen kann und ohne viel Lernen und Anpassungen damit anfangen kann zu entwickeln. Databindung oder direkt Zugriff auf das Element.
POJOs oder komplexe Beans. Wiederverwendbare Komponenten oder eine Komponente aus einzelnen kleinen Komponenten direkt beim Aufbau der GUI konstruieren. Alles ist manchmal nötig und manchmal ist das Gegenteil der bessere Weg. Aber nie ist eines davon an sich falsch. Jeder Entwickler ist anders und geht anders an Probleme heran und in einem Projekt sollte es nie so sein, dass sich die Entwickler darin an einen anderen anpassen müssen, weil sie dann nicht mehr die Leistung bringen, die sie könnten.
Unit-Tests
Unit-Tests sind meiner Erfahrung oft eher Belastung als eine Hilfe. Ein wirklich guter Test braucht Zeit und meistens sind diese Test nichts weiter als Entität speichern, laden, freuen, dass der selbe Wert drin steht, wie beim Speichern. Bei Berechnungen sind die Tests super, weil man schnell prüfen kann, ob eine Berechnung noch korrekt ausgeführt wird. Aber für komplexe Workflows und Anwendungsfälle sind diese Tests meistens sinnlos. Ein paar gute Tester bringen mehr als Unit-Tests. Lieber keine oder wenige Unit-Tests und dafür genug Tester haben. Ein Tester ist ein Mensch und für Schnittstellen, die von Menschen verwendet werden, sind Menschen die besseren Tester,
weil sie an Dinge unterschiedlich heran gehen. 2 Tester können eine Workflow-Schritt durch testen und 2 unterschiedliche Fehler finden, während der Entwickler ohne Fehler getestet hat.
Bloß weil etwas toll ud hip ist, ist es für das eigene Projekt nicht auch immer die beste Lösung. Man muss gucken, ob es einen etwas bring und sich klar sein, dass es nicht die eine richtige Lösung für alles gibt. Unit-Tests für Services sind toll und für GUIs meistens vollkommen unbrauchbar.
Dokumentation ist genau so ein Thema. Ein freier Text kann viel mehr erklären wie ein JavaDoc, wären JavaDoc toll ist während des Programmieren kleine Infos zur Methode zu erhalten. Aber brauch ich eine Info was die Methode load($id) macht?
Team-Leader und Lead-Developer als Unterstützung und nicht als Diktatoren
Ich hatte ja schon mehr Mals im Text erwähnt, dass man viele Dinge im Team klären muss und nicht eine Person, wichtige Dinge für alle entscheiden lassen sollte. Es ist die Aufgabe eine Lead-Developers das Team zu fördern und die Leistung zu steigern und dem Team die Probleme vom Hals zu halten. Es ist nicht die Aufgabe des Teams alles zu tun um dem Team-Leader zu gefallen. Lead-Developer und Team-Leader sind undankbare Jobs und man muss sie machen wollen. Wenn man das nicht will und nur etwas mehr zusagen haben möchte, ist man dort falsch. Auch wenn man nur immer zu allen "Ja" sagt, was von oben kommt und dann die Probleme direkt nach unten zum
Team leitet.
Wenn das Team das Gefühl hat sich in bestimmten Situationen nicht auf den Team-Leader verlassen zu können, hat man ein Problem. Es muss deutlich sein, dass er Verantwortung übernimmt und hinter oder besser noch vor seinem Team steht.
Das selbe gilt für den Lead-Developer und seine Entscheidungen. Er muss Erfahrung haben und seine Entscheidungen erklären können und auch die Verantwortung dafür übernehmen, wenn er eine falsche Entscheidung getroffen hat und den Mut haben diese zu Korrigieren. Wenn also ein falsches Framework ausgewählt wurde mit dem kein Entwickler zurecht kommt, ist es sein Fehler und nicht der Fehler der Entwickler. Dann muss er handeln und
den Fehler beheben.
Fazit Das waren jetzt meine groben Gedanken zu dem Thema und meinen Erfahrungen. Es ist aber klar, dass zur Behebung eines Problems erst einmal das Gespräch gesucht werden muss, denn die Entwickler wissen schon meistens sehr genau was schief läuft. Eine Lösung für das Problem müssen die aber deshalb nicht präsentieren können. Wenn nicht ganz klar sein, sollte wo das Problem liegt und man wirklich mit dem Projekt in Bedrängnis kommt, sollte man sich jemanden holen der Erfahrung hat und solche Situationen kennt und am besten mal durchlebt hat. Auch hier wieder die Feststellung, dass vieles immer sehr ähnlich ist und man von den Problemen und Fehler der anderen oft sehr viel lernen und dann verwenden kann.
Solche Leute sind nicht günstig, aber wenn man mal dagegen rechnet wie viel Zeit eingesperrt werden kann, sind die oft ihr Geld wert.
Probleme innerhalb des Teams könnte auch da sein. Aber das ist ein sehr sensibles Thema und dort gibt es noch weniger als bei den deren Problemfeldern keine einfache Lösung.
Lange Jahre war aoop mein CMS und PHP-Framework für die meisten Projekte, die etwas mehr brauchten als nur JavaScript. Es begann als CMS für meine Homepages. Deswegen unterstützte es die Verwaltung von Pages, konnte mit einer Installation mehrere Domains bedienen und verhielt sich dabei jeweils wie eine komplett eigene Installation. Benutzer-Verwaltung und Logins waren mit im Kern implementiert. Es konnten Module erstellt und für jede Instanz einzelnd deployed werden (jede Instanz konnte sogar eine eigene Version haben, da man später auch pro Instanz eine eigene Datenbank verwenden konnte). Es wurde zu einem doch sehr großem System Vergleich mit einem einfachen kleinen App-Server. Ein Server und eine Installation für alles. Module und Pages wurden immer wieder direkt eingelesen und Menüs automatisch erstellt. Also Modul rein kopieren und damit stand es gleich zur Verfügung.
In letzter Zeit ging ich aber auch dazu über für jeden Bedarf eine eigene Installation mit eigener Datenbank anzulegen, da man bei Problemen so nur eine Installation anfassen musste und bei Updates nur eine Seite für paar Minuten anfassen musste. Die letzten Projekte waren auch Web-Apps die das Framework nutzen aber die Verwaltungsfunktionen des CMS-Teils nicht benötigten. Das Framework ist gut und ich komme damit super zurecht, aber für Web-Apps war dies alles nur Ballast. Web-Apps bestehen auch bei mir momentan aus AngularJS und einem REST-Service. Der REST-Service-Teil von aoop ist relativ neu und nutzt nur wenige andere Klassen des Kern-Systems. Dann kam ich noch mit dem Zend Frameworks in Berührung, die viel hatten, was mir in aoop noch fehlte (Seiten-Aufrufe über URL-Parsing und so.. was aber für die REST-Services schon existierte).
Ich überlegte also mal den REST-Teil heraus zu lösen, um einfacher meine Apps bauen zu können. Ein Problem bei den Apps waren aber die Auslegung auch von AngularJS auf OnePage-Apps. Beruflich hatte ich mit Clients von einem ERP-System zu tun, die nicht ein paar Views und Dialoge hatten sondern pro Modul gerne mal 50 oder mehr und im Client waren auch gerne mal 20 Module installiert. So eine Anzahl an Views und Controllern ist für eine einfache AngularJS-Anwendung zu viel. Also kam ich auf die Idee jeden View/Dialog und seinen Controller als einzelne Komponente zu betrachten und weiterhin Seiten per Request aufzurufen, aber in diesen die Oberfläche aus fertigen Komponenten zusammen zu stellen. Das Laden der Daten und auch Speichern und so sollte die Komponenten dann nur über REST erledigen. Im Grund ein System für 2 Schichten einer 3 Schichten Architektur. REST und Client-View Erzeugung in einem System zusammen gefasst.
Also habe ich mir meine Ideen mal aufgeschrieben und dann angefangen es umzusetzen. Einiges wurde direkt aus aoop übernommen (was auch weiter existieren wird für normale Homepages und so etwas, wo man eben ein CMS braucht). Class-Loader ist eine 1:1 Kopie wo nur ein paar Pfade angepasst wurden.
Damit fing die Entwicklung dann auch an. Class-Loader, neue Modul-Klasse und Klasse zum einlesen aller installierten Module. Dann wurde der REST-Service-Teil kopiert wobei nur ein Klasse ersetzt werden musste, weil eben die Modul-Liste geändert hatte. Damit liefen die REST-Services auf jeden Fall schon mal wieder. PDBC für Datenbankzugriffe musste auch nur
Kopiert werden.
Dann folgte der Teil wo aus Komponenten eine Seite zusammen gebaut werden sollte. Diesmal sollte erst die Page geladen und erzeugt werden bevor angefangen wird das Template zu füllen, was den Vorteil hat, dass jede Seite ihren <title> selbst bestimmen kann und man damit sehr viel flexibler ist. Bei einer Blog-Anwendung können also auch Tags mit in den Title geschrieben werden, obwohl das Template auch für Übersichten und so verwendet werden kann. Also am Ende werden Platzhalter ersetzt.. um es mal genauer zu erklären.
Das URL-Schema ist eigentlich das des REST-Teils geworden:
Also Basis-URL, dann folgt der Type an dem entschieden wird ob eine Page oder ein Service gemeint ist, dann der Modulname und nun folgt etwas beliebiges, das durch das Routing oder Mapping der entsprechenden Teile des Frameworks interpretiert wird und am Ende auf einen Service oder eine Page zeigt.
Meine Planung für den Blog ist momentan, dass ich parallel zur Entwicklung ein paar Beiträge schreibe:
* Class-Loader
* REST-Service
* Pages und Komponten
* ein kleines Beispiel
* Zugriff auf Datenbank und automatisches Mapping von Resultsets auf Objekte
Es ist ein kleines Framework an dem man eigentlich leicht verstehen sollte wie man so etwas bauen kann und wie man bestimmte Dinge darin umsetzen kann (nicht muss.. aber meiner Erfahrung nach funktionieren die Dinge sehr gut :-) )
Eine der Sachen die ich mir schon immer mal ansehen wollte und nie dazu gekommen bin. Aber jetzt bin ich wirklich mal dazu gekommen und es hat sich mal wieder heraus gestellt, dass sich das sehr einfach implementieren auf JavaScript-Seite. Die Server-Seite ist da dann doch etwas komplexer aber sieht sehr viel einfacher aus als WebSocket-Server, da man alles über eine einfache Seite publishen kann und nicht Server intern eine Liste mit den Connections zu den Clients selbst pflegen musst.
Nun werde ich mal gucken, ob ich doch mal etwas damit machen werden. Benachrichtigungen über neue Posts oder doch ein Backend für einfache kleine Multiplayer-Spiele. Z.B. eine Multiplayer-Version von Bottle-Spin oder sowas, sollte sich damit relativ einfach umsetzen lassen, da man im Spiel nur noch auf Events reagieren muss und ab und zu mal über REST eine Methode aufruft. Eine bidirektionale Verbindung bei Websocket braucht auch erstmal wieder ein eigenes Protokoll. Bei SSEs hat man den Event-Type und den Payload (einfach String oder JSON) und die Infrastruktur mit den Events umzugehen ist auch schon fertig.
Mal gucken, ob ich die Zeit finde das mal irgendwie einzu bauen. Erstmal stehen andere Projekte auf dem Plan, die mal fertig werden müssen.
Blog-entries by search-pattern/Tags:
Möchtest Du AdSense-Werbung erlauben und mir damit helfen die laufenden Kosten des Blogs tragen zu können?