Service hos Toyota Hell Bil Lade

Avensisen vårklar i fjor

Avensisen vårklar i fjor

Å ha bilen på service er en dyr og kjedelig nødvendighet, og i år måtte jeg i tillegg sjekke en ulyd i forstillinga og få fiksa AC-anlegget som slett ikke kjølte. Jeg sjekka priser på forskjellige verksteder, og ikke overraskende var det dyrest hos merkeverkstedet Toyota Hell Bil. Men siden AC-anlegget også var i ustand da jeg kjøpte bilen (på nettopp Hell Bil) for to år siden, tok jeg hele sulamitten der for å slippe å være uten bil i flere omganger. Det fikk heller bli litt dyrere tenkte jeg, de er iallfall et seriøst firma.

Jeg ble faktisk svært positivt overrasket da jeg leverte bilen en torsdag morgen. Ved innlevering fikk jeg en ordre å signere, og der var alt oppgitt i minste detalj. Hva jeg hadde sagt på telefonen i forkant, at Hell Bil skulle utbedre ACen på egen regning og at de skulle sjekke ulyden og ringe meg for å avtale hva som evt. skulle gjøres. Ryddig og oversiktlig, akkurat som jeg liker det!

Det var først da jeg fikk SMS fra verkstedet fredag at det ikke var så ryddig lenger:
«Hei, bilen er ferdig og klar til henting, åpent til kl 16.30. Pris 10.095.-» 

Samtalen

Prisen vi hadde avtalt var 5696 kr. Jeg ble kokheit, skjelvende forbanna og ringte verkstedet. Samtalen forløp omtrent som dette:

– «Hei, Rune Andersen her, jeg har nettopp fått en SMS fra dere. 10095 kroner, det var ikke akkurat de 5696 kr vi avtalte? Det er omtrent det dobbelte!»
– «Ja.. skal vi se.. (blar i papirer) Ja, jeg ser det, det er et hjullager som er byttet, derfor det er blitt dyrere.»
– «Dere skulle sjekke, og så ringe meg og avtale hva som skulle gjøres! Det står i ordren, ser du det?»
– «Ja, det står her.»
– «Og det har dere gjort?»
– «Nei, vi har vel ikke det…»
– «Hvordan synes du sjansen min er til å sjekke priser hos andre verksteder nå?»
– «Nei… ikke så bra..?»
– «Dere skal være en stor og seriøs aktør, jeg forventer at dere rydder opp i dette!»

Kundebehandleren bekreftet at han skulle ta det opp med verksmesteren og ringe tilbake, og jeg la på. I mellomtiden sjekket jeg priser på skifte av hjullager et par andre steder.

Etter lunsj ringte verksmesteren. Han forklarte at gutta på verkstedet jobbet sent torsdag, fant et ødelagt hjullager og ringte han for å spørre hva de skulle gjøre. Han hadde tatt sjansen på å fikse det med det samme, heller enn å vente til fredag for å ringe meg, og dermed ikke rekke å ha bilen klar før helga. Jeg var ikke spesielt fornøyd, men han tilbød å kutte prisen slik at totalkostnaden ble 7561 kr for service og hjullagerbytte. Det var et billigere bytte enn på de to jeg hadde rukket å sjekke, men fordi servicen var dyrere havnet totalen omtrent der den ville havnet likevel, så jeg godtok. Alternativet ville vært å tvinge Hell Bil til å sette tilbake det ødelagte lageret og dra et annet sted for å bytte det, men det tjener ingen, verken i tid eller kostnader. Bilen ble hentet etter jobb fredag.

Spekulasjoner

Det er ikke første gang jeg har opplevd lignende (fra andre verksteder), og jeg er vel neppe den eneste bileieren som har vært utsatt for slikt. Selv om situasjonen «løste seg» på et vis, mistenker jeg den representerer en utbredt måte å spekulere i kundens villighet til å betale ekstra. Å bytte ei lyspære uten å ringe er én sak, men 4399 kr ekstra blir noe annet.

Jeg kunne fint blitt oppringt torsdag kveld og sagt ja/nei til reparasjon. Hell Bil kunne også riskert at jeg ikke var i stand til å betale merkostnaden før ved neste lønnsutbetaling (noe jeg kanskje burde insistert på uansett?). Men i de fleste situasjoner antar jeg at folk enten betaler det de blir avkrevd, eller gjør som meg og godtar et «tilbud» som et slags plaster på såret for å bli ferdig med det. Folk flest misliker ekstra prakk, og vil nok bare ha bilen tilbake.

I ettertid har jeg vært tilbake og fått ordnet ACen også. Det forløp uten uenigheter eller overraskelser, og Hell Bil tok regninga for reklamasjonen som avtalt.

