Difference between revisions of "Laadpunt"

From RevSpace
Jump to navigation Jump to search
(Doorduino "Chargeduino")
(Spelling)
 
(One intermediate revision by the same user not shown)
Line 95: Line 95:
 
=== Mod hardware ===
 
=== Mod hardware ===
 
Ik heb een gen 1. Pi model B, die op de ethernetpoort van de Keba kan. De Pi kan zo de statistieken van de energielevering opvragen (http get) en/of bijhouden (UDP luisteren).
 
Ik heb een gen 1. Pi model B, die op de ethernetpoort van de Keba kan. De Pi kan zo de statistieken van de energielevering opvragen (http get) en/of bijhouden (UDP luisteren).
Momenteel gaat het niet mogelijk worden automatisch af te rekenen via de bar, omdat de bar niet de verkoop van een voorgeprogrammeerd item ("lollie", "Club-Mate", "kWh" etc.) in fracties ondersteunt (er is nooit een reden geweest om 2,368 Club-Mate te kunnen verkopen, obviously). Initieel zal het afgekeken waarschijnlijk periodiek, handmatig gaan d.m.v. een "take [ammount] [reason]" operatie op de bar. De Pi zal initieel de lijst met opgenomen kWh's per gebruiker dus zelf vast houden.
+
Momenteel gaat het niet mogelijk worden automatisch af te rekenen via de bar, omdat de bar niet de verkoop van een voorgeprogrammeerd item ("lollie", "Club-Mate", "kWh" etc.) in fracties ondersteunt (er is nooit een reden geweest om 2,368 Club-Mate te kunnen verkopen, obviously). Initieel zal het afrekenen waarschijnlijk periodiek, handmatig gaan d.m.v. een "take [ammount] [reason]" operatie op de bar. De Pi zal initieel de lijst met opgenomen kWh's per gebruiker dus zelf vast houden.
 
De Pi moet ook updates naar IRC kunnen sturen (vergelijkbaar met deuren in de space die geopend worden). Voor het uitlezen van iButtons wordt gebruik gemaakt van een gemodificeerde Doorduino. Het onderbreken van de CP pin zal worden gedaan met een relais aangesloten op de Doorduino.
 
De Pi moet ook updates naar IRC kunnen sturen (vergelijkbaar met deuren in de space die geopend worden). Voor het uitlezen van iButtons wordt gebruik gemaakt van een gemodificeerde Doorduino. Het onderbreken van de CP pin zal worden gedaan met een relais aangesloten op de Doorduino.
  
Line 114: Line 114:
 
Authorisatie wordt dus geheel aan de software op de Pi overgelaten. De Arduino is enkel de interface. Elke staat heeft ook een eigen kleurtje van de led in de iButton lezer socket.<br>
 
Authorisatie wordt dus geheel aan de software op de Pi overgelaten. De Arduino is enkel de interface. Elke staat heeft ook een eigen kleurtje van de led in de iButton lezer socket.<br>
 
De code staat aan het eind van de pagina.
 
De code staat aan het eind van de pagina.
 +
 +
== Code ==
 +
=== Authoduino ===
 +
Dit is begonnen als Doorduino code, maar is inmiddels wat over-engineered voor de laadpunt usecase. Het is vooral het concept van de Doorduino code wat nog over is, daadwerkelijke implementatie is best anders inmiddels.<br>
 +
<br>
 +
Zie: https://github.com/merethan/authoduino
  
 
== Reverse-engineering ==
 
== Reverse-engineering ==
Line 121: Line 127:
 
* lwIP (lightweight IP) TCP/IP stack
 
* lwIP (lightweight IP) TCP/IP stack
 
* Contiki als OS?
 
* Contiki als OS?
 
== Code ==
 
Komt later op Github ofzo, maar voorlopig staat het (ook) hier.
 
 
=== Doorduino "Chargeduino" ===
 
Dit is begonnen als Doorduino code, maar is inmiddels wat over-engineered voor de laadpunt usecase.
 
 
<pre>
 
#include <OneWire.h>
 
 
// Board layout (Doorduino)
 
#define PIN_LED_GREEN 13
 
#define PIN_LED_RED  12
 
