Liip Blog https://www.liip.ch/de/blog Kirby Fri, 12 Oct 2018 00:00:00 +0200 Neueste Artikel aus dem Liip Blog de The Liip Bike Grand Tour Challenge 2018 https://www.liip.ch/de/blog/the-liip-bike-grand-tour-challenge-2018 https://www.liip.ch/de/blog/the-liip-bike-grand-tour-challenge-2018 Fri, 12 Oct 2018 00:00:00 +0200 Birth of an idea

It all started because of Liip's longlasting engagement to Pro Velo's Bike to Work action. It take place every year during May or June. And foster seldom bikers to get into the habit of biking to work, for at least parts of their trip. Liip is a long-time participant and actively encourages Liipers to participate.

I had been thinking of reaching all offices all at once for quite some time: it could be organized in the form of a relay, participants could use different means of transportation, and so on. At the 2018 LiipConf, I shared the idea with other Liipers and got a lot enthousiastic feedback to finally get around to organize "something". That same evening, I turned to my favorite Bike Router and tried to connect the dots. The idea had then become "try to work in every Liip office, bike between the offices".

Initial implementation

With five offices, Liip spreads over most of Switzerland, from lake Geneva to lake Constance, along the Geneva → St.Gallen IC 1 train line. Initially, I thought of spreading the voyage in 5 days, one per office. But looking at the map and at the routing calculations, it quickly became obvious it wouldn't work, because of the Bern → Zürich leg, which is at least a 125 km ride. Cutting it in half, and not staying overnight in Bern made the plan somewhat realistic.

In early September, I announced the plan on Liip's Slack #announcements channel, in hope to find "Partners in Crime":

🚴‍♀️ Liip Bike Grand Tour Challenge 2018 🚴‍♂️