Oppfordring til andre bileiere

Vit hva du skriver under på, og gjør deg kjent med verkstedets lovpålagte (og selvpålagte) plikter. Husk at du har forbrukerkjøpsloven på din side, enten det er kjøleskapet eller bilen som fusker. 2 år minimum, og 5 år for varer som er ment å vare vesentlig lenger (som en bil tross alt skal).

Lær forskjellen mellom garanti og reklamasjon! Her feiler mange. Forhandlerne/verkstedene tilbyr gjerne garantiordninger, men disse skal  ikke være dårligere enn de rettighetene loven gir. Det vil si at det er ulovlig å kreve «egenandel for garantibruk» i tilfeller der du allerede dekkes av kjøpsloven. Hell Bil krevde en slik «egenandel» første gang det var feil på bilen min, 1 år etter at jeg kjøpte den. Den kunne de se langt etter.

Stå på ditt når du vet du har rett. Bli ikke fristet til å godta et urettmessig nederlag bare for å bli ferdig med saken. Er du i tvil, kontakt NAF, de har jurister som garantert har vært borti lignende saker før.

Bartebuss – the beginning

Rutedata m/sanntid

Rutedata m/sanntid

Tidlig i sommer snublet jeg over et prosjekt kalt BusBuddy, hvor noen studenter ved IDI hadde laget et kult busskart med sanntidsdata fra AtB. Men de hadde ikke bare stoppet der, de hadde også lagd et API for å dele rådataene. Siden AtB offisielt enda ikke hadde gjort dette selv, var det nesten som en liten «undergrunnsbevegelse» av bussnerder som begynte å mekke smarte løsninger, meg selv inkludert.

Jeg hadde lyst å lage en mobilvennlig webapp, heller enn noe som bare funket på Android eller iOS (iPhone etc). Trafikantens presentasjon av ruteinfo for buss/trikk i Oslo var utgangspunktet, og jeg satte i gang å leke. Det skulle bli en HTML5- og JavaScript-drevet «dings» som ikke krevde pageloads, som var rask, så bra ut og utnyttet nye HTML5-muligheter, som f.eks. å bufre data og hente brukerens posisjon.

Resultatet av det jeg beskriver under finnes på bartebuss.no, samt som Android-appen Bartebuss på Android Market.

Dette kommer til å bli en ekstremt nerdete, usammenhengende og lang bloggpost. Du er herved advart!

Rammeverket

En webapp bør se ut og oppføre seg litt annerledes enn en vanlig webside, blant annet ville jeg ikke ha mulighet til zooming siden appen likevel skulle bruke standard fontstørrelse og være full skjermbredde, og jeg ville kunne angi pene, store ikoner og splash-screens. iPhone kan kjøre sider i webappmodus (uten adresse- og verktøylinjer), det ville jeg også dra nytte av.

Til slikt finnes det mange fine meta-elementer man kan bruke.

<!-- Full bredde, ingen zooming -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Tillat å kjøre i fullskjermmodus i iOS -->
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- Ikoner og splashscreens for alle varianter av iOS (iPhone/iPad/iPhone retina) -->
<link rel="apple-touch-icon" href="/img/icon-57x57.png" />
<link rel="apple-touch-icon" href="/img/icon-72x72.png" sizes="72x72" />
<link rel="apple-touch-icon" href="/img/icon-114x114.png" sizes="114x114" />
<link rel="apple-touch-startup-image" href="/img/splash-748x1024.png" media="screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation:landscape)" />
<link rel="apple-touch-startup-image" href="/img/splash-768x1004.png" media="screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation:portrait)" />
<link rel="apple-touch-startup-image" href="/img/splash-320x460.png" media="screen and (max-device-width: 320px)" />

For Android må man jukse litt for å unngå konflikt med iOS-ikonene.

if(navigator.userAgent.match(/Android/i))
    $('head').append('<link rel="apple-touch-icon-precomposed" href="/img/icon-114x114.png" />');

Siden verktøylinjene i browseren forsvinner når man kjører i webappmodus, startet jeg med å bygge en verktøylinje med utgangspunkt i hvordan Seesmic og Facebook gjør det. All HTML for denne, pluss skjelett for alle undersidene, ble plassert i én HTML-fil, slik at lasting av undersider ble unødvendig. Målet var i tillegg å bruke minst mulig PHP i brukerens ende, slik at mest mulig kunne kjøres client-side.

HTML5 history