#define PIN_RELAY    11
 
#define PIN_1WIRE    10
 
#define PIN_BUTTON    9
 
 
#define OFF    0 // Undefined state (or off/broken, obviously)
 
#define GREEN  1 // Charging available
 
#define RED    2 // Stuff b0rked
 
#define YELLOW (GREEN | RED) // Yellow means ready for auth (same as Doorduino)
 
 
#define INIT_DELAY 500              // Delay after all setup operations
 
#define LED_BLINK_INTERVAL 2000    // Be nice, blink to people/robots/ghosts/other things passing by
 
#define LED_BLINK_TIME 120          // Each fancy led blink last this much miliseconds
 
#define BUTTON_INTERVAL_TIME 3000  // After an iButton has been read, no read operation for this much miliseconds
 
#define ABANDONED_TIME 30000        // Max interval between serial messages before Arduino considers the managing device down
 
#define ABANDONED_MSG_INTERVAL 5000 // The interval between each message send over serial, when in the ABANDONED state
 
 
OneWire ds(PIN_1WIRE); // Dallas 1-Wire bus
 
 
enum Command {
 
  NONE,    // No command received
 
  ENABLE,  // Manager says user/customer is authorized
 
  DISABLE, // Manager says user/customer not authorized
 
  PING    // Sign of life
 
};
 
 
static enum State {
 
  ABANDONED, // Arduino has not had contact with the managing device for too long, or is yet to receive the first message
 
  ENABLED,  // Charging is available to the user/customer
 
  DISABLED // No charging possible, ready for a new customer
 
} state;  // State the system is in
 
 
// These values are in miliseconds since start of program. Ulongs are 32 bits on arduino, which gets you
 
// up to 4.294.967.295 msec or just over 49 and a half days. So values that affect state need some guards for millis() overflowing back to zero
 
static unsigned long lastblink = 0; // Last time we did a nice blinky on the led
 
static unsigned long lastread = 0;  // Last time an iButton was read
 
static unsigned long keepalive = 0; // Last time a sign of life was received from the managing device (affects device state!)
 