Motivated to join on a Bike Grand Tour with Liipers? The idea is very simple: connect all Liip offices in one week, on a bike.
  • When? W40: Oct 1. → Oct 5.
  • How? On your bike.
  • Work? Yes; from all offices, in a week!

    Afterwards, the team of bikers took some time to materialize: although we are working in a very flexible environment, being available for work half-days only for a week still isn't easy to arrange for: client and internal meetings, projects and support to work on, and so on. After a month, four motivated Liipers decided to join, some for all the legs, some for only some steps.

    It is important to mention that the concept was never thought as a sports' stunt, or being particularly tough: e-bikes were explicitly encouraged, and it was by no means mandatory to participate in all parts. In other words: to enjoy outdoors and have a reachable sports challenge with colleagues matters more than completing the tour in a certain time.

    Now, doing it

    Monday October 1. - Lausanne → Fribourg

    Fast forward to Monday October 1st. The plan was to work in the morning, and leave around 3 p.m. The estimated biking time is approximately 4:30. But the weather in Lausanne was by no means fantastic - light rain for most if not all the trail. That's why we decided to leave early, and were on our bikes at 2 p.m. As for routing, we agreed to go through Romont, which has the advantage of providing an intermediate stop with a train station, in case we wished to stop.

    We started with a 15kms climb up to Forel and one very steep ascend in La Croix-sur-Lutry, on which we made the mistake to stay on our bikes.
    We arrived in Fribourg after 5 hours in the cold, wind and light rain; often in alternance, but also combined. Thankfully, we were welcomed by friendly Liipers in Fribourg who had already planned a pizza dinner and board-games night; It was just perfect!

    Tuesday October 2nd. - Fribourg → Bern

    After a well-deserved sleep; the plan was to work in Fribourg two hours only, to leave on time and arrive in Bern for lunch.

    • ~ 33 km
    • Amplitude: 534m - 674m
    • Ascend: -72m; total 181m
    • Cantons crossed: Fribourg, Bern
    • Fribourg → Bern

    This was frankly a pleasant ride, with an almost 10kms downhill from Berg to Wünnewil, and then a reasonable uphill from Flamatt to Bern. In approximaely two hours, we were able to reach Bern. The weather had become better; not as cold as the previous day, and rain stopped.

    Tuesday October 2nd. - Bern → Langenthal

    In Bern, changes within the team happened; one rider who made it from Lausanne decided to stop and got replaced by a fresh one! ☺ After a General Company Circle Tactical meeting (see the Holacracy – what’s different in our daily life? ), we jumped on our bikes towards the first non-Liip office overnight stop, northern of canton Bern.

    • ~ 45 km
    • Amplitude: 466m - 568m
    • Ascend: -71m; total 135m
    • Cantons crossed: Bern, Solothurn
    • Bern → Langenthal

    Wednesday October 3rd. - Langenthal → Zürich

    After a long night's sleep in a friendly BnB downtown Langenthal and a fantastic gargantuous breakfast, we were now aiming for Zürich. The longest leg so far, crossing Canton Aargau West to East.

    • ~ 80 km
    • Amplitude: 437m - 510m
    • Ascend: -67m; total 391m
    • Cantons crossed: Bern, Aargau, Zürich
    • Langenthal → Zürich

    When approaching Zürich, we initially followed the Route 66 "Goldküst - Limmatt", with small up- and downhills on cute gravel. But after 30 minutes of that fun, we realized that we didn't progress fast enough. Therefore we tried to get to our destination quicker! We re-routed ourselves to more conventional, car-filled routes and arrived in the Zürich office around 1 p.m., quite hungry!

    Thursday October 4th. - Zürich → St. Gallen

    After a half-day of work in the great Zürich office, and sore legs, we geared towards St. Gallen. The longest part with the biggest total ascend of the trip:

    • ~ 88 km
    • Amplitude: 412m - 606m
    • Ascend: 271m; total 728m
    • Cantons crossed: Zürich, Thurgau, St. Gallen
    • Zürich → St. Gallen

    After three days of biking and more than 200 kms in the legs, this step wasn't expected to be an easy ride and it hasn't been indeed. On the other side, it provided with nice downhill slides (Wildberg → Thurbenthal) and fantastic landscapes, with stunning views: from the suburbs of Zürich to Thurgauer farmland and the St. Gallen hills. Besides, the weather was just as it should be: sunny yet not too warm.

    After 4:45 and a finish while the sun was setting, we finally reached the St. Gallen Liip office!

    « Fourbus, mais heureux ! »

    Friday October 5th. St. Gallen

    Friday was the only day planned without biking,. And frankly, for good. We were not only greeted by the very friendly St.Gallen colleagues, but were also lucky enough to arrive on a massage day! (Yes, Liip offers each Liiper a monthly half-hour massage… ⇒ https://www.liip.ch/jobs ☺). After a delicious lunch, it was time to jump on a train back to Lausanne: Four days to come, 3:35 to return. It really brought a bizarre feeling: it's possible to bike from Lake Geneva to Lake Constance in four days; but it still takes 3.5 hours on some of the most efficient trains to run back.

    Wrap up

    • ~ 314.15 kms (yes; let's say approximately 100 * π)
    • 8 cantons crossed
    • ~ 2070 m of cumulated ascend
    • No single mechanical problem
    • Sore legs
    • Hundreds of cows of all colours and sizes
    • One game of Hornussen
    • Wireless electricity in Thurgau

    Learnings

    • Liip has people willing to engage in fun & challenging ideas!
    • Liip has all the good people it takes to support such a project!
    • The second day eightiest kilometer is easier than the fourth day eightiest kilometer: it would have been way easier with legs of decreasing intensity.
    • It takes quite some time to migrate from a desk to a fully-equipped ready-to-go bike.
    • Carrying personal equipment for one full week makes a heavy bike;
    • Bike bags are a must: one of us had a backpack and it's just not bearable;
    • The first week of October is too late in the year, and makes for uneasy conditions (rain and cold);
    • One month advance notice is too short;
    • Classical Bed-and-Breakfast are very charming.

    Thanks

    Managing this ride would not have been possible without:

    • Liip for creating a culture where implementing crazy ideas like this is encouraged ("Is it safe enough to try?");
    • Biking Liipers Tobias & Heiko, for coming along;
    • Supporting Liipers in various roles for arranging or providing accomodation, ordering cool sports T-shirts, organizing cool welcome gatherings (game night, music night), and being always welcoming, encouraging and simply friendly;
    • The SwitzerlandMobility Foundation for providing fantastic cycling routes, with frequent indicators, orientation maps and markings for "analog" orientation.

    Next year

    Given the cool experience, and many declarations of intent, it is very likely that this challenge will happen again next year, in Autumn; but vice versa! Want to join?

    ]]>
    Add syntactic sugar to your Android Preferences https://www.liip.ch/de/blog/syntactic-sugar-android-preferences-kotlin https://www.liip.ch/de/blog/syntactic-sugar-android-preferences-kotlin Tue, 09 Oct 2018 00:00:00 +0200 TL;DR

    You can find SweetPreferences on Github.

    // Define a class that will hold the preferences
    class UserPreferences(sweetPreferences: SweetPreferences) {
        // Default key is "counter"
        // Default value is "0"
        var counter: Int by sweetPreferences.delegate(0)
    
        // Key is hardcoded to "usernameKey"
        // Default value is "James"
        var username: String? by sweetPreferences.delegate("James", "usernameKey") 
    }
    
    // Obtain a SweetPreferences instance with default SharedPreferences
    val sweetPreferences = SweetPreferences.Builder().withDefaultSharedPreferences(context).build()
    
    // Build a UserPreferences instance
    val preferences = UserPreferences(sweetPreferences)
    
    // Use the preferences in a type-safe manner
    preference.username = "John Doe"
    preference.counter = 34

    Kotlin magic

    The most important part of the library is to define properties that run code instead of just holding a value.

    From the example above, when you do:

    val name = preference.username

    what really happening is:

    val name = sweetPreferences.get("username", "James", String::class)

    The username property is converted from a property name to a string, the "James" string is taken from the property definition and the String class is automatically inferred.

    To write this simple library, we used constructs offered by Kotlin such as Inline Functions, Reified type parameters, Delegated Properties, Extension Functions and Function literals with receiver. If you are starting with Kotlin, I warmly encourage you to go check those. It's only a small part of what Kotlin has to offer to ease app development, but already allows you to create great APIs.

    Next time you need to store preferences in your Android app, give SweetPreferences a try and share what you have built with it. We’d like to know your feedback!

    ]]>
    Wie Content Konversion steigert https://www.liip.ch/de/blog/how-content-drives-conversion https://www.liip.ch/de/blog/how-content-drives-conversion Tue, 09 Oct 2018 00:00:00 +0200 Was erwarten Nutzer eigentlich von Content auf einer Webseite? Wir haben eine Bedürfnispyramide erstellt. Entdeckt unsere 5 Insights.

    ]]>
    From coasters to Vuex https://www.liip.ch/de/blog/from-coasters-to-vuex https://www.liip.ch/de/blog/from-coasters-to-vuex Tue, 09 Oct 2018 00:00:00 +0200 You'll take a coaster and start calculating quickly. All factors need to be taken into account as you write down your calculations on the edge of the coaster. Once your coaster is full, you'll know a lot of answers to a lot of questions: How much can I offer for this piece of land? How expensive will one flat be? How many parking lots could be built and how expensive are they? And of course there's many more.

    In the beginning, there was theory

    Architecture students at the ETH learn this so-called "coaster method" in real estate economics classes. Planning and building a house of any size is no easy task to begin with, and neither is understanding the financial aspect of it. To understand all of those calculations, some students created spreadsheets that do the calculations for them. This is prone to error. There are many questions that can be answered and many parameters that influence those answers. The ETH IÖ app was designed to teach students about the complex correlations of different factors that influence the decision. Furthermore, if building a house on a certain lot is financially feasible or not.

    The spreadsheet provided by the client PO

    The product owner at ETH, a lecturer for real estate economics, took the tome to create such speadsheets, much like the students. These spreadsheets contained all calculations and formulas that were part of the course, as well as some sample calculations. After a thorough analysis of the spreadsheet, we came up with a total of about 60 standalone values that could be adjusted by the user, as well as about 45 subsequent formulas that used those values and other formulas to yield yet another value.

    60 values and 45 subsequent formulas, all of them calculated on a coaster. Implementing this over several components would end up in a mess. We needed to abstract this away somehow.

    Exploring the technologies

    The framework we chose to build the frontend application with, was Vue. We used Vue to build a prototype already. so we figured we could reuse some components. We already valued Vue's size and flexibility and were somewhat familiar with it, so it was a natural choice. There's two main possibilities of handling your data when working with Vue: Either manage state in the components, or in a state machine, like Vuex.

    Since many of the values need to be either changed or displayed in different components, keeping the state on a component level would tightly couple those components. This is exactly what is happening in the spreadsheet mentioned earlier. Fields from different parts of the sheet are referenced directly, making it hard to retrace the path of the data.

    A set of tightly coupled components. Retracing the calculation of a single field can be hard.

    Keeping the state outside of the components and providing ways to update the state from any component decouples them. Not a single calculation needs to be done in an otherwise very view-related component. Any component can trigger an update, any component can read, but ultimately, the state machine decides what happens with the data.

    By using Vuex, components can be decoupled. They don't need state anymore.

    Vue has a solution for that: Vuex. Vuex allows to decouple the state from components, moving them over to dedicated modules. Vue components can commit mutations to the state or dispatch actions that contain logic. For a clean setup, we went with Vuex.

    Building the Vuex modules

    The core functionality of the app can be boiled down to five steps:

    1. Find the lot - Where do I want to build?
    2. Define the building - How large is it? How many floors, etc.?
    3. Further define any building parameters and choose a reference project - How many flats, parking lots, size of a flat?
    4. Get the standards - What are the usual prices for flats and parking lots in this region?
    5. Monetizing - What's the net yield of the building? How can it be influenced?

    Those five steps essential boil down to four different topics:

    1. The lot
    2. The building with all its parameters
    3. The reference project
    4. The monetizing part

    These topics can be treated as Vuex modules directly. An example for a basic module Lot would look like the the following:

    // modules/Lot/index.js
    
    export default {
      // Namespaced, so any mutations and actions can be accessed via `Lot/...`
      namespaced: true,
    
      // The actual state: All fields that the lot needs to know about
      state: {
        lotSize: 0.0,
        coefficientOfUtilization: 1.0,
        increasedUtilization: false,
        parkingReductionZone: 'U',
        // ...
      }
    }

    The fields within the state are some sort of interface: Those are the fields that can be altered via mutations or actions. They can be considered a "starting point" of all subsequent calculations.

    Those subsequent calculations were implemented as getters within the same module, as long as they are still related to the Lot:

    // modules/Lot/index.js
    
    export default {
      namespaced: true,
    
      state: {
        lotSize: 0.0,
        coefficientOfUtilization: 1.0
      },
    
      // Getters - the subsequent calculations
      getters: {
        /**
         * Unit: m²
         * DE: Theoretisch realisierbare aGF
         * @param state
         * @return {number}
         */
        theoreticalRealizableCountableFloorArea: state => {
          return state.lotSize * state.coefficientOfUtilization
        },
    
        // ...
      }
    }

    And we're good to go. Mutations and actions are implemented in their respective store module too. This makes the part of the data actually changing more obvious.

    Benefits and drawbacks

    With this setup, we've achieved several things. First of all, we separated the data from the view, following the "separation of concerns" design principle. We also managed to group related fields and formulas together in a domain-driven way, thus making their location more predictable. All of the subsequent formulas are now also unit-testable. Testing their implementation within Vue components is harder as they are tightly coupled to the view. Thanks to the mutation history provided by the Vue dev tools, every change to the data is traceable. The overall state of the application also becomes exportable, allowing for an easier implementation of a "save & load" feature. Also, reactivity is kept as a core feature of the app - Vuex is fast enough to make any subsequent update of data virtually instant.

    However, as with every architecture, there's also drawbacks. Mainly, by introducing Vuex, the application is getting more complex in general. Hooking the data to the components requires a lot of boilerplating - otherwise it's not clear which component is using which field. As all the store modules need similar methods (f.e. loading data or resetting the entire module) there's also a lot of boilerplating going on. Store modules are tightly coupled with each other by using fields and getters of basically all modules.

    In conclusion, the benefits of this architecture outweigh the drawbacks. Having a state machine in this kind of application makes sense.

    Takeaway thoughts

    The journey from the coasters, to the spreadsheets, to a whiteboard, to an actual usable application was thrilling. The chosen architecture allowed us to keep a consistent set up, even with growing complexity of the calculations in the back. The app became more testable. The Vue components don't even care anymore about where the data is from, or what happens with changed fields. Separating the view and the model was a necessary decision to avoid a mess and tightly coupled components - the app stayed maintainable, which is important. After all, the students are using it all the time.

    ]]>
    Enkeltauglichkeit. Verantwortung für übermorgen https://www.liip.ch/de/blog/enkeltauglichkeit https://www.liip.ch/de/blog/enkeltauglichkeit Wed, 03 Oct 2018 00:00:00 +0200 Enkeltauglichkeit. Verantwortung für übermorgen

    Weil wir uns bewusst sind, ein Teil der Natur zu sein. Ein Symbol dafür, dass wir bereit sind, die Natur als wichtigste Stakeholderin in sämtlichen Entscheidungen zu betrachten. Damit wir enkeltauglich sind. Initianten des Konzeptes «Enkeltauglichkeit» sind der Verein enkeltauglich.jetzt, Brot für alle sowie engagierte Menschen aus der Wirtschaft.

    Purpose over Profit

    Erster Schritt für Veränderung ist die Frage nach der inneren Haltung von Unternehmen der Natur gegenüber. Bisher dominierte eine Haltung der Überlegenheit («Wir stehen über der Natur»), mit entsprechenden Ergebnissen. Mit unserem commitment zur «Enkeltauglichkeit» wirtschaften wir aus der inneren Haltung heraus, ein Teil der Natur zu sein.

    Liip denkt und handelt enkeltauglich

    Für Liip ist es Tatsache, dass wir alle mit der Natur verbunden sind. Sie nährt uns und unsere Wirtschaft. Deshalb übernehmen wir Verantwortung. Gegenüber unseren Mitarbeitenden, unseren Kunden, der Gemeinschaft und der Natur. Wir kultivieren eine integrierte Sicht von Wirtschaft und Natur.

    Wir sind heute die Ahnen von morgen

    Liipers nehmen ihre Verantwortung wahr und handeln nachhaltig. Auf ihre pragmatische Art. Wir unterstützen das Anliegen von enkeltauglichkeit.jetzt. Menschen sind von Natur aus dazu angelegt, in Gruppen zu kooperieren, zueinander Sorge zu tragen und unsere Schwarmintelligenz zu nutzen. Nachhaltig und selbstorganisiert. Die Erde ist unser aller Zuhause, die Natur unsere Lebensgrundlage. Wir sind heute die Ahnen von übermorgen. Wie werden unsere Nachfahren auf uns zurückblicken?

    ]]>
    meinplatz.ch https://www.liip.ch/de/blog/meinplatz-ch https://www.liip.ch/de/blog/meinplatz-ch Fri, 28 Sep 2018 00:00:00 +0200 Projekt

    Die neue Plattform bietet alle wichtigen Informationen rund um die Plätze. Beratende Stellen für Menschen mit Behinderungen sind genauso übersichtlich dargestellt, wie die verfügbaren Plätze im institutionellen Umfeld. Als erste Anlaufstelle bekannt, finden alle übersichtlich die Informationen, nach denen sie suchen. Die Herausforderung im Projekt war, die Ansprüche sämtlicher Zielgruppen zu befriedigen. Nicht nur die verfügbaren Plätze sondern alle Plätze finden sich auf der Plattform wieder. Die Plattform hilft Menschen mit Beeinträchtigung ihren Tagesplatz, Wohnplatz oder Arbeitsplatz im Kanton Zürich zu finden.

    Während der Entwicklung der Plattform hat sich das ganze Entwicklungsteam intensiv mit den verschiedenen Zielgruppen auseinandergesetzt. Betroffene und Angehörige, Beratende und zuweisende Stellen, Institutionen, gesetzliche Beistände und Behörden - sie alle waren Stakeholder über die ganze Entwicklungsphase.

    Design

    Für meinplatz.ch hat Liip nicht nur das Logo, sondern auch das gesamte Corporate Identity entwickelt. Das schlichte und einfach gehaltene Design wird für sehr unterschiedliche Zielgruppen attraktiv, die alle die Seite verwenden. . Damit auch die Designentwicklung User zentriert bleibt, wurde der Hauptfokus auf Menschen mit Beeinträchtigungen gelegt. Die Plattform soll in sehr hohem Masse barrierefrei sein, für Angehörige sowie gesetzliche Beistände und Behörden. Für alle soll die Seite einfach und zielführend sein. Beratungsstellen sollen zudem Art Power User unterstützen. Diese Anforderungen in ein einfaches Design zu verpacken war nicht ganz ohne, wurde aber durch unsere erfahrenen User Experience Designer wunschgemäss umgesetzt.

    Technologie

    Umgesetzt wurde die Website mit dem Open Source October CMS. Durch die einfache Bedienbarkeit und dem feingranulare Rollen Berechtigungsschema eignet sich October CMS ideal. Für meinplatz.ch werden unterschiedliche Administratoren Inhalte erfassen und bearbeiten müssen. Durch unsere Erfahrung sowie die Hilfe von "accessibility developer guide" war die barrierefreie Implementierung kein Problem.

    Trust over control

    Gemeinsam mit INSOS Zürich ist es gelungen, eine neue Plattform für Menschen mit Beeinträchtigung, mit fokus auf die barrierefreiheit zu schaffen. Dies mit Vertrauen in die Zusammenarbeit und gemeinsamen Zielen.

    INSOS: Die Zusammenarbeit mit liip war sehr inspirierend und professionell. Liip überzeugt durch eine hohe Transparenz und vorbildliche Kommunikation. Ich freue mich bereits auf die weitere Zusammenarbeit.
    Maya Graf-Seelhofer, Assistentin/stv. Geschäftsführerin INSOS Zürich

    Erfolgreiche Umsetzung mit minimalem Aufwand dank einer unkomplizierten Zusammenarbeit zwischen Liip und INSOS Zürich.
    Marc Brühwiler, Product Owner Liip AG

    ]]>
    Playing with Hololens https://www.liip.ch/de/blog/playing-with-hololens https://www.liip.ch/de/blog/playing-with-hololens Tue, 25 Sep 2018 00:00:00 +0200 Yesterday we took a couple of hours to play with the Hololens device, the augmented reality helmet from Microsoft. We quickly did a prototype without a single line of code, using the basic tools available out of the box in the Hololens: display images, 3D objects or web browser windows in the room. All this was done using the device itself, and looking funny.

    The idea

    As a designer, I wanted to learn how to play and display information in 3D, and of course, have fun with this nice big tech-toy. During the tests, we thought about what was already at our disposal to play with. We remembered a web tool we'd developed internally. It's a simple web interface showing the reservations of our conference rooms. You can display the detail of a room and book it through a simple form. What a nice base to start with!

    The process

    Put up web browsers in the hallway, near the doors to the conference rooms. Display the reservation system in these windows. Then virtually put an image "on" the doors: a green checkmark if the room is free, a red cross if the room is occupied. That's it.

    The result

    We were able to walk in the office, see clearly which room was free and book it through the web interface displayed next to the door. Yay!

    Well, wearing this big device on your head still make your colleagues laugh, but this technology is so fascinating that you quickly forget you look like an astronaut talking to invisible things, lost in the wide space of the office.

    Next steps

    As the prototype is made with the basic tools of the device, it can't be saved and started as an app. All the windows can be moved or removed by the next user, not very convenient. Encapsulate these functionalities into an app should be the next step. In parallel, the UX experience could be adapted to this new 3D environment: bigger buttons, simpler interface, or why not trigger a reservation through a single voice command: “Hey, I need this room right now for 30 minutes!”

    Learnings

    Prototyping for augmented reality can be quick and efficient without effort, even for non coders. Designers can learn intuitively how to layout information, arrange things and create a visual hierarchy directly in the space. A couple of images and a bit of HTML can be enough to deliver great prototypes and be a solid base for your future cutting edge application.

    ]]>
    Delivering Service Design with Scrum - 6 insights https://www.liip.ch/de/blog/delivering-service-design-with-scrum-6-insights https://www.liip.ch/de/blog/delivering-service-design-with-scrum-6-insights Wed, 19 Sep 2018 00:00:00 +0200 Starting something new is always inspiring and exciting.

    Getting the chance to start from scratch designing a new and effective service, together with a team is something I like best in my job as Service Designer at Liip. Immersing myself in customers’ needs, developing great new ideas, making them tangible with prototypes and getting stimulating feedbacks. These parts are definitely the most inspiring and fun of service design projects.

    But the delivery can be a really hard landing.

    When working on service design projects, we break open existing silos. We align all the different parts involved in the service to create a better and more efficient service experience. For the delivery of the new service, that can also entail a high degree of complexity. In addition to the hard work of developing concrete solutions, we also have to deal with other challenges. For example, changing the habits and behavior of people or clarifying organizational uncertainties. The search for the right decision-makers and sponsors between the different parts of the company and technical restrictions as further examples. After the thrill of the first creative phases, delivery can mean a really hard landing.

    Combining service design with agile methods helps facing the challenges of delivering.

    Having worked in both Service Designer and Scrum Master roles in recent years, I tried several ways of combining Service Design with Scrum. My goal is to combine the best of the two ways of working to make this hard landing a little softer. Here are 6 learnings that proved to be very helpful:

    1. Use epics and user stories to split the service into more “digestible” pieces.

    Everyone probably knows the feeling of not seeing the wood for the trees when you’re standing in front of a wall full of sketches and stickies with ideas. Then it’s very helpful to create a list of epics. In the Scrum world, epics are “a large body of work that can be broken down into a number of smaller stories” (see Atlassian). In Service Design, epics can help dividing the entire service into smaller pieces. This reduces complexity, and allows dealing within specific and limited challenges of a single epic, rather than the whole. Also, the ability to clarify one epic gives good clues where to start with this big mountain of work.

    2. Use the service blueprint as the master to create the backlog.

    In software projects we often use user story maps to create epics and user stories. In service design projects, the service blueprint is a very powerful alternative to do user story mapping. Service blueprints help mapping and defining all aspects of the future service - from the targeted experience to internal processes, systems, people, tools, etc involved. This contains a lot of useful information for user stories e.g.

    • The actors involved, eg. the different types of users (as personas), different staff people, systems, tools, etc.
    • The required functions, as each step of a service blueprint usually contains a number of functions that will be written in the different user stories.
    • The purpose of the function, as you can read from each part of the blueprint what is triggered by this step.

    After a first version of the user story backlog is created, you can reassign the user stories to the service blueprint. Mapping all the written stories to the blueprint is also great to determine if some user stories have been forgotten. This helps a lot to have a better overview of what to do and how it affects the service experience in the end.

    3. Do technical spikes in an early stage of the project in order to make your service more feasible.

    If the service contains digital parts, it’s highly recommended to face the technical crack nuts in the project as soon as possible. Scrum provides us with the so called technical spikes - a great chance to dive deeper into different possibilities of solving technical issues of the new service. Strictly timeboxed, they allow developers to explore different technical solutions and suggest the one that fits best. Furthermore the team can discuss the consequences and adapt the service. In order to still create a great experience but also find a feasible way of delivering it.

    4. Estimate the business value of the different aspects of the service.

    In Scrum, we use business value poker to prioritize user stories. A business value is a relative comparison of the value of different user stories. It helps to prioritize the delivery and to show where the most time and money needs to be invested. This process is also very healthy (and tough!) for service ideas. Knowing how much value each part of the service brings to the whole service vision is very valuable and allows the team focus on what really matters.

    You can also do business value poker in combination with an adaption of the six thinking hats method, e.g. one of the team estimates the business value in the hat of the user, one in the hat of the top manager interested in return on investment, and one in the hat of the staff member interested in delivering a service experience that doesn’t mean additional work.

    5. Deliver a “Minimum Viable Service” (MVS) before taking care of the rest.

    Once we have the user story backlog rooted in the service blueprint and we know which story brings most value to our service vision, we start step by step to deliver the service. In agile software projects, the team starts by producing the Minimum Viable Product (MVP). Which means, delivering the smallest amount of features necessary in order to create a valuable, reduced product to users. For services, we are doing the same - creating a “Minimum Viable Service” (MVS). This allows the team developing a first basic version of the service in a short time to market. Delivering results in a early stage of the project is not only motivating the team but also allows continuous learning, adapting and evolving of the service.

    6. Work in cross functional, self organised and fully empowered teams.

    Scrum teams are self organised and include all skills needed. Without having a hierarchy based system. In a service design setting, many different fields of a company are involved and it’s hard to specify decision makers and people responsible. But that’s the key. Including each and every stakeholder of a whole service in the project is never ending and rarely contributing. Therefore dedicate a small and powerful team of experts involved, give them the full competence to decide and to organise themselves but also the responsibility to deliver value.

    Scrum provides great ways to deliver complex service projects.

    This blogpost highlights a few aspects of how we manage the challenges of delivering a complex service project. By combining service design with scrum - from the the tools and artifacts to the mindset and the way how teams work together.

    Yet, also when following all these aspects, delivering a complex service remains a hard piece of work. But definitely an easier one to handle with the structured and well working delivery methods to bring our ideas to life. Step by step - sprint by sprint.

    ]]>
    A personal view on what Holacracy has brought us https://www.liip.ch/de/blog/a-personal-view-on-what-holacracy-has-brought-us https://www.liip.ch/de/blog/a-personal-view-on-what-holacracy-has-brought-us Tue, 18 Sep 2018 00:00:00 +0200 I was invited to share on our adoption of Holacracy in a recent online gathering of the Siemens Grow2Glow network. It gave me the opportunity to think about the impact the Holacracy organisational system has had on the agency, its culture and the way we work. I first focused on the negative impacts, the things we need to fix, but then realized I wasn’t fair to the reality: the benefits outgrow the challenges by far.

    Thinking of it, and having had the opportunity to be in the company through several “eras”, I realized how much things have changed. I have no scientific evidences of what I am sharing here, those are things I experienced and observed, a personal view.

    Good stuff happened before

    Liip always had a strong focus on values and human-centeredness: ethics always had a say, collaborators also. And before the adoption of Holacracy, we benefited a lot from the introduction of the Scrum agile framework (2009) and later from cross-functional teams and guilds (~ Spotify model, 2012).

    That was before the founders adopted Holacracy (2016), a period of time which I will refer to, in this post, as the "partners-era". Family-like dynamics were the norm, partners were the “elders” of the organisation, employees the “grown-up children”.

    The years since our adoption of Holacracy will hereunder be coined the "holacracy-era".

    Good stuff happening, 3 years after Holacracy adoption

    It is ok to try things, even serious things

    Entrepreneurship in the partners-era summed up to: partners decided on life and death of the offering. Adventurous workers had to pitch their ideas and go get buy-in and approval from the partners.

    In the holacracy-era, things are different: services are launched out of the initiative and authority of any employee, creating a momentum that attracts collaborators and clients. In the last two years we have indeed added several services to our portfolio through individual initiatives, and more are incubating.

    It is ok to stop things, even serious things

    If it has gotten ok to launch things, it’s also ok to stop things. In one of the circles I am involved in, we launched a new consulting service a few months ago, thinking it was a great complement to our existing offering. Although I still think it was, it turned out the market was not at the rendez-vous. We took the opportunity of someone leaving the company to consider dropping that new offering.

    In the partners-era, I would have had to raise awareness of the partners to stop the thing – I wouldn’t have had the authority to do so – and the partners would have probably felt compelled to adopt a parental posture “you should have known better”, “be careful next time”, “what will the clients think?”, “how should I now communicate on that?”, …

    Nowadays: I sensed the tension in my role in that circle, and took the initiative: first seeking advice from the ones impacted, clients included, and envisioning with them the possible scenarii. Then I made up my mind on a “closing” scenario. Yet, I sensed the need to give the rest of the company the opportunity to react and potentially on the decision before I would finally enact it. After all, I wasn’t sure all impacted persons had been involved. I launched an integrative decision process on our internal messaging app that read like: “In my role X, I’m about to close service Y, read more in this doc. Today you can ask questions, tomorrow you can give feedbacks, thursday you can raise objections.” It all went very well. Those who cared or were loosely impacted decided to participate, the other ones didn’t feel compelled to participate – great relief – and we closed this service smoothly.

    Continuous, organic micro re-organisations

    In the partners-era I participated and was impacted by several meetings during which we “reshaped teams”. In such meetings we would list all people in the office, and then try to shape a certain amount of “balanced” teams out of them.

    In this Holacracy-era: we don’t “gather and redistribute the cards” anymore. Teams evolve slowly, roles and people come and go organically. An interesting example: a team of 20+ had a very rough year, their financial performance was bad for several months. The team could not agree on how to change things: should they focus? and if yes, on what market, technology, value proposition, ... Disagreement and the implicit need for consensus prevented the situation from evolving.

    What unlocked the situation was that some people from that team literally raised their hands and pitched: “I wanna launch a mini team focused on tech X, I have the passion, we can make it happen, who’s in?” A few joined. Others saw the drive and copied: “I believe there’s a market for Y, who’s in?”. The big team slowly dissolved into smaller teams, that were more focused and with clearer motivation and purpose. The big team had re-purposed itself into smaller ones.

    Organisational fitness

    In the partners-era my job in the company was forcefully important to me, because it was my only job within the company. Like most employees in this world. This one-person-one-job relationship forces people to protect their job, in order to protect their belonging to the organisation, their salary, status, etc. And thus, organisations keep adding jobs, and almost never remove them, except in abrupt attempts: re-organisations.

    In a holacratic organisation employeeship and roles are decoupled: I now see people suppressing some role they fill, because the role is not needed anymore. I see others merging their accountabilities in other roles, that they don't hold. The roles that exist are there because of an existing need, not a past one.

    I am not my roles and my roles are not me, getting rid of my role doesn’t directly threaten me.

    Talents, experience and passion flow to roles

    With Holacracy, we see much more opportunities for employees to act in roles that fit their experience, motivation and/or talents. Talents, experience or passion get noticed, roles get proposed.

    More demand for personal development

    In the partner-era: just a few of us were interested in improving our soft skills. The only incentive would have actually come from a partner, in a talk like “Now that you are a Product Owner, you should improve on this and that soft skills”. In this holacracy-era: I believe the talk happens within each of us: “Now that I am self-org, I sense the need to be a better leader/colleague/collaborator/...”. We do see growing demand and attendance for trainings on social and leadership skills.

    Less rants about the heads and the organisation

    Those who process the annual Employee Meetings sense that there’s much less rants, and that the messages from the employees has moved from “We (meaning you, Boss) need to change this“, to “I know it’s in my hands to make this happen, where do I start?” We moved from expecting change from others to expecting change from ourselves.

    A last word

    I wanted this blogpost to focus on the benefits we are seeing at Liip from having adopted Holacracy. A post on the challenges, again a personal view on them, will follow.

    ]]>
    Experimenting With Android Things https://www.liip.ch/de/blog/experimenting-android-things https://www.liip.ch/de/blog/experimenting-android-things Fri, 07 Sep 2018 00:00:00 +0200 Context

    At Liip we have the great opportunity to experiment in new technologies when working on innovation projects. Within the last two years we developed Houston: a VOIP communication system for buses. The system includes an Android app which takes VOIP calls and collects sensor information like the GPS position. When I heard about the release of Android Things, I thought it’d be interesting to investigate if we could use it to make the app run on IoT devices like the Raspberry PI. Therefore I experimented with the platform for a few days. And I discovered an amazing operating system bringing all the benefits of Android to IoT devices.

    How to start

    The best thing about Android Things is that it is built for Android developers and comes with standard development tools, the ones you are used to. You will develop inside Android Studio. And being able to debug code using adb, like for a normal Android device, is great. Android Things extends the core Android framework with additional APIs provided by the Things Support Library (reference, platform differences). That means it will be easy to use the Android API to develop a user interface, communicate with a server, etc. It is also possible to use Android libraries like Google Firebase (real time datababe, push notifications, ...) or Tensorflow (machine learning).

    To start developing for Android Things, you need a development board. Google supports different hardware among the well-known Raspberry Pi 3 Model B. In 2017, more boards where supported, such as the Intel Edison, but it seems they stopped supporting them (at least officially, list of supported platforms).

    If you don’t have a Raspberry Pi 3 already, you can buy a starter kit like this one or this one. You will get a Raspberry Pi 3 with a power supply with the first kit. Furthermore there will be a SD card with the Android Things OS flashed and the Rainbow Hat. The hat is easy to plug on the Raspberry and contains a buffet of sensors (temperature, pressure, etc.), LEDs, alphanumeric display, etc.. To explore the platform, I wanted to be able to do my own electronic schemes. Therefore I bought the Raspberry itself and this kit that contains a breadboard (thin plastic board used to hold electronic components) with cables, resistors, LEDs and few sensors. Something you shouldn’t forget is buying a cable which allows you to connect the breadboard to the GPIO connector on the Raspberry (like this one).

    If you want to use Android Things with a specific sensor or peripheral, be aware that usage without a driver is impossible. Therefore it is better to look at the list of available drivers first (available here, here and here). It is also possible to write a driver yourself. You’ll find a tutorial here. Once you have a Raspberry PI, it is easy to get Android Things running on it. You can follow this tutorial to flash the OS on a Micro SD card and connect the hardware.

    Prototype 1: Weather station

    The first prototype I built is a small weather station. The temperature in the office was high and my idea was to measure the temperature of the room. Furthermore I wanted to light up a led if the temperature reaches a given threshold. A next step would be to switch on a fan for example .

    the weather station
    the weather station

    To build the electronic circuit on the development breadboard, you’ll need a bit of electronic knowledge. This feels like becoming an electronic engineer, which is great! Reading a tutorial is great as a memory refresher. This one was very helpful to me.

    One import thing to remember is Ohm’s Law U = RI , to know which resistance you have to put between the Raspberry PI and the LED. The resistance needs to respect the intensity of the LED that switches on automatically . It was also not easy to understand how the Peripheral I/O interface works at the beginning (where is the ground (-), power (+), functionality of the different pins, etc.). I printed the scheme here to have it next to me at all times.

    General Purpose Input/Output (GPIO) provides a programmable interface to read the state of a binary input device or control the on/off state of a binary output device (such as an LED). The red LED was connected on pin BCM6 and the green LED was connected on pin BMC 5, for example. To get the temperature via the sensor and display it on the alphanumeric display, I used BCM2 and BMC3 (inter-integrated circuit bus).

    The steps to create the Android Things app are the following:

    1. Create a Android project with a blank Activity in Android Studio and add the Android Things library and drivers in build.gradle
    provided ‘com.google.android.things:androidthings:<version>'
    implementation 'com.google.android.things.contrib:driver-bmx280:<version>'
    implementation 'com.google.android.things.contrib:driver-ht16k33:<version>'
    1. Add the following line in the AndroidManifest.xml under the application tag
    <uses-library android:name="com.google.android.things"/>
    1. In OnCreate of the MainActivity, register the peripherals
    val service = PeripheralManagerService()
    mSensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
    
    //Temperature sensor
    try {
        mEnvironmentalSensorDriver = Bmx280SensorDriver("I2C1")
        mSensorManager.registerDynamicSensorCallback(mDynamicSensorCallback)
        mEnvironmentalSensorDriver.registerTemperatureSensor()
        mEnvironmentalSensorDriver.registerPressureSensor()
        Log.d(TAG, "Initialized I2C BMP280")
    } catch (e: IOException) {
        throw RuntimeException("Error initializing BMP280", e)
    }
    
    //Alphanumeric display
    try {
        mDisplay = AlphanumericDisplay("I2C2")
        mDisplay.setEnabled(true)
        mDisplay.clear()
        Log.d(TAG, "Initialized I2C Display")
    } catch (e: IOException) {
        Log.e(TAG, "Error initializing display", e)
        Log.d(TAG, "Display disabled")
        mDisplay = null
    }
    
    //Green LED
    try {
        mGreenLedGpio = service.openGpio("BCM5")
        mGreenLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW)
    
    } catch (e: IOException) {
        throw RuntimeException("Problem connecting to IO Port", e)
    }
    
    //Red LED
    try {
        mRedLedGpio = service.openGpio("BCM6")
        mRedLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW)
    } catch (e: IOException) {
        throw RuntimeException("Problem connecting to IO Port", e)
    }
    1. And finally register for sensor events:
    private val mTemperatureListener = object : SensorEventListener {
        override fun onSensorChanged(event: SensorEvent) {
    
            mTempCount++
            if (mTempCount % 100 !== 0) {
                return
            }
    
            val temperature = Temperature(System.currentTimeMillis(), event.values[0])
            Log.i(FragmentActivity.TAG, "Temperature: " + temperature.getTemperature())
    
            mTemperatureTexView.setText(String.valueOf(temperature.getTemperature()))
            updateDisplay(temperature.getTemperature())
    
            try {
                if (temperature.getTemperature() >= TEMPERATURE_THRESHOLD) {
                    mRedLedGpio.setValue(true)
                    mGreenLedGpio.setValue(false)
                } else {
                    mRedLedGpio.setValue(false)
                    mGreenLedGpio.setValue(true)
                }
            } catch (e: IOException) {
                Log.e(TAG, "Error", e)
            }
        }
    
        override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
            Log.d(TAG, "accuracy changed: $accuracy")
        }
    }
    
    private fun updateDisplay(value: Float) {
        if (mDisplay != null) {
            try {
                mDisplay.display(value)
            } catch (e: IOException) {
                Log.e(TAG, "Error setting display", e)
            }
        }
    }

    In the onSensorChanged callback for the temperature sensor, we filter events (otherwise we receive too many temperature changes) and display the value on the display with updateDisplay() . Once the value reached a certain threshold (TEMPERATURE_THRESHOLD), we switch the red or the green LED with setValue(true)/setValue(false).

    And that’s pretty much it. Thanks to the Android framework and the implemented drivers it is very simple to communicate with the Raspberry PI using simple interfaces and without the need for low level programming.

    Prototype 2: GPS tracker

    In the next prototype, I wanted to test Android Things with a GPS antenna. If we come back to the Houston project, the idea would be to have an embedded device that is able to track the positions of the buses.

    the Raspberry PI with the Grove GPS
    the Raspberry PI with the Grove GPS

    It was laborious to find out which GPS sensor to buy. There are many models so I decided to use the Grove GPS with GrovePi+. GrovePi+ offers a plug-and-play module for the Raspberry PI. You can connect Grove sensors without cables and breadboards.

    It is possible to use the Grove Pi+ with Android Things, but I am not sure if it will work with all Grove sensors. I guess it depends on the connection interface you have (I2C, UART, …) and if there is a driver available for it. In my case, I needed a UART connection and it was enough to connect the Grove GPS to the RPISER port of the GrovePi+.

    To create the Android Things app, the steps are the following:

    1. Create a Android project with a blank Activity in Android Studio and add the Android Things library and drivers in build.gradle
    provided ‘com.google.android.things:androidthings:<version>'
    implementation 'com.google.android.things.contrib:driver-gps:<version>'
    1. Add the following line in the AndroidManifest.xml under the application tag
    <uses-library android:name="com.google.android.things"/>
    1. In onCreate of the MainActivity, register the GPS sensor
    // Callback when SensorManager delivers temperature data.
    val I2C_BUS = "I2C1"
    val UART_BUS = "UART0"
    val UART_BAUD = 9600
    val ACCURACY = 2.5f // From GPS datasheet
    
    ...
    
    mLocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
    
    // We need permission to get location updates
    if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // A problem occurred auto-granting the permission
        Log.e(TAG, "No ACCESS_FINE_LOCATION permission")
        return
    }
    
    try {
        // Register the GPS driver
        mGpsDriver = NmeaGpsDriver(this, UART_BUS, UART_BAUD, ACCURACY)
        mGpsDriver.register()
    
    } catch (e: Exception) {
        Log.e(TAG, "Unable to open GPS UART", e)
    }
    1. Then, register the listener to receive location updates, just like for a standard Android code base.
     ...
    
    // Register for location updates
    mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2, 0, mLocationListener)
    
    ...
    
    val mLocationListener = object : LocationListener {
        override fun onLocationChanged(location: Location) {
            Log.v(TAG, "Location update: $location")
        }
    
        override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
        override fun onProviderEnabled(provider: String) {}
        override fun onProviderDisabled(provider: String) {}
    }

    When you are running the app, you will see the current locations displayed in logcat. We can imagine to collect the locations in a Firebase Firestore database or display them on a map. We have seen, that it is very simple to build an Android Things prototype. As long as you have a bit of Android development experience and the correct driver and hardware setup, you’ll be okay.

    Next steps

    The goal of this innovation project was to experiment with the Android Things platform and discover if we could use it in our projects. It was great fun to build the electronic circuits and interact with the hardware via the Android framework. The setup is simple and the framework allows us to easily build a lot of amazing apps for IoT devices. You’ll find a lot of interesting use cases on the Web such as controlling you home switches remotely. Or even funnier examples like building an high five machine. Google insists on their website that the platform is not meant just for quick prototyping, but also for real products. Android Things is definitely a platform that was worth a try. The next step is to start integrating some of the Android code bases we have developed for Houston or other projects. We have a lot of ideas already!

    ]]>