For å slippe pageloads, men samtidig ikke ødelegge tilbake-knappen tok jeg i bruk HTML5 history. Det fungerer slik at man dytter en URL og en sidetittel på en stack, sammen med et JSON-objekt som beskriver en tilstand (state). Man velger selv hvordan man ønsker å bygge state-objektet sitt, så lenge man greier å gjenskape den forrige siden basert på dataene det inneholder. Jeg valgte å ta vare på sidens ID, hvilken fane i appen det tilsvarte, og dobbeltlagre lenka.

var state = {
    'page': page.attr('id'),
    'tab': tab.attr('id'),
    'link': link
};
history.pushState(state, null, link);

For hvert pushState man gjør, får man et ekstra innslag i historikken å gå tilbake til. Samtidig endres URLen i adressefeltet, akkurat som om man hadde lastet en ny side. For å unngå å skape et logginslag ved første sidelasting (men samtidig gjøre det mulig å gå tilbake dit), bruker man replaceState ved første pageload. Litt logikk for å finne ut hva som er første er naturligvis også nødvendig.

Når brukeren trykker tilbake-knappen trigges en popstate-event, denne må man knytte en handler til.

$(window).bind('popstate', function(e){
    // Hent det gamle state-objektet fra eventen (eller originalEvent for jQuery)
    var previousState = e.originalEvent.state;
    // Gjør noe magisk, last riktig side, sett riktige variabler osv.
});

Handleren gjør det som er nødvendig for å gjenskape hvordan den forrige siden så ut.

Direktelenker til tilstand

Hvis man ønsker å la det være mulig å gå direkte til lenker/tilstander inni appen (direkte til en søkeside el.l.) må man sjekke sidens URL ved lasting, og gjøre de nødvendige tingene derfra. Jeg brukte JQuery URL Parser plugin, og trigget klikk/tap på lenkene/knappene som normalt fører brukeren til angitt tilstand/side.

var urlSegment = $.url().segment(1);
switch(urlSegment){
    case 'alle':
    case 'sok':
        $('#searchTab a').trigger('tap');
        break;
    case 'orakel':
        $('#oracleTab a').trigger('tap');
        break;
    case 'kart':
        $('#mapTab a').trigger('tap');
        break;
    ...
}

Det er en god grunn til at jeg ikke trigger en click-event, men heller den egendefinerte tap-eventen, mer om det under.

HTML5 localStorage

Resource inspector, ChromeÅ jobbe med ca 1400 holdeplasser for Trondheimsområdet betød at det ville være en fordel å mellomlagre alle på mobilen, heller enn å laste dem ned hver eneste gang. Jeg skrev derfor et script som lastet dem ned én gang, lagret dem i localStorage, og kun oppdaterte hvis lista var over en uke gammel – eller den fikk beskjed om å oppdatere seg (ved viktige endringer).

For å avsløre om brukerens enhet/browser støttet forskjellig «ny» funksjonalitet tok jeg i bruk Modernizr. Datoer tok jeg hånd om med date.js.

$.ajax({
    url: 'http://api.busbuddy.no/api/1.2/busstops?callback',
    dataType: 'jsonp',
    jsonpCallback: 'busbuddyResponse',
    data: {'apiKey': xxx},
    timeout: 5000,
    success: function(data){
        if(Modernizr.localstorage){
            localStorage.setItem(
               'busStops',
               JSON.stringify(data.busStops))
            localStorage.setItem(
               'lastUpdated',
               Date.today().setTimeToNow().toString(bartebuss.timeformat));
        }
        stops = data.busStops;
    },
    error: function(){...},
    complete: function(){...}
});

Tap delay

Selv gode webapps føles tregere enn native apps, og en av grunnene er at det i browseren er en forsinkelse på omkring 300 ms fra brukeren berører skjermen til en klikk-event sendes. Årsaken er at browseren venter på et evt. dobbelklikk, som brukes hvis man vil zoome inn på en bestemt del av siden.

Denne forsinkelsen får man ikke fjernet, men man kan velge å lytte til touchstart-eventen, heller enn click-eventen.

Det finnes forskjellige script som mener å løse problemet, men de fleste har mangler. Ulempen er at det i browsere på enheter uten touch-skjerm ikke fyres touchstart, bare click. Man trenger dermed en fallback i disse tilfellene. Man kan likevel ikke lytte til begge eventene på én gang, fordi Safari på iOS fyrer både touchstart og click (etter 300 ms), og man får da dobbelt opp. Først touchstart, og så click 300 ms senere. Hvis man rekker å endre til en ny side innen de 300 ms, havner click-eventen på den nye sida, heller enn på den opprinnelige knappen/lenka, og ting begynner å skje av seg selv. Veeeldig frustrerende å debugge.