static unsigned long lastmsg = 0;  // Last time we have send a message to the managing device (currently used to limit the abandoned message over serial rate)
 
 
void setup () {
 
  led(YELLOW); // Led test (if the reader is green or red during power-up, the other color is broken)
 
 
  Serial.begin(115200);  // Same as Doorduino
 
  Serial.println("INIT"); // Doorduino says "RESET", Chargeduino says "INIT"
 
  pinMode(PIN_LED_GREEN, OUTPUT);
 
  pinMode(PIN_LED_RED,  OUTPUT);
 
  pinMode(PIN_RELAY,    OUTPUT);
 
  pinMode(PIN_BUTTON,    INPUT); // Unused at this moment. TODO: Make a car explode on push
 
 
  state = ABANDONED; // When system initializes, nothing is possible until managing device has shown a sign of life
 
 
  delay(INIT_DELAY); // To make the led test effective (init is very fast)
 
}
 
 
void loop () {
 
  // Overflow protections regarding timing. Since millis() overflows back to zero
 
  // somewhere in the 49th day, some guard are required to prevent nutty behaviour
 
  if (millis() < keepalive) {
 
    keepalive = 0; // Overflow detected, reset keepalive
 
  }
 
  // The other timing-related values are not affecting state. If anything, a weird led flicker is kinda interesting so yeah whatever
 
 
  // Check for messages from the managing device
 
  Command mancmd = readSerial();
 
  switch (mancmd) {
 
    case ENABLE: {
 
        state = ENABLED;
 
        keepalive = millis();
 
        break;
 
      }
 
    case DISABLE: {
 
        state = DISABLED;
 
        keepalive = millis();
 
        break;
 
      }
 
    case PING: {
 
        keepalive = millis();
 
        break;
 
      }
 
  }
 
 
  // If there has been no input from the managing device, we consider ourselves abandoned.
 
  // First compare loops backwards to near max value first msecs of program operation, hence the second one
 
  if (millis() - ABANDONED_TIME > keepalive && millis() > ABANDONED_TIME) {
 
    state = ABANDONED;
 
  }
 
 
  // Read the one wire bus, see if there's a button
 
  if (state != ABANDONED) { // We only care about iButtons if there's a managing device present
 
    // First compare loops backwards to near max value first msecs of program operation, hence the second one
 
    if (millis() - BUTTON_INTERVAL_TIME > lastread && millis() > BUTTON_INTERVAL_TIME) {
 
      if (readButton()) {
 
        lastread = millis(); // A button was successfully read
 
      }
 
    }
 
  }
 
 
  // Allow or not allow charging, depending on what input has been given before
 
  switch (state) {
 
    case ENABLED: {
 
        digitalWrite(PIN_RELAY, HIGH); // By enabling the relay, the SAE J1772 CP-pin is enabled
 
        led(GREEN);
 
        break;
 
      }
 
    case DISABLED: {
 
        digitalWrite(PIN_RELAY, LOW); // By disabling the relay, the SAE J1772 CP-pin connection is cut
 
        led(YELLOW);
 
        break;
 
      }
 
    case ABANDONED: {
 
        digitalWrite(PIN_RELAY, LOW); // By disabling the relay, the SAE J1772 CP-pin connection is cut
 
        led(RED);
 
        if (millis() - ABANDONED_MSG_INTERVAL > lastmsg && millis() > ABANDONED_MSG_INTERVAL) {
 
          Serial.println("ABANDONED");
 
          lastmsg = millis();
 
        }
 
        break;
 
      }
 
  }
 
}
 
 
void led (byte color) {
 
  if (millis() - LED_BLINK_INTERVAL > lastblink && millis() > LED_BLINK_INTERVAL) {
 
    digitalWrite(PIN_LED_GREEN, 0);
 
    digitalWrite(PIN_LED_RED,  0);
 
    lastblink = millis();
 
  }
 
 
  if (millis() - LED_BLINK_TIME > lastblink) {
 
    digitalWrite(PIN_LED_GREEN, color & GREEN);
 
    digitalWrite(PIN_LED_RED,  color & RED);
 
  }
 
}
 
 
bool readButton() {
 
  byte id[8]; // ID of the iButton will be written into this variable by ds.search()
 
 
  if (ds.reset()) { // After a reset pulse, if one or more slave devices are on the bus, reset returns nonzero
 
    ds.reset_search(); // 1-Wire bus can have multiple slave devices. Reset next use of search() to start/first position
 
    if (ds.search(id)) { // Do a search until something is found, write the ID into id (stateful; next call returns next device). Returns nonzero if a new ID was written to id
 
      if (OneWire::crc8(id, 7) != id[7]) {
 
        return false; // If checksum fails, return
 
      }
 
      led(OFF);
 
      Serial.print("<");
 
      for (byte i = 0; i < 8; i++) { // Dump the found ID to serial out
 
        if (id[i] < 16) Serial.print("0");
 
        Serial.print(id[i], HEX);
 
      }
 
      Serial.println(">");
 
      return true;
 
    }
 
  }
 
 
  return false;
 
}
 
 
Command readSerial() {
 
  while (Serial.available()) {
 
    char c = Serial.read();
 
 
    if (c == 'E') { // Enable charging
 
      Serial.println("ENABLED");
 
      return ENABLE;
 
    }
 
    else if (c == 'D') {
 
      Serial.println("DISABLED");
 
      return DISABLE;
 
    }
 
    else if (c == 'P') { // Yo still there bro?
 
      Serial.println("PONG");
 
      return PING; // In this case, it means exactly the opposite
 
    }
 
  }
 
 
  return NONE;
 
}
 
</pre>
 

Latest revision as of 14:45, 9 September 2018

Project Laadpunt
Keba P20.jpg
Een laadpunt voor elektrische auto's @Revspace
Status In progress
Contact merethan
Last Update 2018-09-09

Er komen meer en meer elektrische auto's op de Nederlandse wegen. Een groot nadeel van deze voertuigen is dat accu's in vergelijking met een brandstoftank nog altijd wat beperkt zijn in hoeveel energie ze kunnen vasthouden. Om lekker rond te kunnen karren heb je dus wat vaker toegang nodig tot een stopcontact dan dat je een brandstof auto moet tanken. Niet alleen vaker, maar ook langer, want het laden duurt even.

