TBD25 Andreas, was macht Teams erfolgreich?

Sind agile Teams wie Fußballmannschaften? Beide sind selbstorganisiert, lösen komplexe Probleme und sollen sich dabei auch noch verbessern. Kann man also die Erfolgsstrategien vom Fußball einfach auf Teams übertragen? In dieser Folge beleuchten wir die Strategien, die die Teams erfolgreich machen!


Andreas Kolmer ist auf den meisten Plattformen als @andreaskolmer erreichbar, zum Beispiel auf LinkedIn: https://www.linkedin.com/in/andreas-kolmer/. Alternativ könnt ihr Feedback an tbd „at“ kolmer.one senden.

Das folgende Buch behandelt die besprochenen Strategien ausführlich:

  • Tobias Escher, Was Teams erfolgreich macht: Die Formel hinter dem Triumph von Bayern München, Liverpool und Co., ISBN 978-3499008535.

TBD24 Markus, wie können Organisationen auf gesunde Art transformiert werden?

Eine agile Transformation kann sowohl für die Mitarbeiter als auch für die gesamte Organisation sehr belastend sein. Der Erfolg hängt in hohem Maße von verträglichen, sprich gesunden, Transformationsschritten ab. Aber wie können wir herausfinden, ob ein Transformationsschritt gesund ist oder die Organisation überfordert? In dieser Folge erklärt Markus Tecza, wie das Konzept der Salutogenese dabei helfen kann, gesunde Transformationsschritte zu finden.


Markus Tecza erreicht ihr entweder persönlich über LinkedIn: https://www.linkedin.com/in/markus-tecza/
Alternativ könnt ihr ihn über das Kontaktformular der Valtech GmbH erreichen: https://www.valtech.com/de-de/about/kontakt/.

Außerdem sprechen wir folgende Themen an:


TBD23 Botond, wie können Teams besser Software erstellen und ausliefern?

Zu viele Teams kämpfen noch mit Firefighting, Bugs, und trägen Prozessen, um ihre Software auszuliefern. Um den Mehrwert des Produkts signifikant zu steigern und auch die Zufriedenheit bei den Mitarbeiter:innen zu erhöhen, lohnt sich die Investition in gute Entwicklungspraktiken wie Continuous Integration und Continuous Delivery. Was dazu benötigt wird und was dieses Thema mit Zähneputzen zu tun hat, erklärt Botond Gal in dieser Folge.


Botond Gal erreicht ihr entweder über LinkedIn: https://www.linkedin.com/in/botond-gal/
Alternativ ist er per E-Mail erreichbar: botond.gal „at“ valtech.com

Außerdem werden einige Lese-Empfehlungen erwähnt:

  • Jez Humble, David Farley, Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation, ISBN 978-0321601919.
  • David Farley, Modern Software Engineering: Doing What Works to Build Better Software Faster, ISBN 978-0137314911.
  • Nicole Forsgren, Jez Humble, Gene Kim, Das Mindset von DevOps. Accelerate: 24 Schlüsselkompetenzen, um leistungsstarke Technologieunternehmen zu entwickeln und zu skalieren, ISBN 978-3800659630.
  • Gene Kim, Jez Humble, Patrick Debois, John Willis, Nicole Forsgren, Das DevOps-Handbuch: Teams, Tools und Infrastrukturen erfolgreich umgestalten, ISBN 978-3960091998.

TBD22 Deike, braucht die digitale Transformation die Menschen überhaupt?

Die digitale Transformation beschleunigt die Produkt-Weiterentwicklung. Dabei darf der Nutzer aber nicht abgehängt werden, sondern muss mitgenommen werden. In dieser Folge erläutert Deike Moggert, wie der Nutzer mit Hilfe von gutem Content Design und Content Strategy an die Hand genommen werden kann.


Deike Moggert könnt ihr entweder auf LinkedIn erreichen: https://www.linkedin.com/in/moggertdeike/
Oder auf Xing: https://www.xing.com/profile/Deike_Moggert/


TBD21 Christian, was zeichnet ein gutes Coding Dojo aus?

Musiker:innen proben, Sportler:innen trainieren, aber Softwareentwickler:innen können alles, ohne zu üben? Für Christian Schmoll ist das unlogisch. Daher bietet er Coding Dojos an, die ein Übungsraum (nicht nur) für Softwareentwickler:innen sind. Wie diese funktionieren, und wer davon profitieren kann, erzählt er in dieser Folge.


Christian Schmoll erreicht ihr am besten per E-Mail: christian.schmoll „at“ valtech.com. Er bietet außerdem Coding Dojos in Düsseldorf an, die nächsten Termin sind am 1. Februar 2023 und 1. März 2023.