Heldigvis løser  jQuery.tappable plugin problemet rimelig greit. Android 2.1 hadde problem med at klikkene døde med mindre man var veldig lett på fingeren, fordi den trodde fingeren hadde flyttet seg mellom touchstart og touchend. Jeg løste det ved å hacke inn en buffersone på noen få piksler rundt berøringsstedet. Jeg la også til min egen tap-event, som jeg kunne trigge for å simulere en berøring eller et klikk – avhengig av hvilken enhet brukeren hadde.

$('#backButton').tappable(function(){
    history.back();
});

Siste rest av weben

Markering av valgt elementFremdeles er det småting som avslører web vs. native app, f.eks. markeringen/outline browseren legger på områdene man berører/klikker, samt klipp-lime-funksjonen. Dette løser man enkelt i CSS.

/* Ingen klipp-lim */
-webkit-user-select: none;
/* Ingen popups på siden */
-webkit-touch-callout: none;
/* Ingen markering av "berørt" område */
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
/* Ingen automatisk tekstskalering */
-webkit-text-size-adjust: 100%;

/* Hvis man er dristig kan man fjerne outline på lenker/knapper osv også */
input[type=submit],
button,
a.knapp {
    outline: none;
}

Det siste avslørende momentet overshoot på scrolling, altså at man kan trekke siden opp/ned og få en gummistrikkeffekt om der ikke er mer innhold å vise. Det kan skrus av ved å fikle med touchmove-eventen, men siden jeg ønsker å ha rulling på siden likevel (pga. lange lister) har jeg ikke tatt meg bryet med å ordne en «fast» side.

Installering

Maseboble (Cubiq-versjonen) På iPhone/iPad er det veldig enkelt å «installere» en webapp. Alt man trenger gjøre er å legge til et bokmerke på hjem-skjermen, og vips får man et pent ikon med runde kanter og gloss. (Gitt at man har fulgt oppskriften over). Når man starter webappen derfra forsvinner verktøylinjene og appen vises i fullskjerm-/webappmodus. På Android må man først lage et bokmerke, og deretter plassere bokmerket på hjem-skjermen. Litt mer omstendelig, men man oppnår også da et pent ikon. Splash og fullskjermmodus må man dog være foruten.

Hvis man ønsker/tør å plage brukerne en ekstra gang for å få dem til å «installere» (dvs. bokmerke) appen, kan man legge til en «maseboble» (annen variant) som spretter opp og ber brukeren om å legge til et bokmerke.

Jeg brukte Googles variant i starten, men bestemte meg for å fjerne den i tilfelle den var til bry og irritasjon.

Da skulle basiskunnskapen være på plass for å lage en god og rask webapp, som det vil kreve et trent øye for å skille fra en native app.

Soting av vinduer i Avensisen

Jeg har lenge hatt lyst på mørke vinduer i bilen. Ikke rånesort, men halvgjennomsiktige elegante. Etter å ha fått tilbud om ferdiglagt solfilm for 5000 kr hos Riis Bilglass på Lade (og beskjed om at de ikke solgte metervare), kjørte jeg til Stjørdal og kjøpte noen meter der i stedet. 300 kr kosta det. Litt billigere altså. En hjelpsom kar hjalp meg å velge riktig type. Jeg la solfilm på Almeraen selv også, så følte meg rimelig selvsikker på at jeg kom til å få det til. Man trenger i grunn bare å være nøyaktig i planlegging og arbeid, så går det nesten ikke an å gjøre feil.

Folien åpnes for å komme til skruene

Folien åpnes for å komme til skruene

Fire vinduer ferdige

Fire vinduer ferdige

Vinduene i passasjerdørene bak er det enkleste. De plukket jeg ut for å få lagt filmen helt inni vinduskarmene i døra. Resultatet blir penest da. Sidevinduene i bagasjerommet var litt verre. De kan ikke tas ut, og panelene ligger helt inntil glasset. Siden filmen monteres ved at man spryter Zalovann på glasset, legger filmen på, og presser vannet ut med en nal, ville det blitt et fryktelig søl inni veggene om jeg bare satte i gang å jobbe. Etter å ha klødd meg i hodet noen dager bestemte jeg meg for at alt måtte ut.

En del av panelene satt bare fast med plaststifter, andre steder måtte det skrus. Det er viktig å demontere (og montere igjen) i riktig rekkefølge, ellers blir det fort vanskelig å finne skruhullene 🙂 Det tok noen timer, men det ble pent til slutt.

Remonteringen starter

Remonteringen starter

Resultatet fra utsiden

Resultatet fra utsiden

Så gjenstår bare bakluka, men der regner jeg med jeg må ha proffhjelp.

[picasaView album=»SotingAvVinduer» instantView=»true»]