Omdat het laden even duurt is het daarom handig een stopcontact te hebben op de plek waar je heen gaat. Terwijl je ergens bent kan je auto dan opladen. Revspace is zo'n plek waar ik regelmatig ben, maar tot nu toe geen "echt" laadpunt was.

Sinds september 2016 heb ik een Renault Twizy. Daar heb je eigenlijk geen "echt" laadpunt voor nodig, want hij laad slechts met 230VAC 10A (enkele fase). Er zit dan ook een doodnormale Schuko stekker aan, en niet de in Europa voor auto's bekende Mennekes Type 2. Wanneer ik wat laag aan de acculading zat deed ik mijn Twizy dan ook via een normaal (geschikt) verlengsnoer opladen bij Revspace. Vanaf het begin waren er al geluiden dat dit problemen kon gaan geven omdat het niet echt als "fair use" te verkopen valt aan de partij waarvan Revspace het pand van huurt. Maar gezien de Twizy niet een "echte" auto was en ik het niet heel vaak deed, werd een oogje toe geknepen.

Sinds ergens begin 2018 heeft mux echter ook een elektrische kar, namelijk een 1st gen. Nissan Leaf (binnenkort met extra 18650's uitgerust, I kid you not). Toen die ook kwam laden was de pand eigenaar "not amused". Nu er meer en ook grotere rijdende accu's Revspace aandoen, hebben we dus een "echt" laadpunt nodig, die stroom per "klant" afrekent; gezien het significante stroomverbruik tijdens het laden van voertuigen kan dit niet meer onder de elektra fair use policy van de rest van de space geschaard worden.

Het laadpunt

Momenteel zijn er twee laadpunten in bouw. Mux heeft er voor gekozen allerhande spulletjes uit China over te laten komen, en uit componenten zelf iets te fabriceren. Ik (merethan) heb er voor gekozen naar een tweede hands of kapotte op zoek te gaan, en die net zo lang te hacken tot het doet wat ik wil. Ik heb wat rond gezocht en gemaild, waarna ik reactie van laadpunt.nl heb gekregen. Die hadden nog een ingeruilde liggen, die ik voor een relatief zacht prijsje mocht overnemen, mits ik er ook echt wat boeiends mee ging doen. Dank aan laadpunt.nl daarvoor.

Keba P20

De Keba P20 gekocht door merethan

Het apparaat betreft een Keba KeContact P20. Hij heeft reeds ruim 2 jaar dienst gedaan bij de vorige eigenaar. De vorige eigenaar heeft 'em ingeruild voor een nieuwer en geavanceerder model, naar verluid omdat hij/zij meer management opties wilde.

Keba AG

Keba AG. is een Oostenrijks bedrijf wat actief is in meerdere markten. Voor ze laadpalen zijn gaan maken deden ze al allerhande andere automatisering, waaronder machines voor plastic gieten, metaalbewerking, kluisjessystemen en bankautomaten (flappentappen & contant deposit).

Specs & features

De Keba P20 geopend

Het volledige modelnummer is: KC-P20-ES240010-00R. De installatiehandleiding bevat een handig tabelletje om dat te decoderen. Het komt neer op het volgende: KeContact, model P20, Europese uitvoering, met een Socket (ipv vaste kabel), 2 = Mennekes Type-2, 4 = 32A versie, 00 = 0 meter kabel (duh..), 1 = b-series model, 0 = "Contactor electrics" (wut??), 00R = met RFID uitgevoerd.

Het betreft dus, gezien het 3-fase 230V op 32A is, een 22kW laadpunt.

Installatie

Het apparaat moet upstream afgezekerd worden met een automaat die bij de specs van de bekabeling past en een eigen aardlekschakelaar. Ook moet het maximale laadvermogen dmv DIP-switches ingesteld worden, zodat de paal dit kan communiceren aan de auto.

Interfaces

Het apparaat heeft meerdere interfaces via welke het interactie heeft met de rest van de wereld.

Mennekes Type 2 plug met SAE J1772 signallering

De meest elementaire interface aan het laadpunt is het stopcontact voor de auto: De Mennekes Type 2 connector. Deze bevat naast een PE, N, L1, L2 en L3 (de pinnen die je kent van krachtstroom) ook nog de pinnen PP (proximity pilot) en CP (control pilot). Via PP en CP communiceren de auto, de kabel en het laadsysteem hoeveel vermogen er getrokken mag worden. De logica hierachter is echt heel low-tech en niet uniek voor deze plug. Het "protocol" is namelijk overgenomen van een andere standaard: De Japans/Amerikaanse SAE J1772 plug.

Via de PP pin laat de kabel (de stekker eigenlijk) weten voor hoeveel ampère de kabel geschikt is. Dit werkt zeer low-tech: Een bepaalde weerstand tussen de +12V PP pin en de PE pin codeert van welke klasse de kabel is. Via deze pin kan zowel de auto als het laadstation dus ook detecteren wanneer er een kabel ingeplugd is. De PP pin is ook korter dan de andere pinnen, zodat het laadstation of de auto de stroom kan afschakelen voordat de rest van de pinnen contact verliezen (dit om vonken te voorkomen). De PP pin is niet van de ene naar de andere kant van de kabel verbonden.

De CP pin is wel verbonden door de kabel heen, wat de auto en het laadpunt in staat stelt om te communiceren met elkaar. Again, dit werkt zeer low-tech: Het laadpunt zet een square-wave van ±12V (-12V tot +12V) op de CP pin, met een frequentie van 1Khz. Als de PWM 1Khz. is betekent dat dat de auto "vol vermogen" mag trekken. Hoe lager de frequentie, hoe minder amps de auto mag trekken. Online zijn tabellen te vinden van welke PWM cycle hoeveel ampères betekent.

De CP pin is aan de auto kant verbonden met de PE pin via een weerstand en een diode. Omdat maar de helft van de ±12V square-wave afgevlakt wordt (diode) weet het laadstation dat het snoer ook echt in een auto zit en niet in de regen ligt. De weerstand die de auto tussen CP en PE plaatst codeert verschillende "staten" waarin de auto zich bevind. Zo is er bijvoorbeeld een specifieke weerstand waarmee de auto aan het laadsation aangeeft dat hij wil gaan laden. Online zijn tabellen te vinden met welke weerstand welke staat codeert.

Meer diepgaande uitleg en tabellen van coderingen is op Wikipedia te vinden.

Voor de duidelijkheid: Het laadpunt is enkel een circuit breaker. Het laadpunt doet niets in de trand van power duty cycle regeling. Als de auto meer amps trekt dan het door het laadpunt opgegeven maximum, doet het laadpunt de stroom gewoon uit.

GreenPhy protocol

Het laadstation ondersteunt ook PLC (Power Line Communication) met de auto dmv het GreenPhy protocol. Voor wat ik er nu van begrijp stelt dat de auto in staat om via de AC kabels op 10mbit te communiceren met het LAN waar het laadpunt aan vast zit. Zeer vergelijkbaar met "power line ethernet" wat je binnen je huis kunt doen, als je te lui bent om kabels te trekken.

RFID

Bijna alle laadstations hebben een methode voor authorisatie/authenticatie. Het authorisatie/authenticatiesysteem van het door mij gekochte model werkt op basis van RFID tokens. RFID functionaliteit wordt verzorgd door een ddm Hopt+Schuler 881 module (datasheet). Deze reader is compatible met Mifare/ISO14443/ISO15693 tokens. Voor zover ik het systeem nu begrijp blaft de module gewoon het serienummer van de gepresenteerde token over een RS232 TTL lijn heen en dat is dan de sleutel.

Enable-input

Binnenin het laadstation zit een enable-input (terminal X1) voor interfacing met een ander systeem. Door deze terminal kort te sluiten is het systeem "enabled". Hierin slaat "enabled" niet op authorisatie: Deze input schakelt het laden aan of uit, maar voorkomt aankoppelen niet. Dus als de enable-input onderbroken (uit) is, en iemand koppelt een kabel/auto aan, dan wordt die wel gelocked en begint initialisatie van het laadproces. Laden (stroom leveren) begint echter pas als je X1 kortsluit. (Dat zou je bijvoorbeeld kunnen gebruiken icm een zonnepanelen systeem, zodat je enkel overcapaciteit in je auto laad.) De enable-input is dus geen access control systeem of te gebruiken om een access control systeem op aan te sluiten.

Ethernet

De Keba P20 heeft een ethernetpoortje (terminal X3). De IP instellingen zijn (zeer beperkt) te regelen met de DIP-switches. Momenteel gebruikt het apparaat 192.168.25.11 als adres.

UDP input

Keba laadpunten ondersteunen volgens de UDP programmers manual een setje commando's die je via ethernet kunt sturen. Dit zijn simpele tekst-gebaseerde commando's over UDP, op poort 7090. Open een shell met 'netcat -l -p 7090 -u -b 192.168.25.11 7090' om te luisteren, ga in een andere shell commando's sturen met 'echo -n "[command]" | netcat -q 0 -u 192.168.25.11 7090', en je bent in business.

De door mij gekochte versie is echter het instapmodel, en ondersteunt daarom vrijwel niks van wat in de UDP manual van Keba staat. Dit is waarschijnlijk slechts een upselling scheme wat enkel in de software verankerd is, maar voor nu even waar we het mee moeten doen. De enige commando's waar mijn model zover op gereageerd heeft is i, waarop hij antwoord met "Firmware: KEBA P20 v 2.5a3 (160613-061001)", en report 1, waarop je iets meer info terug krijgt (ook serienummer & modelnummer). En dat was het.

UDP output

De ethernetpoort is niet geheel waardeloos, want hij doet wel nuttige UDP broadcasts. Bij elke status verandering doet hij een bijpassende broadcast met de veranderde waarden. Denk aan de toestand van het apparaat (wachten/aankoppelen/laden etc.), het koppelen/ontkoppelen van de kabel en/of auto, wanneer er authorisatie is (RFID/UDP), enable input (X1) open/dicht, en een verandering in hoeveelheid geleverde energie. Zie de UDP programmers guide van Keba voor een overzicht & uitleg.

Hij gaat overigens pas broadcasts sturen nadat je tegen hem gepraat heb. Het is net een dronkenlap in een bar: Je moet even één vraag stellen maar daarna houd hij niet meer op met praten.

HTTP

Op poort 80 zit een webserver, die een pagina serveert waar wat statistieken op staan vergelijkbaar met wat via UDP broadcasts gepubliceert wordt.

OCPP

Het apparaat lijkt iets van "communication hub mode" ofzo met een KeContact C10 communication hub te kunnen via OCPP. Geen idee wat het precies is, maar wellicht het onderzoeken waard. Het lijkt iets te zijn waarbij je "intelligent" energie kunt verdelen, indien je een systeem heb met meerdere van deze laadstations.

Interfacing met de space

Wat ik wil maken is dat elke deelnemer zich met zijn/haar Secure_iButton kan authenticeren op het laadstation en dat de kosten voor de geleverde energie worden afgerekend via de bar. Er moet dus op een manier een iButton lezer in, en een interface naar de bar gemaakt worden. Ook lijkt het mij leuk om status updates te doen op het IRC kanaal, vergelijkbaar met deuren die geopend worden.

Mogelijke mods om iButton lezer te koppelen

Authenticatie bij de door mij gekochte uitvoering van het laadstation werkt door RFID-tags in te programmeren en die te gebruiken als sleutel. RFID wordt verzorgd door een losse module, die door een eigen stuk hardware te emuleren is. Hij zit via RS232 TTL vast aan de rest en heeft een manual, dus met wat logic analyzer magic, RTFM en blijven proberen moet dat wel te gebruiken zijn als aansluit interface voor eigen access control (stukje hardware wat iButtons kan lezen).

Keba palen kunnen hetgeen wat met RFID kaartjes kan ook via de ethernetpoort, als je genoeg geld neerlegt bij Keba. Het door mij gekochte model is echter de goedkope versie, die deze features "niet heeft" (ofwel het staat uit in de software). De afwezigheid van deze features is waarschijnlijk de reden geweest dat de vorige eigenaar dit laadstation heeft ingeruild voor een nieuwere/duurdere.

Zoals eerder genoemd bij de Enable-input sectie: Deze is niet te gebruiken voor authorisatie. Deze input is om het laden tijdelijk te onderbreken en weer verder te gaan met laden wanneer er weer zonlicht op de zonnepanelen valt.

Een andere mod die erg goed blijkt te werken is CP pin onderbreken. Wanneer de CP niet meer verbonden is met de PE pin stopt de software het laden en wordt de stekker ontgrendeld. Bij inpluggen (PP wordt dan met PE verbonden) wordt de stekker wel altijd vergrendeld, maar als er geen laadoperatie gestart wordt in ~30 sec. gaat hij alsnog weer los. Ook als de stekker al los is gegaan door de timeout kan alsnog een laadsessie gestart worden door de CP pin weer te verbinden (de stekker vergrendeld dan weer). Dit tezamen met een lege ACL in de Keba hardware en een relais lijkt de ideale hack om een eigen authorisatie/authenticatiesysteem in te bouwen.

Voor verbruiksstatistieken en status updates naar IRC zijn de UDP broadcasts op de ethernet poort bruikbaar. Voor de meest actuele verbruiksstand kan ook de output van de webserver gebruikt worden.

Mod hardware

Ik heb een gen 1. Pi model B, die op de ethernetpoort van de Keba kan. De Pi kan zo de statistieken van de energielevering opvragen (http get) en/of bijhouden (UDP luisteren). Momenteel gaat het niet mogelijk worden automatisch af te rekenen via de bar, omdat de bar niet de verkoop van een voorgeprogrammeerd item ("lollie", "Club-Mate", "kWh" etc.) in fracties ondersteunt (er is nooit een reden geweest om 2,368 Club-Mate te kunnen verkopen, obviously). Initieel zal het afrekenen waarschijnlijk periodiek, handmatig gaan d.m.v. een "take [ammount] [reason]" operatie op de bar. De Pi zal initieel de lijst met opgenomen kWh's per gebruiker dus zelf vast houden. De Pi moet ook updates naar IRC kunnen sturen (vergelijkbaar met deuren in de space die geopend worden). Voor het uitlezen van iButtons wordt gebruik gemaakt van een gemodificeerde Doorduino. Het onderbreken van de CP pin zal worden gedaan met een relais aangesloten op de Doorduino.

Raspberry Pi

Softwares? Hoe de boel te scripten danwel programmeren in een daemon?

iButton lezer

Het is gestart als Doorduino code, maar inmiddels zoveel werk ondergaan dat de routine die hij doorloopt niet meer herkenbaar is.
Wat het doet, is het volgende:

* Het serienummer van de iButton over serial sturen wanneer er eentje wordt aangeboden op de lezer
* Laden toestaan op commando van de Pi
* Laden niet langer toestaan op commando van de Pi
* De huidige staat vast houden zo lang er ping berichten worden ontvangen
* Bij verlies verbinding met Pi (te lang geen ping of ander commando), laden niet langer toestaan ("abandoned mode", error mode in feite)
* Enige manier om uit abandoned mode te komen is als managing device (Pi) het commando laden toestaan of laden niet toestaan stuurt. Een ping veranderd de staat niet

Authorisatie wordt dus geheel aan de software op de Pi overgelaten. De Arduino is enkel de interface. Elke staat heeft ook een eigen kleurtje van de led in de iButton lezer socket.
De code staat aan het eind van de pagina.

Code

Authoduino

Dit is begonnen als Doorduino code, maar is inmiddels wat over-engineered voor de laadpunt usecase. Het is vooral het concept van de Doorduino code wat nog over is, daadwerkelijke implementatie is best anders inmiddels.

Zie: https://github.com/merethan/authoduino

Reverse-engineering

Initieel ligt de focus op het realiseren van een laadpunt. Later gaan we de hardware en software nog reverse-engineeren. Voor shits & giggles, en wie weet wat er allemaal nog mogelijk blijkt (hint: die UDP aansturingsfeatures zijn wel leuk om te hebben).

Paar losse flarden info:

  • lwIP (lightweight IP) TCP/IP stack
  • Contiki als OS?