Die folgenden Themen sprechen wir an:

  • Katas für Coding Dojos: https://codingdojo.org/kata/
  • Tobias Escher, Der Schlüssel zum Spiel: Wie moderner Fußball funktioniert, ISBN 978-3499001987.

TBD20 Gero, wie komme ich zu einer Roadmap für mein Produkt?

Digitale Produkte müssen ständig weiterentwickelt werden. Aber wie kann man entscheiden, welche der vielen Ideen die beste ist? Womit fängt man an? Und was mache ich, wenn ich mit dem Produkt irgendwo steckengeblieben bin? In dieser Folge erklärt Gero Grebe, wie man in solchen Situationen zu einer Produkt-Roadmap kommt, und wie digitale Produktstrategie wirklich funktioniert.


Gero Grebe könnt ihr entweder auf LinkedIn erreichen: https://www.linkedin.com/in/gero-grebe/
Oder ihr schreibt eine E-Mail an info „at“ valtech.com.


openHAB XIV: System-Update für Idioten

Geschätzte Lesezeit: 3 Minuten.

Mit dem Wort „Idioten“ im Titel meine ich explizit mich. Denn ich könnte diesen Artikel sehr kurz schreiben, wenn ich einfach nur zu mir selbst sagen würde: Mach es halt ordentlich, dann funktioniert es auch.

Okay, etwas länger soll es dann doch sein.

Die folgenden Schritte werden alle per SSH in der Konsole durchgeführt. Zuerst mache ich ein Backup, mit diesem Befehl:

sudo $OPENHAB_RUNTIME/bin/backup

Dann aktualiere ich die Update-Verzeichnisse, das ist ganz wichtig. Warum, erkläre ich später. Und ja, wir brauchen beide Zeilen bzw. beide Befehle.

sudo apt-get update
sudo apt update

Dann öffne ich das openHAB-Konfigurations-Tool:

sudo openhabian-config

Hier wähle ich Punkt 2, Upgrade System. Und dann rödelt das System hoffentlich ohne Fehler, und alles klappt. Hoffentlich.

Und nun komme ich zu dem (langen) Weg, der mich zu diesen kurzen Schritten gebracht hat.

Tag 1: Lass uns doch mal updaten

Man sollte alle Software immer aktuell halten. Das gilt ganz generell, und das gilt natürlich auch für openHAB. Also möchte ich mein System von der Version 3.0.1 auf die neueste Version aktualisieren (3.3.0).

Glücklicherweise habe ich ja mal einen Guide zum Update auf openHAB 3.0 geschrieben, daran kann ich mich gut orientieren. Ich öffne ich das openHAB-Konfigurations-Tool:

sudo openhabian-config

Hier wähle ich Punkt 2, Upgrade System. Aber leider bricht es immer wieder ab. Es wird gesagt, wenn du diesen Fehler siehst, geh doch mal auf diese Seite: https://github.com/openhab/openhabian/blob/main/docs/openhabian-DEBUG.md. Okay, Debugging anschalten, das mache ich dann mal. Ich navigiere mich zu /etc/:

sudo nano openhabian.conf

Ja, natürlich habe ich das sudo zuerst vergessen und mich gewundert, warum ich nicht speichern kann. Ich sagte ja, „Idiot“. Jedenfalls ändere ich debugmode=off zu debugmode=maximum (und später schalte ich es natürlich wieder aus).

Und dann klicke ich etwas rum. Ich aktualisiere eigentlich alles, was so geht. Ich reboote. Ich wähle verschiedene Branches. Ich mache alles Mögliche, aber es funktioniert nicht.

Da muss ich mir wohl doch mal das Debugging ansehen. Seltsam, da gibt es diese Zeile:

E: Failed to fetch http://raspbian.raspberrypi.org/raspbian/pool/main/b/base-files/base-files_10.3+rpi1+deb10u10_armhf.deb 404 Not Found [IP: 93.93.128.193 80]

Okay, copy-paste nach Google, und ich lande hier: https://forum-raspberrypi.de/forum/thread/47483-apt-get-probleme/. Anscheinend ist das Problem, dass der Updater nach Updates auf Servern sucht, die es nicht mehr gibt. So ein Mist, wie sage ich dem Ding denn, dass es an der richtigen Stelle suchen soll – und was ist die richtige Stelle?

Das steht zum Glück auch dort.

sudo apt-get update

Und nochmal von vorne, und leider scheitert das openHAB-Update erneut. Also lese ich den Thread weiter und finde:

sudo apt update

Mache ich auch, und versuche nochmals ein Update. Und jetzt funktioniert es!

openHAB XIII: Weihnachtsbeleuchtung mit Twinkly

Geschätzte Lesezeit: 9 Minuten.

In der Adventszeit wurde es Zeit für ein neues Projekt. Ich möchte gerne Lichterketten in mein Smart Home integrieren. Grundsätzlich sind mir dafür zwei Strategien eingefallen:

  • Lichterketten an schaltbare Steckdosen anschließen, dann kann ich sie an- und ausschalten
  • Smarte Lichterketten nutzen, die vielleicht noch mehr können als „nur“ an oder aus

Ich habe mich für die zweite Variante entschieden und zwei Lichterketten von Twinkly, genauer gesagt Twinkly Strings 400 RBG,1einmal für 98,99€ bei click-licht.de, und einmal für 129,90€ bei lampenwelt.de organisiert.

Tag 1: Die Einbindung

Grundsätzlich ist die Installation der Twinkly-Lichterketten simpel. Es sollte aber erwähnt werden, dass eine App und ein Account benötigt werden. Möglicherweise ist diese Lösung daher nicht datensparsam – damit habe ich mich noch nicht auseinander gesetzt. Jedenfalls kann man die Lichterketten über eine spezielle App ein- und ausschalten, Farben ändern, Animationen wählen, das ist schon ziemlich cool. Es gibt auch eine Zeitschalt-Funktion, allerdings kann man damit die Lichterkette nur einmal pro Tag an- und einmal ausschalten. Und es ist auch eine feste Uhrzeit, zum Beispiel geht die Lichterkette jeden tag um 16:30 Uhr an.

Ich möchte aber mehr.

Ich möchte, dass die Lichterkette morgens an- und ausgeht, und abends ebenfalls an und aus. Und außerdem soll der Beginn und das Ende helligkeitsabhängig sein. Also werde ich die Twinkly-Lichterkette in openHAB einbinden. Leider gibt es kein Binding dafür, aber trotzdem ein gutes Tutorial. Hinter diesem Link versteckt sich ein Python-Skript, das ich jetzt erst einmal hier dokumentieren möchte.

import sys
import json
import urllib.request
import codecs

ARG_ON = 'on'
ARG_OFF = 'off'
ARG_STATE = 'state'
ARG_BRIGHT = 'brightness'

ARG_IP = sys.argv[1]
ARG_ACTION = sys.argv[2]


URL = "http://" + ARG_IP + "/xled/v1/"

LOGIN_URL = URL + "login"
VERIFY_URL = URL + "verify"
MODE_URL = URL + "led/mode"
BRIGHT_URL = URL + "led/out/brightness"

AUTH_HEADER = 'X-Auth-Token'

AUTHENTICATION_TOKEN = 'authentication_token'
CHALLENGE_RESPONSE = 'challenge-response'
MODE = 'mode'
MODE_ON = 'movie'
MODE_OFF = 'off'


HEADERS = {'Content-Type': 'application/json'}
LOGIN_DATA = {'challenge': 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8='}
TURN_ON_DATA = {MODE: MODE_ON}
TURN_OFF_DATA = {MODE: MODE_OFF}

if len(sys.argv) > 3: #check if the thirth argument is given, save it in a variable and create the brightness data variable
    ARG_ACTION2 = int(sys.argv[3])
    BRIGHTNESS_DATA = {'value': ARG_ACTION2, 'type': 'A'}


def formatData(data):
  return json.dumps(data).encode('utf8')

def processRequest(request):
  return urllib.request.urlopen(request)

def processRequestJSON(request):
  loginResponse = processRequest(request)
  reader = codecs.getreader("utf-8")
  return json.load(reader(loginResponse))

# login to api - get challenge response and auth token
loginRequest = urllib.request.Request(url = LOGIN_URL, headers = HEADERS, data = formatData(LOGIN_DATA))
loginData = processRequestJSON(loginRequest)

challengeResponse = loginData[CHALLENGE_RESPONSE]
authToken = loginData[AUTHENTICATION_TOKEN]

HEADERS[AUTH_HEADER] = authToken
verifyData = {CHALLENGE_RESPONSE: challengeResponse}

# verify token by responding with challenge response
verifyRequest = urllib.request.Request(url = VERIFY_URL, headers = HEADERS, data = formatData(verifyData))
verifyData = processRequestJSON(verifyRequest)

def turnOn():
  onRequest = urllib.request.Request(url = MODE_URL, headers = HEADERS, data = formatData(TURN_ON_DATA))
  processRequest(onRequest)
  print(1)

def turnOff():
  offRequest = urllib.request.Request(url = MODE_URL, headers = HEADERS, data = formatData(TURN_OFF_DATA))
  processRequest(offRequest)
  print(0)
  
def setBrightness():
  brightRequest = urllib.request.Request(url = BRIGHT_URL, headers = HEADERS, data = formatData(BRIGHTNESS_DATA))
  processRequest(brightRequest)

def getState():
  modeRequest = urllib.request.Request(url = MODE_URL, headers = HEADERS)
  modeData = processRequestJSON(modeRequest)

  if modeData[MODE] != MODE_OFF:
    print(1)
  else:
    print(0)
    
if ARG_ACTION == ARG_ON:
  turnOn()
elif ARG_ACTION == ARG_OFF:
  turnOff()
elif ARG_ACTION == ARG_STATE:
  getState()
elif ARG_ACTION == ARG_BRIGHT:
  setBrightness()

Ganz ehrlich, ich kann kein Python, ich weiß nicht genau, was dieses Skript macht. Ich kann nur sagen, dass es funktioniert. Wie? Dazu kommen wir jetzt.

Als erstes habe ich dieses Skript als twinkly.py im Ordner /var/lib/openhab/ abgespeichert. Dann habe ich mir über das openHAB-Benutzerinterface ein neues Item Lichterketten vom Typ Switch angelegt.

Und dann habe ich mir folgende lichterkette.rules gebastelt:

rule "Twinkly Christmas Tree Power State"
when 
  Item Lichterketten received command
then
  if (receivedCommand == ON) {
    executeCommandLine("python3","twinkly.py","x.x.x.37","on")
    executeCommandLine("python3","twinkly.py","x.x.x.43","on")
  }
  else {
    executeCommandLine("python3","twinkly.py","x.x.x.37","off")
    executeCommandLine("python3","twinkly.py","x.x.x.43","off")
  }
end

Hier sind zwei Dinge zu beachten. Erstens benötigt man die IP von jeder Lichterkette. Ich habe in meinem Fritzbox-Router feste IP-Adressen für die Lichterketten hinterlegt, damit dieser hart gecodede Befehl funktioniert. Zweitens ist bei dieser Rule die Syntax extrem wichtig. Ursprünglich habe ich die folgende, nicht funktionierende Zeile benutzt:

executeCommandLine("python3 twinkly.py 192.168.0.209 on")

Aber damit erhält man eine Fehlermeldung: File or directory not found when running executeCommandLine. Man muss wirklich darauf achten, dass die einzelnen Befehls-Elemente mit "," voneinander getrennt sind. Das ist ganz wichtig!

So, abschließend habe ich noch den Switch auf meiner openHAB-Startseite eingebunden. Damit bin ich erst einmal zufrieden.

Tag 2: Zeitgesteuertes Ein- und Ausschalten

ich möchte ja, dass die Lichterketten morgens und abends jeweils an- und wieder aus gehen. Dazu nutze ich Sonnenauf- und -untergang, die zugehörigen Daten fallen aus dem Astro-Binding. Das muss ich noch dokumentieren, hier gibt es erst einmal nur die Code-Schnipsel.

Für die lichterkette.rules

rule "Lichterketten morgens an"
when
   Item Tageszeit changed to "Morgen"
then
   Lichterketten.sendCommand(ON)
end

rule "Lichterketten morgens aus"
when
   Item Tageszeit changed to "Tag"
then
   Lichterketten.sendCommand(OFF)
end

rule "Lichterketten abends an"
when
   Item Tageszeit changed to "Vorabend"
then
   Lichterketten.sendCommand(ON)
end

rule "Lichterketten abends aus"
when
   Item Tageszeit changed to "Nacht"
then
   Lichterketten.sendCommand(OFF)
end

Und dann gibt es noch die tageszeit.rules, welches das oben genutzte Item Tageszeit verändert:

rule "Es wird morgen"
when
   Item Sonne_Hohenwinkel changed
then
   if (Sonne_Hohenwinkel.state == NULL || Sonne_Hohenwinkel.state > -12|"°") {
	  if (Tageszeit.state == "Nacht") {
         Tageszeit.sendCommand("Morgen")
	  }
   }
end

rule "Es wird Vormittag"
when
    Channel "astro:sun:local:rise#event" triggered START
then
    Tageszeit.sendCommand("Vormittag")
end

rule "Es wird Tag"
when
   Item Sonne_Hohenwinkel changed
then
   if (Sonne_Hohenwinkel.state == NULL || Sonne_Hohenwinkel.state > 3|"°") {
	  if (Tageszeit.state == "Vormittag") {
         Tageszeit.sendCommand("Tag")
	  }
   }
end

rule "Es ist Tag"
when
   Time cron "0 0 12 ? * * *"
then
   Tageszeit.sendCommand("Tag")
end

rule "Es wird Vorabend"
when
   Item Sonne_Hohenwinkel changed
then
   if (Sonne_Hohenwinkel.state == NULL || Sonne_Hohenwinkel.state < 3|"°") {
	  if (Tageszeit.state == "Tag") {
         Tageszeit.sendCommand("Vorabend")
	  }
   }
end

rule "Es wird Abend"
when
   Item Sonne_Hohenwinkel changed
then
   if (Sonne_Hohenwinkel.state == NULL || Sonne_Hohenwinkel.state < -2|"°") {
	  if (Tageszeit.state == "Vorabend") {
         Tageszeit.sendCommand("Abend")
	  }
   }
end

rule "Es ist Nacht 1"
when
   Time cron "0 15 22 ? * * *"
then
   Tageszeit.sendCommand("Nacht")
end

rule "Es ist Nacht 2"
when
   Time cron "0 0 4 ? * * *"
then
   Tageszeit.sendCommand("Nacht")
end

rule "Debugging"
when
   Item Tageszeit changed
then
   logWarn("Tageszeit", "Tageszeit changed. Ist jetzt: {}", Tageszeit.state)
end

Und es funktioniert. Wie durch Magie gehen die Lichterketten in der Morgen- und Abenddämmerung an und wieder aus. Jeden Tag zu einer leicht anderen Uhrzeit, immer so, dass es gerade dunkel ist.

Tag 3: Nächstes Jahr

Die obigen Schritte habe ich im Jahr 2021 durchgeführt (aber den Artikel nie veröffentlicht). Irgendwann nach Weihnachten habe ich damals die Lichterketten wieder abgebaut und die lichterkette.rules entfernt. Jetzt ist November 2022, und ich habe die Lichterketten wieder aufgehängt. Und sie sollen auch bitte wieder funktionieren, also lade ich die unveränderte lichterkette.rules wieder auf meinen openHAB-Server. Und siehe da, ich kann die Lichterketten immer noch ausschalten.

Aber nur ausschalten. Anschalten funktioniert nicht mehr. Das ist sehr seltsam.

Ich gehe in den Debugging-Modus, versuche herauszufinden, ob das if-else-Konstrukt der lichterkette.rules funktioniert. Und was soll ich sagen, daran liegt es nicht, denn es funktioniert. Also muss ja die twinkly.py defekt sein, denn was soll es sonst sein? Aber, oh Schreck, ich kann ja immer noch kein Python, was mache ich denn jetzt?

Naja, ich nutze Google. Ich finde andere Menschen mit dem gleichen Problem, aber leider ohne Lösung. Das wäre ja auch zu einfach gewesen.

Ich finde ein (inoffizielles) Twinkly-Binding, hier. Das ist doch vielversprechend, aber leider unterstützt es erst openHAB ab Version 3.2, und ich bin ja noch bei 3.0.1. - ich sollte sowieso updaten. Wie das geht, beschreibe ich in einem anderen Artikel, denn hier habe ich wieder ziemlich geflucht. Aber jetzt kommt die Magie: Nach dem Update auf openHAB 3.3 funktioniert twinkly.py wieder problemlos. Anscheinend hat das Update alles gelöst, und ich muss das Binding nicht ausprobieren. Und mein Garten erstrahlt wieder im Twinkly-Glanz.

TBD19 Kerstin, warum sind Männer der Standard und Frauen die Ausnahme?

Männer sind der Standard, Frauen die Ausnahme. Das klingt völlig überholt? Leider ist das in vielen Produktentwicklungen und in vielen datengetriebenen Vorgehen die Realität. Zu welchen Problemen dies führt, und wie mehr Diversität in Teams und Unternehmen diesen Gender Data Gap beseitigen kann, darüber spreche ich mit Kerstin Fels.


Kerstin Fels erreicht ihr am besten über LinkedIn: https://www.linkedin.com/in/kerstin-fels-5800a915/. Alternativ könnt ihr auch eine E-Mail an kerstin.fels „at“ valtech.com schreiben.

Die angesprochene McKinsey-Studie zu verbesserten Geschäftserfolgen durch mehr Diversität findet ihr hier: https://www.mckinsey.de/news/presse/2020-05-19-diversity-wins.